[Home] [Downloads] [Search] [Help/forum]

Gammon Software Solutions forum

See www.mushclient.com/spam for dealing with forum spam. Please read the MUSHclient FAQ!

[Folder]  Entire forum
-> [Folder]  MUSHclient
. -> [Folder]  Bug reports
. . -> [Subject]  Sequences not honored among different plugins.

Home  |  Users  |  Search  |  FAQ
Username:
Register forum user name
Password:
Forgotten password?
(New message)
Subject: Sequences not honored among different plugins.
Name:
Your forum user name.
Register forum user name
Password:
Your forum password.
Forgotten password?
Message:
Message to be posted (in English, please).
Forum codes:
Check this if your message uses 'forum codes' or templates (auto-detected for new posts).
Forum codes Templates

Save this message ...


Subject review (reverse sequence)

Pages: 1 2  

Posted by Worstje   Netherlands  (867 posts)  [Biography] bio
Date Mon 05 Mar 2007 12:27 AM (UTC)  quote  ]
Message
Well, I already have a plugin that loads/reloads the plugin I edit most (and is largest) with aliases. I'm merely reloading the PromptTweak right after it now. It's not a solution I like to use, and I have yet to figure out a better way to do this when deploying stuff to my users without having to supply a different file.

But I'm always brainstorming. :D Thanks for your help, it is really appreciated.
[Go to top] top

Posted by Shaun Biggs   USA  (644 posts)  [Biography] bio
Date Sun 04 Mar 2007 10:02 PM (UTC)  quote  ]
Message
Why would you have to reload the plugins a lot? Or is it just because of editing them often?

You can do a quick workaround for that with the LoadPlugin function as I mentioned. When you need to reload the plugins, have the first plugin reload all the other plugins when it's loaded.

It is much easier to fight for one's ideals than to live up to them.
[Go to top] top

Posted by Worstje   Netherlands  (867 posts)  [Biography] bio
Date Sun 04 Mar 2007 05:59 PM (UTC)  quote  ]
Message
Okay. I can somewhat live with that, I suppose. I still dislike it, though. Seems more like a hack since a simple thing like 'world.ReloadPlugin()' already messes the order up from my tests... and since I tend to do that alot, it means I will -also- have to reload my prompttweak plugin for 'reliable' results. Oh well.

Nick, if you ever change your mind, please let me know?
[Go to top] top

Posted by Shaun Biggs   USA  (644 posts)  [Biography] bio
Date Sun 04 Mar 2007 03:04 PM (UTC)  quote  ]

Amended on Sun 04 Mar 2007 03:05 PM (UTC) by Shaun Biggs

Message
Quote:
I just don't see how a prompt-replacement plugin and my curing, channel-replacement, autobasher and all other plugins should be in the same plugin. They are not dependant on eachother. The only aspect they have in common is that they 1) trigger the same prompt and 2) I'd like for them to be able to display a message next to my prompt which my prompt-replacement plugin provides.

Umm... that does make them depend on each other. You can't append anything to the prompt through the prompt plugin without having the prompt plugin there in the first place.

Quote:
Would it be possible to make it possible somehow make it easy for the end-user to change the order in which plugins load?

This is quite a bit simpler than it sounds. At the end of the world file, there is a section listing the plugins. They load in that order, so just have the end user either add in the list manually, or change around the order themselves.

<!-- plugins -->
<include name="C:\Program Files\MUSHclient\worlds\plugins\Aard\pktracker.xml" plugin="y" />
<include name="C:\Program Files\MUSHclient\worlds\plugins\Aard\AardSW.xml" plugin="y" />
<include name="C:\Program Files\MUSHclient\worlds\plugins\Aard\Aardwolf_Colored_ConsiderLUA.xml" plugin="y" />
<include name="C:\Program Files\MUSHclient\worlds\plugins\Aard\Aardwolf_SpellupLUA.xml" plugin="y" />
<include name="C:\Program Files\MUSHclient\worlds\plugins\Aard\GainMonitor.xml" plugin="y" />
<include name="C:\Program Files\MUSHclient\worlds\plugins\Aard\AardColours.xml" plugin="y" />
<include name="C:\Program Files\MUSHclient\worlds\plugins\Aard\QReporter.xml" plugin="y" />
<include name="C:\Program Files\MUSHclient\worlds\plugins\Aard\QuestMob.xml" plugin="y" />

