Jump to content

reapler

Elite user
  • Posts

    288
  • Joined

  • Last visited

Posts posted by reapler

  1. I believe this should work:

            /// <summary>
            /// Used to get the facing from two positions based on the origin rotation.
            /// </summary>
            /// <param name="from">The 1. position.</param>
            /// <param name="to">The 2. position.</param>
            /// <param name="originRotation">The origin rotation.</param>
            /// <returns>Negative radian on the right; positive on the left.</returns>
            public float FacingCenter(WoWPoint from, WoWPoint to, float originRotation)
            {
                var face = NormalizeRadian(Atan2Rotation(from, to) - originRotation);
                if (face < Math.PI)
                    return -face;
                return NormalizeRadian(originRotation-Atan2Rotation(from, to));
            }
    
            /// <summary>
            /// Used to normalize the input radian.
            /// </summary>
            /// <param name="radian">The radians to normalize.</param>
            public float NormalizeRadian(float radian)
            {
                if (radian < 0.0)
                    return (float) (-(- radian % (2.0 * Math.PI)) + 2.0 * Math.PI);
                return radian % 6.283185f;
            }
        
            /// <summary>
            /// Used to calculate atan2 of to positions.
            /// </summary>
            /// <param name="from">Position 1.</param>
            /// <param name="to">Position 2.</param>
            /// <param name="addRadian">Radians to add.</param>
            /// <returns></returns>
            public static float Atan2Rotation(WoWPoint from, WoWPoint to, float addRadian = 0)
            {
                return (float) Math.Atan2(to.Y - from.Y, to.X - from.X) + addRadian;
            }
    
            /// <summary>
            /// Used to calculate new position by parameter.
            /// </summary>
            /// <param name="from">The position to calculate from.</param>
            /// <param name="rotation">The rotation of the object in radians.</param>
            /// <param name="radius">The radius to add.</param>
            /// <returns></returns>
            public static WoWPoint CalculateNewPosition(WoWPoint from, float rotation, float radius)
            {
                return new WoWPoint(Math.Sin(rotation) * radius + from.X, Math.Cos(rotation) * radius + from.Y, from.Z);
            }

     

  2. On 1/28/2019 at 10:38 PM, Garub said:

    1 - I did a quick search on goole and saw that C # is in version 7.x, s I want to start developing for wow 3.3.5 that will work? Or will I have to apprehend the C # version of the time that wow 3.3.5 was released?

    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

    On 1/28/2019 at 10:38 PM, Garub said:

    2 - What topic on the internet do I have to find, about C # to start? (Correct me if I'm wrong.) Example: I believe the first thing I should learn is, how to write and read in memory using C #. (I want to study how a bot works, perhaps by creating my own bot.

    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

  3. Hello you can use a hashset for this purpose like this:

    private HashSet<int> safeList = new HashSet<int>
    {
        12345,
        12346,
    }
    
    private void ProtectItem(WoWItem item)
    {
        safeList.Add(item.GetItemInfo.ItemId);
    }
    
    private void ProtectItem(int itemId)
    {
        safeList.Add(itemId);
    }
    
    private void PulseDestroy() 
    {
        if (ButlerSettings.CurrentSetting.DestroyGray) 
        {
            foreach (WoWItem item in bagItems) 
            {
                if ((item.GetItemInfo.ItemRarity==0 
                    || item.GetItemInfo.ItemRarity==1)
                    && !safeList.Contains(item.GetItemInfo.ItemId)) 
                {
                    while (ObjectManager.Me.InCombat || ObjectManager.Me.IsDead) 
                    {
                        Thread.Sleep(shortDelay);
                    }
                    List<int> BagAndSlot=Bag.GetItemContainerBagIdAndSlot(item.Entry);
                    Logging.Write(ButlerPrefix+"destroying \""+item.GetItemInfo.ItemName+"\"");
                    Lua.LuaDoString(string.Format("PickupContainerItem({0}, {1}); DeleteCursorItem()",
                                    (object) BagAndSlot[0],(object) BagAndSlot[1]),false);
                    Thread.Sleep(shortDelay);
                }
            }
        }
    }

     

  4. 1 hour ago, Ivkan1997 said:

    Also SmoothMove still have delays even on 50fps ingame. Sometimes it just delays for 0.5sec every second while searching for another waypoint.

    I cant give my game client more than 50 fps, even that is too much for my 25 seassons.

    Hello, you may decompile or create project with dotpeek for the plugin and tweak it abit. The used methods are correct to turn the character(the same methods which are called for mouse turns).

    One problem is, wrobot is hooking endscene to execute methods of wow and this is also affected by fps, it must be also mentioned it is a safe method to do it.

    Injected it could calls the used methods directly with a higher ratio.

    Also the plugin itself is in my eyes still a prototype. A pid controller, better fps / latency dependent settings can be implemented in order to work 'ok' with endscene.

  5. 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:

    Spoiler

    To get started you may take a look into a few .cs files under the download section.

    To understand the used function you will need a decompiler and search for the terms.

    If you would like to develop this sort of fightclasses, i'd recommend Visual Studio.

    I recommend to take small steps, see what's going on and take other fightclasses / plugins as reference. 

    Searching for a few threads in the developers section should be also helpful in the most cases.

     

  6. 19 minutes ago, Ordush said:

    Jamba uses the chat, that is easy. I was thinking of going outside of wow.

    Hello, you may take a look into memory mapped objects / remote procedure call(RPC). 

    For example:

    https://github.com/spazzarama/SharedMemory

    http://csharptest.net/projects/rpclibrary/index.html

    These can be also installed via nuget packet manager on Visual Studio and can be binded with fody with your distributed library(fightclass / plugin).

    Note: RPC is rather for client / server communication but you may also exchange data via calls.

     

    If this may take abit too much effort, you can also save a file to disk(like fightclass settings) and read from another wrobot instance.

  7. Hello, you can subscribe to the movement events to block the movement. It could look like this(not tested):

        //call at initialize
        public void SubscribeEvents()
        {
            MovementEvents.OnMovementPulse += MovementEventsOnOnMovementPulse;
        }
    
        //call at dispose
        public void UnSubscribeEvents()
        {
            MovementEvents.OnMovementPulse -= MovementEventsOnOnMovementPulse;
        }
    
    
        private void MovementEventsOnOnMovementPulse(List<Vector3> path, CancelEventArgs cancelEventArgs)
        {
            if (DestinationTmp != Vector3.Empty
                && path.LastOrDefault()?.Action != "custom"
                )
            {
                cancelEventArgs.Cancel = true;
            }
        }
    
    
    
    
    
        public static Vector3 DestinationTmp = Vector3.Empty;
        public static void MoveTo(Vector3 destination)
        {
            List<Vector3> path = PathFinder.FindPath(ObjectManager.Me.Position, destination);
            var last = path.LastOrDefault();
            if (last != null)
                last.Action = "custom";
            DestinationTmp = MovementManager.CurrentPath.LastOrDefault() ?? ObjectManager.Me.Position;
            MovementManager.Go(path);
        }
    
        public static void GoBack()
        {
            List<Vector3> path = PathFinder.FindPath(ObjectManager.Me.Position, DestinationTmp);
            DestinationTmp = Vector3.Empty;
            MovementManager.Go(path);
        }

     

  8. 8 minutes ago, Skygirl779 said:

    That said, it's not perfect; is there an API that allows me to safely call WoW functions from wRobot? I have the necessary technical knowledge, I just don't know how to get wRobot to execute asm in WoW's main thread.

    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
            );
        }

     

  9. 47 minutes ago, Matenia said:

    Do you happen to know if SpellManager.CastSpellByNameOn(name, unit) works in Vanilla?

    Yes, in vanilla you need to change the target guid, since the api only allows target or local player as argument. It looks like this:

        public void CastSpell(string spellName, WoWObject obj)
        {
            if (!obj.IsValid)
                return;
            ulong tmp = wManager.Wow.Memory.WowMemory.Memory.ReadUInt64(
                (uint) wManager.Wow.Memory.WowMemory.Memory.MainModuleAddress + 0x74E2D8);
            wManager.Wow.Memory.WowMemory.Memory.WriteUInt64(
                (uint) wManager.Wow.Memory.WowMemory.Memory.MainModuleAddress + 0x74E2D8, obj.Guid);
            Lua.LuaDoString("CastSpellByName('"+spellName+"');");
            wManager.Wow.Memory.WowMemory.Memory.WriteUInt64(
                (uint) wManager.Wow.Memory.WowMemory.Memory.MainModuleAddress + 0x74E2D8, tmp);
        }

    Someone may think why not using objectmanager's target property from local player, the reason is the setter has some additional code for actually change the target and some other features.

  10. 1 minute ago, Matenia said:

    For anyone reading this - this will only work in TBC and onwards where "focus" is an existing unit.
    The direct ASM function call reapler was talking about *might* be your only solution in Vanilla if you want to achieve exactly this.

    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);
        }

     

  11. 1 hour ago, Skygirl779 said:

    Thank you, but this only lets me target by name and I need to target by guid :(

    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);

     

  12. Hello, if someone is familiar with its programming language, this person can also write up such a detection.

    They may have an excellent serverside detection, recording paths of players and process the data aswell logging playtime per day, 

    multiple accounts on the same ip address, trades, mails and everything you could think of that can be useful to detect, can trigger a notification if the action is uncommon.

    However it should be considered also players can just report you as a bot(most of the time it is obvious).

  13. A small template, also creates an instance on null. Saving manually with "sRogueSettings.CurrentSetting.Save();"

    
        public class SRogueSettings : robotManager.Helpful.Settings
        {
            public bool UseBuffFood { get; set; }
    
            public string BuffFoodName { get; set; }
    
            //...
    
            public static SRogueSettings CurrentSetting
            {
                get
                {
                    if (_currentSetting == null && !_cannotLoad)
                        Load();
                    return _currentSetting;
                }
                set
                {
                    _currentSetting = value;
                }
            }
    
            private static bool _cannotLoad;
            private static SRogueSettings _currentSetting;
    
            public bool Save()
            {
                try
                {
                    _cannotLoad = !Save(AdviserFilePathAndName("SRogue", ObjectManager.Me.Name + "." + Usefuls.RealmName));
                    return !_cannotLoad;
                }
                catch (Exception e)
                {
                    Logging.WriteError(e.ToString());
                    _cannotLoad = true;
                    return false;
                }
            }
            
            public static bool Load()
            {
                try
                {
                    if (File.Exists(AdviserFilePathAndName("SRogue", ObjectManager.Me.Name + "." + Usefuls.RealmName)))
                    {
                        CurrentSetting = Load<SRogueSettings>(AdviserFilePathAndName("SRogue", ObjectManager.Me.Name + "." + Usefuls.RealmName));
                        return true;
                    }
                    _cannotLoad = true;
                    CurrentSetting = new SRogueSettings
                    {
                        UseBuffFood = true,
                        BuffFoodName = "",
                    };
                }
                catch (Exception e)
                {
                    Logging.WriteError(e.ToString());
                }
                return false;
            }
        }

     

  14. 31 minutes ago, Seminko said:

    How do I pinpoint where the error is?

    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.

  15. Hello, if something crashes and it's not a stack overflow (recursive call) you may wrap your code in a try-catch statement:

        private void FoodManager()
        {
            try
            { 
                if (sRogueSettings.CurrentSetting.UseBuffFood && sRogueSettings.CurrentSetting.BuffFoodName != null && sRogueSettings.CurrentSetting.BuffFoodBuffName != null)
                {
                    uint foodID = wManager.Wow.Helpers.ItemsManager.GetIdByName(sRogueSettings.CurrentSetting.BuffFoodName);
                    if (!ObjectManager.Me.HaveBuff(sRogueSettings.CurrentSetting.BuffFoodBuffName) && ItemsManager.HasItemById(foodID) && wManagerSetting.CurrentSetting.FoodName != sRogueSettings.CurrentSetting.BuffFoodName)
                    {
                        wManagerSetting.CurrentSetting.FoodName = sRogueSettings.CurrentSetting.BuffFoodName;
                    }
                    else if (ObjectManager.Me.HaveBuff(sRogueSettings.CurrentSetting.BuffFoodBuffName) && wManagerSetting.CurrentSetting.FoodName != originalFoodSetting)
                    {
                        wManagerSetting.CurrentSetting.FoodName = originalFoodSetting;
                    }
                }
            }
            catch (Exception e)
            {
                robotManager.Helpful.Logging.WriteError(e.ToString());
            }
        }

    I think you have probably a null reference exception on your settings, so you would check for "sRogueSettings.CurrentSetting" whether it is null at first.

    And "sRogueSettings.CurrentSetting.BuffFoodName != null" is not necessary on a string, since checking against null will result always in false.

  16. Hello @Weicheng, adding the references to your visual studio project shouldn't make any problems in the end. The compiled libary can be put in the desired folder and can be run as long the referenced libraries are in "\WRobot\Bin\" or in the same folder with its executing library but this doesn't count for net framework related libraries.

    So, yes under normal conditions you can distribute your library and they're good to go.

  17. 2 hours ago, Marsbar said:

    @reapler Sadly not working for me. Getting a Index was out of range error. I'm doing this for soul shard management, wanting to delete all soul shards exepct for a certain amount.

    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);

     

  18. @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:

     

×
×
  • Create New...