PHP Engine In MUSH 3.65

Posted by Aimjielu on Sat 20 Aug 2005 03:08 PM — 13 posts, 54,530 views.

#0
Hi All

Whenever I try to use the PHPScript in MUSH I get this :
"Error -2147221005 occurred when finding CLSID of scripting language "PhpScript":

Invalid class string
"

When I click Register DLL, it says the specified module is not found.

I am of course missing some important piece of the puzzle that
would make it work. But I cannot seem to find it.

Thanks
Aimji
USA #1
What version of PHP do you have installed?
Canada #2
I'm having the same problems... god.. what I wouldn't give to have a php-scriptability in MUSH...

I've got all the ActiveScript php dlls in the same directory as MUSH's .exe. The version of php5activescript.dll I have is 5.1.1.1.

Any help would be rewarded with gold and quest points! ;)

Jarett Langton.
Australia Forum Administrator #3
Gold *and* quest points, eh? Better get started ...

I thought this rang a bell. There is a forum thread about PHP:

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

The major problem with the version at the time (in that thread) was that errors in PHP would cause MUSHclient to immediately exit. I guess the script designers thought that making the program exit on error was a good idea.

This seems to be fixed in version 5.1.1.

First thing is, you need 2 downloads from the www.php.net site:


php-5.1.1-Win32.zip
pecl-5.1.1-Win32.zip


The first one has the "core" PHP in it, the second one has the important DLL:


php5activescript.dll


This last file is what MUSHclient needs to register, which has the script engine in it.

What I did was unzipped both files (you need to make a root directory for them, as the archive does not have a "top" directory), eg.


c:\php.5.1.1\


You can probably unzip both archives into the same directory, but at the very least you need to copy php5activescript.dll to be in the same directory as the files from the php-5.1.1-Win32.zip download.

Then you should be able to use the "Register DLL" button in the MUSHclient script window to make it recognise the DLL. Personally I couldn't, so I had to run :


regsvr32 php5activescript.dll


I'm not sure if you will have regsvr32 installed on your PC, if not try to get a copy from the Microsoft site somewhere under developers tools. However only do that if the script engine is still not recognised.

Having done that, you should be able to use PHP from MUSHclient. For a start, try this, in the command window:


/$world->Note ("Hello, world");


Also try:


/$world->Note (phpversion());


You should see 5.1.1 displayed.



Problems with using script file

The major thing I still couldn't get working was calling a script in the script file using the "fill in the script name in the box" method that MUSHclient has always used.

As a test, I had this in my script file:


function f ($alias_name, $alias_output, $wildcards)
{
  $world->Note("in f");
  $world->Note("name = " . $alias_name);
  $world->Note("output = " . $alias_output);
  $world->Note("wildcards = " . $wildcards);
}

$world->Note("test.php loaded");



When loading that I see "test.php loaded", so the file was processed OK.

Now if I make an alias:


<aliases>
  <alias
   name="blah"
   script="f"
   match="test"
   enabled="y"
   sequence="100"
  >
  </alias>
</aliases>


I get the error message "The alias (blah) subroutine named "f" could not be found.".

However, I can call the function manually:


/f (1, 2, 3);


I see:


in f
name = 1
output = 2
wildcards = 3


So, the function exists and can be called. Maybe you have to somehow "export" the function so the script engine can detect it? Don't know how to do that.

However you can work around that by sticking to "send to script", or calling a function in your script file from "send to script", like this:


<aliases>
  <alias
   match="test"
   enabled="y"
   send_to="12"
   sequence="100"
  >
  <send>f ("blah", "%0", "%1");</send>
  </alias>
</aliases>


This behaviour is not exactly the same as the normal MUSHclient alias function call, as not all 10 wildcards are passed to the function, however you simply script around that.



Having said all that, I would recommend taking a look at Lua as an alternative script engine. In many ways it is similar to use to PHP, and has some nice features. :)
Amended on Sat 03 Dec 2005 08:25 PM by Nick Gammon
Australia Forum Administrator #4
Footnote:

regsvr32 does in fact seem to be supplied as default with Windows XP. If you can't register the script DLL from within MUSHclient, do this:

  1. Open a command window (Start -> Run -> type "cmd" )
  2. Navigate to the directory which has php5activescript.dll
    in it (along with the other PHP files), eg.


    cd \php.5.1.1

  3. Run the program:


    regsvr32 php5activescript.dll

  4. Exit the command window:


    exit


Canada #5
Thanks alot Nick. I ended up using regsvr32 to get the DLL registerd. Opening a script file in MUSHclient... gives me a screenful of popup errors... and oddly enough... it works just dandy.