I have the last four plugins triggering on a lot of the same text for quests, but they don't interfere with each other, and I can swap it all around. In fact, QReporter has triggers that are tripped on things that GainMonitor, AardColours, QuestMob, and the main world gag to replace, as does another set of triggers that I'm working into a plugin at the moment.

It is much easier to fight for one's ideals than to live up to them.
[Go to top] top

Posted by Worstje   Netherlands  (867 posts)  [Biography] bio
Date Sun 04 Mar 2007 06:07 AM (UTC)  quote  ]
Message
Hrm, sadness :(. I can't say I agree, but I suppose you have your reasons.

I just don't see how a prompt-replacement plugin and my curing, channel-replacement, autobasher and all other plugins should be in the same plugin. They are not dependant on eachother. The only aspect they have in common is that they 1) trigger the same prompt and 2) I'd like for them to be able to display a message next to my prompt which my prompt-replacement plugin provides.


I'd love for the order -not- to matter, but because they have the shared resource (the actual prompt), one of them has to deal with it on a displaying level.

Would it be possible to make it possible somehow make it easy for the end-user to change the order in which plugins load? (yes, I'll keep trying relentlessly. The arrow has to hit the bullseye some time, right?)
[Go to top] top

Posted by Nick Gammon   Australia  (18,770 posts)  [Biography] bio   Forum Administrator
Date Sat 03 Mar 2007 10:38 PM (UTC)  quote  ]
Message
Quote:

It doesn't actually say in what way the information is processed. It doesn't say plugin A goes before plugin B. It doesn't say B goes before A. It is dependant on the loading order.


It shouldn't matter. The general idea is that (say) a prompt line might cause a "status bar" plugin to update a status line. The same prompt line might cause a "low health" warning. The exact order these occur should not matter.

Another plugin might generate "random socials". Another, implement a chat system.

My point is that if trigger evaluation order is really essential to you, and you are writing two plugins that both match the same line, they should really be one plugin. Make "include files" if necessary to share common functionality.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Nick Gammon   Australia  (18,770 posts)  [Biography] bio   Forum Administrator
Date Sat 03 Mar 2007 10:35 PM (UTC)  quote  ]
Message
Quote:

It might even be useful to have a setting for "Plugin warnings", which would include things like, "Warning, this plugin uses Omit From Output, which could potentially interfer with the correct operation of other plugins.


How would this work? Setting omit from output can be done dynamically, so it doesn't really know at load time if this has been done, plus such a warning might only apply for triggering on the same line. However the "same line" can be matched in different ways. For example:


Nick says, *
* says, *


These might (or might not) match on the same line but look like different triggers. Also, what does it matter if one omits from output? The other plugins will still match on the line. Really, the order in which lines are matched should't matter. If multiple plugins are displaying things, which are generated from matching on the same line, then obviously those displays will occur in the order in which the plugins are executed.

Quote:

A plugin that is a 'jack of all trades' would make the plugin concept pretty useless.


The whole idea is that each plugin solves one problem, and that people load the ones they want

Making MUSHclient evaluate each trigger in sequence, taking all plugins together, would involve building up a list of all triggers in all plugins, sorting it into sequence order, for every line that has to be matched.

Then you have the issue that normally, unless "keep evaluating" is checked, that once a match is made, we stop matching any further (in that plugin). Now we would need to go through this master list, and delete from it all subsequent triggers, for that plugin only. It sounds like a mess to me.

