Page 1 of 4

Monitoring ingame events.

Posted: Tue Mar 29, 2011 9:13 pm
by rock5
After reading a post today I'm thinking of doing a project to monitor ingame events. I've thought about it before but now I think I'll give it a go. I'm writing this post to help me think it through.

This is how I think it will work.

1. There will be an ingame addon ready to monitor events and accept commands from rombot. Maybe I'll make it part of the ingamefunctions.

2. Lets say you want to know when your party leader sends a message to the party chat so you can respond to it. You would issue a command to the addon to monitor the event and include filter options, in this case only messages from your leader. It might be something like

Code: Select all

MonitorEvent("LeaderChat","CHAT_MSG_PARTY",{nil,nil,nil,"Leadername"})
"LeaderChat" is just a name to identify this monitor.
"CHAT_MSG_PARTY" is the event to monitor.
{nil,nil,nil,"Leadername"} is the filter and means that it will only record an event if the 4th argument of the event (the senders name) is "Leadername".

3. The addon monitors the event, checking the filter options. If it detects a message from the leader it saves it in an event log, recording the time, monitor name and arguments. eg.

Code: Select all

12:21, "LeaderChat", {"Get Ready", link with perons name, unknown, "Leadername"}
12:22, "LeaderChat", {"Attack!", link with perons name, unknown, "Leadername"}
4. You would need to have the bot check for events on a regular basis. I would make it so you can specify which arguments you want returned. It would look something like

Code: Select all

time, args, remaining = CheckEvent("LeaderChat",{true,false,false,false})
The addon would return the time and args of the first event, in this case only the first arg which is the actual message, and indicate if there are more events remaining. It would then clear it from the log. You would keep collecting the messages and dealing with them until 'remaining' = 0.

A more detailed example

Code: Select all

repeat
    time, args, remaining = CheckEvent("LeaderChat",{true,false,false,false})
    if args[1] == "Get ready" then
        RoMScript("SendChatMessage('Im ready', 'RAID')")
    elseif args[1] == "Attack!" then
        player:fight()
    end
until remaining == 0
5. And lastly there would need to be a stop function. eg

Code: Select all

StopMonitoring("LeaderChat")
With the monitor naming, any number of bot userfunctions can monitor events, even the same events, without interfering with each other.

How does that sound?

Re: Monitoring ingame events.

Posted: Wed Mar 30, 2011 3:28 am
by Auto Pilot
Looks promising for quite a few things :
- Managing tells with bot directly at least (at least a beep, and it would be pretty easy to create more advanced features : a whitelist of persons to ignore, logging off after X tells, logging off when receiving X tells after more than X hours botting, ...)
- Maybe some simple & non-suspicious bot communication (leader typing "r?" and bots responding "r" or a countdown, which is pretty much what a team chat of a party on Vent/TS/... looks like)
- Detecting the new phase on some boss scripts (thinking of some DoD farm bot here :mrgreen: ) if ingame addons can easily capture everything that appears in chat

And probably more that I can't think of right now

Re: Monitoring ingame events.

Posted: Wed Mar 30, 2011 5:37 am
by Tsutomu
Well i can think of one more use.
Setting up a character that will be a party inviter (for multiple characters to farm instances).

You wiper him the set-up word like "hitme" and he automaticaly invites you.

It's much easier running 3 instead of 4 clients, 4 instead of 6 etc. :)

Re: Monitoring ingame events.

Posted: Wed Mar 30, 2011 7:12 am
by lisa
"Come on in" addon already does invites and can be started with a function which can be called by using ROMScript()

Re: Monitoring ingame events.

Posted: Wed Mar 30, 2011 7:40 am
by rock5
Just to make something clear, this would be able to be used to monitor any event.

Some examples;
  • System messages
  • Party invites
  • Trade requests
  • New mail
Pretty much any event that can be monitored by ingame addons.

Re: Monitoring ingame events.

Posted: Wed Mar 30, 2011 7:42 am
by lisa
I think it's an awesome idea rock, sounds like a big project though.

My comment on the addon was purely for Tsutomu and wanting a join party aspect. I should have quoted him I guess so you knew.

Re: Monitoring ingame events.

Posted: Thu Mar 31, 2011 11:31 am
by rock5
Ok, this is what I have so far. These functions are finished and working. Just needs a bit more testing to iron out any bugs.

