What's new
  • Visit Rebornbuddy
  • Visit Panda Profiles
  • Visit LLamamMagic
  • Visit Resources
  • Visit Downloads
  • Visit Portal

[beta] compatible Gem Leveler

Status
Not open for further replies.

buddyfu

New Member
Joined
Aug 27, 2014
Messages
24
Reaction score
0
I've updated to old gem leveler to be compatible with the new API. All the logic remains the same. The only difference is that you will see your inventory window opening when comes the time to level up a gem.

TJPl4rf.jpg


Create a new folder called GemLeveler inside {your Exilebuddy folder}/plugins/

Inside this folder, create these files:

ConfigWindow.cs
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Loki.Game;
using Loki.Game.Inventory;
using Loki.Game.Objects.Items;
using Loki.Game.GameData;
using Loki.Game.Objects;

namespace GemLeveler
{
    public partial class ConfigWindow : Form
    {
        public ConfigWindow()
        {
            InitializeComponent();

            ReloadAllGems();

            dataGridView1.DataSource = GemLevelerSettings.Instance.EnabledGems;
        }

        private void ReloadAllGems()
        {
            using (LokiPoe.AcquireFrame())
            {
                // Only allow this if we've cleared the list.
                if (GemLevelerSettings.Instance.EnabledGems.Count != 0)
                    return;

                IEnumerable<Inventory> inventories = GemLeveler.UsableInventories;

                foreach (Inventory inv in inventories)
                {
                    InventoryType type = inv.PageType;

                    Item item = inv.Items.FirstOrDefault();
                    // Either nothing equipped, or a 2H + nothing combo
                    if (item == null)
                    {
                        continue;
                    }

                    var socketedItem = item as SocketableItem;

                    // Quivers and whatnot
                    if (socketedItem == null)
                    {
                        continue;
                    }

                    foreach (SkillGem gem in socketedItem.SocketedGems)
                    {
                        if (gem == null)
                            continue;

                        var g = new GemLevelerSettings.EnabledGem {PageType = type, GemName = gem.Name, Enabled = true};
                        GemLevelerSettings.Instance.EnabledGems.Add(g);
                    }
                }

                GemLevelerSettings.Instance.Save();
            }
        }

        private void HandleReloadAllGemsButtonClick(object sender, EventArgs e)
        {
            dataGridView1.DataSource = null;
            // Clear the list first, then reload the known gems
            GemLevelerSettings.Instance.EnabledGems.Clear();
            ReloadAllGems();
            dataGridView1.DataSource = GemLevelerSettings.Instance.EnabledGems;
        }
    }
}

ConfigWindow.Designer.cs
Code:
namespace GemLeveler
{
    partial class ConfigWindow
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.label1 = new System.Windows.Forms.Label();
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.label2 = new System.Windows.Forms.Label();
            this.dataGridView1 = new System.Windows.Forms.DataGridView();
            this.enabledGemBindingSource = new System.Windows.Forms.BindingSource(this.components);
            this.button1 = new System.Windows.Forms.Button();
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.enabledGemBindingSource)).BeginInit();
            this.SuspendLayout();
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(12, 9);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(113, 13);
            this.label1.TabIndex = 0;
            this.label1.Text = "Globally Ignored Gems";
            // 
            // textBox1
            // 
            this.textBox1.Location = new System.Drawing.Point(12, 25);
            this.textBox1.Multiline = true;
            this.textBox1.Name = "textBox1";
            this.textBox1.Size = new System.Drawing.Size(187, 341);
            this.textBox1.TabIndex = 1;
            // 
            // label2
            // 
            this.label2.AutoSize = true;
            this.label2.Location = new System.Drawing.Point(210, 9);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(137, 13);
            this.label2.TabIndex = 2;
            this.label2.Text = "Enabled by Socket && Name";
            // 
            // dataGridView1
            // 
            this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            this.dataGridView1.Location = new System.Drawing.Point(205, 25);
            this.dataGridView1.Name = "dataGridView1";
            this.dataGridView1.Size = new System.Drawing.Size(402, 341);
            this.dataGridView1.TabIndex = 3;
            // 
            // button1
            // 
            this.button1.Location = new System.Drawing.Point(497, 372);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(110, 23);
            this.button1.TabIndex = 4;
            this.button1.Text = "Reload all Gems";
            this.button1.UseVisualStyleBackColor = true;
            this.button1.Click += new System.EventHandler(this.HandleReloadAllGemsButtonClick);
            // 
            // ConfigWindow
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(619, 404);
            this.Controls.Add(this.button1);
            this.Controls.Add(this.dataGridView1);
            this.Controls.Add(this.label2);
            this.Controls.Add(this.textBox1);
            this.Controls.Add(this.label1);
            this.Name = "ConfigWindow";
            this.Text = "Gem Leveler Config";
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.enabledGemBindingSource)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.TextBox textBox1;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.DataGridView dataGridView1;
        private System.Windows.Forms.BindingSource enabledGemBindingSource;
        private System.Windows.Forms.Button button1;
    }
}

GemLeveler.cs
Code:
using System;
using System.Collections.Generic;
using System.Linq;

using log4net;

using Loki.Game;
using Loki.Game.Inventory;
using Loki.Game.Objects.Items;
using Loki.Utilities;
using Loki.Game.GameData;
using Loki.Bot;
using Loki.Game.Objects;
using System.Windows.Controls;
using System.IO;
using System.Windows.Markup;
using System.Windows;
using System.Threading.Tasks;
using System.Threading;

namespace GemLeveler
{
    public class GemLeveler : IPlugin
    {
        #region Implementation of IEquatable<IPlugin>

        /// <summary>
        ///     Indicates whether the current object is equal to another object of the same type.
        /// </summary>
        /// <returns>
        ///     true if the current object is equal to the <paramref name="other" /> parameter; otherwise, false.
        /// </returns>
        /// <param name="other">An object to compare with this object.</param>
        public bool Equals(IPlugin other)
        {
            return Name.Equals(other.Name);
        }