There is nothing stopping you making "subroutines" in a separate plugin - I think a couple of people here have done that - and use CallPlugin to call that when you need it. However that is not reliant on trigger evaluation order, that is simply using a separate plugin to hold common functions.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Worstje   Netherlands  (867 posts)  [Biography] bio
Date Sat 03 Mar 2007 07:09 PM (UTC)  quote  ]
Message
Hrm, that is an option I hadn't thought about.

I must be honest though and say I still don't like it. It seems more like a hack than a solid solution. It requires seperate coding, knowledge of filenames and their locations to 'fix' the order. It would still not help 'solve' the issue that a simple method to 'fix' the order in which triggers amonst different plugins are evaluated does not exist.

Besides, didn't someone say earlier in this topic that you need a very good reason to use plugins that were dependant on others to work properly? (I know, low blow :D... but it came to mind anyhow.)
[Go to top] top

Posted by Shadowfyr   USA  (1,774 posts)  [Biography] bio
Date Sat 03 Mar 2007 06:34 PM (UTC)  quote  ]

Amended on Sat 03 Mar 2007 06:55 PM (UTC) by Shadowfyr

Message
Sort, why wouldn't it make more sense to adjust the behaviour of the plugin load wizard so you can "set" which order they need to load, and thus execute in? Scripting the loading of scripts is fine, if you know how to do it, but some people wanting to use the plugins may not want to even try to learn how to do that, just use the existing plugins.

Or, actually, in this case we are actually also talking about what might be called "dependencies". I.e., to create consistent behaviour in plugins B, C and D, you need to make sure A exists to feed them the information, persumably in the right order. It might be up to the coder of A to check what plugins are "actually" installed, so they figure out the right order to send them messages (in some cases), but you still need to make sure A is loaded. So.. Your actually talking about setting things up like:

1. Mushclient plugin list - Tell the loader, "Plugin A **must** be loaded before B, C or D."

2. Plugins B-D - list "in" the XML a <Dependencies>Plugin A</Dependencies> feature. If A fails to load, so do B, C and D, and errors are generated to show *why* they failed to load. (Because A wasn't loaded correctly first or failed to load correctly.)

In fact, point 2 would tell someone if they forgot to set point 1 correctly in the plugin load list. Since if they tried to load C, B, A, then D, only A and D would correctly load, the other two would generate an error like, "Plugin C: This plugin requires Plugin A to be loaded first. Plugin not installed."

Isn't it fun the sorts of non-trivial things that can pop up in stuff you *thought* worked right to start with? lol

Oh, and.. It might even be useful to have a setting for "Plugin warnings", which would include things like, "Warning, this plugin uses Omit From Output, which could potentially interfer with the correct operation of other plugins. Setting the load order for this plugin to load after other plugins may prevent any problems caused by this." In other words, if the parser knows a conflict "could" happen, and warnings are turned on, you get a clear debug message telling you "why" the plugin might be causing other plugins to got wonky and how to maybe fix it.

Though, just for the sake of reasonable design, another alternative is to cache the original line, then have each plugin process the line, *as though it was never omited*, even if something has already done so. Not sure if that change would be any worse than altering the way plugins load and making dependecy checking work, or even *if* there is some unknown problem with that. Only thing I could think of is the obvious funny of having two plugins omit and both produce a replacement line, the line only being removed "once" by the first plugin, but both of them generating their lines based on the assumption that its still there in the second plugin. lol Even then, a warning, such as, "X plugins appear to both omit the same lines." might be nice, to warn you this is going to happen, if you have warnings turned on. In fact, if you warn about omit at all, you kind of want to warn about that case as well. And that unfortunately isn't too easy, since comparing identical triggers is one thing. Comparing ones with "identical function", but different design... may not be possible.

Damn, you really opened a can of worms here. lol

main {
__if (Schrodinger_Cat is Alive or version >= "XP"){
____if version = "Vista" then Performance /= Number_of_Cores;
____call Functional_Code();}
__else
____call Crash_Windows();}
[Go to top] top

Posted by Shaun Biggs   USA  (644 posts)  [Biography] bio
Date Sat 03 Mar 2007 04:22 PM (UTC)  quote  ]
Message
Another option, since the tiggers are evaluated in the order the plugins are loaded, you can just have one plugin load them in whatever order you need. You would have a base master plugin load up in the world file, like normal, but without the extra class specific plugins loaded in. Just figure out which way you want things ordered, and load them like this:

