-
Posts
288 -
Joined
-
Last visited
Reputation Activity
-
reapler got a reaction from Pudge in Fight Class - Check if Target is Humanoid
@apexx wManager.Wow.ObjectManager.ObjectManager.Me.TargetObject.CreatureTypeTarget == "Humanoid"
-
reapler got a reaction from Pudge in Difference between Friendly and Hostile targets condition
Hello, i've created a small example how to use the c# code: heal.xml
Because reactions are ordered you can use it like this:
wManager.Wow.ObjectManager.ObjectManager.Me.TargetObject.Reaction > Reaction.Neutral
-
reapler got a reaction from Garub in More questions from a novice programmer.
It depends, if you compile yourself any framework version should work. If you let for example WRobot compile your C# files(.cs) it will be on C# 4.0 / net framework 4.0. Prefered would be a higher version. https://stackoverflow.com/questions/247621/what-are-the-correct-version-numbers-for-c
At first a small project like a plugin for WRobot is good enough to start off, later you may take other sources as reference and improve your code style, structure & performance preferably with C# projects on github or here at the download section.
If the goal is to create a bot, you can also just start your own project and take other bot sources as reference.
It is also advisable to google as much you can to follow the best practices and apply it to the code.
Recommend tools:
Visual Studio(IDE)
DotPeek(Decompiler) - if you would like to view the API
Recommend links:
https://github.com/ - Many open source projects to explore
http://stackoverflow.com - For me a good a resource on things like how to do X
https://www.dotnetperls.com - Good & small code examples for handling different tasks
https://docs.microsoft.com/en-us/dotnet/framework/index - C# / Net framework reference
https://docs.microsoft.com/en-us/dotnet/framework/wpf/getting-started/walkthrough-my-first-wpf-desktop-application - Create your own app with Wpf
Bot sources:
https://github.com/miceiken/IceFlake
https://github.com/tanis2000/babbot/
https://github.com/Zz9uk3/ZzukBot_V3
-
reapler reacted to Marsbar in Unofficial WRobot API Documentation
Hi!
There are often questions regarding the wrobot api and what functions it has, generally you're told to either decompile the dlls or reference them in your visual studio project and use the object browser.
Some people only want to know a certain function name and don't wish to go into the deeper realms of development. There isn't a resource they can use to obtain that info without some effort on their part, that's hopefully where this site I generated will come in handy:
Unofficial WRobot API Docs
It was created by decompiling the vanilla wmanager and robotmanager dlls and generating an api web template using docfx.
Currently it doesn't give you anything more than you'd have by decompiling the dlls yourself but I'm hoping to update this with method, property, constructer etc. descriptions and potentially basic code snippets for a better understanding of the wrobot api.
If you're interested in contributing let me know and I can add you to the gitlab project (sorry if you don't like gitlab but it was quick and easy with free private repos).
-
reapler reacted to Droidz in Test version (vanilla, tbc, wotlk)
Hello,
I need some review (and eventually new bugs report) of this version.
Close WRobot, download, extract and replace files in the folder "WRobot\Bin\", when you will start WRobot he will request you update, ignore it (if you update you go back to live version).
This update is mainly for improve moving, I tried to remove the stops, but I fixed several bugs and added some options like "Ignore fights when travaling" (in advanced general settings), this option is disabled by default, but if you can try to activate it and give me review (I would like to know if I activate it or not by default)
vanilla.rar
tbc.zip
wotlk.zip
-
reapler got a reaction from morris79 in Creating a plugin with debugging?
Hello, you can decompile wrobot's library to get the api documentation(MemoryRobot-, robotManager- & wManager in Wrobot\Bin) common decompiler are Jetbrains dotPeek, ILSpy, redgate's .net reflector & Justcompile. I also recommend to add it to reference and good extensions for VS make your life easier: ReSharper or Coderush are good extensions.
And for testing things i'll prefer to link the build to Wrobots plugins folder so you can just compile and run directly with Wrobot & output the log with "robotManager.Helpful.Logging.Write("text");".
-
reapler got a reaction from Garub in .xml file and .cs file
Hello, .cs files are written in C# and allows the developer to take advantage of the full Wrobot API / Bot behavior.
This means C# written routines are superior towards routines created by the fightclass editor
because every action of the character can controlled by these C# routines.
In case if you would like to develop yourself these fightclasses:
-
reapler reacted to Droidz in WRobot 2.0 released
Hello,
I just released WRobot 2.0. It is mainly UI update, but I have added some features like LuaBot language (to make your WRobot plugins/scripts with lua, you can launch the dev tool to see code sample), better vb.net support... (I'll write changelog in next days).
If you get problem to launch it, check if you use recent Framework version (min 4.5), Windows XP support has ended.
In the next week, I'll primarily work during next weeks/months to improve artificial intelligence/movement/reaction of the bot to try to look more natural (for that I will also have to improve my personal knowledge).
A lot of users abuse of the "unlimited sessions by IP", I think than I'll change rules for the new subscriptions (like 1 session for 20€ per year, 5 for 30€/y...), and probably limit number of session of the old subscriptions (like max 25 sessions, some user running currently more than 100 sessions at the same time...).
As said here WRobot will be a bot only for private servers, I need to edit/reorganize sites/forums/downloads for that (I'll do it in next weeks).
EDIT 25 April 2018: If you get black WRobot window read this, if WRobot closes automatically when you use the same key on multiple IP address at the same time it is normal, an old bug allowed to do it (with unlimited and private subscriptions) but it was fix in this update.
EDIT 26 April 2018: I edited homepage to formalize than WRobot is a private servers bot. I also added new type of subscription, based maximum of running sessions at the same time (no IP limit, it is better if you want to use several IPs), but you cannot run at the same time more than X sessions at the same time), and I converted old "unlimited" and "for private servers" subscriptions to the new type of subscription with the maximum of 10 sessions at the same time. You can see new subcriptions and the price in the store.
I repeat, update of WRobot for official servers was planned before than I decide to stop this version, I released it but this but that does not change my decision, I will definitely close WRobot for official server at the latest at the "Battle for Azeroth" pre-patch (Wow version 8.x.x) .
View full article
-
reapler got a reaction from FNV316 in Bag.GetBagItem()
Not fully tested, but this should work:
/// <summary> /// Used to get the item quantity by name. /// </summary> /// <param name="itemName">The item name.</param> /// <remarks>Replacement for GetItemCount in vanilla.</remarks> /// <returns></returns> public static int GetItemQuantity(string itemName) { var execute = "local itemCount = 0; " + "for b=0,4 do " + "if GetBagName(b) then " + "for s=1, GetContainerNumSlots(b) do " + "local itemLink = GetContainerItemLink(b, s) " + "if itemLink then " + "local _, stackCount = GetContainerItemInfo(b, s)\t " + "if string.find(itemLink, \"" + itemName + "\") then " + "itemCount = itemCount + stackCount; " + "end " + "end " + "end " + "end " + "end; " + "return itemCount; "; return Lua.LuaDoString<int>(execute); } /// <summary> /// Used to delete all items by name. /// </summary> /// <param name="itemName">The item to delete.</param> /// <param name="leaveAmount">The amount of items which remain in the bag.</param> /// <remarks>Bug at links with "-"</remarks> public static void DeleteItems(string itemName, int leaveAmount) { var itemQuantity = GetItemQuantity(itemName) - leaveAmount; if (string.IsNullOrWhiteSpace(itemName) || itemQuantity <= 0) return; var execute = "local itemCount = "+itemQuantity+"; " + "local deleted = 0; " + "for b=0,4 do " + "if GetBagName(b) then " + "for s=1, GetContainerNumSlots(b) do " + "local itemLink = GetContainerItemLink(b, s) " + "if itemLink then " + "local _, stackCount = GetContainerItemInfo(b, s)\t " + "local leftItems = itemCount - deleted; " + "if string.find(itemLink, \""+ itemName + "\") and leftItems > 0 then " + "if stackCount <= 1 then " + "PickupContainerItem(b, s); " + "DeleteCursorItem(); " + "deleted = deleted + 1; " + "else " + "if (leftItems > stackCount) then " + "SplitContainerItem(b, s, stackCount); " + "DeleteCursorItem(); " + "deleted = deleted + stackCount; " + "else " + "SplitContainerItem(b, s, leftItems); " + "DeleteCursorItem(); " + "deleted = deleted + leftItems; " + "end " + "end " + "end " + "end " + "end " + "end " + "end; "; Lua.LuaDoString(execute); } Usage:
DeleteItems("Soul Shard", 20);
-
reapler got a reaction from anonymous123 in Plugins and Accept User Keyboard Input
I've looked into it, you need to run the hook on its own context via "Application.Run();" to get it working:
using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Threading.Tasks; using System.Windows.Forms; using robotManager.Helpful; using wManager.Plugin; public class Main : IPlugin { public void Initialize() { KeyBoardHook.Initialize(); KeyBoardHook.OnKeyDown += KeyDown; } public void Dispose() { KeyBoardHook.OnKeyDown -= KeyDown; KeyBoardHook.Dispose(); } public void Settings() { } private static void KeyDown(object sender, KeyBoardHook.KeyArgs keyArgs) { Logging.Write(keyArgs.Key.ToString()); } public class KeyBoardHook { private const int WH_KEYBOARD_LL = 13; private const int WM_KEYDOWN = 0x0100; private const int WM_KEYUP = 0x101; private static readonly LowLevelKeyboardProc Proc = HookCallback; private static IntPtr _hookId = IntPtr.Zero; private static Keys _lastKeyDown = Keys.None; public delegate void KeyBoardHookEventHandler(object sender, KeyArgs e); public static event KeyBoardHookEventHandler OnKeyDown = delegate{}; public static event KeyBoardHookEventHandler OnKeyUp = delegate{}; internal static void Initialize() { Task.Factory.StartNew(() =>//avoid thread blocking from Application.Run(); { _hookId = SetHook(Proc); Application.Run(); //important! need to run in its own "context" }); } internal static void Dispose() { UnhookWindowsHookEx(_hookId); Application.Exit(); } private static IntPtr SetHook(LowLevelKeyboardProc proc) { using (var curProcess = Process.GetCurrentProcess()) using (var curModule = curProcess.MainModule) { return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0); } } private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam); private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) { if (nCode < 0) return CallNextHookEx(_hookId, nCode, wParam, lParam); if (wParam == (IntPtr) WM_KEYDOWN) { var vkCode = (Keys) Marshal.ReadInt32(lParam); if (_lastKeyDown == vkCode) return CallNextHookEx(_hookId, nCode, wParam, lParam); OnKeyDown(null, new KeyArgs(vkCode)); _lastKeyDown = vkCode; } else if (wParam == (IntPtr) WM_KEYUP) { var vkCode = (Keys) Marshal.ReadInt32(lParam); OnKeyUp(null, new KeyArgs(vkCode)); if (_lastKeyDown == vkCode) _lastKeyDown = Keys.None; } return CallNextHookEx(_hookId, nCode, wParam, lParam); } [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool UnhookWindowsHookEx(IntPtr hhk); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam); [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr GetModuleHandle(string lpModuleName); public class KeyArgs : EventArgs { public Keys Key { get; private set; } public KeyArgs(Keys key) { this.Key = key; } } } } So far it worked well.
-
reapler reacted to iMod in Left click unit
Targeting by guid for vanilla (not tested)
private static readonly object LockTargeting = new object(); public static void TargetUnit(ulong guid) { // Allocate memory for the target guid uint alloc = Memory.WowMemory.Memory.AllocateMemory(8); // Write guid Memory.WowMemory.Memory.WriteUInt64(alloc, guid); // Create asm string[] asm = new string[] { $"mov ecx, {alloc}", $"call {0x489A40}", Memory.WowMemory.RetnToHookCode }; lock (LockTargeting) { // Execute Memory.WowMemory.InjectAndExecute(asm); } // Free memory Memory.WowMemory.Memory.FreeMemory(alloc); }
-
reapler got a reaction from Skygirl779 in Left click unit
Yes, you can. For example:
//3.3.5a 12340 public void MoveForwardStart() { wManager.Wow.Memory.WowMemory.InjectAndExecute( new [] { //more parameters can be appended by the wrapper wManager.Wow.Memory.WowMemory.CallWrapperCode( (uint)wManager.Wow.Memory.WowMemory.Memory.MainModuleAddress + 0x1FC200), wManager.Wow.Memory.WowMemory.RetnToHookCode, }, true ); }
-
reapler got a reaction from Skygirl779 in Left click unit
This should gonna do its work:
public void Target(ulong guid) { wManager.Wow.Helpers.Lua.RunMacroText("/target "+wManager.Wow.ObjectManager.ObjectManager.GetObjectByGuid(guid)?.Name+""); } Edit: i reconsider my answer, this may not be a ideal solution.
If you gonna look at the interact function in WRobot, you'll notice it's a direct function call via asm.
So another solution would be to overwrite the guid from the local player's focus and target it via lua:
public void Target(WoWObject obj) { var tmp = ObjectManager.Me.FocusGuid; ObjectManager.Me.FocusGuid = obj.Guid; Lua.RunMacroText("/target focus"); ObjectManager.Me.FocusGuid = tmp; } public void Target(ulong guid) { var tmp = ObjectManager.Me.FocusGuid; ObjectManager.Me.FocusGuid = guid; Lua.RunMacroText("/target focus"); ObjectManager.Me.FocusGuid = tmp; } Usage:
var firstOrDefault = ObjectManager.GetObjectWoWUnit().OrderBy(i => i.GetDistance).FirstOrDefault(); if (firstOrDefault != null) Target(firstOrDefault.Guid);
-
reapler got a reaction from Matenia in Left click unit
It's also possible to do this on vanilla, but with mouseover guid:
public void Target(ulong guid) { if (guid == 0) return; ulong tmp = wManager.Wow.Memory.WowMemory.Memory.ReadUInt64( (uint) wManager.Wow.Memory.WowMemory.Memory.MainModuleAddress + 0x74E2C8); wManager.Wow.Memory.WowMemory.Memory.WriteUInt64( (uint) wManager.Wow.Memory.WowMemory.Memory.MainModuleAddress + 0x74E2C8, guid); wManager.Wow.Helpers.Lua.LuaDoString("TargetUnit('mouseover');"); wManager.Wow.Memory.WowMemory.Memory.WriteUInt64( (uint) wManager.Wow.Memory.WowMemory.Memory.MainModuleAddress + 0x74E2C8, tmp); }
-
reapler got a reaction from Seminko in Why does this code crash WRobot?
You may check first whether "sRogueSettings.CurrentSetting" is null:
private void FoodManager() { try { if (sRogueSettings.CurrentSetting == null) robotManager.Helpful.Logging.Write("CurrentSetting is null"); else robotManager.Helpful.Logging.Write("CurrentSetting is not null"); } catch (Exception e) { robotManager.Helpful.Logging.WriteError(e.ToString()); } } You get probably "CurrentSetting is null" ;)
So in this case this means you haven't initialized "CurrentSetting" = no instance to your object is given = "CurrentSetting" is null, hence you cannot accessing its properties.
In the end you need to call "sRogueSettings.Load();" to create an instance.
However If it's not the case, you may check for other variables against null.
-
reapler got a reaction from happiness7 in Sleep/Pause/Wait for all theards
Hello @happiness7 this should fit:
//minimum net framework 4.5 Task.Run(() => { Products.InPause = true; Thread.Sleep(6000); Products.InPause = false; }); If you also want to block plugin thread, just remove "Task.Run"
-
reapler got a reaction from Seminko in sending a shift+right-click to an inventory-item
Hello, since you are using vanilla i assume the method doesn't work correctly but i'm not sure("DoString" is obfuscated).
You also can't use the "/use <item>" it wasn't implemented on vanilla. So you need to iterate the items in your bag with lua.
I tried this on 3.3.5a but since the used api functions is also present on vanilla, it should also work:
public void UseItemByName(string name, bool lootItem = true) { if (lootItem) { Task.Run(async delegate { robotManager.Helpful.Keyboard.DownKey(wManager.Wow.Memory.WowMemory.Memory.WindowHandle, System.Windows.Forms.Keys.ShiftKey); await Task.Delay(2000); robotManager.Helpful.Keyboard.UpKey(wManager.Wow.Memory.WowMemory.Memory.WindowHandle, System.Windows.Forms.Keys.ShiftKey); }); } wManager.Wow.Helpers.Lua.LuaDoString( @" for b=0,4 do for s=1,GetContainerNumSlots(b) do if (string.find(tostring(GetContainerItemLink(b,s) or """"), """+wManager.Wow.Helpers.ItemsManager.GetIdByName(name)+@""" )) then UseContainerItem(b,s, onSelf); end end end " ); } Usage:
UseItemByName("Hearthstone", false); or
UseItemByName("Heavy Crate", true);
-
reapler got a reaction from sowelu in Bag.GetBagItem()
Not fully tested, but this should work:
/// <summary> /// Used to get the item quantity by name. /// </summary> /// <param name="itemName">The item name.</param> /// <remarks>Replacement for GetItemCount in vanilla.</remarks> /// <returns></returns> public static int GetItemQuantity(string itemName) { var execute = "local itemCount = 0; " + "for b=0,4 do " + "if GetBagName(b) then " + "for s=1, GetContainerNumSlots(b) do " + "local itemLink = GetContainerItemLink(b, s) " + "if itemLink then " + "local _, stackCount = GetContainerItemInfo(b, s)\t " + "if string.find(itemLink, \"" + itemName + "\") then " + "itemCount = itemCount + stackCount; " + "end " + "end " + "end " + "end " + "end; " + "return itemCount; "; return Lua.LuaDoString<int>(execute); } /// <summary> /// Used to delete all items by name. /// </summary> /// <param name="itemName">The item to delete.</param> /// <param name="leaveAmount">The amount of items which remain in the bag.</param> /// <remarks>Bug at links with "-"</remarks> public static void DeleteItems(string itemName, int leaveAmount) { var itemQuantity = GetItemQuantity(itemName) - leaveAmount; if (string.IsNullOrWhiteSpace(itemName) || itemQuantity <= 0) return; var execute = "local itemCount = "+itemQuantity+"; " + "local deleted = 0; " + "for b=0,4 do " + "if GetBagName(b) then " + "for s=1, GetContainerNumSlots(b) do " + "local itemLink = GetContainerItemLink(b, s) " + "if itemLink then " + "local _, stackCount = GetContainerItemInfo(b, s)\t " + "local leftItems = itemCount - deleted; " + "if string.find(itemLink, \""+ itemName + "\") and leftItems > 0 then " + "if stackCount <= 1 then " + "PickupContainerItem(b, s); " + "DeleteCursorItem(); " + "deleted = deleted + 1; " + "else " + "if (leftItems > stackCount) then " + "SplitContainerItem(b, s, stackCount); " + "DeleteCursorItem(); " + "deleted = deleted + stackCount; " + "else " + "SplitContainerItem(b, s, leftItems); " + "DeleteCursorItem(); " + "deleted = deleted + leftItems; " + "end " + "end " + "end " + "end " + "end " + "end " + "end; "; Lua.LuaDoString(execute); } Usage:
DeleteItems("Soul Shard", 20);
-
reapler got a reaction from Marsbar in Bag.GetBagItem()
Not fully tested, but this should work:
/// <summary> /// Used to get the item quantity by name. /// </summary> /// <param name="itemName">The item name.</param> /// <remarks>Replacement for GetItemCount in vanilla.</remarks> /// <returns></returns> public static int GetItemQuantity(string itemName) { var execute = "local itemCount = 0; " + "for b=0,4 do " + "if GetBagName(b) then " + "for s=1, GetContainerNumSlots(b) do " + "local itemLink = GetContainerItemLink(b, s) " + "if itemLink then " + "local _, stackCount = GetContainerItemInfo(b, s)\t " + "if string.find(itemLink, \"" + itemName + "\") then " + "itemCount = itemCount + stackCount; " + "end " + "end " + "end " + "end " + "end; " + "return itemCount; "; return Lua.LuaDoString<int>(execute); } /// <summary> /// Used to delete all items by name. /// </summary> /// <param name="itemName">The item to delete.</param> /// <param name="leaveAmount">The amount of items which remain in the bag.</param> /// <remarks>Bug at links with "-"</remarks> public static void DeleteItems(string itemName, int leaveAmount) { var itemQuantity = GetItemQuantity(itemName) - leaveAmount; if (string.IsNullOrWhiteSpace(itemName) || itemQuantity <= 0) return; var execute = "local itemCount = "+itemQuantity+"; " + "local deleted = 0; " + "for b=0,4 do " + "if GetBagName(b) then " + "for s=1, GetContainerNumSlots(b) do " + "local itemLink = GetContainerItemLink(b, s) " + "if itemLink then " + "local _, stackCount = GetContainerItemInfo(b, s)\t " + "local leftItems = itemCount - deleted; " + "if string.find(itemLink, \""+ itemName + "\") and leftItems > 0 then " + "if stackCount <= 1 then " + "PickupContainerItem(b, s); " + "DeleteCursorItem(); " + "deleted = deleted + 1; " + "else " + "if (leftItems > stackCount) then " + "SplitContainerItem(b, s, stackCount); " + "DeleteCursorItem(); " + "deleted = deleted + stackCount; " + "else " + "SplitContainerItem(b, s, leftItems); " + "DeleteCursorItem(); " + "deleted = deleted + leftItems; " + "end " + "end " + "end " + "end " + "end " + "end " + "end; "; Lua.LuaDoString(execute); } Usage:
DeleteItems("Soul Shard", 20);
-
reapler got a reaction from nudl in Bag.GetBagItem()
Not fully tested, but this should work:
/// <summary> /// Used to get the item quantity by name. /// </summary> /// <param name="itemName">The item name.</param> /// <remarks>Replacement for GetItemCount in vanilla.</remarks> /// <returns></returns> public static int GetItemQuantity(string itemName) { var execute = "local itemCount = 0; " + "for b=0,4 do " + "if GetBagName(b) then " + "for s=1, GetContainerNumSlots(b) do " + "local itemLink = GetContainerItemLink(b, s) " + "if itemLink then " + "local _, stackCount = GetContainerItemInfo(b, s)\t " + "if string.find(itemLink, \"" + itemName + "\") then " + "itemCount = itemCount + stackCount; " + "end " + "end " + "end " + "end " + "end; " + "return itemCount; "; return Lua.LuaDoString<int>(execute); } /// <summary> /// Used to delete all items by name. /// </summary> /// <param name="itemName">The item to delete.</param> /// <param name="leaveAmount">The amount of items which remain in the bag.</param> /// <remarks>Bug at links with "-"</remarks> public static void DeleteItems(string itemName, int leaveAmount) { var itemQuantity = GetItemQuantity(itemName) - leaveAmount; if (string.IsNullOrWhiteSpace(itemName) || itemQuantity <= 0) return; var execute = "local itemCount = "+itemQuantity+"; " + "local deleted = 0; " + "for b=0,4 do " + "if GetBagName(b) then " + "for s=1, GetContainerNumSlots(b) do " + "local itemLink = GetContainerItemLink(b, s) " + "if itemLink then " + "local _, stackCount = GetContainerItemInfo(b, s)\t " + "local leftItems = itemCount - deleted; " + "if string.find(itemLink, \""+ itemName + "\") and leftItems > 0 then " + "if stackCount <= 1 then " + "PickupContainerItem(b, s); " + "DeleteCursorItem(); " + "deleted = deleted + 1; " + "else " + "if (leftItems > stackCount) then " + "SplitContainerItem(b, s, stackCount); " + "DeleteCursorItem(); " + "deleted = deleted + stackCount; " + "else " + "SplitContainerItem(b, s, leftItems); " + "DeleteCursorItem(); " + "deleted = deleted + leftItems; " + "end " + "end " + "end " + "end " + "end " + "end " + "end; "; Lua.LuaDoString(execute); } Usage:
DeleteItems("Soul Shard", 20);
-
reapler got a reaction from Marsbar in Bag.GetBagItem()
@Marsbar Hello, i've written a method for this:
public struct BagInfo { public int Bag; public int Slot; public BagInfo(int bag, int slot) { Bag = bag; Slot = slot; } public override string ToString() { return "Bag = " + Bag + " ; Slot = " + Slot; } } /// <summary> /// Used to get a list of locations of the item as bag and slot position. /// </summary> /// <param name="itemName">The item name to search.</param> /// <returns></returns> public static List<BagInfo> GetItemLocations(string itemName) { var execute = "local bs = {}" + "for b=0,4 do " + "if GetBagName(b) then " + "for s=1, GetContainerNumSlots(b) do " + "local itemLink = GetContainerItemLink(b, s) " + "if itemLink then " + "local itemName, itemLink, itemRarity, itemLevel, itemMinLevel, itemType, itemSubType, itemStackCount, itemEquipLoc, itemTexture, itemSellPrice = GetItemInfo(itemLink) \t" + "if itemName == '"+itemName+"' "; execute += "then " + "table.insert(bs, b); " + "table.insert(bs, s); " + "\tend\tend\tend end end return unpack(bs);"; var bs = Lua.LuaDoString<List<int>>(execute); var list = new List<BagInfo>(); for (var i = 0; i < bs.Count; i += 2) list.Add(new BagInfo(bs[i], bs[i+1])); return list; } Usage:
GetItemLocations("Mutton Chop").ForEach(i => Logging.Write(i.ToString()));
Here are also other similar methods to interact with items:
-
reapler got a reaction from BetterSister in PathFinder.Pather.FindZ(); on dalaran
Yes, the result is good :) I just added my height + 20:
Thank you.
-
reapler got a reaction from Seminko in Find NPC by ID (longer than visible range)
Hello, this is a limitation from the server itself, other servers could also have a dynamic object scope(performance reasons).
-
reapler got a reaction from nudl in Quest Editor
A small update from me:
Since i'm almost done with the database, i can continue working on my editor again. But my first design wasn't really good.
I'm thinking to use a more simpler solution which doesn't require to assign a "Action parameter" at the sorted quests.
In the end each action define a step which are selectable on the bar like this:
By the way, if you have a custom pulse like "KillAndLoot", "Gatherer" or something else which is often used, you are welcome to post it and i can create a seperate setting gui for it.
-
reapler got a reaction from Avvi in Plugins and Accept User Keyboard Input
I've looked into it, you need to run the hook on its own context via "Application.Run();" to get it working:
using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Threading.Tasks; using System.Windows.Forms; using robotManager.Helpful; using wManager.Plugin; public class Main : IPlugin { public void Initialize() { KeyBoardHook.Initialize(); KeyBoardHook.OnKeyDown += KeyDown; } public void Dispose() { KeyBoardHook.OnKeyDown -= KeyDown; KeyBoardHook.Dispose(); } public void Settings() { } private static void KeyDown(object sender, KeyBoardHook.KeyArgs keyArgs) { Logging.Write(keyArgs.Key.ToString()); } public class KeyBoardHook { private const int WH_KEYBOARD_LL = 13; private const int WM_KEYDOWN = 0x0100; private const int WM_KEYUP = 0x101; private static readonly LowLevelKeyboardProc Proc = HookCallback; private static IntPtr _hookId = IntPtr.Zero; private static Keys _lastKeyDown = Keys.None; public delegate void KeyBoardHookEventHandler(object sender, KeyArgs e); public static event KeyBoardHookEventHandler OnKeyDown = delegate{}; public static event KeyBoardHookEventHandler OnKeyUp = delegate{}; internal static void Initialize() { Task.Factory.StartNew(() =>//avoid thread blocking from Application.Run(); { _hookId = SetHook(Proc); Application.Run(); //important! need to run in its own "context" }); } internal static void Dispose() { UnhookWindowsHookEx(_hookId); Application.Exit(); } private static IntPtr SetHook(LowLevelKeyboardProc proc) { using (var curProcess = Process.GetCurrentProcess()) using (var curModule = curProcess.MainModule) { return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0); } } private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam); private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) { if (nCode < 0) return CallNextHookEx(_hookId, nCode, wParam, lParam); if (wParam == (IntPtr) WM_KEYDOWN) { var vkCode = (Keys) Marshal.ReadInt32(lParam); if (_lastKeyDown == vkCode) return CallNextHookEx(_hookId, nCode, wParam, lParam); OnKeyDown(null, new KeyArgs(vkCode)); _lastKeyDown = vkCode; } else if (wParam == (IntPtr) WM_KEYUP) { var vkCode = (Keys) Marshal.ReadInt32(lParam); OnKeyUp(null, new KeyArgs(vkCode)); if (_lastKeyDown == vkCode) _lastKeyDown = Keys.None; } return CallNextHookEx(_hookId, nCode, wParam, lParam); } [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool UnhookWindowsHookEx(IntPtr hhk); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam); [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr GetModuleHandle(string lpModuleName); public class KeyArgs : EventArgs { public Keys Key { get; private set; } public KeyArgs(Keys key) { this.Key = key; } } } } So far it worked well.