        #endregion

        private static readonly ILog Log = Logger.GetLoggerInstanceForType();
        private const bool DebugStatements = false;
        private readonly WaitTimer _levelWait = WaitTimer.FiveSeconds;
        private readonly Random _random = new Random();

        #region Implementation of IPlugin

        public string Author
        {
            get { return "Apoc"; }
        }

        public Version Version
        {
            get { return new Version(0, 1, 0, 0); }
        }

        public string Name
        {
            get { return "Gem Leveler"; }
        }

        public string Description
        {
            get { return "Levels gems as they become available for... leveling!"; }
        }

        /// <summary> Executes the pulse action. This is called every "tick" of the bot. </summary>
        public void Tick()
        {
            // We never want to update gems while stash is open, because we access all inventories, which causes
            // more stash pages to be requested than we want.
            if (LokiPoe.InGameState.StashPanel.IsOpened)
                return;

            // Sooo... yeah...
            // We basically only want to level a gem every couple of seconds.
            // Anywhere between 1 and 3 seconds seems fine.
            if (_levelWait.IsFinished)
            {
                _levelWait.Reset(TimeSpan.FromMilliseconds(_random.Next(1000, 3000)));
                LevelGems();
            }
        }

        /// <summary>Initializes this plugin.</summary>
        public void Initialize()
        {
            Log.DebugFormat("[GemLeveler] Initialize");
        }

        /// <summary> The plugin start callback. Do any initialization here. </summary>
        public void Start()
        {
            Log.DebugFormat("[GemLeveler] Start");
        }

        /// <summary> The plugin stop callback. Do any pre-dispose cleanup here. </summary>
        public void Stop()
        {
            Log.DebugFormat("[GemLeveler] Stop");
        }

        public JsonSettings Settings
        {
            get { return GemLevelerSettings.Instance; }
        }

        /// <summary> The routine's settings control. This will be added to the Exilebuddy Settings tab.</summary>
        public UserControl Control
        {
            get
            {
                using (var fs = new FileStream(@"Plugins\GemLeveler\SettingsGui.xaml", FileMode.Open))
                {
                    var root = (UserControl)XamlReader.Load(fs);

                    // Your settings binding here.

                    Button openWindowButton = (Button)LogicalTreeHelper.FindLogicalNode(root, "OpenGemLevelerButton");

                    if (openWindowButton == null)
                    {
                        Log.DebugFormat(
                            "[SettingsControl] SetupButtonBinding failed for 'OpenGemLevelerButton'.");
                        throw new Exception("The SettingsControl could not be created.");
                    }

                    openWindowButton.Click += openGemLevelerWindow;

                    // Your settings event handlers here.

                    return root;
                }
            }
        }

        public void openGemLevelerWindow(object sender, RoutedEventArgs e)
        {
            Log.DebugFormat("[GemLeveler] click OpenGemLevelerButton");
            ConfigWindow gemLevelerWindow = new ConfigWindow();
            gemLevelerWindow.Show();
        }

        /// <summary> The plugin is being enabled.</summary>
        public void OnEnable()
        {
            Log.DebugFormat("[GemLeveler] OnEnable");
        }

        /// <summary> The plugin is being disabled.</summary>
        public void OnDisable()
        {
            Log.DebugFormat("[GemLeveler] OnDisable");
        }

        #endregion

        #region Implementation of IDisposable

        /// <summary> </summary>
        public void Dispose()
        {
        }

        #endregion

        #region Override of Object

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return Name + ": " + Description;
        }

        #endregion

        public static IEnumerable<Inventory> UsableInventories
        {
            get
            {
                return new[]
                {
                    LokiPoe.InGameState.InventoryPanel.LeftHandInventory,
                    LokiPoe.InGameState.InventoryPanel.RightHandInventory,
                    LokiPoe.InGameState.InventoryPanel.OffLeftHandInventory,
                    LokiPoe.InGameState.InventoryPanel.OffRightHandInventory,
                    LokiPoe.InGameState.InventoryPanel.HeadInventory,
                    LokiPoe.InGameState.InventoryPanel.ChestInventory,
                    LokiPoe.InGameState.InventoryPanel.GlovesInventory,
                    LokiPoe.InGameState.InventoryPanel.BootsInventory,
                    LokiPoe.InGameState.InventoryPanel.LeftRingInventory,
                    LokiPoe.InGameState.InventoryPanel.RightRingInventory,
                };
            }
        }