igf_events:StartMonitor(monitorname, event, filter)
  • Example:

Code: Select all

igf_events:StartMonitor("Leadersaid", "CHAT_MSG_PARTY", {nil,nil,nil,"LeaderName"} )
  • This will start monitoring party messages from "LeaderName" and saving the event data under the name of "Leadersaid". When overwriting or replacing an existing monitor with the same name, the previous log data will be removed.
igf_events:StopMonitor(monitorname)
  • Example:

Code: Select all

igf_events:StopMonitor("Leadersaid")
  • This will stop the "Leadersaid" monitor. The monitored event will also be unregistered unless it is being used by another monitor. All log entries under the monitors name will be deleted.
igf_events:PauseMonitor(monitorname)
  • Example:

Code: Select all

 igf_events:PauseMonitor("Leadersaid")
  • This will pause the monitor so it will no longer save events to the log under that name.
igf_events:ResumeMonitor(monitorname)
  • Example:

Code: Select all

igf_events:ResumeMonitor("Leadersaid")
  • This will resume a previously paused monitor.
igf_events:GetLogEvent(monitorname, returnfilter, lastentryonly)
  • Example:

Code: Select all

local time, more, message, sender = igf_events:GetLogEvent("Leadersaid", "4,1", true)
  • This will return the oldest logged event saved under the name of "Leadersaid". It will return the time the event triggered and if there are more messages. You can use the second returned value, the 'more' value, to determine if you need to collect more log entries. It will then return the event arguments as indicated by the filter and in the order specified. In this case the 4th and 1st arguments which are the message and sender. It will then delete that entry from the log.

    If the lastentryonly value is specified then only the last entry will be returned and all older entries will be cleared.
These are the ingame addon functions. At the moment for testing I'm using RoMScript to execute them but i'll probably add rombot functions to simplify it.

How does it sound so far? Am I missing anything?

Re: Monitoring ingame events.

Posted: Fri Apr 01, 2011 8:25 am
by rock5
These are the user friendly rombot functions names I'm thinking of using. What do you think?
MonitorEventStart
MonitorEventStop
MonitorEventPause
MonitorEventResume
MonitorEventCheck

While writing the rombot functions I came across a problem. I can't easily send a table of values with RoMScript, which the filter for MonitorEventStart needs. So I'll have to change it to a comma separated string. eg. instead of using {nil,nil,nil,"Sendersname"} I'll use "nil,nil,nil,Sendersname" or "nil,nil,nil,'Sendersname'" or ",,,Sendersname". I'm not sure yet which way i'll go.

Re: Monitoring ingame events.

Posted: Fri Apr 01, 2011 12:11 pm
by squeekthegeek
for the party invite, there is an addon on curse (invite last group) you can just put in a waypoints xml

Code: Select all

RoMScript("ilg destroy"); RoMScript("ilg inv"); 
then of course you need all party members to auto-accept invites from party leader (which can be done with the Addon XBar, that is what i currently use but it can easily be implemented in the bot)

if monitoring events works as Rock5 says, then synchronizing bots using all the same waypoints file would be pretty easy. say for an instance run, you put in the waypoint before the boss fight

Code: Select all

bossWaypoint();
then make another lua for the synchronisation

Code: Select all


[blah blah blah...] 

function bossWaypoint()
StartMonitoring("LeaderChat")

[blah blah blah... check if current player coordinates match waypoint coordinates...] then


if ( settings.profile.options.PARTY_LEADER ) then
 RoMScript("SendChatMessage(Get ready, 'RAID')")
end

if (not settings.profile.options.PARTY_LEADER ) then
repeat
    time, args, remaining = CheckEvent("LeaderChat",{true,false,false,false})
    if args[1] == "Get ready" then
        RoMScript("SendChatMessage('Im ready', 'RAID')")
    elseif args[1] == "Attack!" then
        StopMonitoring("LeaderChat")
        player:fight()
    end
until remaining == 0
end
not sure if that's how you mean it...

just a thought :D

Re: Monitoring ingame events.

