Owner or Group Scripts in LSL

This is just a quick post on an issue that is easy to overlook in making touch scripts work only for the owner or a group. If for example, you set an object to no group, that should include everybody – but it doesn’t! If, for example, you want a door that can be switched to owner or group only on certain occasions by altering its group, but at other times all people (no group) should be able to open that door simply by altering its group back to none, anybody who has a group selected will not be able to open the door as expected.

Try this:

default
{
    touch_start(integer touched)
    {
        if (llDetectedKey(0) == llGetOwner() || llSameGroup(llDetectedKey(0)) == TRUE )
        {
            llSay(0,"This works if you are the owner or in the same group. However, if you the object is in no group and you activate one of your groups, it will react counter-intuitively as though you are not in the same group as it.");
        }
    }
}

Here is a script that enables you to run the relevant tests:

default
{ 
    touch_start(integer n)
    {
        if (llDetectedKey(0) == llGetOwner()) llSay(0,"Owner");
        if (llDetectedGroup(0) == TRUE) llSay(0,"Same group - test one");
        if (llSameGroup(llDetectedKey(0)) == TRUE) llSay(0, "Same group - test two");
        if (llSameGroup(NULL_KEY) == TRUE) llSay(0,"No group");
    }
}

Here is the solution:

default
{
    touch_start(integer touched)
    {
        if (llDetectedKey(0) == llGetOwner() || llSameGroup(llDetectedKey(0)) == TRUE || llSameGroup(NULL_KEY) == TRUE) )        {
            llSay(0,"This works if you are the owner or in the same group. If the group has no valid key i.e. the object is in no group, you can now operate the script even if you have a group enabled.");
        }
    }
}

Sometimes simple things are worth documenting too 🙂

YEngine and C# coding in OpenSim

YEngine in OpenSim 0.9.1.0 “Snail” release does not specifically provide the full range of C# programming in OpenSim. However, it provides a great deal of more C-like structure including objects, associative mutable arrays, database functions and more. For those interested in vehicles, the ability to move scripts across region boundaries with a seated avatar is also an advance. It also allows in-line manipulation of events and queuing and de-queuing simulated events, which may offer some interesting possibilities, not only in testing. YEngine is not yet fully documented, so watch out for interesting developments.

[Ed. 2020-04-26: The YEngine documentation has disappeared since this was written but the XMREngine documentation is still available and valid for YEngine, this being its previous name.]

This release also sees the end of Adam Frisby’s Mini Region Modules (MRMs), since the module has not been maintained for a long time. This particular door is now closed to further C# scripting in world. You can write full region modules but this is effectively like writing new parts of OpenSim, so you need to be a competent developer.

This prompted me to check what other scripting languages are available and test which script engine can run which languages. According to the page on scripting languages on the OpenSim web site, it used to be possible to use C#, VB.NET (but not on Linux/Unix), JScript.NET and Yield Prolog. If you look at the file [install folder]/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs in the source code, you will notice that //using Microsoft.JScript; is commented out, which gives you a bit of a clue that it’s not available any more, whereas both C# and VB.NET seem available:

using Microsoft.CSharp;
//using Microsoft.JScript;
using Microsoft.VisualBasic;

There is another section commented out below that makes it clear that JScript.NET is not functional. There is no sign whatsoever of Yield Prolog.

According to Justin Clark-Casey in November 2008 (no longer an OpenSim developer), it was is dangerous to allow C# and VB.NET because some .NET classes could can access the server, e.g. System.File.IO.Delete(“path/to/file”), which would obviously be a bad thing. Fortunately, I have a test region for just such purposes so I first restricted access to my eponymous agent-avatar Starflower Bracken and one trusted admin account. If access to such classes has had not been restricted, one does would not want anybody running a script to be able to use them, as unlikely as such coincidental mind-reading might be coming from somebody just happening to be testing C# or VB.NET scripts on random grids even though the vast majority only allow LSL with OSSL and Mod* functions on XEngine and possibly a few might recently have enabled YEngine. Better safe than sorry? Ed.: Let’s find out: keep reading but you may be surprised…