Thanks again for your quick responses. I look forward to the next MUSHclient version.

RashinLord
Australia Forum Administrator #6
Glad it worked.

Let me define for a moment the problem with the script function declarations ...

When MUSHclient loads (or reloads) a script, it tries to map each "known" script function to a "dispatch ID" (DISPID). This dispatch ID is a number which is subsequently used for calling the script.

According to the script documentation it is valid to do this once and then cache the numbers that are returned.

"Known" functions are things like:

  • Triggers, aliases and timers that call a script
  • Function defined on the script configuration page, such as "world open", "world close" etc.
  • MXP functions, such as MXP startup, MXP shutdown
  • Plugin functions such as "OnPluginInstall"


This is done by the system call: GetIDsOfNames.

All these, when found, are remembered for the current script space (main world, or plugin). If any are not found you see the error message mentioned earlier, like "The alias (blah) subroutine named "f" could not be found."

Then, when it is time to call the function (eg. when a trigger fires) it calls "Invoke" using the dispatch ID.

(Lua does not use the Windows script engine, and does things differently).

Now, this method has worked so far for all the supported script engines in MUSHclient: VBscript, JScript, Perlscript, Python and Tcl. They all use exactly the same code, except for the "registration" of which script engine to install initially.

However it seems that PHP is returning "function not found" during this process, and hence the functions declared in the script file cannot be used in the usual way.

Now, either this is a bug in the PHP script engine, or there is some way to "export" a function so it is recognised by GetIDsOfNames. I haven't found any documentation so far on how to export functions in PHP, nor any real documentation (by Googling) on whether or not this is a known problem.

You can press ahead and script in PHP without the problem being fixed, except that using the above techniques won't work (eg. plugin callbacks, "on world open" and so on).

However, as I mentioned earlier, you can use "send to script" for triggers, aliases and timers, to do scripting, including calling functions in the script file.
Australia Forum Administrator #7
Further research into this problem seems to indicate a more serious problem with PHP scripting.

If you try this, by typing 2 separate commands into the command window:


/$a = 5;

/$world->Note ($a);


You get an error message "Undefined variable: a".

However if you do it as a single command like this:


/$a = 5; $world->Note ($a);


It works.

Now what this is telling me is that the script "space" is not persisting from one "parse" to the next.

This would account for why the functions are not visible - it compiles them, but they do not persist.

<< long pause while Nick things about that ... >>

Hmmm, that can't be right, as I could call a function in the script file.

OK, this works then:


/global $a; $a = 5;

/global $a; $world->Note ($a);


By declaring $a as global it can be re-accessed on subsequent lines.

So, you can have variables persist from one thing to another (eg. one alias call to another) provided you declare the variable as global in the script snippet.
Australia Forum Administrator #8
OK, got to the bottom of the problem, with some extensive debugging. :)

It seems the problem was that PHP's script engine was returning a dispatch ID of zero for the first script function. In fact, when you request a dispatch ID, it finds the function, and assigns a number to it, starting at zero (ie. 0, 1, 2, 3 ...).

Now I had assumed that a dispatch ID of zero would be invalid, and indeed no other language has used that. Therefore I was using the dispatch ID of zero as a flag for "no such function".

I have changed MUSHclient version 3.71 to use DISPID_UNKNOWN as the "no such function" indicator (which is in fact -1).

Unfortunately there are about 371 places in the source code where MUSHclient refers to dispatch IDs, so I have had to carefully check each one and change tests for "equal to zero" or "not equal to zero", plus "set to zero" to use DISPID_UNKNOWN instead. As you can imagine, I can't simply search for the number 0.

I think I have found them all, but would like to test for a few days, to make sure that normal scripting for everybody else is still working properly.

However having made that change, the PHP scripts now seem to work properly. :)
Canada #9
*Rubs his hands together in greedy anticipation.*
Australia Forum Administrator #10
I lodged a bug report with the PHPscript developers:

http://pecl.php.net/bugs/bug.php?id=6141

They seem to agree that it was a bug, and state that if you download from:

http://pecl4win.php.net/ext.php/php5activescript.dll

... once there is a version there dated after 2005-12-04, then it will be fixed.

That may be quicker, or not, than waiting for the MUSHclient update.
Australia Forum Administrator #11
Try version 3.71 which is now released, in case the phpscript file is not released yet.
Canada #12
Maybe I'm blind but I don't see that version anywhere yet.
----
Nevermind, I found it. I guess you JUST put it up. =o

http://www.gammon.com.au/files/mushclient/