world.loadplugin ("file1")
world.loadplugin ("file2")
...


It is much easier to fight for one's ideals than to live up to them.
[Go to top] top

Posted by Worstje   Netherlands  (867 posts)  [Biography] bio
Date Sat 03 Mar 2007 03:37 PM (UTC)  quote  ]
Message
@ Nick Gammon:

I would go with that option, if it was actually feasible to maintain and use. My reasons for 'disliking' this option so strongly:

1) Many of the plugins are used by different people: half of them I wouldn't want to have/see the stuff the others do.

2) Plugins give the benefit of loading different kinds of functionality. A plugin that is a 'jack of all trades' would make the plugin concept pretty useless.

3) All of the scripts would need rewriting for the way they currently deal with plugin scripting callbacks. Right now, some of them are in Python, others are in Lua. Python because of the huge versatility it offers, while I use Lua to make sure everyone can use it straight away. Rewriting Python to Lua is something that I couldn't do unless I completely rewrote the script (and waste another 500 hours) and Lua to Python is a requirement I'd have to make to more people.

4) It would require a main 'framework' file, to which other plugins adhered. Another layer of abstraction. I could make it use mush variables + savestate to remember what to load, but I'd be re-inventing the wheel in a very uncomfortable manner. It would slowly grow into a huge beast that had to mirror MUSHclients functions (or atleast scripting callbacks) and offer them to the flock of 'plugins' it contains. One plugin has a bug that triggers an error? None of them may get their 'prompt trigger' or OnPluginSent callback anymore.

5) One plugin fails during loading? It takes the rest with them. I am not the only one who is using this PromptTweak plugin; others write for it too. This way, I could have to offer support for scripts I haven't even written myself nor any knowledge about.

So with all due respect, that method has far too many drawbacks, the most important is time to spend on it and versatility.

Oh, also a slight 'reminder' if you read over it... there are more plugins than just 'plugin A'. Merging would mean I'd have to merge around 10 scripts with wildly different purposes.

@ Shaun Biggs:

Quote:
Plugins are self-contained collections of related triggers, aliases, timers, variables and script routines.


I'd like to interpret that line differently. Plugins are, indeed, self-contained collections. This means (to me) that you can load them seperately, that their code and triggers will not be able to interfere with eachother. EnableTrigger, GetTimerList and so forth only work on said plugin, not the others. Basically, wherever it is possible, plugins will NOT affect eachother.

Now the 'catch': It doesn't actually say in what way the information is processed. It doesn't say plugin A goes before plugin B. It doesn't say B goes before A. It is dependant on the loading order. While I honestly admit I haven't researched it too much, I believe this can be different for each world. Two worlds with the same plugins might have different orders of loading them. This could cause one world's plugins to function 'properly' and the other world to have atleast one malfunctioning plugin.

There seems to be two ways to interpret this:

1) Plugins shouldn't be able to affect eachother anyhow. However, with stuff as keep_evaluating, custom_colors, omit_from_output and other things that affect a 'shared' resource (the line itself), they WILL clash on some points. So this interpretation seems to me not to apply all that well.

2) Plugins can affect eachother. The way this is done is out of the scripters hands. There are no precautions that can be taken, but rather it is up to the 'mystical' order in which the plugins get loaded. Basically, it is the flip of a coin: will it work, or will it not?