Once safe, I then added AllowedCompilers = lsl, cs, vb under both [XEngine] and [YEngine]. I also tried js, yp and a dummy entry fs (perhaps for F#, if that had an imaginary compiler available) and predictably then all failed, so I removed them again to stop the errors. I can tell you now that I saw nothing in the startup related to YEngine taking note of this instruction, so I was suspicious that this directive only works exists for XEngine at the time of writing.

Ed. (same day, 10:00 GMT): Having now checked, the only place in the source code that mentions AllowedCompilers is [install folder]/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs, but this appears to work only under [XEngine] even though by rights it ought to be shared as described. One must presume YEngine simply doesn’t use this but I have not yet got to the bottom of it for certain: there is a lot of code!

My next step was to test the script engines for language support. I tried the default, i.e. no script engine specified (in my case still XEngine), explicit XEngine and explicit YEngine, which you can see how to enable in OpenSim.ini as published since the release of 0.9.1.0 “Snail” release. Forgive me, there now follow a total of 9 test scripts:

//lsl
default
{
    state_entry()
    {
        llSay(0, "Default: LSL");
    }
}
//XEngine:lsl
default
{
    state_entry()
    {
        llSay(0, "X: LSL");
    }
}
//YEngine:lsl
default
{
    state_entry()
    {
        llSay(0, "Y: LSL");
    }
}
//c#
public void default_event_state_entry()
{
    llSay(0, "Default: C#");
}
//Xengine:c#
public void default_event_state_entry()
{
    llSay(0, "X: C#");
}
//YEngine:c#
public void default_event_state_entry()
{
    llSay(0, "Y: C#");
}
//vb
Public Sub default_event_state_entry()
    llSay(0, "Default: VB")
End Sub
//XEngine:vb
Public Sub default_event_state_entry()
    llSay(0, "X: VB")
End Sub
//YEngine:vb
Public Sub default_event_state_entry()
    llSay(0, "Y: VB")
End Sub

Of these, those running on the default script engine predictably behaved identically to those explicitly running on XEngine but one might as well be thorough. All of these worked except VB.NET, even after I tried sudo apt-get install mono-vbnc as documented on the Mono site. However, it became clear, as I suspected, that YEngine will only run LSL. Here are the results:

XEngine – runs LSL (with OSSL, Mod* etc), C# – does it still also run VB.NET on Windows?
YEngine – runs LSL (with OSSL, Mod* etc plus YEngine extensions)

Since I don’t run Windows, I cannot confirm whether VB.NET works but this would mean any scripts being transported between grids, i.e. attached to an avatar, would fail whenever travelling to a grid running on Mono (i.e. Linux/Unix/BSD etc) so unless Mono supports it natively in future or some other fix is put in place, that remains a restriction. The OpenSim code does support VB.NET and perhaps others who run Windows servers can testify how well it works.

I then tested Justin’s test XML parser script that does make use of the System.IO and System.Xml classes. This would not compile. It is not certain evidence that .NET classes are now restricted so I would still advise caution until that has been verified either by somebody who knows the code or by thorough testing. I need to allow debugging and see what actually happens when trying to compile it.

Ed.: Later I checked how these scripts are compiled and it seems clear that they do NOT allow arbitrary .NET classes, which makes them apparently safe. A lot of work has been done on permissions since Justin Clark-Casey’s time. A further script by Wizardry and Steamworks also failed to compile, although it most evidently did so back in 2011.

Lastly I tried some C# syntax that does not use these codes, i.e. setting up a string array and then using llSay to access it. This did work, so it seems that C# syntax is available. Unlike in LSL, you can actually call an event from another event, as though it were also just an ordinary function. I don’t know how useful that is but I stumbled across it and so may as well share the fact. So, presumably, one can do the full range of OOP or whatever other C# structures that you like to use in your programming.

Justin Clark-Casey mentioned that there are experimental means to restrict scripts to certain users. I need to check this further but there is nothing in OpenSimDefaults.ini that one can mine for further information, so it will be a matter of checking the source code again for useful snippets. Ed.: there are some available config options not found in the .ini files supplied, including the ability to allow only some people to access each scripting language. I will test these and hope to post further about them in future. The major disadvantage that he noted is be that it would restrict all scripts, including LSL. Until such time as a means to restrict access to specific compilers by user exists or else I can confirm that .NET classes have been restricted anyway since Justin wrote his piece 11 years ago, I will not be enabling C# (or VB.NET, though this is unsupported on Mono anyway) on any regions to which others have access. At present, it seems pretty clear that the source code does not contain any such means to restrict specific compilers by user.

I have not yet now tried WriteScriptSourceToDebugFile = true (default is false) but I can see that CompileWithDebugInformation = true from typing config show Xengine in order to view the config settings. This perhaps might help me find out why Justin’s script did not work. Adding the appropriate using directives did not make any difference.

At least we now know that JScript.NET is for the moment dead on OpenSim and that Yield Prolog has long since vanished, that only XEngine will compile C# and apparently VB.NET scripts and that YEngine is restricted to LSL as extended.

Disclaimer: I never said that this was safe! Ed.: However, it looks reasonably safe but check this with a more experienced OpenSim developer if you are in any doubt before you enable C# or VB.NET on public regions.

[Edited same day at 17:45]