The way DoString works in WoW menu

User Tag List

Results 1 to 8 of 8
  1. #1
    tanis2000's Avatar Active Member
    Reputation
    39
    Join Date
    Feb 2009
    Posts
    123
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    The way DoString works in WoW

    I'm trying to get my mind set on how DoString actually works in WoW and understand if I can use that to do what I want

    I suppose that Lua_DoString is actually the same lua_dostring() that exists in LUA (and that appears to have been deprecated in 5.1+).

    As far as I can tell from the manual Lua: 4.0 reference manual you pass a string with a chunk of LUA code and the interpreter executes it.

    Lua_DoString pushes onto the stack any values eventually returned by the chunk and then it's up to me/us to retrieve them from the stack or just discard them.

    Now, what I didn't understand is if this chunk of code once executed becomes part of the global code that has been loaded into the LUA interpreter and thus it's like if I loaded one more addon, so to speak or if it just gets discarded.

    What I would like to use it for is to do things like this:

    Code:
    local function test()
    	SetMapToCurrentZone()
    	local continent = "test"..GetCurrentMapContinent()
    	return continent
    end
    
    res = test()
    Define a function that does something and returns something, execute it and then pop off the stack the return values. And of course I don't want to taint the global space.

    Is that something viable or am I going in a completely wrong direction?

    The way DoString works in WoW
  2. #2
    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)
    It's different.

    What everyone calls "DoString" is actually called FrameScript__Execute, which is a wrapper around the Lua funcs for executing code. FrameScript__Execute actually discards the return values on the stack afaik so you can't retrieve them. That's why people register a callback to be used as a 'wrapper'.

    I'm no expert though, if you want more info then find someone who has reversed it to the point that they've reimplemented it (e.g. Greyman if he sees this thread, or maybe Amadmonk, I think he may have done it too).

  3. #3
    tanis2000's Avatar Active Member
    Reputation
    39
    Join Date
    Feb 2009
    Posts
    123
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks Cypher!

    I've been toying around with this stuff and I noticed that FrameScript__Execute is actually acting differently than I first thought (reason n.1 being that as you say, it's not just the standard lua_dostring)

    As an example, I would expect that if I call

    Code:
    FrameScript__Execute("MyInputHandler(return 1,'a')")
    I'd get as a result in the stack those two values.
    Instead I find nothing.

    But if I just do

    Code:
    FrameScript__Execute("MyInputHandler(1,'a')")
    then I get the two values in the stack (although in reverse order compared to the original LUA DoString function).

    I wonder if there's a way to actually access the original lua_dostring instead of having to call FrameScript__Execute passing your own wrapper as it seems that FrameScript__Execute is actually doing something with the code you pass, and if it likes it then it returns the values in reverse order. Now this is opening yet another hole in my mumblings.. are the other lua_gettop, lua_tostring functions actually those of the LUA interpreter or are they some other custom functions from Blizzard?

  4. #4
    MaiN's Avatar Elite User
    Reputation
    335
    Join Date
    Sep 2006
    Posts
    1,047
    Thanks G/R
    0/10
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by tanis2000 View Post
    Code:
    FrameScript__Execute("MyInputHandler(return 1,'a')")
    Eh, that's a LUA error. If you want to do it like that you need to define a dynamic function.
    Code:
    FrameScript__Execute("MyInputHandler((function() return 1, 'a' end)()")
    [16:15:41] Cypher: caus the CPU is a dick
    [16:16:07] kynox: CPU is mad
    [16:16:15] Cypher: CPU is all like
    [16:16:16] Cypher: whatever, i do what i want

  5. #5
    berserk85's Avatar Member
    Reputation
    8
    Join Date
    Apr 2008
    Posts
    35
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    From my exp i can say that lua_gettop and lua_tostring act like original lua function.
    If you are trying to execute a lua function without DoString() you can try with lua_pcall or lua_call ...
    Code:
    void Lua_CallVarg(const char *func, const char *sig, ...)
    {    //http://www.lua.org/pil/25.3.html
    
    			void *L;
    			L = GetLuaState();
    			//DBGLOG( (PDWORD)L );
    			char* str;
    			 va_list vl;
    			  int narg, nres;  /* number of arguments and results */
    			  va_start(vl, sig);
    			  Lua_Getglobal(L, func);  /* get function */
    		    
    			  /* push arguments */
    			  narg = 0;
    			  while (*sig) {  /* push arguments */
    				switch (*sig++) {
    		    
    				  case 'd':  /* double argument */
    					Lua_pushnumber(L, va_arg(vl, double));
    					break;
    		    
    				  case 'i':  /* int argument */
    					Lua_pushnumber(L, va_arg(vl, int));
    					break;
    		    
    				  case 's':  /* string argument */
    					str = va_arg(vl, char *);
    					Lua_pushstring(L, str,strlen(str));
    					break;
    		    
    				  case '>':
    					goto endwhile; // ugly conditional branch
    		    
    				  default:
    					  DBGLOG( "Lua_CallVarg : Invalid option " << *(sig - 1) );
    				}
    				narg++;
    				//luaL_checkstack(L, 1, "too many arguments");
    			  } endwhile:
    		    
    			  /* do the call */
    			  nres = strlen(sig);  /* number of expected results */
    			  unsigned int size;
    			  if (Lua_pcall(L, narg, nres, 0) != 0)  /* do the call */
    				DBGLOG("error running function " << func << " " << Lua_tostring(L, -1,&size) );
    		    
    			  /* retrieve results */
    			  nres = -nres;  /* stack index of first result */
    			  while (*sig) {  /* get results */
    				switch (*sig++) {
    		    
    				  case 'd':  /* double result */
    					if (!Lua_isnumber(L, nres))
    					  DBGLOG ( "wrong result type");
    					*va_arg(vl, double *) = Lua_tonumber(L, nres);
    					break;
    		    
    				  case 'i':  /* int result */
    					if (!Lua_isnumber(L, nres))
    					  DBGLOG ( "wrong result type");
    					*va_arg(vl, int *) = (int)Lua_tonumber(L, nres);
    					break;
    		    
    				  case 's':  /* string result */
    					if (!Lua_isstring(L, nres))
    					  DBGLOG ( "wrong result type");
    					unsigned int size;
    					*va_arg(vl, const char **) = Lua_tostring(L, nres, &size);
    					break;
    		    
    				  default:
    					DBGLOG ( "invalid option " << *(sig - 1));
    				}
    				nres++;
    			  }
    			  va_end(vl);
    }
    and call the GetCurrentMapContinent() with

    Code:
    int *i;
    Lua_CallVarg("GetCurrentMapContinent",">i",i);
    Last edited by berserk85; 10-15-2009 at 10:22 AM.

  6. #6
    tanis2000's Avatar Active Member
    Reputation
    39
    Join Date
    Feb 2009
    Posts
    123
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by MaiN View Post
    Eh, that's a LUA error. If you want to do it like that you need to define a dynamic function.
    Shame on me for taking for granted the sample code from the lua-users wiki :-P
    lua-users wiki: Getting Values From Lua

    With your code it actually works of course.

    So I guess I could actually wrap any piece of code into a dynamic function and use that with FrameScript_Execute. I'll give it a go with something a bit more complex to see what happens.

    As a side note, do you have any reference to how tables returned by dostring are stored in the stack?


    @berserk85: if there's a way to get what I need by using FrameScript_Execute, I'll stick to that.. otherwise I guess I'll switch to lua_pcall. Thanks for the code sample though!

  7. #7
    MaiN's Avatar Elite User
    Reputation
    335
    Join Date
    Sep 2006
    Posts
    1,047
    Thanks G/R
    0/10
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by tanis2000 View Post
    Shame on me for taking for granted the sample code from the lua-users wiki :-P
    lua-users wiki: Getting Values From Lua
    Eh, FrameScript__Execute != lua_dostring (as Cypher already told you) - IIRC lua_dostring defines a dynamic function internally, and calls that.

    Originally Posted by tanis2000 View Post
    As a side note, do you have any reference to how tables returned by dostring are stored in the stack?
    I really don't know. When I need to return a table I use unpack. Eg.:
    Code:
    Lua.ReturnValues("local testTable = {\"test\", \"test2\"} return testTable")
    That returns an empty array.

    However, using
    Code:
    Lua.ReturnValues("local testTable = {\"test\", \"test2\"} return unpack(testTable)")
    will return an array of 2 items (test and test2 obviously).
    Last edited by MaiN; 10-15-2009 at 03:17 PM.
    [16:15:41] Cypher: caus the CPU is a dick
    [16:16:07] kynox: CPU is mad
    [16:16:15] Cypher: CPU is all like
    [16:16:16] Cypher: whatever, i do what i want

  8. #8
    Nesox's Avatar ★ Elder ★
    Reputation
    1280
    Join Date
    Mar 2007
    Posts
    1,238
    Thanks G/R
    0/3
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Take à look at lua_load and lua_pcall

Similar Threads

  1. need help (don't know how to get the edits to work in wow)
    By Daluur in forum WoW ME Questions and Requests
    Replies: 5
    Last Post: 01-07-2008, 10:16 AM
  2. [Release/in the works] Ascent WoW Lich King Website !
    By latruwski in forum World of Warcraft Emulator Servers
    Replies: 12
    Last Post: 12-16-2007, 05:24 AM
All times are GMT -5. The time now is 10:48 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