So... take the following example. Someone complains a plugin doesn't work. The plugin author asks for a trace and gets it. He sees his plugin fire after another one. However, he can personally only get it to execute the other way around. Should he point fingers and say the other plugin isn't working properly? Should he send his own worldfile where it DOES work correctly so the user has it working until somehow the plugins switch order again? Should he merge the two plugins after asking the other author whether he is allowed to do so (assuming it is an option)?

Hence my proposal. 'Mix' the matching of plugin triggers (and aliases) and make them execute in a defined way the scripter can 'depend' on. The user won't notice a difference in the actual functioning of the plugins. They will still clash on some points, but not at any points they didn't clash on before. So there is no loss of functionality.

However, for the more complicated scripts (like mine), it removes a big bump from the road: we can influence the order in which they execute.
[Go to top] top

Posted by Shaun Biggs   USA  (644 posts)  [Biography] bio
Date Sat 03 Mar 2007 08:43 AM (UTC)  quote  ]

Amended on Sat 03 Mar 2007 08:49 AM (UTC) by Shaun Biggs

Message
Quote:
I have several characters on this same mud. I have different plugins which have different functions. One handles curing which is pretty global, another offense which is pretty specific to the class and so forth. I can't put all of those in the same plugin without duplicating tons of code each time I make a different character. Even with include files (I already use this for curing, actually) it would become a huge mess.

I'm not sure which language you're using, but you should be able to have just one plugin used, where you store information about the character's class, and have it call the apropriate function. Quick pseudo code here, but it should be fairly easy.

function catchprompt
  if warrior then
    kick or bash or whatever
  else if thief then
    some poison
  else if mage
    fireball
  end class check
end function


I may be completely misinterpreting what you're saying, but I had an alt on my mud at one point, and had the same world file used for both characters. I just had a plugin get the character name when I first logged in, it swapped in the appropriate numberpad macros to my thief or warrior, and enabled and disabled certain triggers. I used the number pad to quickly send my attack skills to the mud. I believe I also had to change a macro for different healing potions as well.

Another option is using Lua, which can have different functions tossed into a table. You could have combat["warrior"]() and combat.["cleric"](). When you assign "warrior" to the variable class and then a combat.class() is called, Lua will call whatever function is stored in the "warrior" section. Yes, the plugin will wind up much larger, but you should be able to use just one plugin there. Eliminating cascading ifs whenever possible is a pretty good way to keep code legible and less buggy.

Quote:
My problem is that all plugins are essentially considered seperate by MUSHclient.

and from http://www.gammon.com.au/mushclient/plugins/
Quote:
Plugins are self-contained collections of related triggers, aliases, timers, variables and script routines.

Self-contained is the big thing here. Plugins should be completely seperate by nature because you have removed them from the main world and encapsulated them. The ability to call the world file, then each script individually and to mesh all of the triggers and aliases together is really just a design choice with benefits and drawbacks to both. Having to sort through each trigger sequence change any time a plugin is added or remove, or even just one trigger is very time consuming, for example. It really shouldn't matter, since each plugin should only be concerned with itself except for rare circumstances.

It is much easier to fight for one's ideals than to live up to them.
[Go to top] top

Posted by Nick Gammon   Australia  (18,770 posts)  [Biography] bio   Forum Administrator
Date Sat 03 Mar 2007 05:58 AM (UTC)  quote  ]

Amended on Sat 03 Mar 2007 05:59 AM (UTC) by Nick Gammon

Message
Quote:

The trigger in plugin A uses world.CallPlugin() to call a function in plugin P. After that, plugin P. uses the information gathered through the world.CallPlugin() call when it gags + outputs data.


OK I understand the problem now, but isn't this a rather obscure way of achieving the result? You have two plugins, both matching the same thing, and one plugin is doing calculations to "feed" to the other plugin. And all this relies on both plugins being loaded, and things being executed in a certain order.

