Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.

Due to spam on this forum, all posts now need moderator approval.

 Entire forum ➜ MUSHclient ➜ Plugins ➜ XML includes

XML includes

It is now over 60 days since the last post. This thread is closed.     Refresh page


Posted by Tsunami   USA  (204 posts)  Bio
Date Mon 24 Jul 2006 09:12 PM (UTC)
Message
Within the XML of my plugin, I have an include statement, basically:

<include name="path/filename.xml" />

Now, unless I use an absolute path, MUSHclient uses the plugins directory as the working directory for the include. I can't use an absolute path I have no control over where user's put my plugin. Right now, if the plugin isn't directly inside the default plugins directory, the includes won't work. My question, why isn't the working directory the directory the plugin is in? This seems to make more sense to me. Anyways, if this isn't possible, is there some fix so that the user doesn't have to place my plugin in a specific location, ie right inside the default plugin directory?

Thanks, Tsunami
Top

Posted by Nick Gammon   Australia  (23,140 posts)  Bio   Forum Administrator
Date Reply #1 on Mon 24 Jul 2006 09:49 PM (UTC)
Message
How could that work? Say you have 5 plugins, all in different directories. There is only one current directory, and all 5 plugins scripts can run at any time (eg. when a trigger fires). Thus, there can't be 5 current directories. I suppose MUSHclient could change the current directory every time it calls a plugin script, but this sounds like needless overhead to me.

I suggest you use:


GetPluginInfo (GetPluginID (), 6)


Example output when I tested that was:


C:\Program Files\MUSHclient\worlds\plugins\MXP_Tag_Fixer.xml


Use a bit of mucking around with regexps to convert that into directory\filename, and you have the plugin directory.


See:

http://www.gammon.com.au/scripts/doc.php?function=GetPluginInfo

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Nick Gammon   Australia  (23,140 posts)  Bio   Forum Administrator
Date Reply #2 on Mon 24 Jul 2006 09:52 PM (UTC)

Amended on Mon 24 Jul 2006 09:54 PM (UTC) by Nick Gammon

Message
When I read your post again I see my solution won't really work as that is for plugin load time. :)

If you are coding in Lua you can use my suggestion and use dofile to load shared stuff, rather than the include method.

What version of MUSHclient are you using? I seem to recall this issue came up a couple of months ago. See:

http://www.gammon.com.au/forum/bbshowpost.php?bbsubject_id=6316

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Tsunami   USA  (204 posts)  Bio
Date Reply #3 on Wed 26 Jul 2006 10:06 PM (UTC)
Message
Aye, it does load them at runtime of course, so I was thinking as it loads each plugin, simply setting the working dir for each.