Posted: Fri Apr 01, 2011 7:41 pm
by rock5
Hm.. could be useful to partying. I don't think Lisa has added any support for auto invite/accept. With my 'events' changes the leader could easily monitor for party invites then invite them. Comeonin is an option but if we could make a solution that isn't dependent on addons then people wont have to install the addon to use the solution. But then the comeonin makes it one less thing the bot needs to worry about. Hm... I think I'd go with comeonin. It already does the job well and monitoring for an event on a regular basis from the bot might slow it down.

As to using it for comunication, I'll leave it to lisa if she wants to use it after i release it.

Re: Monitoring ingame events.

Posted: Fri Apr 01, 2011 8:56 pm
by lisa
I try to avoid relying on addons as not everyone wants to install addons and you rely on the developer of the addon to keep it up to date with RoM patches.

When you get the event manager working I can deff think of a few ways to intergrate it with party bot =)

Re: Monitoring ingame events.

Posted: Sun Apr 03, 2011 1:37 am
by rock5
Ok I've committed the event monitor changes. You can read how to use the functions in the wiki.
http://www.solarstrike.net/wiki/index.p ... _Functions

Even though monitoring events could be useful in a huge number of situations, please remember that these functions use RoMScript commands so would be slower that any solutions that only read memory. So I envision these functions to be most useful when there is no other way of doing something. An example of this is monitoring chat.

Things to watch out for:
  • The time returned was taken by using os.time(). It's not the same value that is returned by rombot's os.time(). I'm not sure what the best format for saving the time is. If anyone has suggestions, I could always change it.
  • I've limited it to saving only 6 event arguments. I'm not sure what the maximum number of event arguments is but if anyone tries to use an event that has more, let me know and I can increase it.
  • I'm not sure if events only return strings or if there are some that return something else that can't be passed on to rombot. If any events return anything but string it will probably cause an error in which case there will probably need to be exemptions added.

Re: Monitoring ingame events.

Posted: Tue Apr 19, 2011 12:09 am
by lisa
Ok I just want to check I have my head around this.

in Cyclops last boss, Uguda he says " Come out my servants! Catch these weaklings! " and then puts the little bubble ont he party members positions that explode.

So I could do this

Code: Select all

if target.Name == "Uguda" then
EventMonitorStart("Ugudaskill", "CHAT_MSG_SAY",",,,Uguda")
end
and then

Code: Select all

local time, moreToCome, name, msg = EventMonitorCheck("Ugudaskill", "4,1")
if msg == "Come out my servants" then
--move away from that spot
end
or would it need the entire message?

Code: Select all

if msg == "Come out my servants! Catch these weaklings!"
Does that look right?

Re: Monitoring ingame events.

Posted: Tue Apr 19, 2011 2:19 am
by rock5
Well the 'msg' returns the whole message so you have to use

Code: Select all

if msg == "Come out my servants! Catch these weaklings!"
or

Code: Select all

if string.find(msg, "Come out my servants") then
Don't forget you need to itterate through all saved messages just incase he spoke more than once since you last checked.
eg.

Code: Select all

local time, moreToCome, name, msg = EventMonitorCheck("Ugudaskill", "4,1")
repeat
    if msg == "Come out my servants! Catch these weaklings!" then
        --move away from that spot
    end
until not moreToCome
Make sure you let us know how well it worked. :)

Re: Monitoring ingame events.

Posted: Tue Jun 28, 2011 12:20 pm
by Mushroomstamp
I hate to necro an old thread for what may very well be a stupid question, but does this code go in your waypoint? I think this is going to be a better way to go for the first boss in DOD... being that I haven't been able to get a timed move to work after 4 hours. :?

Re: Monitoring ingame events.

Posted: Tue Jun 28, 2011 7:59 pm
by rock5
If you want to monitor messages from a boss, you would start the monitoring before you start fighting, maybe in the waypoint before you reach the boss.
That's the EventMonitorStart command.

Then you need to check the messages regularly, eg. in the onLeaveCombat section. If the message is detected then you act accordingly. That's the EventMonitorCheck command. The example above looks wrong. It should be.

Code: Select all

repeat
    local time, moreToCome, name, msg = EventMonitorCheck("Ugudaskill", "4,1")
    if msg == "Come out my servants! Catch these weaklings!" then
        --move away from that spot
    end
until not moreToCome
You should also stop the monitor after the fight with the EventMonitorStop command.

