Is there anyway to make something like a "Broadcast" command? For example, a speedwalk plugin could broadcast "Destination reached", and other plugins that would have the OnPluginBroadcast event would read the message and act accordingly. Currently I can send something to the world and have the other plugin trigger on that, but that is inefficient and I would have to change my plugin (If I wanted to use plugin A but not plugin B, the broadcast would be transparent and all plugins would just ignore the broadcast). I suppose it is something like DDE for plugins...
Plugin broadcast.
Posted by Poromenos on Tue 24 May 2005 01:40 PM — 20 posts, 83,816 views.
Do it with aliases and world.Execute()? It's how I've solved it.
That'll still send to world if the plugin that receives the information isn't installed though...
Oh, also, CallPlugin isn't a good way for this because there might be many plugins that could use that info. A Broadcast function would enable people to write plugins that cooperated with other plugins without the need to modify the latter.
UDP? Although that gets messy.
Or you could write a handler plugin. All of your (previous) execute commands could be prefixed with a string (so your new plugin can catch commands for it) and then inside that plugin you could dish out the information to other plugins (have each plugin register with the handler, or have the handler figure out callable procedures of each new plugin).
This seems... familiar...
http://www.gammon.com.au/forum/bbshowpost.php?bbsubject_id=3931
Something LIKE that. Although I agree, having unknown IDs is a good thing. You could broadcast a 'Kill' message, and have all your plugins do whatever they should do once something dies (except the handler would worry about everything).
That seems very useful. Especially once a framework has been setup (once you have a plugin listening for a death message or whatever), it can be easy to add a set of triggers for a particular server (whether those triggers are on the world level, or on the plugin level would be irrelevant).
Or you could write a handler plugin. All of your (previous) execute commands could be prefixed with a string (so your new plugin can catch commands for it) and then inside that plugin you could dish out the information to other plugins (have each plugin register with the handler, or have the handler figure out callable procedures of each new plugin).
This seems... familiar...
http://www.gammon.com.au/forum/bbshowpost.php?bbsubject_id=3931
Something LIKE that. Although I agree, having unknown IDs is a good thing. You could broadcast a 'Kill' message, and have all your plugins do whatever they should do once something dies (except the handler would worry about everything).
That seems very useful. Especially once a framework has been setup (once you have a plugin listening for a death message or whatever), it can be easy to add a set of triggers for a particular server (whether those triggers are on the world level, or on the plugin level would be irrelevant).
Actually, You could just prefix all of your executes with something, and then have one generic alias that catches those, and doesn't send anything (with a high sequence).
Just a fall through that throws the command out.
The prefix is only needed because it means you only need one alias to toss it out.
I suppose we could ask nick for an option (either a flag, or a new sendto) that acts as an execute command, but never, under any circumstances, gets sent to the server, but that seems like a lot of work, for not a lot of gain. (Unless there are other advantages?)
Just a fall through that throws the command out.
The prefix is only needed because it means you only need one alias to toss it out.
I suppose we could ask nick for an option (either a flag, or a new sendto) that acts as an execute command, but never, under any circumstances, gets sent to the server, but that seems like a lot of work, for not a lot of gain. (Unless there are other advantages?)
UDP would be too messy, yes, especially if the port was in use... I also recall the handler plugin, although I would prefer if I didn't have to use one. I think it would be a nice feature and relatively easy for Nick to add, and many people could benefit from it. The execute approach doesn't work very well because I really don't want to have to change the sender plugin to that extent. If there was a broadcast command, plugins could broadcast "Pluginname: Dest_reached" or something and not care if anyone was listening, they could do it just in case. I believe this is a very useful feature, since the plugin architecture allows for (and encourages) plugins to cooperate to do one job, but there aren't really any universal functions to help plugins do that.
How would a listener listen then?
Theyd have to be listening for specific messages (with an arbitrary name prefix)? or just for messages from certain plugins?
You can broadcast with execute, and include a null route in your own plugin, if you're going to include the plugin name in each message. Although I think including a plugin name (as a prefix) is a bit clumsy, since you'll be forcing each plugin to know which other plugins it needs to listen to (or have things that listen for *:* if theyre listening for multiple messages from multiple plugins, which seems like a lot of extra computation with all the other messages and other plugins).
Theyd have to be listening for specific messages (with an arbitrary name prefix)? or just for messages from certain plugins?
You can broadcast with execute, and include a null route in your own plugin, if you're going to include the plugin name in each message. Although I think including a plugin name (as a prefix) is a bit clumsy, since you'll be forcing each plugin to know which other plugins it needs to listen to (or have things that listen for *:* if theyre listening for multiple messages from multiple plugins, which seems like a lot of extra computation with all the other messages and other plugins).
There would be an OnPluginBroadcast function that returned the broadcast text. The plugin name thing is just an example, you could just broadcast "Dest_reached" or whatever. Also, the only plugin that has to know the plugin name to listen to is the plugin you are making, and you probably already know what you want to listen to. Using execute would be slower, since you would have to evaluate all the aliases, and generally it would pass through several systems it doesn't need to.
Come to think of it, this would allow for plugin separation. For example, I have a plugin to fight that also heals. If this was implemented I could have a healing plugin that broadcast "Done healing", the fighting plugin would receive that and resume fighting. I could then remove the fighting plugin and replace it with another plugin that worked off healing without changing any of the code. Another user could make one plugin that worked with my healing one without having to change mine.
Yeah, it would allow for plugins to become modular. Like I was saying earlier (hmm, maybe I deleted it, no there it is, at the end), you can have a set of plugins that does all of the stuff behind the scenes, and then you just need to include a plugin to localize it to a server (triggers to catch things, and skeleton command aliases to reply).
Problem with making it a plugin callback is that then we would force it to be a plugin only thing.
Having an interface with the world would be handy so I could have my aforementioned localization stuff be in my world file, instead of my plugin.
Actually, I suppose the localization would be better suited for a plugin, since chances are you'd be distributing it, but you get the idea.
I know this is going to be a great improvement for plugins, I'm just not sure that it should become its own message system.
Problem with making it a plugin callback is that then we would force it to be a plugin only thing.
Having an interface with the world would be handy so I could have my aforementioned localization stuff be in my world file, instead of my plugin.
Actually, I suppose the localization would be better suited for a plugin, since chances are you'd be distributing it, but you get the idea.
I know this is going to be a great improvement for plugins, I'm just not sure that it should become its own message system.
Well, as for the world, the callback could be added, like the rest of the callbacks. Also, "message system" makes it sound more complicated that it is, it's just a loop that does "CallPlugin 'x', 'OnPluginBroadcast', data".
By the way, the plugin implementation is:
But it's easy to implement, useful and having it rely on one plugin that would mess everything up if it wasn't installed is too big a price to pay.
By the way, the plugin implementation is:
Sub sbBroadcast(strData)
Dim lstPlugins
lstPlugins = GetPluginList
If Not IsEmpty (lstPlugins) Then
For Each plPlugin In lstPlugins
CallPlugin GetPluginInfo (plPlugin, 7), "OnPluginBroadcast", strData
Next
End If
End Sub
But it's easy to implement, useful and having it rely on one plugin that would mess everything up if it wasn't installed is too big a price to pay.
I feel that this feature is not only useful, but essential for having plugins that work as intended, and I'm surprised noone suggested it before. I think plugins were designed and are supposed to work like this.
I definately agree with Poromenos. Back when I was getting started with MC, I expected that the plugins would be able to work like this so I made mine very modular. One for healing, one for fighting, one for anti-theft, etc... Then I started to realize however that all of them depended on some of the same constants (I play IRE, so balance, eq, etc..) It was inefficient to have each plugin try and catch these and react to them on their own, especially since then they would be competing with each other for execute precendence instead of working together. In the end, I just solved it by putting everything in one big plugin so they could share variables etc... This idea would go a long way towards a more modularized approach, and I especially like the idea of being able to work with other peoples plugins in a much more 'oop' way if you like.
I'm beginning to worry about Nick... He hasn't posted in a month and he used to check the forums every day... Anyone know where he is?
He posted two days ago (on the 15th), in the programming forum. For the past month now, he's posted a total of thrice; each about two weeks apart.
I agree, it isn't normal of him, but I'm sure he's just busy or something.
I agree, it isn't normal of him, but I'm sure he's just busy or something.
God, I hope I don't have to bump this again. It's been a few months since I posted initially.
Here's the broadcast plugin:
And here's how to use it:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE muclient>
<!-- Saved on Thursday, June 05, 2003, 9:00 PM -->
<!-- MuClient version 3.42 -->
<muclient>
<plugin
name="Broadcast"
author="Poromenos"
id="e58a316339d27af6ddc6bd3c"
language="VBscript"
purpose="Broadcasts data."
save_state="y"
date_written="2003-06-05 21:00:18"
requires="3.42"
version="1.0"
>
</plugin>
<!-- Script -->
<script>
<![CDATA[
Sub sbBroadcast(strData)
Dim lstPlugins
lstPlugins = GetPluginList
If Not IsEmpty (lstPlugins) Then
For Each plPlugin In lstPlugins
strPluginID = GetPluginInfo (plPlugin, 7)
If World.PluginSupports (strPluginID, "OnPluginBroadcast") = eOK then
CallPlugin GetPluginInfo (plPlugin, 7), "OnPluginBroadcast", strData
End If
Next
End If
End Sub]]>
</script>
</muclient>
And here's how to use it:
def fnBroadcast(strData):
if (world.PluginSupports("e58a316339d27af6ddc6bd3c", "sbBroadcast") == eOK):
world.CallPlugin("e58a316339d27af6ddc6bd3c", "sbBroadcast", "%s|%s" % (world.GetPluginName, strData))
def OnPluginBroadcast(strData):
# Do something with the data.
pass
This idea is now incorporated into version 3.67. Any plugin (or main script file) can do a BroadcastPlugin script call.
This will attempt to find an OnPluginBroadcast handler in all installed plugins.
If found, the handler is called with 4 arguments, two that you supply (a number and a string), and 2 automatically generated, which identify the calling plugin ID and name.
The intention of those arguments is to make sure that the plugin broadcast comes from the plugin that you are expecting.
This will attempt to find an OnPluginBroadcast handler in all installed plugins.
If found, the handler is called with 4 arguments, two that you supply (a number and a string), and 2 automatically generated, which identify the calling plugin ID and name.
The intention of those arguments is to make sure that the plugin broadcast comes from the plugin that you are expecting.
Ah, that is great. I think it will make the plugin system much more flexible and useful.