I can't use Lua includes because the included files contain XML themselves (triggers/aliases and all that jazz). For all the pure Lua files, that would certainly work, and in fact that's about how I do it (I'm just using pcall instead), using a regex to parse that and find the plugin directory. That won't work with XML of course, so if it's placed in the wrong directory, the plugin spits out all kinds of nasty error messages which people bug me about ;)

-Tsunami
Top

Posted by Nick Gammon   Australia  (23,140 posts)  Bio   Forum Administrator
Date Reply #4 on Thu 27 Jul 2006 05:36 AM (UTC)

Amended on Thu 27 Jul 2006 05:58 AM (UTC) by Nick Gammon

Message
OK, how about this? Rather than using the XML include, do it in Lua? You can include an XML file like this (eg. if it contains triggers etc.):


f = assert (io.open ("my_includes.lua", "r"))
s = f:read ("*a") 
f:close ()  -- close it
ImportXML (s)  -- import triggers, aliases etc.


Now if you make that into a general function, you can pass down the pathname to it, and it can include as many files as you want, similarly to what you are doing for including the pure Lua. Like this:


function include_stuff (name)
  local f = assert (io.open (name, "r"))
  local s = f:read ("*a") 
  f:close ()  -- close it
  ImportXML (s)
end -- include_stuff 

include_stuff ("my_includes.lua")

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Tsunami   USA  (204 posts)  Bio
Date Reply #5 on Fri 28 Jul 2006 07:10 PM (UTC)
Message
That is indeed possible, but, correct me if I'm wrong, the default Lua sandbox sets io to nil, disallowing any file io. Therefore I'd have to tell the user to edit their Lua sandbox, and I've essentially exchanged one set of instructions to the user for another. Both of which they can (will) screw up, heh. Thanks, Tsunami
Top

Posted by Nick Gammon   Australia  (23,140 posts)  Bio   Forum Administrator
Date Reply #6 on Fri 28 Jul 2006 09:00 PM (UTC)
Message
Yes, you are right, io is set to nil as default. However:

Quote:

For all the pure Lua files, that would certainly work, and in fact that's about how I do it ...


Won't you have the same problem here then?

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Tsunami   USA  (204 posts)  Bio
Date Reply #7 on Sat 29 Jul 2006 08:50 PM (UTC)
Message
Pure lua files I use the require function, which isn't dependant on io.
Top

Posted by Gore   (207 posts)  Bio
Date Reply #8 on Fri 09 Feb 2007 12:18 PM (UTC)

Amended on Fri 09 Feb 2007 12:24 PM (UTC) by Gore

Message
How exactly would I use pcall to include straight lua files into my system? I'd love to be able to seperate my script files from my xml files..

edit: Sorry I did a little research and saw that you can do:

require"filename"


but is there anyway to require a file that isn't in my Mushclient\lua directory, and is in my mushclient\scripts directory instead?
Top

Posted by Tsunami   USA  (204 posts)  Bio
Date Reply #9 on Fri 09 Feb 2007 05:49 PM (UTC)
Message
First you have to set the Lua package path variable. I do it like this:


_,_,PATH = string.find(world.GetPluginInfo(world.GetPluginID(),6),'^(.+\)')
package.path = package.path .. ';' ..PATH .. 'modules\scripts\?.lua' .. ';' .. PATH .. 'modules\plugins\?.lua'


This adds the listed directories to the path variable. Then, for simplicity's sake, I created a function:


function load_module(module)
	result,error = pcall(require,module)
	
	if(not result) then
		world.Note('[WARNING]: ' .. string.upper(module) .. ' MODULE LOAD ERROR: ' .. error)
		return false
	elseif(CTRL_DEBUG) then
		world.Note('[DEBUG]: ' .. string.upper(module) .. ' MODULE LOADED.')
	end

	return true
end


Calling load_module('scripts') then will look for a file called scripts.lua in any of the directories in the package.path variable, and attempt to load it.
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #10 on Fri 09 Feb 2007 06:08 PM (UTC)
Message
To keep with the semantics of require, your load_module function should return nil when the require fails, and the module table itself when the require succeeds.

This lets you do things like:


util = load_module("long.nested.module.hierarchy.util")
if not util then
  -- die one way or another
end

util.do_something(foo)


If you don't return the module table like that, then you have to refer to things by their entire package name, unless you subsequently manually set an alias.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Nick Gammon   Australia  (23,140 posts)  Bio   Forum Administrator
Date Reply #11 on Fri 09 Feb 2007 07:38 PM (UTC)
Message
Just a reminder that "dofile" will load an arbitrary file name of Lua code, and execute it, effectively including it.

So, you could do something like:


dofile ("mushclient/scripts/myfile.lua")


The difference is that, unlike "require", dofile does not check to see if the module is already loaded. However if this is part of the startup code for a plugin, that might not matter much.

However if you prefer to use require, because of its integration with the package system, see this post:

http://www.gammon.com.au/forum/bbshowpost.php?id=7336

That discusses how you can use MUSHclient to find its executable directory, and then build up a path variable, suitable for your needs, from that.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Tsunami   USA  (204 posts)  Bio
Date Reply #12 on Sat 10 Feb 2007 11:14 PM (UTC)
Message
Re: David Haley

In my case it isn't an issue, because I don't particularly care what was loaded, it's up to the writer of that piece of code to check that it functions with my code as intended. Still, your point is a good one, and I hadn't thought of it.
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


38,430 views.

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.