jOpenSim HowTo Terminals

From jOpenSimWiki
Revision as of 18:00, 27 March 2021 by Foto50 (talk | contribs) (→‎jOpenSimTerminal LSL Script)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

If you already have users with active inworld accounts but installed jOpenSim later, the component has no idea how to connect them with a Joomla account.

The terminal can help in this case.

The user needs to create a Joomla account without creating an inworld account (e.g. via jOpenSimRegister). If the user did so already, you need to delete the user relation in the user admin (it is the last entry in the drop down list)

manage user relation between Joomla and OpenSimulator

To enable inworld account identification you need to 1.: enable it on the global configuration of jOpenSim:

enable inworld terminals

2.: place an object inworld containing the terminal script (see below):

example object from jOpenSimWorld

When the script starts or resets, it should register in your terminal list under "Misc":

Here you see a list of all registered terminals

There you can set behaviours of the terminals and also ping them to see if they respond correct with jOpenSim:

Terminal overview

If everything is correct, a ping should return

Terminal Ping Response

Presuming you also provided a menu item for the jOpenSim Inworld Account view, users without any relation to inworld accounts now get 1. a form to create a new inworld account 2. a link how to identify inworld This will provide a special command, the user needs to copy&paste in front of your inworld terminal, screenshot example:

Terminal Identification Command

This command will stay valid for the minutes you saved in the global configuration. If the user fails to find your terminal within this time, a new process needs to be initiated.

jOpenSimTerminal LSL Script

Note: you find this script also in your Joomla installation at ./administrator/components/com_opensim/lsl-scripts/

In jOpenSim there was a bug in this script, so please use this updated one.

//* TerminalScript for jOpenSim  *
//*                              *
//* created 2021-03-27 by FoTo50 *
//*     *

// if you find a bug or even a security issue,
// I would be happy for a report at the support forum at

string targetUrl            = "http://path-to-your-joomla/index.php?option=com_opensim&view=interface"; // this is the target script, handling the requests
string inworldUrl           = "http://path-to-your-joomla/inworld-account.html"; // Add here the url for the inworld account to provide an easy link to go
integer listenchannel       = 555; // Channel for the Tracker to listen to
string terminalDescription  = "jOpenSim Terminal"; // This will appear as a brief description at the "Terminal Link List" of jOpenSim

// some values for easier translation:
string llD_explain = "\nI am a jOpenSim terminal!\nWant to get a notecard to see what I can do for you?";
string llD_yes        = "Yes";
string llD_no        = "No";
string llD_cancel    = "Cancel";
string llD_site        = "Website";
string llD_Click    = "Click to visit your account page on the Website!";

// nothing interesting to change below this point!!!
key        urlRequestId;
key        requestId;
key        registerId;
key        response_key;
string    resident;
string    myurl;
string    querystring;
key        owner;
integer    dialogchannel;

default {
    state_entry() {
        if(targetUrl == "http://path-to-your-joomla/components/com_opensim/interface.php") {
            llOwnerSay("Please enter the correct path for 'targetUrl' first");
        } else {
            dialogchannel = (integer)(llFrand(99999.0) * -1);
            owner = llGetOwner();
            urlRequestId = llRequestURL();
            llOwnerSay("Terminal running");
            string registerUrl = targetUrl+"&action=register&terminalDescription="+llEscapeURL(terminalDescription)+"&myurl="+myurl;
            registerId = llHTTPRequest(registerUrl,[HTTP_METHOD,"GET"],"");
            llListen(listenchannel, "", NULL_KEY, "");
            llListen(dialogchannel,"", NULL_KEY,"");

    listen( integer channel, string name, key id, string message ) {
        if (channel != listenchannel && channel != dialogchannel) {

        if(channel == dialogchannel) {
            if(id == owner) {
                if(message == llD_yes) {
                    string registerUrl = targetUrl+"&action=setState&state=1";
                    registerId = llHTTPRequest(registerUrl,[HTTP_METHOD,"GET"],"");
                if(message == llD_no) {
                    string registerUrl = targetUrl+"&action=setState&state=0";
                    registerId = llHTTPRequest(registerUrl,[HTTP_METHOD,"GET"],"");
                if(message == llD_site) {
                    llLoadURL(id, llD_Click, inworldUrl);
            } else {
                if(message == llD_yes) {
                    llGiveInventory(id,llGetInventoryName(INVENTORY_NOTECARD, 0));
                if(message == llD_site) {
                    llLoadURL(id, llD_Click, inworldUrl);
        } else {

            string action = llGetSubString(message,0,7);
            string identString = llGetSubString(message,9,-1);
            if( action == "identify" ) {
                response_key = id;
                string requestUrl = targetUrl+"&action=identify&identString="+llEscapeURL(identString)+"&identKey="+(string)id;
                requestId = llHTTPRequest(requestUrl,[HTTP_METHOD,"GET"],"");

    changed(integer change) {
        if (change & (CHANGED_OWNER | CHANGED_INVENTORY)) llResetScript();
        if (change & (CHANGED_REGION | CHANGED_REGION_START | CHANGED_TELEPORT)) urlRequestId = llRequestURL();

    http_request(key id, string method, string body){    
        if (id == urlRequestId) {
            string registerUrl = targetUrl+"&action=register&terminalDescription="+llEscapeURL(terminalDescription)+"&myurl="+myurl;
            registerId = llHTTPRequest(registerUrl,[HTTP_METHOD,"GET"],"");
        } else if(method=="GET" || method=="POST") {
            querystring = llGetHTTPHeader(id,"x-query-string");
            if(querystring == "ping=jOpenSim") {
                llHTTPResponse(id,200,"ok, I am here");

    touch_start(integer count) {
        if(llDetectedKey(0) == owner) {
            llDialog(llDetectedKey(0), "\nShow this terminal in jOpenSim?",
                 [llD_yes, llD_no, llD_cancel], dialogchannel);
        } else {
            llDialog(llDetectedKey(0), llD_explain,
                 [llD_yes, llD_no, llD_site], dialogchannel);

    http_response(key request_id, integer status, list metadata, string body) {
        if (request_id == requestId) {
            integer i = llSubStringIndex(body,resident);
            string messagestring = llGetSubString(body,i,i+llStringLength(resident)+36);
            string seentrigger = llGetSubString(messagestring,0,4);
            if(response_key != NULL_KEY) llInstantMessage(response_key,body);
        if(request_id == registerId) {
            integer i = 0;
            integer end = llGetListLength(metadata);
            for (i=0; i<end; i++) {
                llOwnerSay("string=" + llList2String(metadata,i));