C# Lua Wrapper (No ASM, Requires injected CLR) menu

Shout-Out

User Tag List

Page 2 of 2 FirstFirst 12
Results 16 to 30 of 30
  1. #16
    Cypher's Avatar Kynox's Sister's Pimp
    Reputation
    1358
    Join Date
    Apr 2006
    Posts
    5,368
    Thanks G/R
    0/6
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Actually, it's real name is:
    FrameScript_Execute.

    Its in the Alpha PDB.

    C# Lua Wrapper (No ASM, Requires injected CLR)
  2. #17
    Apoc's Avatar Angry Penguin
    Reputation
    1388
    Join Date
    Jan 2008
    Posts
    2,750
    Thanks G/R
    0/13
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Cypher View Post
    Actually, it's real name is:
    FrameScript_Execute.

    Its in the Alpha PDB.
    What Cypher said.

    Most (if not all) the functions I'm calling, are WoW functions, which just wrap the Lua stuff.

    And yes, this class works perfectly fine, without issues.

  3. #18
    qjlex's Avatar Member
    Reputation
    1
    Join Date
    Oct 2007
    Posts
    39
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I have a question.
    How to submit a Lua command in UTF8 encoding?

    I fixed it
    Code:
    LuaCmd = Marshal.AllocHGlobal(Encoding.UTF8.GetBytes(command).Length + 1);
    LuaInterface.WhiteMagic.Write<Byte[]>(LuaCmd, Encoding.UTF8.GetBytes(command));
    Lua_DoString(LuaCmd, lua_cmd, 0);
    Last edited by qjlex; 08-02-2010 at 08:04 AM.

  4. #19
    PyGuy's Avatar Corporal
    Reputation
    14
    Join Date
    Jan 2011
    Posts
    20
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    P.S. Lua needs some time to start up before you can call FrameScript::RegisterCommand. You'll get a null pointer dereference if you try to register your command before Wow has had time to set up Lua properly. There's probably better ways to do it, but I just skipped the bulk of my EndScene code for the first 60 times through.

  5. #20
    sylvisj's Avatar Member
    Reputation
    20
    Join Date
    Apr 2007
    Posts
    24
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Code:
    LuaCmd = Marshal.AllocHGlobal(Encoding.UTF8.GetBytes(command).Length + 1);
    LuaInterface.WhiteMagic.Write<Byte[]>(LuaCmd, Encoding.UTF8.GetBytes(command));
    Lua_DoString(LuaCmd, lua_cmd, 0);
    Err... Why are you calling GetBytes(command) twice?
    Do it once and store the result. No point in doing something again (very) unnecessarily.

  6. #21
    amadmonk's Avatar Active Member
    Reputation
    124
    Join Date
    Apr 2008
    Posts
    772
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Note that there's another way to do Lua in a WoW bot. Read the "C API" sections of the Lua document and you'll get an idea of what you can do.

    I will say that nearly the entire standard Lua API is available in WoW (including the real pcall, exec, and so on functions), and with this API you can do vast and wonderful things in Lua. Lua is more than capable of running an entire, fully functioning group bot. I have a group bot that I can and do use to farm heroics with (and just like Apoc and Cypher etc. all said: no, I won't respond to PM's, and no I wouldn't invite you to the Elite section even if that were in my power :P)

    Point of my post: don't write off Lua as just something to do a little "glue code" and pass strings around with. Lua is an extremely powerful scripting language and with a little work and some interop magic can easily be the backbone of your bot.
    Don't believe everything you think.

  7. #22
    reggggg's Avatar Member
    Reputation
    1
    Join Date
    Sep 2009
    Posts
    22
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by amadmonk View Post
    Note that there's another way to do Lua in a WoW bot. Read the "C API" sections of the Lua document and you'll get an idea of what you can do.

    I will say that nearly the entire standard Lua API is available in WoW (including the real pcall, exec, and so on functions), and with this API you can do vast and wonderful things in Lua. Lua is more than capable of running an entire, fully functioning group bot. I have a group bot that I can and do use to farm heroics with (and just like Apoc and Cypher etc. all said: no, I won't respond to PM's, and no I wouldn't invite you to the Elite section even if that were in my power :P)

    Point of my post: don't write off Lua as just something to do a little "glue code" and pass strings around with. Lua is an extremely powerful scripting language and with a little work and some interop magic can easily be the backbone of your bot.
    I have written a heal bot for my druid purely by declaring my entire "addon" with FrameScript::Execute as WoW launches, and then just pulsing it in EndScene. Obviously it can't navigate (much!). However, I keep reading that Blizzard dislikes people messing with their LUA system. I wrote a name obfuscator which I run over my LUA code each runtime, but this only hides it from the possibility that Blizzard will start detecting using LUA symbols - 'banned addons' etc. My real fear is that they will start checking the call stack on protected functions or something silly like that if this becomes widespread.

    Thoughts?

  8. #23
    amadmonk's Avatar Active Member
    Reputation
    124
    Join Date
    Apr 2008
    Posts
    772
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by reggggg View Post
    I have written a heal bot for my druid purely by declaring my entire "addon" with FrameScript::Execute as WoW launches, and then just pulsing it in EndScene. Obviously it can't navigate (much!). However, I keep reading that Blizzard dislikes people messing with their LUA system. I wrote a name obfuscator which I run over my LUA code each runtime, but this only hides it from the possibility that Blizzard will start detecting using LUA symbols - 'banned addons' etc. My real fear is that they will start checking the call stack on protected functions or something silly like that if this becomes widespread.

    Thoughts?
    Well, I can't tell you what Blizzard will or won't do in the future, but my guess is that they're not going to start scraping the Lua stack for valid callers, since call-stack sanitizing is NOT trivial and they could very quickly end up banning a lot of people.

    As for the banned addons thing, how are they going to detect your "addon" if it's all loaded dynamically? Aside from stack scraping or symbols scraping (which is also full of pitfalls that could lead Blizzard to a PR nightmare), I'm not sure precisely what they could do to detect your Luabot.
    Don't believe everything you think.

  9. #24
    ostapus's Avatar Active Member
    Reputation
    60
    Join Date
    Nov 2008
    Posts
    180
    Thanks G/R
    3/10
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by reggggg View Post
    I have written a heal bot for my druid purely by declaring my entire "addon" with FrameScript::Execute as WoW launches, and then just pulsing it in EndScene. Obviously it can't navigate (much!). However, I keep reading that Blizzard dislikes people messing with their LUA system. I wrote a name obfuscator which I run over my LUA code each runtime, but this only hides it from the possibility that Blizzard will start detecting using LUA symbols - 'banned addons' etc. My real fear is that they will start checking the call stack on protected functions or something silly like that if this becomes widespread.

    Thoughts?
    pretty much what i am doing/using. my "bot" is 99% is written on lua and basically is valid wow addon. C++ part just provides about 15 methods (like read/write memory) and some supplemental functions (like enumerate objects). In my case on wow patch, i've to update only C++ part (and in 90% cases i even dont need recompile, just update xml file w/ patterns and offsets). Navigation is moved to external app "navigation server" which takes commands and return results thru pipe. As you pointed out, the beauty of this approach - possibility to use whole WOW API w/o nigtmare to update offsets/patterns with each patch. Cons so far in my case - some perfomance issues when i need to scan objects (thru enumerating objects around) but these issues easy to avoid by more accurate coding. I am not even mention how easy to debug it, at any time in the game i can update code and just instantly reload (not UI reload) whole bot lua code.
    Just looked at C DLL - last time i recompiled it - at the cata start.
    Just looked at lua part - 300kb of lua code and 25kb of C code (w/o nav server), jeez...

    ---------- Post added at 11:57 AM ---------- Previous post was at 11:48 AM ----------

    just a thought - a lot of time been spent for a stuff i am not even using that much, i am not grinding money or something, just for fishing/herbing/mining once or twice per week purely for myself... lol
    Last edited by ostapus; 02-04-2011 at 11:53 AM.

  10. #25
    jujuman's Avatar Member
    Reputation
    1
    Join Date
    Jun 2008
    Posts
    2
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Surely I am not the juju you are refering too?

    I just started reading these forums again after a very long hiatus from the game. As you can tell I do not make posts very often this being my second ever.

  11. #26
    PyGuy's Avatar Corporal
    Reputation
    14
    Join Date
    Jan 2011
    Posts
    20
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by ostapus View Post
    pretty much what i am doing/using. my "bot" is 99% is written on lua and basically is valid wow addon.... I am not even mention how easy to debug it, at any time in the game i can update code and just instantly reload (not UI reload) whole bot lua code.
    Do you mind sharing some info on that?

    I assume you've got your lua in a text file that looks something like this:
    Code:
    MyBotSetup = function()
    -- Create a new frame and register for events
    -- Setup variables and callbacks
    -- Etc...
    end
    
    MyBotPulse = function()
    -- Do stuff every frame
    end
    And then you register a C++ callback for MyBotReload that grabs the latest version of your text file and calls FrameScript::Execute on the contents so that you can do /script MyBotReload() in wow and get any code updates. In each EndScene call you would do FrameScript::Execute("MyBotPulse()")

    How do you debug then? Wait for a lua exception? Or do you also register a function to write out a log?

  12. #27
    amadmonk's Avatar Active Member
    Reputation
    124
    Join Date
    Apr 2008
    Posts
    772
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You can't really live debug Lua code in WoW, because the code is executing synchronously on the main UI thread; breaking into the thread would break the game (you could in theory write an addon to an external debugger app that would let you live-debug Lua; I've had a task on my "to-do list" for a long time now).

    However, this isn't really a big deal; with WoW's built-in pexec and error functions and the stack trace function, you can do extremely sophisticated debug-through-printf code.

    BTW: one word for your pulse function: coroutines. These are the number one reason for choosing to write a bot in Lua; coroutines make complicated behavioral choices that are "pulsed" from frame to frame almost trivial. The number two reason for writing your bot in Lua is something ostapus already mentioned: a very small number of offsets.

    Also, I should mention that performance isn't an issue with judicious use of coroutines and careful decisions about what to do when; for instance, do you REALLY need to scan the entire object list every frame? Surely every 100ms or so would work... By doing these kinds of optimizations, plus caching some expensive calculated values, I can run a full bot AI with at most a 1-2fps slowdown in heavy combat with 10-30 mobs. Most times, my measured framerate while running the bot is exactly the same as without the bot. Performance is super important when you want to run a group of 5-10 bots on a single machine
    Don't believe everything you think.

  13. #28
    ostapus's Avatar Active Member
    Reputation
    60
    Join Date
    Nov 2008
    Posts
    180
    Thanks G/R
    3/10
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    the "pulse" function - simple frame with "onUpdate" event.. no need to hook "endscene" at all... C DLL "exports" one function which in its case provide some functionality, example from the code:

    class CHelper
    {
    .....
    ... basic lua API functions
    the signature of these functions is not changing at all (well or very rare)

    FUNC(void, lua_createtable, (lua_State *L, int narray, int nrec)) ;
    FUNC(void, lua_pushvalue, (lua_State *L, int idx)) ;
    FUNC(void, lua_settable, (lua_State *l, int idx)) ;
    FUNC(void, lua_getfield, (lua_State *l, int idx, const char *k)) ;
    FUNC(void, lua_setfield, (lua_State *l, int idx, const char *k)) ;
    FUNC(void, lua_pushnumber, (lua_State *l, lua_Number n)) ;
    FUNC(void, lua_pushinteger, (lua_State *l, lua_Integer n)) ;
    FUNC(void, lua_pushstring, (lua_State *l, const char *v)) ;
    FUNC(void, lua_pushcclosure, (lua_State *l, lua_CFunction fn, int n)) ;
    FUNC(void, lua_pushnil, (lua_State *l)) ;
    FUNC(int, lua_type, (lua_State *l, int idx)) ;
    FUNC(void, lua_settop, (lua_State *l, int idx)) ;
    FUNC(int, lua_gettop, (lua_State *l)) ;
    FUNC(void, lua_call, (lua_State *l, int nargs, int nresults));
    FUNC(void, lua_replace, (lua_State *L, int idx)) ;
    FUNC(void, lua_insert, (lua_State *L, int idx)) ;
    FUNC(void, lua_remove, (lua_State *L, int idx)) ;
    FUNC(char*, lua_tolstring, (lua_State *l, int idx, size_t *len)) ;
    FUNC(int, lua_pcall, (lua_State *L, int nargs, int nresults, int errfunc)) ;
    FUNC(lua_Integer, lua_tointeger,(lua_State *L, int idx)) ;
    FUNC(lua_Number, lua_tonumber, (lua_State *L, int idx)) ;
    ..... some other function
    }

    patterns to lua_XXX functions defined by pattern in xml file (findpattern) and haven't changed in years.

    void CExportedFunction(lua_state *L)
    {
    if ( gpCHelper->lua_gettop(L) <= 0 )
    {
    Debug(__FUNCTION__ " called with 0 arguments") ;
    return 0 ;
    }
    op = gpCHelper->lua_tointeger(L, 1) ;
    gpCHelper->lua_remove(L, 1) ;

    Debug(__FUNCTION__ " op:%d args:%d", op, gpCHelper->lua_gettop(L)) ;

    switch(op)
    {
    case 1:
    gpCHelper->mlf_readInteger(L) ;
    break ;
    case 2:
    gpCHelper->mlf_readDouble(L) ;
    break ;
    case 3:
    gpCHelper->mlf_readShort(L) ;
    break ;
    case 4:
    gpCHelper->mlf_readDword(L) ;
    break ;
    ....
    case 20: ....

    from lua the usage is like

    function WrapperCall(operation, ...)
    return CExportedFunction(operation, ...)
    end

    function GetInteger(address)
    return WrapperCall(1, address)
    end

    function GetDouble(address)
    return WrapperCall(2, address)
    end
    ... etc, you got the idea how lua communicates to injected part.. obviously DLL provides methods (besides read/write memory) like CTM wrapper, object enumeration
    ie, object enumeration wrapper basically callback provided lua function with object information - guid, object addr, object type, distance to object (from player position),

    say - find closest enemy stub
    _wrapperToCallWowFunctionsOverGuid - simple puts provided guid into focus, calls WoW api functions and restores previous "focus" guid, just simple way to call WOW API not over predefined units (like "target", "player" etc) but over any object



    -- checks if target is valid enemy, returns: true - valid, false not valid, string - "reason"
    function IsValidEnemy(u)
    local rc
    if ( not UnitExists(u) ) then return false, "not exists" end
    if ( UnitIsDeadOrGhost(u) ) then return false, "dead" end
    if ( not UnitCanAttack("player", u) ) then return false, "can't attack" end
    if ( UnitIsPlayer(u) and UnitIsPVP(u) and UnitIsPVP("player")) then return true, "PVP and me" end
    if ( UnitIsTapped(u) and UnitIsTappedByPlayer(u) ) then return true, "tapped and mine" end
    if ( UnitName(u .. "target") == UnitName("player")) then return true, "targeting me" end
    if ( UnitExists("playerpet") and UnitName(u .. "target") == UnitName("playerpet") ) then return true, "targetting my pet" end
    if ( RaidRoster:GetUnit(u .. "target").unit ) then return true, "targeting raid/party member" end
    return false, "nothing match, not valid target"
    end

    -- basically this lua callback will be called for each object which is UNIT AND ENEMY within 60 feet radius from the player

    function CanBeFindEnemyFunction(spellToMeasureDistance)
    return GeneralEnumerateFunction(
    function(obj, lo, hi, dist, hp)
    return _wrapperToCallWowFunctionsOverGuid(lo, hi, IsValidEnemy, "focus") and
    _wrapperToCallWowFunctionsOverGuid(lo, hi, IsInLos, "focus") and -- IsInLos - wrapper for Intersect function
    _wrapperToCallWowFunctionsOverGuid(lo, hi, IsSpellInRange, spellToMeasureDistance, "focus") and -- checks if within spell distance
    0 or 1 -- 0 if no more objects, we found one... 1 - if continue enumeration
    end, T_ANYENEMY, FastEnum.SEARCH_ENEMY, FastEnum.SORT_DISTANCE, 60)
    end

    -- this is general search function
    function GeneralEnumerateFunction(mycallback, unitType, searchType, sortType, maxDistance)
    local rc = {}
    rc.object, rc.guidLo, rc.guidHi, rc.objectType = CExportedFunction(
    function(object, lo, hi, dist, hp, otype)
    return mycallback(object, lo, hi, dist, hp, otype)
    end, unitType, searchType, sortType, maxDistance)

    if ( rc.object ~= nil and rc.object ~= 0) then
    return rc
    end
    end
    return nil
    end

    further in lua code i can use it like

    rc = CanBeFindEnemyFunction("Wrath")
    if ( rc ) then
    _wrapperToCallWowFunctionsOverGuid(rc.lo, rc.hi, TargetUnit, "focus")
    ... attack logic ...
    end

    again, think you've got the idea..

    debugging is pretty simple, just write to log file or in my case i just use
    _G["ChatFrame" .. i]:AddMessage with debug/log messages (i've dedicated chat frame for only "bot" messages

    lua loading part:
    i've "main" stub, which is not changing so i dont have to "reload UI" which is slow and that main stub is loading rest of the code... ex:

    this function can be called on "main stub" load or whenever you need to reload bot code (for example if you change something)

    function ExampleToLoadLuaCode()
    local className = string.gsub(UnitClass("player"), " ", "_")
    for _, name in pairs ( { "BaseFunction", "CoreFunctions", className, "SomeCodeRelatedToNavigation", "SomeCodeRelatedToFarming", "SomeCodeRelatedToFishing"} ) do
    local file = _PATH .. name .. ".lua"
    str = _ReadFile(file) -- wrapper call to read file into string
    mylog(" loading %s", name)
    local code, error = loadstring(str)
    if ( type(code) ~= "function" )
    then
    mylog(" load of %s.lua failed %s", name, tostring(error) )
    mylog("Loadng aborted...")
    return
    end
    mylog(" executing %s", name)
    local success, errorMessage = pcall(code)
    if ( not success ) then
    mylog(" pcall failed %s, either error in the code... check output", errorMessage)
    error("FAILED")
    end
    end

    and when i need to reload "bot" code i can just type /script ExampleToLoadLuaCode() directly in the game

    ---------- Post added at 02:25 PM ---------- Previous post was at 02:21 PM ----------

    as amadmonk point it out, by "debug" i dont meant step debugger but rather debug message w/ stack tracing... bleh, i am just using "BugSack" or w/e name for this "official" addon is to catch syntax errors
    for extensive testing, i am just redirecting all bot output into the file for later review.

  14. #29
    amadmonk's Avatar Active Member
    Reputation
    124
    Join Date
    Apr 2008
    Posts
    772
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Nice!

    I've built a Lua package load/require mechanism (built entirely in Lua, woohoo!) that lets me build a directory structure of Lua packages and modules. As your bot code base grows, the ability to separate individual chunks into separate modules/packages is invaluable.
    Don't believe everything you think.

  15. #30
    ostapus's Avatar Active Member
    Reputation
    60
    Join Date
    Nov 2008
    Posts
    180
    Thanks G/R
    3/10
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    yup, exactly same for me, my bot consist of 4 directories (3 functionality directories and one for data like mining/herbing data and so on)and like 15 lua files where each file defines "class".

Page 2 of 2 FirstFirst 12

Similar Threads

  1. Limit FPS with injected clr app
    By Corthezz in forum WoW Memory Editing
    Replies: 13
    Last Post: 11-09-2015, 01:29 PM
  2. Replies: 1
    Last Post: 01-19-2012, 03:14 AM
  3. Dostring Lua Formatting - multi-line , ";" required?
    By mongoosed in forum WoW Memory Editing
    Replies: 4
    Last Post: 12-14-2010, 05:10 PM
  4. Unlock Protected LUA with a Patch? (Without Injecting code?)
    By Zeroi9 in forum WoW Memory Editing
    Replies: 15
    Last Post: 03-30-2009, 05:58 PM
  5. Injecting ASM problems
    By lanman92 in forum WoW Memory Editing
    Replies: 33
    Last Post: 03-16-2009, 06:46 AM
All times are GMT -5. The time now is 09:27 AM. Powered by vBulletin® Version 4.2.3
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Google Authenticator verification provided by Two-Factor Authentication (Free) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search