        private void LevelGems()
        {
            var me = LokiPoe.ObjectManager.Me;

            // We need these stats for the "can level" checks.
            var myS = me.GetStat(StatType.Strength);
            var myD = me.GetStat(StatType.Dexterity);
            var myI = me.GetStat(StatType.Intelligence);
            var myL = me.Level;

            foreach (var Inventory in UsableInventories)
            {
                var pageType = Inventory.PageType;

                // Now, for each item, we need to check all the available skill gems.
                // There's a max of 6, so we can simply iterate 6 :)
                foreach (Item inventoryItem in Inventory.Items)
                {
                    if (inventoryItem == null)
                        continue;

                    // This is a base-class of Weapon and Armor. This is exactly why it was split!
                    var item = inventoryItem as SocketableItem;

                    if (item == null)
                    {
                        if (DebugStatements)
                        {
                            Log.Debug(inventoryItem.FullName +
                                      " is not socketable. Is this item a quiver or other non-socketable armor/weapon?");
                        }
                        continue;
                    }

                    var enabledGems =
                        GemLevelerSettings.Instance.EnabledGems.Where(s => s.PageType == pageType).ToList();

                    // Now, iterate the gems of the item... (There's always 6, but in case API changes to only provide 4 for gloves/boots, then we'll be safe)
                    for (int idx = 0; idx < item.SocketedGems.Length; idx++)
                    {
                        SkillGem gem = item.SocketedGems[idx];
                        // Not all sockets will have gems.
                        // So check the ones we actually care about.
                        // Thanks!
                        if (gem == null)
                        {
                            continue;
                        }

                        // Ignore any "globally ignored" gems. This just lets the user move gems around
                        // equipment, without having to worry about where or what it is.
                        if (GemLevelerSettings.Instance.IgnoredByNameGlobal.Contains(gem.Name))
                            continue;

                        // If our settings are disabled for the gem, ignore it.
                        // Check !Any() because if the gem isn't named, we don't want to level it, just in case.
                        // The user is responsible for making sure the gem is there, and enabled.
                        if (!enabledGems.Any(setting => setting.GemName == gem.Name && setting.Enabled))
                            continue;

                        // Srsly, ignore gems that aren't ready to be leveled.
                        if (gem.ExperiencePercent < 100)
                        {
                            continue;
                        }

                        if (gem.Experience == gem.ExperienceMaxLevel)
                        {
                            if (DebugStatements)
                            {
                                Log.Debug("I can't level up " + gem.Name + " because it is already at max level!");
                            }
                            continue;
                        }

                        // Now we just need to get the stats required for the next level.
                        int s, d, i, l;
                        gem.GetAttributeRequirements(out s, out d, out i, out l);

                        var canLevel = true;
                        if (myL < l)
                        {
                            canLevel = false;
                            if (DebugStatements)
                            {
                                Log.Debug("I'm not at the required level to level up " + gem.Name + "! (" + myL + "/" +
                                          l + ")");
                            }
                        }

                        if (myS < s)
                        {
                            canLevel = false;
                            if (DebugStatements)
                            {
                                Log.Debug("I don't have enough strength to level up " + gem.Name + "! (" + myS + "/" + s +
                                          ")");
                            }
                        }

                        if (myD < d)
                        {
                            canLevel = false;
                            if (DebugStatements)
                            {
                                Log.Debug("I don't have enough dexterity to level up " + gem.Name + "! (" + myD + "/" +
                                          d + ")");
                            }
                        }

                        if (myI < i)
                        {
                            canLevel = false;
                            if (DebugStatements)
                            {
                                Log.Debug("I don't have enough intelligence to level up " + gem.Name + "! (" + myI + "/" +
                                          i + ")");
                            }
                        }

                        if (canLevel)
                        {
                            string gemName = gem.Name;
                            Log.Debug("I can level up " + gemName + "!");

                            Loki.Bot.v3.Coroutines.OpenInventoryPanel();
                            LokiPoe.InGameState.InventoryPanel.LevelSkillGem(gem);
                            Loki.Bot.v3.Coroutines.CloseBlockingWindows();

                            Log.Debug(gemName + " has been leveled!");

                            // Wait before we level the next gem so we don't spam gem level ups.
                            return;
                        }
                    }
                }
            }
        }
    }
}

GemLevelerSettings.cs
Code:
using System;
using System.Collections.Generic;

using Loki.Game;
using Loki.Game.Inventory;
using Loki.Utilities;
using Loki.Game.NativeWrappers;
using Loki.Game.GameData;

namespace GemLeveler
{
    public class GemLevelerSettings : JsonSettings
    {
        private static GemLevelerSettings _instance;
        private List<EnabledGem> _enabledGems;
        private List<string> _ignoredByNameGlobal;

        // It's highly recommended that you use the "Plugins" path under the Character/League folders for any plugin configuration.
        // This will keep things organized on a per-character basis, and makes thing much easier to find for end-users.
        public GemLevelerSettings()
            : base(GetSettingsFilePath("Character", LokiPoe.InstanceInfo.League, LokiPoe.ObjectManager.Me.Name, "Plugins", "Gem Leveler", "Settings.json"))
        {
            if (EnabledGems == null)
            {
                EnabledGems = new List<EnabledGem>();
            }
            if (IgnoredByNameGlobal == null)
            {
                IgnoredByNameGlobal = new List<string>();
            }
        }

        public static GemLevelerSettings Instance
        {
            get { return _instance ?? (_instance = new GemLevelerSettings()); }
        }

        public List<string> IgnoredByNameGlobal
        {
            get { return _ignoredByNameGlobal; }
            set
            {
                if (Equals(value, _ignoredByNameGlobal))
                {
                    return;
                }
                _ignoredByNameGlobal = value;
                NotifyPropertyChanged(() => IgnoredByNameGlobal);
            }
        }

        public List<EnabledGem> EnabledGems
        {
            get { return _enabledGems; }
            set
            {
                if (Equals(value, _enabledGems))
                {
                    return;
                }
                _enabledGems = value;
                NotifyPropertyChanged(() => EnabledGems);
            }
        }

        public class EnabledGem : IEquatable<EnabledGem>
        {
            public InventoryType PageType { get; set; }

            public string GemName { get; set; }

            public bool Enabled { get; set; }

            #region Equality members

            /// <summary>
            ///     Indicates whether the current object is equal to another object of the same type.
            /// </summary>
            /// <returns>
            ///     true if the current object is equal to the <paramref name="other" /> parameter; otherwise, false.
            /// </returns>
            /// <param name="other">An object to compare with this object.</param>
            public bool Equals(EnabledGem other)
            {
                if (ReferenceEquals(null, other))
                {
                    return false;
                }
                if (ReferenceEquals(this, other))
                {
                    return true;
                }
                return PageType == other.PageType && string.Equals(GemName, other.GemName);
            }

