Page 1 of 3
Need some explanations about RoM and LUA
Posted: Mon Nov 14, 2011 11:51 pm
by Zangetsu
Hey,
I'm working atm on coding some cool addons and some userscripts for MM.
I have a solid coding knowledge and just "learned" LUA in 3-4 days (I'm still improving and learning of course)
The reason of this post is that I don't understand why some script is working in Scite (LUA Editor/Debugger) and not in RoM.
By example "require" is returning a nil value when executing the script via RoM. But "require" is a valid LUA built-in function
It's maybe not super clear, then I'll give an example. In this script I'm just sending the Mob ID using the RoM API.
The idea is to get drops of the mob and displaying it into the Chat window. The script is doing more (like adding drops to the table when the combo mobid+itemid doesn't exist, and so on...)
Code: Select all
function GetMobDrops(MobID)
-- loading the MySQL dll
assert (package.loadlib ("luasql/mysql.dll", "luaopen_luasqlmysql")) ()
env = assert(luasql.mysql())
con = assert(env:connect("RoM_db","user","pass","localhost","3306"))
cur = assert (con:execute"SELECT mob_id, mob_name, item_name FROM mob_drops WHERE `mob_id` = '"..MobID.."'")
row = cur:fetch ({}, "a")
while row do
local OutputMessage = string.format("%s drops: %s", row.mob_name, row.item_name)
DEFAULT_CHAT_FRAME:AddMessage(OutputMessage);
row = cur:fetch (row, "a")
end
cur:close()
con:close()
env:close()
end
And the error in the game is that "require" is returning a nil value.
When i'm executing this (and replacing DEFAULT_CHAT_FRAME:AddMessage(OutputMessage); by print(OutputMessage);) in Scite, I got a correct output like:
Scite Debugger wrote:
MobSomething drops: SomeItem
MobSomething drops: AnotherItem
...
My question is: Why it's not working when executing this script from the game?
I have LUA installed on my PC and every librairies I need are installed as well.
Thanks a LOT for your help.
Re: Need some explanations about RoM and LUA
Posted: Tue Nov 15, 2011 1:13 am
by BillDoorNZ
pretty sure require and include are removed from the lua implementation in the ROM api. Otherwise there is nothing to stop people doing all sorts of nasty stuff with executing scripts through addons.
Re: Need some explanations about RoM and LUA
Posted: Tue Nov 15, 2011 1:18 am
by Zangetsu
BillDoorNZ wrote:pretty sure require and include are removed from the lua implementation in the ROM api. Otherwise there is nothing to stop people doing all sorts of nasty stuff with executing scripts through addons.
Thanks Bill for your answer
Ok then MM can execute include, require and other built-in function, but how?
It is possible to run MM as a code executor? I mean doing nothing (not botting, not moving, not executing skills) beside executing lua scripts?
Re: Need some explanations about RoM and LUA
Posted: Tue Nov 15, 2011 1:31 am
by lisa
If you want MM to perform a script in game use RoMScript()
Code: Select all
RoMScript("DEFAULT_CHAT_FRAME:AddMessage("..OutputMessage..");")
Re: Need some explanations about RoM and LUA
Posted: Tue Nov 15, 2011 1:52 am
by Zangetsu
lisa wrote:If you want MM to perform a script in game use RoMScript()
Code: Select all
RoMScript("DEFAULT_CHAT_FRAME:AddMessage("..OutputMessage..");")
Yeah lisa, already knew that

I wanted to know if MM was able to execute my script in first post by example and if yes, how?

Re: Need some explanations about RoM and LUA
Posted: Tue Nov 15, 2011 3:15 am
by lisa
If function GetMobDrops(MobID) is a function inside an addon then
Obviously you need to state what MobID is still.
If you mean you just want to do that function from MM without doing anything then just start RoM bot with path commandline
rom/bot path:commandline
It will give you a command prompt that you can use to execute code.
Or create a WP calling that function onLoad.
There are many ways to do it.
If you want to perform functions via keypresses then create a WP and use this as an example.
Code: Select all
<?xml version="1.0" encoding="utf-8"?><waypoints type="TRAVEL">
<onLoad><![CDATA[
--=== key usage ===--
--=== fly NUMPAD1 ===--
--=== flyoff NUMPAD2 ===--
--=== speed NUMPAD4 ===--
--=== speedoff NUMPAD5 ===--
cprintf(cli.blue, "Press numpad 1 to fly\n")
cprintf(cli.blue, "Press numpad 2 to not fly\n")
cprintf(cli.green, "Press numpad 4 to run fast\n")
cprintf(cli.green, "Press numpad 5 to walk normal speed\n")
cprintf(cli.red, "Press Ctrl + L to exit\n")
local delay = 1 -- time between key presses.
local time = os.time()
while(true) do
if keyPressed(key.VK_NUMPAD1) and (os.time() - time > delay ) then
fly()
time = os.time()
end
if keyPressed(key.VK_NUMPAD2) and (os.time() - time > delay ) then
flyoff()
time = os.time()
end
if keyPressed(key.VK_NUMPAD4) and (os.time() - time > delay ) then
speed("on")
time = os.time()
end
if keyPressed(key.VK_NUMPAD5) and (os.time() - time > delay ) then
speed("off")
time = os.time()
end
if keyPressed(key.VK_NUMPAD6) and (os.time() - time > delay ) then
speed(70)
time = os.time()
end
end
]]></onLoad>
</waypoints>
Re: Need some explanations about RoM and LUA
Posted: Tue Nov 15, 2011 9:36 am
by Zangetsu
Thanks a lot lisa, I was searching the good way

I'll try it but It might work well

Re: Need some explanations about RoM and LUA
Posted: Tue Nov 15, 2011 12:26 pm
by Zangetsu
It seems to be harder than I thought.
I've tried to launch the script in first post with a test.xml file:
Code: Select all
<?xml version="1.0" encoding="utf-8"?><waypoints type="TRAVEL">
<onLoad>
function GetMobDrops(MobID)
-- loading the MySQL dll
assert (package.loadlib ("luasql/mysql.dll", "luaopen_luasqlmysql")) ()
env = assert(luasql.mysql())
con = assert(env:connect("RoM_db","user","pass","localhost","3306"))
cur = assert (con:execute"SELECT mob_id, mob_name, item_name FROM mob_drops WHERE `mob_id` = '"..MobID.."'")
row = cur:fetch ({}, "a")
while row do
local OutputMessage = string.format("%s drops: %s", row.mob_name, row.item_name)
cprintf(cli.blue, "" .. OutputMessage .. "\n");
row = cur:fetch (row, "a")
end
cur:close()
con:close()
env:close()
end
cprintf(cli.blue, "Press J to launch function\n")
local delay = 1 -- time between key presses.
local time = os.time()
while(true) do
if keyPressed(key.VK_J) and (os.time() - time > delay ) then
GetMobDrops(1) -- 1 for the example
time = os.time()
end
end
</onLoad>
</waypoints>
And I got an error that luasql/mysql.dll was not found in the path C:\Blahblah\plugins
So I've pasted this dll into the C:\Blahblah\plugins
Launched MM again, it was taking a bit more time to launch but it launched
Then, I've loaded the test.xml file
I saw
Press J to launch function and it's fine.
I'm pressing the J key and here the error I have:
Error from MM window translated in english wrote:
scripts\rom/bot.lua:445: onLoad error: [string "..."]:4: the procedure specified was not found.
I've opened the log and this is what it said:
MM Log wrote:
...
Tue Nov 15 18:15:17 2011 : findWindow() returned 0. Window not found or other error occured.
In main thread:
stack traceback:
scripts\rom/bot.lua:445: in function 'foo'
C:\Users\Zangetsu\Desktop\micromacro\lib\lib.lua:586: in function <C:\Users\Zangetsu\Desktop\micromacro\lib\lib.lua:584>
----------TRACEBACK END----------
Tue Nov 15 18:15:17 2011 : scripts\rom/bot.lua:445: onLoad error: [string "..."]:4: the procedure specified was not found.
Tue Nov 15 18:15:17 2011 : Execution error: Runtime error
I'm completely lost. I'm trying to execute a simple script from MM which is working in Scite. LUA 5.1 is installed on this machine. I don't know how it's working completely so I can do stupid things
It seems that mysql.dll is a LUA library, then do I need to do something to make MM loading this library?
Thanks for helping
Re: Need some explanations about RoM and LUA
Posted: Tue Nov 15, 2011 1:31 pm
by Zangetsu
Ok the script is now working.
The error was that mysql.dll wasn't found in C:\Blahblah and even putting the dll in this folder isn't working.
To make it work, I had to copy it in the SAME folder than my script is.
Why I have not thought about before?

Re: Need some explanations about RoM and LUA
Posted: Tue Nov 15, 2011 2:04 pm
by Zangetsu
Now, I'm trying to send command to MM from the game and I can't find the way to do it in the Wiki.
I had a look in macros created by MM or ingamefunctions into the addon directory, but I still don't see how to do it.
Any tips?

Re: Need some explanations about RoM and LUA
Posted: Tue Nov 15, 2011 2:19 pm
by BillDoorNZ
You can't send commands directly from the game to MM. You have to use the event monitor stuff:
http://www.solarstrike.net/wiki/index.p ... _Functions
Re: Need some explanations about RoM and LUA
Posted: Tue Nov 15, 2011 5:01 pm
by Zangetsu
EDIT
nvm, my bad. I should read your answer twice before checking the link. Going to check that.
Re: Need some explanations about RoM and LUA
Posted: Tue Nov 15, 2011 5:38 pm
by BillDoorNZ
you cannot call your code from the game as it is being run in micromacro. Some explanation is prolly necessary here:
Client.exe is the game client for playing ROM
Micromacro is the botting framework that is used to run all the rombot scripts.
Rombot is a collection of lua scripts that execute within micromacro to allow us to 'bot' ROM.
Waypoints are .xml files that contain a set of xml elements that define the x,y,z coordinates of locations in the game and may contain LUA code (and often have an OnLoad element that contains code specific to the waypoint file).
Your scripts extend Rombot via a waypoint file. You have a waypoint file with your GetMobDrops function defined. To execute this, it has to be done from withing Rombot (and therefore Micromacro as MM is 'hosting' your code).
You cannot call any rombot or MM stuff from the ROM game client.
rombot CAN monitor in-game events via the EventMonitor functions that rock5 wrote. These are defined in the ingamefunctions addon that he wrote that lives in the ROM/interface/addons/ folder. Using the eventmonitor stuff, you can monitor and events in ROM and use that to 'trigger' your code.
See some of Rock5's examples for that (search the forums for EventMonitor or the like).
Re: Need some explanations about RoM and LUA
Posted: Tue Nov 15, 2011 5:56 pm
by Zangetsu
Thanks a lot, nice explanation, it's clear now
The idea is to send command from the game to MM, then I need to use EventMonitor, ok.
If I understood wiki and example right, it can only "monitor" text strings on the chat, then no command possible, ok.
So, I can put a macro using the Rom API to send a string to display as SystemChat and monitor it with EventMonitor like
Code: Select all
EventMonitorStart("MyFunction", "CHAT_MSG_SYSTEM");
local time, moreToCome, name, msg = EventMonitorCheck("MyFunction", "MyFunction(arg1)")
and basically launch my function with "
msg"
Am I right?
And another question if you don't matter. SystemChat is not sent on the server right? I mean it's like an "/echo" and it's only client side?
Thanks for you help Bill

Re: Need some explanations about RoM and LUA
Posted: Tue Nov 15, 2011 6:08 pm
by BillDoorNZ
yes, that looks more like it
I'm not sure about argument passing tho, i image that as long as you type in a chat msg in the correct format, then you can parse the received string in the eventmonitor bit and pull it out. then execute your GetModId with it
and yes, SystemChat only goes to the client - not sure if it generates a chat event msg tho. y'd have to test that.
Re: Need some explanations about RoM and LUA
Posted: Tue Nov 15, 2011 6:48 pm
by Zangetsu
Hmm it seems good but it's doing nothing and no errors.
Code: Select all
function MyFunction()
local time, moreToCome, name, msg = EventMonitorCheck("MyFunctionEvent", "4,1")
if time ~= nil then
cprintf(cli.yellow, msg);
end
end
function startTest()
unregisterTimer("MyFunctionTimer");
printf("MyFunctionTimer started\n");
EventMonitorStart("MyFunctionEvent", "CHAT_MSG_SYSTEM");
registerTimer("MyFunctionTimer", 5000, MyFunction);
end
And In RoM, I'm sending:
Code: Select all
/script DEFAULT_CHAT_FRAME:AddMessage("Test");
And it's printing it in yellow in the chat.
Function startTest() is loaded with a WP file and I got the notice "startTest() loaded"
What I'm doing wrong?
Re: Need some explanations about RoM and LUA
Posted: Tue Nov 15, 2011 6:53 pm
by BillDoorNZ
Code: Select all
/script DEFAULT_CHAT_FRAME:AddMessage("Test");
is obviously not triggering an event

Re: Need some explanations about RoM and LUA
Posted: Tue Nov 15, 2011 6:58 pm
by Zangetsu
Tried with:
It's displaying something in the chat window but nothing MM's side still...
Re: Need some explanations about RoM and LUA
Posted: Tue Nov 15, 2011 7:03 pm
by BillDoorNZ
Rock's code for the events is shown here:
Code: Select all
function igf_events:OnEvent(this, event, arg1, arg2, arg3, arg4, arg5, arg6 )
local args = { arg1, arg2, arg3, arg4, arg5, arg6 }
local triggerTime = os.time()
-- for each monitor
for monitorName, monitorArgs in pairs(Monitors) do
-- check if event matches and it isn't paused
if monitorArgs.Event == event and not monitorArgs.Paused then
local isMatch = true
-- check if monitor has an arg filter
if monitorArgs.Filter then
-- for each monitor arg filter
for argNumber, argValue in pairs(monitorArgs.Filter) do
if argValue ~= nil then
if args[argNumber] == nil then
isMatch = false
break
elseif string.find(args[argNumber], argValue) == nil then
isMatch = false
break
end
end
end
end
if isMatch then -- Save in log
if not EventLog[monitorName] then
-- create it
EventLog[monitorName] = { First = 1, Last = 0 }
EventLog[monitorName].Data = {}
end
-- increment last place
EventLog[monitorName].Last = EventLog[monitorName].Last + 1
-- save the data
EventLog[monitorName].Data[EventLog[monitorName].Last] = {Time = triggerTime, Args = {arg1, arg2, arg3, arg4, arg5, arg6} }
end
end
end
end
you can probably call that directly instead to FORCE it to add it

I suspect the way you are doing it does not fire any events.
e.g.
Code: Select all
/script igf_events:OnEvent(nil, "CHAT_MSG_SYSTEM", "test")
Re: Need some explanations about RoM and LUA
Posted: Tue Nov 15, 2011 8:00 pm
by Zangetsu
It's parsing when using CHAT_MSG_SAY and using /s in the game
Not parsing when using CHAT_MSG_SYSTEM
@Bill
Code: Select all
/script igf_events:OnEvent(nil, "CHAT_MSG_SYSTEM", "test")
This is returning "nil" in the console but I don't understand the way you'll take and what you're trying to do :s