Raising an event like "CHAT_MSG_SAY" from C++ menu

User Tag List

Results 1 to 14 of 14
  1. #1
    Ellesar1's Avatar Member
    Reputation
    20
    Join Date
    Feb 2009
    Posts
    78
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Raising an event like "CHAT_MSG_SAY" from C++

    I've already inserted additional functions to WoW's LUA-interpreter using lua_register and the code caving method to prevent the pointer-in-range check. This allows me to communicate with my program over the Lua-interpreter.
    However, I want to achieve the opposite now: some communication channel from the C++-dll to the lua engine.
    Since the interface is based on events, I think that the easiest way is to somehow register an additional event (RegisterInterfaceEvents hook?) and to raise it from the C++ code whenever I want to communicate with my addon.

    I'm not pretty far right now. Playing around with olly and trying to understand how an event like CHAT_MSG_SAY is actually raised. Pretty confusing...

    I would be glad if someone of you could give me a hint to the right direction :-) (I don't expect full solutions, even if you have some small hint, please share it)

    Raising an event like "CHAT_MSG_SAY" from C++
  2. #2
    kynox's Avatar Member
    Reputation
    830
    Join Date
    Dec 2006
    Posts
    888
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    .text:007D1150 ; void FrameScript_SignalEvent(int eventId, const char *fmt, ...)

  3. #3
    Ellesar1's Avatar Member
    Reputation
    20
    Join Date
    Feb 2009
    Posts
    78
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks, this helps alot :-)

    now just having to figure out how this strange format string is used exactly and how to call this function from the main thread when my additional thread finds that it needs to send something to the Lua addon.

  4. #4
    Robske's Avatar Contributor
    Reputation
    305
    Join Date
    May 2007
    Posts
    1,062
    Thanks G/R
    3/4
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The string is composed as such: (%Type)*
    For example: %b%s%u%f would indicate 4 arguments, respectivly boolean, string, unsigned integer and float.
    "Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live." - Martin Golding
    "I cried a little earlier when I had to poop" - Sku

  5. #5
    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)
    For the most part it's just similar to a normal C-style format string.

  6. #6
    nitrogrlie's Avatar Member
    Reputation
    11
    Join Date
    Oct 2009
    Posts
    81
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Cypher View Post
    For the most part it's just similar to a normal C-style format string.
    What about the not-"most" part? What's different?

  7. #7
    Ellesar1's Avatar Member
    Reputation
    20
    Join Date
    Feb 2009
    Posts
    78
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    guessed something like printf syntax. however, it's confusing since CHAT_MSG_SAY has 3 arguments according to wowwiki.com and the format string contains about 10 of them?!

  8. #8
    nitrogrlie's Avatar Member
    Reputation
    11
    Join Date
    Oct 2009
    Posts
    81
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Ellesar1 View Post
    guessed something like printf syntax. however, it's confusing since CHAT_MSG_SAY has 3 arguments according to wowwiki.com and the format string contains about 10 of them?!
    No, it's probably exactly like printf() which takes 2 args:
    1) the pointer to the format string (with as many vars as you need) Example: "Print Name: %s, Address: 0x%08x, Pointer: %p, Decimal: %d\n"
    2) a pointer to the variable list to use in placing into the format string) Example: szName, dwAddr, ptrBase, size

    The 3rd argument for the WoW function is just the type of MSG (e.g. yell, say, whisper, channel, etc.)

    For more info on how printf works underneath the hood check out the description for vprintf() on MSDN

    That's my guess.

  9. #9
    Robske's Avatar Contributor
    Reputation
    305
    Join Date
    May 2007
    Posts
    1,062
    Thanks G/R
    3/4
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Ellesar1 View Post
    guessed something like printf syntax. however, it's confusing since CHAT_MSG_SAY has 3 arguments according to wowwiki.com and the format string contains about 10 of them?!
    CHAT_MSG_SAY - World of Warcraft Programming: A Guide and Reference for Creating WoW Addons
    "Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live." - Martin Golding
    "I cried a little earlier when I had to poop" - Sku

  10. #10
    Ellesar1's Avatar Member
    Reputation
    20
    Join Date
    Feb 2009
    Posts
    78
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    That clarifies alot and gives this long format string some sense. Thanks and +rep!

    (seems that wowwiki is out of date on such things)
    Last edited by Ellesar1; 12-19-2009 at 04:30 PM.

  11. #11
    RoKFenris's Avatar Member
    Reputation
    16
    Join Date
    Jun 2008
    Posts
    69
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Wouldn't it be easier to just call some lua-implemented function from your C++ code, using RunScript or something similar? (I'm working totally OOP so I never paid much attention to the procedure, but I believe calling lua functions by evaluating some lua code from an external program has been exhaustively discussed here.)

  12. #12
    Ellesar1's Avatar Member
    Reputation
    20
    Join Date
    Feb 2009
    Posts
    78
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    @RoKFenris: that sounds nice but isn't as flexible as an event in my case. Additionaly, I want to learn the event-based approach, too :-)


    So, I could spend another hour and found that I have spent most of the time copying some of my old comments into the new one (is there some easier way to take old comments in OllyDbg to a new version?) due to the patch 3.3 :-)

    Here is how I think that FrameScript_SignalEvent works:

    1. lua_pushstring(eventName)
    2. for each argument that should be passed, push it on the lua stack according to it's type which is defined in the format string
      1. lua_pushstring("message")
      2. lua_pushstring("senders name")
      3. lua_pushstring("Orcish")
      4. ...
    3. Raising the event:
      Code:
      _asm {
          mov ebx, numberOfLuaPushesUntilHere;
          mov esi, lua_StatePointer;
          mov edx, eventId;
          mov eax, 0x007f3750;
          push ebx;
          push esi;
          push edx;
          call eax;
      }
    4. lua_settop(-1 - numberOfLuaPushesUntilHere) to cleanup the lua stack

    I'll test this out the next time I get some spare time :-)

    The only problems I see now are as follows:
    1. If it works, we can call events which are already in the game. But how to add some own event with an own name?
      I've seen that the pointers to the event structs are stored in an array at [0d5ec24]. The "eventId" is the array index where the pointer to the specific event struct lies. Offset 0x14 in an event struct seems to point to the event's name.
      Either I'll have to look at the function at 0x007f3750 to understand the event struct or I am just too stupid to find the correct function to register an event.
    2. Is there a method to invoke FrameScript_SignalEvent from an additional thread without suspending the main thread?

  13. #13
    Ellesar1's Avatar Member
    Reputation
    20
    Join Date
    Feb 2009
    Posts
    78
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well, I found again some time to work on my project and could raise a "CHAT_MSG_SAY" event from an additional thread :-)

    The following describes what I've did thus far for the next part of my question which stated to have a custom event available:

    1. In FrameScript_SignalEvent, I could find that pointers to all event objects are stored in an array starting at [0d5ec28].
    2. Hardware-breakpoint (on write) to this address gave me two functions which are writing there. 1st is some cleaning function which resets the address to zero and frees memory, 2nd one is RegisterInterfaceEvents
    3. So, I've looked at RegisterInterfaceEvents and could "reverse" how the function gets called.
      Code:
      void RegisterInterfaceEvents (char ** eventNames, int numberOfEvents);
      (please correct me if I am wrong ^^)
    4. Basically, what this function does is to cleanup first, then allocating a new memory block with size numberOfEvents * sizeof(char *) and then creating event objects using multiple function calls, finally resulting in a pointer to these event objects in the previously allocated memory block.
    5. It seems very easy to add a new event. Just calling RegisteRInterfaceEvents with a new event table... This assumption resulted in some crappy testing code which looks as follows:
      Code:
      typedef void (* p_RegisterInterfaceEvents) (char ** eventNames, int numberOfEvents);
      p_RegisterInterfaceEvents RegisterInterfaceEvents = 
          (p_RegisterInterfaceEvents)0x7f4320; // Credits: Apoc
      
      char * eventNameList[666];
      char customEvent[] = "MyEvent";
      
      int lua_RegisterNewEvent (lua_State *L) {
          memcpy((void *)eventNameList, (void *)0x00c3d678, 665 * sizeof (char *));
          // if you forget the sizeof (char *), you'll debug for > 1 hour!
          eventNameList[665] = customEvent;
          RegisterInterfaceEvents(eventNameList, 666);
          return 0;
      }
    6. lua_RegisterNewEvent was then registered to the Lua engine


    Invoking RegisterInterfaceEvents doesn't crash the game. However, I didn't have the time yet to put some final testing project together which checks whether the new event is also working.

  14. #14
    Ellesar1's Avatar Member
    Reputation
    20
    Join Date
    Feb 2009
    Posts
    78
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well, just tried it and it works :-) Thanks for the initial push to FrameScript_SignalEvent at this time again.


    What I did tot try it was to create a crappy addon with source:

    Code:
    local f = CreateFrame("Frame");
    
    f:RegisterEvent("CHAT_MSG_SAY");
    
    local handle = function (self, event, ...)
    	f:RegisterEvent("MyEvent");
    	print(event);
    end
    
    f:SetScript("OnEvent", handle);
    and afterwards, do the following

    1. expose another function to lua which does
      Code:
      Offsets::FrameScript_SignalEvent(665, "%d", 42);
    2. inject DLL
    3. call
      Code:
      /script print("EVENT REGISTRATION:", RegisterNewEvent())
    4. say something in the chat to register the frame to the new event
    5. raise the event using
      Code:
      /script FunctionFromFirstPointInList()


    it worked nice :-) thanks again for help, and hoping that this thread will help someone who also wants to raise lua events from C++

Similar Threads

  1. Quotes from Steven Write
    By Amedis in forum Community Chat
    Replies: 2
    Last Post: 11-14-2022, 10:26 AM
  2. "Quotes"
    By Krazyglue in forum Community Chat
    Replies: 2
    Last Post: 11-16-2007, 09:36 PM
  3. WTB Powerleveling - Need Quotes!!
    By Drovos in forum Members Only Gold And Powerleveling Buy Sell
    Replies: 7
    Last Post: 10-14-2007, 10:26 AM
  4. Quote: For a Steam Account!
    By Obama in forum Members Only Accounts And CD Keys Buy Sell
    Replies: 0
    Last Post: 09-16-2007, 07:57 PM
  5. Funny GM quotes
    By shadowfox47 in forum World of Warcraft General
    Replies: 9
    Last Post: 08-13-2007, 07:24 PM
All times are GMT -5. The time now is 05:23 PM. 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