            /// <summary>
            ///     Determines whether the specified <see cref="T:System.Object" /> is equal to the current
            ///     <see cref="T:System.Object" />.
            /// </summary>
            /// <returns>
            ///     true if the specified <see cref="T:System.Object" /> is equal to the current <see cref="T:System.Object" />;
            ///     otherwise, false.
            /// </returns>
            /// <param name="obj">The <see cref="T:System.Object" /> to compare with the current <see cref="T:System.Object" />. </param>
            public override bool Equals(object obj)
            {
                if (ReferenceEquals(null, obj))
                {
                    return false;
                }
                if (ReferenceEquals(this, obj))
                {
                    return true;
                }
                if (obj.GetType() != GetType())
                {
                    return false;
                }
                return Equals((EnabledGem) obj);
            }

            /// <summary>
            ///     Serves as a hash function for a particular type.
            /// </summary>
            /// <returns>
            ///     A hash code for the current <see cref="T:System.Object" />.
            /// </returns>
            public override int GetHashCode()
            {
                unchecked
                {
                    return ((int) PageType * 397) ^ (GemName != null ? GemName.GetHashCode() : 0);
                }
            }

            public static bool operator ==(EnabledGem left, EnabledGem right)
            {
                return Equals(left, right);
            }

            public static bool operator !=(EnabledGem left, EnabledGem right)
            {
                return !Equals(left, right);
            }

            #endregion
        }
    }
}

SettingsGui.xaml
Code:
<UserControl
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             mc:Ignorable="d">
  <Grid x:Name="Root">
        <Button x:Name="OpenGemLevelerButton" Height="30" Width="130">
            <Label>Open Gem Leveler</Label>
        </Button>
  </Grid>
</UserControl>

Report errors if you find some, I didn't test this too long.

Also, I would like feedback on this piece of code, at the very end of GemLeveler.cs. Is there a better way to proceed?
Code:
Loki.Bot.v3.Coroutines.OpenInventoryPanel();
LokiPoe.InGameState.InventoryPanel.LevelSkillGem(gem);
Loki.Bot.v3.Coroutines.CloseBlockingWindows();
 
Also, I would like feedback on this piece of code, at the very end of GemLeveler.cs. Is there a better way to proceed?
Code:
Loki.Bot.v3.Coroutines.OpenInventoryPanel();
LokiPoe.InGameState.InventoryPanel.LevelSkillGem(gem);
Loki.Bot.v3.Coroutines.CloseBlockingWindows();

This is exactly how you'd do it. :)

To level a skill gem outside the main hud, you have to open the inventory panel, and click the skill gem you want to level, and then close the inventory panel. The API doesn't have the ability to close individual windows yet, but it's something I'd eventually like to get added.

The reason you don't handle leveling skill gems from the HUD, is just because it'd be extra work, and if the user already has gems hidden due to level requirmentts, it would miss leveling up those gems. As a result, doing it though the inventory panel handles all cases.

When you use LevelSkillGem, you should process the return value, and at least output the error if it's not LevelSkillGemError.None. There are cases where you can't level skillgems, and the API will detect them and return an error. In doing so, you can add extra logic checks to make sure you don't try leveling them at the wrong time. I've not read over all your code yet, but basically, I'd say just level them outside of town, so you don't have to worry about the in town cases.
 
is it supposed to be

ConfigWindow.Designer.cs or ConfigWindowDesigner.cs ?
 
Works, will be testing. thanks for the upload buddyfu
 
the plugin is broken with the new .903

Current routine set to ExampleRoutine.
Compiler Error: c:\Users\*\Downloads\ExilebuddyBETA 0.1.2693.903\Plugins\GemLeveler\GemLeveler.cs(23,18) : error CS0535: 'GemLeveler.GemLeveler' implementerer ikke grænseflademedlemmet 'Loki.Bot.IEnableable.Enable()'
Compiler Error: c:\Users\*\Downloads\ExilebuddyBETA 0.1.2693.903\Plugins\GemLeveler\GemLeveler.cs(23,18) : error CS0535: 'GemLeveler.GemLeveler' implementerer ikke grænseflademedlemmet 'Loki.Bot.IEnableable.Disable()'
Compiler Error: c:\Users\*\Downloads\ExilebuddyBETA 0.1.2693.903\Plugins\GemLeveler\GemLeveler.cs(23,18) : error CS0535: 'GemLeveler.GemLeveler' implementerer ikke grænseflademedlemmet 'Loki.Bot.IEnableable.IsEnabled'

[AutoFlask] Initialize
 
Last edited:
it's probably something to do with the gui being removed.

Edit it's this from changelog.

IPlugin interface updated so plugins maintain their own enabled status. Plugins are expected to adhere to the design.


Sec, i'll see if I can update it.

Edit Again, Ok Change GemLeveler.cs to this

Code:
using System;
using System.Collections.Generic;
using System.Linq;

using log4net;

using Loki.Game;
using Loki.Game.Inventory;
using Loki.Game.Objects.Items;
using Loki.Utilities;
using Loki.Game.GameData;
using Loki.Bot;
using Loki.Game.Objects;
using System.Windows.Controls;
using System.IO;
using System.Windows.Markup;
using System.Windows;
using System.Threading.Tasks;
using System.Threading;

namespace GemLeveler
{
    public class GemLeveler : IPlugin
    {
        #region Implementation of IEquatable<IPlugin>

        /// <summary>
        ///     Indicates whether the current object is equal to another object of the same type.
        /// </summary>
        /// <returns>
        ///     true if the current object is equal to the <paramref name="other" /> parameter; otherwise, false.
        /// </returns>
        /// <param name="other">An object to compare with this object.</param>
        public bool Equals(IPlugin other)
        {
            return Name.Equals(other.Name);
        }

        #endregion

        private static readonly ILog Log = Logger.GetLoggerInstanceForType();
        private const bool DebugStatements = false;
        private readonly WaitTimer _levelWait = WaitTimer.FiveSeconds;
        private readonly Random _random = new Random();
        private bool _enabled;
        #region Implementation of IPlugin

        public string Author
        {
            get { return "Apoc"; }
        }

        public Version Version
        {
            get { return new Version(0, 1, 0, 0); }
        }