Can't you just make a single plugin that does it all in one spot?

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Worstje   Netherlands  (867 posts)  [Biography] bio
Date Sat 03 Mar 2007 01:49 AM (UTC)  quote  ]
Message
Hehe, I'll try to explain again, highly simplified. All good things in three, heh.

Plugin A: triggers something.
Plugin P: triggers the same thing, gags it and echoes something else in its place.

Idea:

The trigger in plugin A uses world.CallPlugin() to call a function in plugin P. After that, plugin P. uses the information gathered through the world.CallPlugin() call when it gags + outputs data.

Problem:

I can not decide the order in which A's trigger and P's trigger fire. No matter what I do, P will fire before A.
<trigger sequence="xxx" /> does not affect it. I can not seem to control the order in which my plugins are loaded, either.

This ends up in messages either not showing or an execution of P's trigger too late, when it can be pretty irrelevant (or very confusing at the very least).

Solution(s):

1) Rewrite my plugins. I don't have an 'A', I also have a B, C, D which all have very different functions. Plugin P is meant as a general plugin that deals with showing information, while the others contain the logic. Merging them is impossible (I have multiple worlds myself that don't use 'all' plugins).

2) Represent the information a different way. This is very unuseful, since the text usually applies to the status right above the prompt it shows up. Rather than wasting an entire line with a Note(), this is supposed to make it easier to read. Putting the information only in the log and display it in a different window is also problematic: my eyes don't reach that far when text is scrolling by quickly. The Infobar is already utilized to the maximum width I have available.

3) Ask Nick Gammon to make it possible to have sequences affect the order in which all (plugin-)triggers are matched. I'll try to explain this with some pseudocode:

Current situation (if I understand your explanation):

for sequenced worldfile.triggers do
    if matchTrigger then executeTrigger
end
for loaded_order all_plugins do
    for sequenced current_plugin.triggers do
        if matchTrigger then executeTrigger
    end
end


Proposed change:


for sequenced worldfile.triggers do
    if matchTrigger then executeTrigger
end
for sequenced all_plugins.triggers do
    if matchTrigger then executeTrigger
end


or maybe even:


for sequenced (all_plugins.triggers + worldfile.triggers) do
    if matchTrigger then executeTrigger
end



I don't believe this would be too difficult to implement (maybe one extra flag to keep track of the source of the trigger), while (if you are using a linked list), you'd have very simple and 'lowcost' adding/removing trigger algorithm that would be negligibly slower than the current.

An extra 'plus' would be that the order plugins fire isn't dependant on loading order anymore, which makes it (in my opinion) hard to reproduce incompatibilities between plugins when someone tells you it 'does not work'.


I hope this explains it a bit better, Nick?
[Go to top] top

Posted by Nick Gammon   Australia  (18,770 posts)  [Biography] bio   Forum Administrator
Date Sat 03 Mar 2007 01:05 AM (UTC)  quote  ]
Message
Quote:

... my reason for 'depending' on another plugin is that I want to attach messages to my prompt ...


I still don't fully understand the problem here. If you do CallPlugin, that will happen immediately, it doesn't depend on tne order of the plugins or the triggers or anything.

An alternative to doing CallPlugin however is to "require" common code, that is make it a Lua module. That gives you more flexibility of the calling sequences for shared functions.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] 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.


4,620 views.

This is page 1, subject is 2 pages long: 1 2  [Next page]

[Reply to this subject]  Reply to this subject   [New subject]  Start a new subject   [Refresh] Refresh page

Go to topic:           Search the forum


[Go to top] top

[Home]

Written by Nick Gammon - 5K

Comments to: Gammon Software support
[RH click to get RSS URL] Forum RSS feed ( http://www.gammon.com.au/rss/forum.xml )

[Best viewed with any browser - 2K]    [Internet Contents Rating Association (ICRA) - 2K]    [Web site powered by FutureQuest.Net]