Re: Monitoring ingame events.

Posted: Wed Jun 29, 2011 4:44 pm
by wizzyslo
I pritty confuse of those "new" event monitors and need little explenations.

I want to farm some boss for mementos and for detecting skills i'm going to use event monitor and boss helper addon wich write skills on party chat.

Addon will write on party chat like this expample:

Code: Select all

[wizzyslo]:Okander "Mad Man" Mallen: Leap




Most important word is "Leap" that mean i can use it in filter. Am I correct?
onSkillCast i need function to find that word "Leap" and need to go to onother waypoint.

If i put this together it should look like this in waypoint:

Code: Select all

<?xml version="1.0" encoding="utf-8"?><waypoints>
   <onSkillCast>
   if EventMonitorCheck(test, Leap, true) then
   __WPL:setWaypointIndex(__WPL:findWaypointTag("runaway"));
   end
   </onSkillCast>


   <!-- #  1 --><waypoint x="1651" z="-4921" y="752">   </waypoint>
   <!-- #  2 --><waypoint x="1669" z="-5103" y="760">   </waypoint>
   <!-- #  3 --><waypoint x="1695" z="-5157" y="759">   </waypoint>   
   <!-- #  1 --><waypoint x="1857" z="2887" y="433" >   </waypoint>
   <!-- #  2 --><waypoint x="1991" z="2758" y="433" >
   EventMonitorStart(test)            
   </waypoint>
   <!-- #  3 --><waypoint x="2112" z="2612" y="432" >      </waypoint>   --boss place
   <!-- #  1 --><waypoint x="2221" z="2470" y="401" >      </waypoint>       
   <!-- #  1 --><waypoint x="2311" z="2411" y="401" >   
   EventMonitorStop(test)   
   </waypoint>   

   <!-- #  9 --><waypoint x="2237" z="2466" y="401" tag="runaway">   </waypoint>
   <!-- #  10 --><waypoint x="2345" z="2322" y="401">   </waypoint>   
   <!-- #  11 --><waypoint x="2082" z="2651" y="432">   </waypoint>
   <!-- #  12 --><waypoint x="1889" z="2867" y="433">   </waypoint>
   <!-- #  13 --><waypoint x="1704" z="2887" y="433">   </waypoint>
   <!-- # 14 --><waypoint x="1640" z="-4927" y="752">   </waypoint>
</waypoints>
	



ATM i didnt test it only trying to understand it.

Now i need to know where I did mistakes and what i need to fix or is going to work like this?

If i understand i dont need anymore addon for boss but only monitoring

Code: Select all

    local time, name, msg = EventMonitorCheck("Okander "Mad Man" Mallen", "4,1")
    if msg == "Leap" then
        __WPL:setWaypointIndex(__WPL:findWaypointTag("runaway"));
    end


Re: Monitoring ingame events.

Posted: Wed Jun 29, 2011 6:19 pm
by rock5

Re: Monitoring ingame events.

Posted: Wed Jun 29, 2011 7:58 pm
by lisa
Rock is there any way to kind of inject the time into the ingame function when starting the timer with bot?

Having issues with getting the time ingame, the ignoring records older then 60 seconds. D303 hasn't been updated for almost a year now.

Actually just did some browsing of d303fix

SetTime(param) - Allows to set current time by using parameter
•number - time in seconds from 1970-01-01
•string - Date and time in standard ISO format yyyy-MM-dd HH:mm:ss

Going to see if I can set the time using this function for d303fix and using RoMScript. It wouldn't actually need to be the correct time as all we need it to do is count time from last message. So setting it to anything is good enough.

Re: Monitoring ingame events.

Posted: Wed Jun 29, 2011 11:10 pm
by rock5
Ah, finally someone needs the time value.

Do I understand correctly? You want the time so that you can discard messages that are too old?

--------------------
Grr... I've rewritten this response 2 times and I didn't like either answer. If we use a set time for the messages and save the start time then we still need to check the ingame current time everytime we want to compare the time. If we use os.date which should yield the same time in both the game and bot, then you have problems because if d303fix isn't installed properly then comparisons wont work.

The only solution I can think of that is reasonable is for the ingame function to remember the time of the messages but when EventMonitorCheck runs it returns the age of the message at that time. What do you think?