        public string Name
        {
            get { return "Gem Leveler"; }
        }

        public string Description
        {
            get { return "Levels gems as they become available for... leveling!"; }
        }

        /// <summary> Executes the pulse action. This is called every "tick" of the bot. </summary>
        public void Tick()
        {
            // We never want to update gems while stash is open, because we access all inventories, which causes
            // more stash pages to be requested than we want.
            if (LokiPoe.InGameState.StashPanel.IsOpened)
                return;

            // Sooo... yeah...
            // We basically only want to level a gem every couple of seconds.
            // Anywhere between 1 and 3 seconds seems fine.
            if (_levelWait.IsFinished)
            {
                _levelWait.Reset(TimeSpan.FromMilliseconds(_random.Next(1000, 3000)));
                LevelGems();
            }
        }

        /// <summary>Initializes this plugin.</summary>
        public void Initialize()
        {
            Log.DebugFormat("[GemLeveler] Initialize");
        }

        /// <summary> The plugin start callback. Do any initialization here. </summary>
        public void Start()
        {
            Log.DebugFormat("[GemLeveler] Start");
        }

        /// <summary> The plugin stop callback. Do any pre-dispose cleanup here. </summary>
        public void Stop()
        {
            Log.DebugFormat("[GemLeveler] Stop");
        }

        public JsonSettings Settings
        {
            get { return GemLevelerSettings.Instance; }
        }

        /// <summary> The routine's settings control. This will be added to the Exilebuddy Settings tab.</summary>
        public UserControl Control
        {
            get
            {
                using (var fs = new FileStream(@"Plugins\GemLeveler\SettingsGui.xaml", FileMode.Open))
                {
                    var root = (UserControl)XamlReader.Load(fs);

                    // Your settings binding here.

                    Button openWindowButton = (Button)LogicalTreeHelper.FindLogicalNode(root, "OpenGemLevelerButton");

                    if (openWindowButton == null)
                    {
                        Log.DebugFormat(
                            "[SettingsControl] SetupButtonBinding failed for 'OpenGemLevelerButton'.");
                        throw new Exception("The SettingsControl could not be created.");
                    }

                    openWindowButton.Click += openGemLevelerWindow;

                    // Your settings event handlers here.

                    return root;
                }
            }
        }

        public void openGemLevelerWindow(object sender, RoutedEventArgs e)
        {
            Log.DebugFormat("[GemLeveler] click OpenGemLevelerButton");
            ConfigWindow gemLevelerWindow = new ConfigWindow();
            gemLevelerWindow.Show();
        }

		 /// <summary>Is this plugin currently enabled?</summary>
        public bool IsEnabled
        {
            get { return _enabled; }
        }

        /// <summary> The plugin is being enabled.</summary>
        public void Enable()
        {
            Log.DebugFormat("[GemLeveler] Enable");
            _enabled = true;
        }

        /// <summary> The plugin is being disabled.</summary>
        public void Disable()
        {
            Log.DebugFormat("[GemLeveler] Disable");
            _enabled = false;
        }
        #endregion

        #region Implementation of IDisposable

        /// <summary> </summary>
        public void Dispose()
        {
        }

        #endregion

        #region Override of Object

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return Name + ": " + Description;
        }

        #endregion

        public static IEnumerable<Inventory> UsableInventories
        {
            get
            {
                return new[]
                {
                    LokiPoe.InGameState.InventoryPanel.LeftHandInventory,
                    LokiPoe.InGameState.InventoryPanel.RightHandInventory,
                    LokiPoe.InGameState.InventoryPanel.OffLeftHandInventory,
                    LokiPoe.InGameState.InventoryPanel.OffRightHandInventory,
                    LokiPoe.InGameState.InventoryPanel.HeadInventory,
                    LokiPoe.InGameState.InventoryPanel.ChestInventory,
                    LokiPoe.InGameState.InventoryPanel.GlovesInventory,
                    LokiPoe.InGameState.InventoryPanel.BootsInventory,
                    LokiPoe.InGameState.InventoryPanel.LeftRingInventory,
                    LokiPoe.InGameState.InventoryPanel.RightRingInventory,
                };
            }
        }

        private void LevelGems()
        {
            var me = LokiPoe.ObjectManager.Me;

            // We need these stats for the "can level" checks.
            var myS = me.GetStat(StatType.Strength);
            var myD = me.GetStat(StatType.Dexterity);
            var myI = me.GetStat(StatType.Intelligence);
            var myL = me.Level;

            foreach (var Inventory in UsableInventories)
            {
                var pageType = Inventory.PageType;

                // Now, for each item, we need to check all the available skill gems.
                // There's a max of 6, so we can simply iterate 6 :)
                foreach (Item inventoryItem in Inventory.Items)
                {
                    if (inventoryItem == null)
                        continue;

                    // This is a base-class of Weapon and Armor. This is exactly why it was split!
                    var item = inventoryItem as SocketableItem;

                    if (item == null)
                    {
                        if (DebugStatements)
                        {
                            Log.Debug(inventoryItem.FullName +
                                      " is not socketable. Is this item a quiver or other non-socketable armor/weapon?");
                        }
                        continue;
                    }

                    var enabledGems =
                        GemLevelerSettings.Instance.EnabledGems.Where(s => s.PageType == pageType).ToList();

                    // Now, iterate the gems of the item... (There's always 6, but in case API changes to only provide 4 for gloves/boots, then we'll be safe)
                    for (int idx = 0; idx < item.SocketedGems.Length; idx++)
                    {
                        SkillGem gem = item.SocketedGems[idx];
                        // Not all sockets will have gems.
                        // So check the ones we actually care about.
                        // Thanks!
                        if (gem == null)
                        {
                            continue;
                        }

                        // Ignore any "globally ignored" gems. This just lets the user move gems around
                        // equipment, without having to worry about where or what it is.
                        if (GemLevelerSettings.Instance.IgnoredByNameGlobal.Contains(gem.Name))
                            continue;

                        // If our settings are disabled for the gem, ignore it.
                        // Check !Any() because if the gem isn't named, we don't want to level it, just in case.
                        // The user is responsible for making sure the gem is there, and enabled.
                        if (!enabledGems.Any(setting => setting.GemName == gem.Name && setting.Enabled))
                            continue;

                        // Srsly, ignore gems that aren't ready to be leveled.
                        if (gem.ExperiencePercent < 100)
                        {
                            continue;
                        }

                        if (gem.Experience == gem.ExperienceMaxLevel)
                        {
                            if (DebugStatements)
                            {
                                Log.Debug("I can't level up " + gem.Name + " because it is already at max level!");
                            }
                            continue;
                        }

                        // Now we just need to get the stats required for the next level.
                        int s, d, i, l;
                        gem.GetAttributeRequirements(out s, out d, out i, out l);

                        var canLevel = true;
                        if (myL < l)
                        {
                            canLevel = false;
                            if (DebugStatements)
                            {
                                Log.Debug("I'm not at the required level to level up " + gem.Name + "! (" + myL + "/" +
                                          l + ")");
                            }
                        }

                        if (myS < s)
                        {
                            canLevel = false;
                            if (DebugStatements)
                            {
                                Log.Debug("I don't have enough strength to level up " + gem.Name + "! (" + myS + "/" + s +
                                          ")");
                            }
                        }

                        if (myD < d)
                        {
                            canLevel = false;
                            if (DebugStatements)
                            {
                                Log.Debug("I don't have enough dexterity to level up " + gem.Name + "! (" + myD + "/" +
                                          d + ")");
                            }
                        }

                        if (myI < i)
                        {
                            canLevel = false;
                            if (DebugStatements)
                            {
                                Log.Debug("I don't have enough intelligence to level up " + gem.Name + "! (" + myI + "/" +
                                          i + ")");
                            }
                        }

                        if (canLevel)
                        {
                            string gemName = gem.Name;
                            Log.Debug("I can level up " + gemName + "!");

                            Loki.Bot.v3.Coroutines.OpenInventoryPanel();
                            LokiPoe.InGameState.InventoryPanel.LevelSkillGem(gem);
                            Loki.Bot.v3.Coroutines.CloseBlockingWindows();

                            Log.Debug(gemName + " has been leveled!");

                            // Wait before we level the next gem so we don't spam gem level ups.
                            return;
                        }
                    }
                }
            }
        }
    }
}
 
Last edited:
the plugin is broken with the new .903

Current routine set to ExampleRoutine.
Compiler Error: c:\Users\*\Downloads\ExilebuddyBETA 0.1.2693.903\Plugins\GemLeveler\GemLeveler.cs(23,18) : error CS0535: 'GemLeveler.GemLeveler' implementerer ikke grænseflademedlemmet 'Loki.Bot.IEnableable.Enable()'
Compiler Error: c:\Users\*\Downloads\ExilebuddyBETA 0.1.2693.903\Plugins\GemLeveler\GemLeveler.cs(23,18) : error CS0535: 'GemLeveler.GemLeveler' implementerer ikke grænseflademedlemmet 'Loki.Bot.IEnableable.Disable()'
Compiler Error: c:\Users\*\Downloads\ExilebuddyBETA 0.1.2693.903\Plugins\GemLeveler\GemLeveler.cs(23,18) : error CS0535: 'GemLeveler.GemLeveler' implementerer ikke grænseflademedlemmet 'Loki.Bot.IEnableable.IsEnabled'

[AutoFlask] Initialize


Follow pushedx's post to fix this:
https://www.thebuddyforum.com/exile...75565-beta-quicksilver-support-autoflask.html
 
Cyber this has nothing to do with flasks, or did I miss something in the link you refered to ?

Dark thanks man, I'll give it a shot.
it's the same thing I did with this, all plugins will need to be changed to the new code to work. Going to see if i can make the plugin work on new chars without actually clicking the settings.
 
you are a godsend... working well so far though the settings window popout not having an "ok" of some kind did leave me wondering if the settings actually saved or not found out the answer soon enough when it started lvling my gems.
 
you are a godsend... working well so far though the settings window popout not having an "ok" of some kind did leave me wondering if the settings actually saved or not found out the answer soon enough when it started lvling my gems.

so far so good thanks its working like a charm been waiting for this one :cool:
 
getting this error
Compiler Error: c:\Users\Steven\Desktop\ExilebuddyBETA 0.1.2706.907\Plugins\GemLeveler\GemLeveler.cs(23,18) : error CS0535: 'GemLeveler.GemLeveler' does not implement interface member 'Loki.Bot.IEnableable.Enable()'
Compiler Error: c:\Users\Steven\Desktop\ExilebuddyBETA 0.1.2706.907\Plugins\GemLeveler\GemLeveler.cs(23,18) : error CS0535: 'GemLeveler.GemLeveler' does not implement interface member 'Loki.Bot.IEnableable.Disable()'
Compiler Error: c:\Users\Steven\Desktop\ExilebuddyBETA 0.1.2706.907\Plugins\GemLeveler\GemLeveler.cs(23,18) : error CS0535: 'GemLeveler.GemLeveler' does not implement interface member 'Loki.Bot.IEnableable.IsEnabled'
 
working on it tonight, had to finish my last set of 40 bots, and it just finished, all 80's and grinding.
there are 2 fixes that this needs,
a check to run the plugin if in game only, and the check on every map/transition to grind zone to trigger gem refresh, therefore leveling needed gems. Hope this happens after auras gets casted.
There are issues where if the bot is in combat after death, the gems will not level and tigger an error.
Push is guiding me.
 
it's probably something to do with the gui being removed.

Edit it's this from changelog.

IPlugin interface updated so plugins maintain their own enabled status. Plugins are expected to adhere to the design.


Sec, i'll see if I can update it.

Edit Again, Ok Change GemLeveler.cs to this

Code:
using System;
using System.Collections.Generic;
using System.Linq;

using log4net;

using Loki.Game;
using Loki.Game.Inventory;
using Loki.Game.Objects.Items;
using Loki.Utilities;
using Loki.Game.GameData;
using Loki.Bot;
using Loki.Game.Objects;
using System.Windows.Controls;
using System.IO;
using System.Windows.Markup;
using System.Windows;
using System.Threading.Tasks;
using System.Threading;

namespace GemLeveler
{
    public class GemLeveler : IPlugin
    {
        #region Implementation of IEquatable<IPlugin>

        /// <summary>
        ///     Indicates whether the current object is equal to another object of the same type.
        /// </summary>
        /// <returns>
        ///     true if the current object is equal to the <paramref name="other" /> parameter; otherwise, false.
        /// </returns>
        /// <param name="other">An object to compare with this object.</param>
        public bool Equals(IPlugin other)
        {
            return Name.Equals(other.Name);
        }

        #endregion

        private static readonly ILog Log = Logger.GetLoggerInstanceForType();
        private const bool DebugStatements = false;
        private readonly WaitTimer _levelWait = WaitTimer.FiveSeconds;
        private readonly Random _random = new Random();
        private bool _enabled;
        #region Implementation of IPlugin

        public string Author
        {
            get { return "Apoc"; }
        }

        public Version Version
        {
            get { return new Version(0, 1, 0, 0); }
        }

        public string Name
        {
            get { return "Gem Leveler"; }
        }

        public string Description
        {
            get { return "Levels gems as they become available for... leveling!"; }
        }

        /// <summary> Executes the pulse action. This is called every "tick" of the bot. </summary>
        public void Tick()
        {
            // We never want to update gems while stash is open, because we access all inventories, which causes
            // more stash pages to be requested than we want.
            if (LokiPoe.InGameState.StashPanel.IsOpened)
                return;

            // Sooo... yeah...
            // We basically only want to level a gem every couple of seconds.
            // Anywhere between 1 and 3 seconds seems fine.
            if (_levelWait.IsFinished)
            {
                _levelWait.Reset(TimeSpan.FromMilliseconds(_random.Next(1000, 3000)));
                LevelGems();
            }
        }

        /// <summary>Initializes this plugin.</summary>
        public void Initialize()
        {
            Log.DebugFormat("[GemLeveler] Initialize");
        }

        /// <summary> The plugin start callback. Do any initialization here. </summary>
        public void Start()
        {
            Log.DebugFormat("[GemLeveler] Start");
        }

        /// <summary> The plugin stop callback. Do any pre-dispose cleanup here. </summary>
        public void Stop()
        {
            Log.DebugFormat("[GemLeveler] Stop");
        }

        public JsonSettings Settings
        {
            get { return GemLevelerSettings.Instance; }
        }

        /// <summary> The routine's settings control. This will be added to the Exilebuddy Settings tab.</summary>
        public UserControl Control
        {
            get
            {
                using (var fs = new FileStream(@"Plugins\GemLeveler\SettingsGui.xaml", FileMode.Open))
                {
                    var root = (UserControl)XamlReader.Load(fs);

                    // Your settings binding here.

                    Button openWindowButton = (Button)LogicalTreeHelper.FindLogicalNode(root, "OpenGemLevelerButton");

                    if (openWindowButton == null)
                    {
                        Log.DebugFormat(
                            "[SettingsControl] SetupButtonBinding failed for 'OpenGemLevelerButton'.");
                        throw new Exception("The SettingsControl could not be created.");
                    }

                    openWindowButton.Click += openGemLevelerWindow;

                    // Your settings event handlers here.

                    return root;
                }
            }
        }

        public void openGemLevelerWindow(object sender, RoutedEventArgs e)
        {
            Log.DebugFormat("[GemLeveler] click OpenGemLevelerButton");
            ConfigWindow gemLevelerWindow = new ConfigWindow();
            gemLevelerWindow.Show();
        }

		 /// <summary>Is this plugin currently enabled?</summary>
        public bool IsEnabled
        {
            get { return _enabled; }
        }

        /// <summary> The plugin is being enabled.</summary>
        public void Enable()
        {
            Log.DebugFormat("[GemLeveler] Enable");
            _enabled = true;
        }

        /// <summary> The plugin is being disabled.</summary>
        public void Disable()
        {
            Log.DebugFormat("[GemLeveler] Disable");
            _enabled = false;
        }
        #endregion

        #region Implementation of IDisposable

        /// <summary> </summary>
        public void Dispose()
        {
        }

        #endregion

        #region Override of Object

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return Name + ": " + Description;
        }

        #endregion

        public static IEnumerable<Inventory> UsableInventories
        {
            get
            {
                return new[]
                {
                    LokiPoe.InGameState.InventoryPanel.LeftHandInventory,
                    LokiPoe.InGameState.InventoryPanel.RightHandInventory,
                    LokiPoe.InGameState.InventoryPanel.OffLeftHandInventory,
                    LokiPoe.InGameState.InventoryPanel.OffRightHandInventory,
                    LokiPoe.InGameState.InventoryPanel.HeadInventory,
                    LokiPoe.InGameState.InventoryPanel.ChestInventory,
                    LokiPoe.InGameState.InventoryPanel.GlovesInventory,
                    LokiPoe.InGameState.InventoryPanel.BootsInventory,
                    LokiPoe.InGameState.InventoryPanel.LeftRingInventory,
                    LokiPoe.InGameState.InventoryPanel.RightRingInventory,
                };
            }
        }

        private void LevelGems()
        {
            var me = LokiPoe.ObjectManager.Me;

            // We need these stats for the "can level" checks.
            var myS = me.GetStat(StatType.Strength);
            var myD = me.GetStat(StatType.Dexterity);
            var myI = me.GetStat(StatType.Intelligence);
            var myL = me.Level;

            foreach (var Inventory in UsableInventories)
            {
                var pageType = Inventory.PageType;

                // Now, for each item, we need to check all the available skill gems.
                // There's a max of 6, so we can simply iterate 6 :)
                foreach (Item inventoryItem in Inventory.Items)
                {
                    if (inventoryItem == null)
                        continue;

                    // This is a base-class of Weapon and Armor. This is exactly why it was split!
                    var item = inventoryItem as SocketableItem;

                    if (item == null)
                    {
                        if (DebugStatements)
                        {
                            Log.Debug(inventoryItem.FullName +
                                      " is not socketable. Is this item a quiver or other non-socketable armor/weapon?");
                        }
                        continue;
                    }

                    var enabledGems =
                        GemLevelerSettings.Instance.EnabledGems.Where(s => s.PageType == pageType).ToList();

                    // Now, iterate the gems of the item... (There's always 6, but in case API changes to only provide 4 for gloves/boots, then we'll be safe)
                    for (int idx = 0; idx < item.SocketedGems.Length; idx++)
                    {
                        SkillGem gem = item.SocketedGems[idx];
                        // Not all sockets will have gems.
                        // So check the ones we actually care about.
                        // Thanks!
                        if (gem == null)
                        {
                            continue;
                        }

                        // Ignore any "globally ignored" gems. This just lets the user move gems around
                        // equipment, without having to worry about where or what it is.
                        if (GemLevelerSettings.Instance.IgnoredByNameGlobal.Contains(gem.Name))
                            continue;

                        // If our settings are disabled for the gem, ignore it.
                        // Check !Any() because if the gem isn't named, we don't want to level it, just in case.
                        // The user is responsible for making sure the gem is there, and enabled.
                        if (!enabledGems.Any(setting => setting.GemName == gem.Name && setting.Enabled))
                            continue;

                        // Srsly, ignore gems that aren't ready to be leveled.
                        if (gem.ExperiencePercent < 100)
                        {
                            continue;
                        }

                        if (gem.Experience == gem.ExperienceMaxLevel)
                        {
                            if (DebugStatements)
                            {
                                Log.Debug("I can't level up " + gem.Name + " because it is already at max level!");
                            }
                            continue;
                        }

                        // Now we just need to get the stats required for the next level.
                        int s, d, i, l;
                        gem.GetAttributeRequirements(out s, out d, out i, out l);

                        var canLevel = true;
                        if (myL < l)
                        {
                            canLevel = false;
                            if (DebugStatements)
                            {
                                Log.Debug("I'm not at the required level to level up " + gem.Name + "! (" + myL + "/" +
                                          l + ")");
                            }
                        }

                        if (myS < s)
                        {
                            canLevel = false;
                            if (DebugStatements)
                            {
                                Log.Debug("I don't have enough strength to level up " + gem.Name + "! (" + myS + "/" + s +
                                          ")");
                            }
                        }

                        if (myD < d)
                        {
                            canLevel = false;
                            if (DebugStatements)
                            {
                                Log.Debug("I don't have enough dexterity to level up " + gem.Name + "! (" + myD + "/" +
                                          d + ")");
                            }
                        }

                        if (myI < i)
                        {
                            canLevel = false;
                            if (DebugStatements)
                            {
                                Log.Debug("I don't have enough intelligence to level up " + gem.Name + "! (" + myI + "/" +
                                          i + ")");
                            }
                        }

                        if (canLevel)
                        {
                            string gemName = gem.Name;
                            Log.Debug("I can level up " + gemName + "!");

                            Loki.Bot.v3.Coroutines.OpenInventoryPanel();
                            LokiPoe.InGameState.InventoryPanel.LevelSkillGem(gem);
                            Loki.Bot.v3.Coroutines.CloseBlockingWindows();

                            Log.Debug(gemName + " has been leveled!");

                            // Wait before we level the next gem so we don't spam gem level ups.
                            return;
                        }
                    }
                }
            }
        }
    }
}

Use this instead, OP should have updated it using this but didn't for some reason. You wont get that error anymore if changing to this.
 
Use this instead, OP should have updated it using this but didn't for some reason. You wont get that error anymore if changing to this.
You will still get an error when not in game, it's due to the plugin wanting info it's not going to get, cause you aren't in game, other then that, working.
 
I get tis error now when loading EB

[Load] An exception occurred: System.Exception: Only part of a ReadProcessMemory or WriteProcessMemory request was completed, at addr: 00000000, Size: 11976
at GreyMagic.ExternalProcessMemory.ReadByteBuffer(IntPtr addr, Void* buffer, Int32 count)
at GreyMagic.MemoryBase.ReadBytes(IntPtr addr, Int32 count)
at Loki.Game.LokiPoe.InstanceInfo.()
at Loki.Game.Utilities.PerCachedValue`1.get_Value()
at Loki.Game.LokiPoe.InstanceInfo.()
at Loki.Game.LokiPoe.InstanceInfo.()
at Loki.Game.Utilities.PerCachedValue`1.get_Value()
at Loki.Game.LokiPoe.InstanceInfo.get_League()
at GemLeveler.GemLevelerSettings..ctor()
at GemLeveler.GemLevelerSettings.get_Instance()
at GemLeveler.GemLeveler.get_Settings()
at Loki.Bot.Utility.(Object )
at Loki.Bot.PluginManager.Load().
 
dont worry about it, it won't cause issues, or at least I do not think.
It basically means Gem Leveler wants to read memory, but you are not in game so It cannot, trying to get a fix into gem leveler to check if it's in game.

Something along the lines of
Code:
public void Tick()
        {
            if (!LokiPoe.IsInGame)
                return;
        }
 
Status
Not open for further replies.
Back
Top