• Bitte schaltet eure Ad Blocker aus. SLinfo kann nur betrieben werden, wenn es durch Werbung Einnahmen erzielt. Vielen Dank!!
  • Wir freuen uns, wenn du dich in unserem Forum anmeldest. Bitte beachte, dass die Freigabe per Hand durchgeführt wird (Schutz vor Spammer). Damit kann die Freigabe bis zu 24 Stunden dauern.
  • Wir verwenden Cookies, um Inhalte und Anzeigen zu personalisieren, Funktionen für soziale Medien anbieten zu können und die Zugriffe auf unsere Website zu analysieren. Sie geben Einwilligung zu unseren Cookies, wenn Sie unsere Webseite weiterhin nutzen.

gorean Restrained-Life 1*1

Ich wollte zwar eigentlich keine Werbung machen, aber so ganz kann ich es mir doch nicht verkneifen.
Ich halte das Opencollar für recht gut, .....

Für etwas wie das Open Collar kannste, mein ich, ruhig Werbung machen, handelt es sich doch um ein Freebie und ein gutes noch dazu.
 
naja... bei dem Opencollar stören mich eben 2 Sachen sehr:
Das Subspy-Script, das Sub noch nicht mal meldet, wenn Dom beschlossen hat, seine Sub zu belauschen. Nicht jeder weiss, dass man es rausnehmen kann...
Das Zweite ist (was aber auch an mir liegen kann), ich hab noch keinen gefunden, den ich was fragen kann.. was ist z.B. Remoteon...???

Ist ein tolles Freebie, keine Frage, aber wenn ich bei Sylvie oder meiner Herrin sehen wie viele Stunden man sich mit Scripten um die Ohren schlagen kann, finde ich die 300 oder 400L$, die das Script in meinem Collar mal vor 10 Monaten gekostet hat, keinesfalls zuviel. Vor allem da es noch einen Lebenslangen Support und Updates dabei hat...
 
also Updates bekommst du auch automatisch angeboten, hab gerade Freitag eins bekommen. Das "SubSpy" meldet sich im Chat der Sub schon bei Statusänderung....bin mir ziemlich sicher. Müsste ich bei Gelegenheit noch mal ausprobieren.

Die Gefahr hast du beim Amethyst aber auch, da die meisten Herren dir gleich das Feature-Pack von Amethyst mit reinpacken. Das macht nichts anderes.

Sicher...Supportanspruch bei einem geschenktem Teil hat man natürlich nicht.
 
Hat eigentlich schon jemand das VGS Collar getestet? https://www.xstreetsl.com/modules.php?name=Marketplace&file=item&ItemID=457732

Ari Blackthornes "Empfehlung" am Ende der Seite liest sich da schon interessant...insbesondere würde mich aber interessieren ob die Scripte auch in einem anderen Collar als dem mitgelieferten funktionieren würden. Hier ist ein Knackpunkt wo die meisten Collarhersteller die ihre Scripte nicht stand-alone verkaufen immer wieder für Enttäuschung sorgen.

@Open Collar: Auch ich würde das Collar bedenkenlos empfehlen. Ich finde durch eine recht lückenhafte Dokumentation (was mich bei einem Open Source Projekt wie diesem schon verwundert) ist es Leuten unnötig schwer gemacht worden, ihr Collar zu personalisieren (eigene Anis, Ao, Scripte löschen etc). Wenn man es nur benutzen will ists dagegen sehr gut, sowohl für alte Hasen als auch Einsteiger. Supportanspruch hat man nicht, aber die Chatgruppe beim Opencollar kann einem in den allermeisten Fällen weiterhelfen.

Oh mist man schweift ab zu den Collaren, allerdings noch eine Frage zu den Fesseln etc. die man dazu kaufen kann. Ich hab gesehen das es Scripte zu kaufen gibt die eine "normale" Fessel Restraint Life fähig machen. HAt jemand damit schon Erfahrungen gemacht?
 
.....Das Zweite ist (was aber auch an mir liegen kann), ich hab noch keinen gefunden, den ich was fragen kann.. was ist z.B. Remoteon...???

Wenn remoteon gesetzt ist, dann kann der Dom Dich über sein Owners Hud steuern, sofern er Dich in dieses eingetragen hat. In dieses Hud können mehrer Subs eingetragen werden. Dem Owner wird so die Auswahl der Collarbefehle für die jeweilige Sub erleichtert.

lg
Sveta
 
Die Gefahr hast du beim Amethyst aber auch, da die meisten Herren dir gleich das Feature-Pack von Amethyst mit reinpacken.

Wer sowas annimmt und trägt hat selber schuld.. oder großes Vertrauen. Grundsätzlich sehe ich genau darin ein Problem, denn den meisten Leuten in SL kann man nicht weiter trauen als man sie werfen kann.
Das Feature Pack wie du es nennst (Amethyst Plugins Box), kann man erstens ohne weiteres wieder rauswerfen oder auch die Scripte einfach nur deaktivieren. Erkennbar sind sie (soweit sie nicht verändert wurden) auch einfach daran, dass es die einzigen Modify Scripte sind, die mit "Amethyst ..." anfangen. Das Vorhandensein des "Amethyst Skeleton Plugin Script" weißt dann noch auf völlige Ahnungslosigkeit hin (ist eben nur ein Beisspielgerüst eines Scriptes, völlig ohne Funktion).
 
So, habe gestern mit dem open Collar herumgespielt.
Und definitiv bekommt die Sub keinerlei Meldung, wenn ein Herr das Radar aktiviert, den Chat mitschneidet oder.. irgendwas drittes kann er auch mit dem Spyscript.
Problemlos lies sich das SubSpy Script aber löschen.

Wenn ich weitere Erkenntnisse habe, werde ich mal was zum Perosnalisieren des open Collars aus sicht eibnes absolut Ungeübten schreiben :)
Sollte ich das hinbekommen, schafft es jeder.
 
Kaya, wenn Du magst, kann ich das entsprechend umschreiben, ist jeweils nur eine einzige Script-Zeile, die an entsprechender Stelle eingefügt werden muss: llOwnerSay("Dein Herr bespitzelt Dich jetzt");
 
wenn ich auch darf...
OpenCollar - subspy - 3.202
Code:
// Spy script for the OpenCollar Project (c)
//Licensed under the GPLv2, with the additional requirement that these scripts remain "full perms" in Second Life.  See "OpenCollar License" for details.

integer timeout = 60;
//MESSAGE MAP
integer COMMAND_NOAUTH = 0;
integer COMMAND_OWNER = 500;
integer COMMAND_SECOWNER = 501;
integer COMMAND_GROUP = 502;
integer COMMAND_WEARER = 503;
integer COMMAND_EVERYONE = 504;
integer CHAT = 505;
integer COMMAND_SAFEWORD = 510;  // new for safeword

//integer SEND_IM = 1000; deprecated.  each script should send its own IMs now.  This is to reduce even the tiny bt of lag caused by having IM slave scripts
integer POPUP_HELP = 1001;

integer HTTPDB_SAVE = 2000;//scripts send messages on this channel to have settings saved to httpdb
                            //str must be in form of "token=value"
integer HTTPDB_REQUEST = 2001;//when startup, scripts send requests for settings on this channel
integer HTTPDB_RESPONSE = 2002;//the httpdb script will send responses on this channel
integer HTTPDB_DELETE = 2003;//delete token from DB
integer HTTPDB_EMPTY = 2004;//sent when a token has no value in the httpdb

integer MENUNAME_REQUEST = 3000;
integer MENUNAME_RESPONSE = 3001;
integer SUBMENU = 3002;
integer MENUNAME_REMOVE = 3003;

string dbtoken = "spy";
//5000 block is reserved for IM slaves

//string UPMENU = "↑";
//string MORE = "→";
string UPMENU = "^";
string MORE = ">";
string parentmenu = "Main";
string submenu = "Spy";
string currentmenu;

key owner = NULL_KEY;
string subName;
integer menuchannel;
integer menuhandle;
string location;
list avsNearby;
float sensorRange = 8.0;
float sensorRepeat = 300.0;
integer listenhandle;
list settings;

integer listenCap = 20; // Distance for owner to be from sub for listener to shut off
integer listenCheckRepeat = 5;
float sensorTiming;
float sensorCountdown = 0;
integer listenEnabled; // Toggled by the sensor; only applies if listen is actually on

updateSensor() {
    llSensorRemove();
    float range = listenCap;
    if (!enabled("listen") && enabled("radar")) {
        range = sensorRange;
    }
    if (enabled("listen")) {
        sensorTiming = listenCheckRepeat;
    } else {
        sensorTiming = sensorRepeat;
    }
    if (enabled("listen")) {
        // || enabled("radar"))
        llSensorRepeat("" ,"" , AGENT, range, PI, listenCheckRepeat);
    } else if (enabled("radar")) {
        llSensorRepeat("" ,"" , AGENT, range, PI, sensorRepeat);
    }
}

integer enabled(string token) {
    integer index = llListFindList(settings, [token]);
    if(index == -1) {
        return FALSE;
    } else {
        if(llList2String(settings, index + 1) == "on") {
            return TRUE;
        } else if(llList2String(settings, index + 1) == "off") {
            return FALSE;
        } else {
            return FALSE;
        }
    }
}

string GetTimestamp() {
    // Return a string of the date and time
    integer t = (integer)llGetWallclock(); // seconds since midnight

    return GetPSTDate() + " " + (string)(t / 3600) + ":" + PadNum((t % 3600) / 60) + ":" + PadNum(t % 60);
}

string PadNum(integer value) {
    if(value < 10) {
        return "0" + (string)value;
    }
    return (string)value;
}

string GetPSTDate() {
    //Convert the date from UTC to PST if GMT time is less than 8 hours after midnight (and therefore tomorow's date).
    string DateUTC = llGetDate();
    if (llGetGMTclock() < 28800) {
        // that's 28800 seconds, a.k.a. 8 hours.
        list DateList = llParseString2List(DateUTC, ["-", "-"], []);
        integer year = llList2Integer(DateList, 0);
        integer month = llList2Integer(DateList, 1);
        integer day = llList2Integer(DateList, 2);
        day = day - 1;
        return (string)year + "-" + (string)month + "-" + (string)day;
    }
    return llGetDate();
}

DialogSpy(key id) {
    currentmenu = "spy";
    list buttons ;
    string text = "These are ONLY Primary Owner options:\n";
    text += "Trace turns on/off notices if the sub teleports.\n";
    text += "Radar turns on/off a report every "+ (string)((integer)sensorRepeat/60) + " of who joined  or left " + subName + " in a range of " + (string)((integer)sensorRange) + "m.\n";
    text += "Listen turns on/off if you get directly said what " + subName + " says in public chat.\n";
    text += "This menu will time out in " + (string)timeout + " seconds.";
    
    if(enabled("trace")) {
        buttons += ["Trace Off"];
    } else {
        buttons += ["Trace On"];
    }
    if(enabled("radar")) {
        buttons += ["Radar Off"];
    } else {
        buttons += ["Radar On"];
    }
    if(enabled("listen")) {
        buttons += ["Listen Off"];
    } else {
        buttons += ["Listen On"];
    }
    buttons += ["RadarSettings"];
    buttons += [UPMENU];
    buttons = RestackMenu(FillMenu(buttons));
    menuhandle = llListen(menuchannel, "", id, "");
    llDialog(id, text, buttons, menuchannel);
    llSetTimerEvent(timeout);
}

DialogRadarSettings(key id) {
    currentmenu = "radarsettings";
    list buttons;
    string text = "Choose the report repeat and sensor range:\n";
    text += "Current Report Range is: " + (string)((integer)sensorRange) + " meter.\n";
    text += "Current Report Frequenz is: " + (string)((integer)sensorRepeat/60) + " minutes.\n";
    buttons += ["5 meter", "8 meter", "10 meter", "15 meter"];
    buttons += ["2 minutes", "5 minutes", "8 minutes", "10 minutes","15 minutes", "30 minutes", "60 minutes"];
    buttons += [UPMENU];
    buttons = RestackMenu(FillMenu(buttons));
    menuhandle = llListen(menuchannel, "", id, "");
    llDialog(id, text, buttons, menuchannel);
    llSetTimerEvent(45.0);    
}

SendIM(key id, string str) {
    if (id != NULL_KEY) {
        llInstantMessage(id, str);
    }
}
list FillMenu(list in) {
    //adds empty buttons until the list length is multiple of 3, to max of 12
    while (llGetListLength(in) != 3 && llGetListLength(in) != 6 && llGetListLength(in) != 9 && llGetListLength(in) < 12) {
        in += [" "];
    }
    return in;
}

list RestackMenu(list in) {
    //re-orders a list so dialog buttons start in the top row
    list out = llList2List(in, 9, 11);
    out += llList2List(in, 6, 8);
    out += llList2List(in, 3, 5);    
    out += llList2List(in, 0, 2);    
    return out;
}

SendNotify(string newlocation) {
    string message = subName + " teleported from " + location + " to " +  newlocation + " at "  + GetTimestamp() + ".";
    SendIM(owner, message);
    location = newlocation;
}

ReportAviList(list sensed) {
    string message = "Avis in a " + (string)((integer)sensorRange) + "m range around " + subName + ":\n";
    if(llGetListLength(sensed)) {
        message += llDumpList2String(sensed, ",");
    } else {
        message += "None.";
    }
    SendIM(owner, message);
}

SaveSettings(string str, key id) {
    list temp = llParseString2List(str, [" "], []);
    string option = llList2String(temp, 0);
    string value = llList2String(temp, 1);
    integer index = llListFindList(settings, [option]);
    if(index == -1) {
        settings += temp;
    } else {
        settings = llListReplaceList(settings, [value], index + 1, index + 1);
    }
    string save = llDumpList2String(settings, ",");
    llMessageLinked(LINK_SET, HTTPDB_SAVE, save, NULL_KEY);
    if(currentmenu == "spy") {
        llMessageLinked(LINK_SET, SUBMENU, submenu, id);
    }
}

SetSettings() {
    integer i;
    integer listlength = llGetListLength(settings);
    for(i = 1; i < listlength; i += 2) {
        string option = llList2String(settings, i);
        string value = llList2String(settings, i + 1);
        if(option == "listen") {
            if(value == "on") {
                listenhandle = llListen(0, subName, llGetOwner(), "");
            } else if(value == "off") {
                llListenRemove(listenhandle);
            }
        } else if(option == "meter") {
            sensorRange = (float)value;
        } else if(option == "minutes") {
            sensorRepeat = (float)value;
        }
    }
    sensorCountdown = sensorRepeat;
    updateSensor();
}

TurnAllOff() {
    // set all values to off and remove sensor and listener
    llSensorRemove();
    llListenRemove(listenhandle);
    list temp = ["radar", "listen", "trace"];
    integer i;
    for (i=0; i < llGetListLength(temp); i++) {
        string option = llList2String(temp, i);
        integer index = llListFindList(settings, [option]);
        if(index != -1) {
           settings = llListReplaceList(settings, ["off"], index + 1, index + 1);
        }
    }
    string save = llDumpList2String(settings, ",");
    llMessageLinked(LINK_SET, HTTPDB_SAVE, save, NULL_KEY);
}

default {
    state_entry() {
        menuchannel = -llFloor(llFrand(999999.0))  - 9999;
        subName = llKey2Name(llGetOwner());
        settings = [dbtoken + "="];
        location=llGetRegionName();
        llSleep(1.0);
        llMessageLinked(LINK_SET, MENUNAME_RESPONSE, parentmenu + "|" + submenu, NULL_KEY);
    }
    listen(integer channel, string name, key id, string message) {
        if(id == llGetOwner() && channel == 0) {
            if (listenEnabled) {
                string objectName = llGetObjectName();
                if(llGetSubString(message, 0, 2) == "/me") {
                    llSetObjectName(subName + " emoted: " + subName);
                } else {
                    llSetObjectName(subName + " said");
                }
                SendIM(owner, message);
                llSetObjectName(objectName);
            }
        } else if(channel == menuchannel) {
            llListenRemove(menuhandle);
            llSetTimerEvent(0.0);
            if(message == UPMENU) {
                if(currentmenu == "radarsettings") {
                    DialogSpy(id);
                } else {
                    llMessageLinked(LINK_SET, SUBMENU, parentmenu, id);
                }
            } else if(currentmenu == "radarsettings") {
                list temp = llParseString2List(message, [" "], []);
                float value = (float)llList2String(temp,0);
                string option = llList2String(temp,1);
                if(option == "meter") {
                    sensorRange = value;
                    SaveSettings(option + " " + (string)value, id);
                    SendIM(id, "You change the Report Range to " + (string)((integer)value) + " meters.");
                } else if(option == "minutes") {
                    sensorRepeat = value * 60;
                    SaveSettings(option + " " + (string)sensorRepeat, id);
                    sensorCountdown=sensorRepeat;
                    SendIM(id, "You changed the Report Frequency to " + (string)((integer)value) + " minutes.");
                }
                if(enabled("radar")) {
                    updateSensor();
                }
                DialogSpy(id);
            } else if(message != " ") {
                llMessageLinked(LINK_SET, COMMAND_NOAUTH, llToLower(message), id);
            }
        }
    }
    link_message(integer sender, integer auth, string str, key id) {
        //only the primary owner can use this !!
        if (auth == COMMAND_OWNER) {
            owner = id;
            if(str == "spy") {
                DialogSpy(id);
            }
            if(str == "radarsettings") {
                DialogRadarSettings(id);
            } else if(str == "trace on") {
                SaveSettings(str, id);
                llOwnerSay("Your owner turned on tracing you. Every teleport will noticed to your owner.");
                SendIM(id, "Teleport tracing is now turned on for " + subName + ".");
                location=llGetRegionName();
            } else if(str == "trace off") {
                SaveSettings(str, id);
                llOwnerSay("Your owner turned off tracing you.");
                SendIM(id, "Teleport tracing is now turned off for " + subName + ".");
            } else if(str == "radar on") {
                SaveSettings(str, id);
                sensorCountdown=sensorRepeat;
                updateSensor();
                llOwnerSay("Your owner turned on reporting all avatars in range of "+ (string)((integer)sensorRange) + "m near you.");
                SendIM(id, "Avatar reporting a range of " + (string)((integer)sensorRange) + "m your sub " + subName + " is now turned ON.");
            } else if(str == "radar off") {
                SaveSettings(str, id);
                updateSensor();
                llOwnerSay("Your owner turned off reporting avatars around your location.");
                SendIM(id, "Avatar reporting in a range of " + (string)((integer)sensorRange) + "m your sub " + subName + " is now turned OFF.");
            } else if(str == "listen on") {
                SaveSettings(str, id);
                listenhandle = llListen(0, subName, llGetOwner(), "");
                updateSensor();
                llOwnerSay("Your owner now is listening all you will say in public chat.");
                SendIM(id, "You listen now to everything your sub " + subName + " says in public chat.");
            } else if(str == "listen off") {
                SaveSettings(str, id);
                llListenRemove(listenhandle);
                updateSensor();
                llOwnerSay("Your owner stopped listening your public chat.");
                SendIM(id, "You stopped to listen your sub " + subName + "'s public chat.");
            }
        } else if (auth == HTTPDB_RESPONSE) {
            list params = llParseString2List(str, ["="], []);
            string token = llList2String(params, 0);
            string value = llList2String(params, 1);
            if(token == "owner") {
                owner = (key)llList2String(llParseString2List(value, [","], []), 0);
            } else if (token == dbtoken) {
                //llOwnerSay("Loading Spy Settings: " + value + " from Database.");
                settings = llParseString2List(str, [","], []);
                SetSettings();
            }
        } else if (auth == COMMAND_OWNER && str == "reset") {
            llResetScript();
        } else if (auth == COMMAND_WEARER && (str == "reset" || str == "runaway")) {
            llResetScript();
        } else if (auth == MENUNAME_REQUEST && str == parentmenu) {
            llMessageLinked(LINK_SET, MENUNAME_RESPONSE, parentmenu + "|" + submenu, NULL_KEY);
        } else if (auth == SUBMENU && str == submenu) {
            DialogSpy(id);
        } else if((auth > COMMAND_OWNER) && (auth <= COMMAND_EVERYONE)) {
            list cmds = ["trace on","trace off", "radar on", "radar off", "listen on", "listen off"];
            if (~llListFindList(cmds, [str])) {
                SendIM(id, "Sorry, only the primary owner can set trace on or off.");
            }
        } else if(auth == COMMAND_SAFEWORD) {
            //we recieved a safeword command, turn all off
            TurnAllOff();
        }
    }
    on_rez(integer param) {
        //should reset on rez to make sure the parent menu gets populated with our button
        llResetScript();
    }
    sensor(integer num_detected) {
        integer i;
        string detectedName;
        list allSensed = [];
        vector position = llGetPos();
        listenEnabled = 1;
        for(i=0; i < num_detected; i++) {
            detectedName = llDetectedName(i);
            if(detectedName != subName) {
                float distance = llVecDist(llDetectedPos(i), position);
                if (distance <= listenCap && llDetectedKey(i) == owner) {
                    listenEnabled = 0; // Shut off listener because owner is present
                }
                if (distance <= sensorRange && enabled("radar")) {
                    allSensed += [detectedName];
                }
            }
        }
        sensorCountdown -= sensorTiming;
        if (sensorCountdown <= 0 && enabled("radar")) {
            ReportAviList(allSensed);
            sensorCountdown = sensorRepeat;
        }
    }
    no_sensor() {
        listenEnabled = 1; // If nobody is present, then owner is not present
        
        sensorCountdown -= sensorTiming;
        if (sensorCountdown <= 0 && enabled("radar")) {
            ReportAviList([]);
            sensorCountdown = sensorRepeat;
        }
    }
    attach(key id) {
        if(id != NULL_KEY) {
            location = llGetRegionName();
        }
    }
    changed(integer change) {
        if(enabled("trace")) {
            if((change & CHANGED_TELEPORT) || (change & CHANGED_REGION)) {
                SendNotify(llGetRegionName());
            }
        }
    }
    timer() {
        llSetTimerEvent(0.0);
        llListenRemove(menuhandle);
    }
}

Ok ok, es ist noch verbesserungswürdig....
 
/me kratzt sich am Kopf

ich verstehe die Aufregung immer noch nicht so ganz, unabhängig von der rechtlichen lage die ich mal ausser Acht lassen will.
Es gibt für ein Collar genau zwei Ansatzpunkte: das Roleplay in einer virtuellen Welt innerhalb einer virtuellen Welt...nennen wir es mal Gor ;-). Da benötigt keiner die Spyskripte, genauso wie die meisten der anderen Skripte innerhalb der Collars denn das wäre ja die unbeliebte Fernsteuerung.

Und das Roleplay in der virtuellen Welt an sich,..sprich die Unterwerfung...und das tut man nur wenn Vertrauen besteht...also ist es eine reine Vertrauensfrage die Skripte drin zu lassen und sie nicht zu benutzen....ganz einfach.

Ich mag naiv sein, oder nur zu ehrlich...aber wenn ich meinem Master / meiner Miss nicht traue.....lasse ich es am besten ganz, denn sie/ er scheint nicht der/die richtige zu sein
 
@Bo
Das ist, warum ich OpenCollar .... scheisse finde... Das ist mehr Code, als das gesamte GRP-Collar hat - und das hat einen aktiven, voll funktionierenden Text-Parser. OpenCollar ist einfach nur mistig programmiert und eine totale Lag-Bombe.

@trish
Ist nicht persönlich gemeint, aber ich finde Deine Aussage reichlich naiv. ICH nehme jedenfalls kein Collar mehr an, das nicht von mir selbst gescriptet wurde. Menschen sind schwach, und die Versuchung ist SO groß und stark ... ;)
 
@Bo
Das ist, warum ich OpenCollar .... scheisse finde... Das ist mehr Code, als das gesamte GRP-Collar hat - und das hat einen aktiven, voll funktionierenden Text-Parser. OpenCollar ist einfach nur mistig programmiert und eine totale Lag-Bombe.

:shock: .. ähhhhhm, so gaaaanz glaub ich dir das jetzt mal nicht. Aber stimmt grundsätzlich was du sagst. Reichlich viel Code für so wenig Funktion. Wobei die doch auch Teile der offenen Amethyst Scripte geklaut haben, die im Ansatz schon den richtigen Weg weisen. Und wenn man den offenen Kanal permanent abstellt, dann ist Amethyst so ne große Lagschleuder auch nicht. Was sagt uns das? Zumindest der Teil den Amethyst "tattle" nennt, gehört in gar kein Script. Dieser Art Spione verführen tatsächlich eher und sagen dem Owner doch nichts, weil in nicht verfälschten Scripten ja nur das, was Sub sagt an Owner gepetzt wird.

@trish
Ist nicht persönlich gemeint, aber ich finde Deine Aussage reichlich naiv. ICH nehme jedenfalls kein Collar mehr an, das nicht von mir selbst gescriptet wurde. Menschen sind schwach, und die Versuchung ist SO groß und stark ... ;)

Ich hatte 2 mal angesetzt zu antworten. Das Problem ist, dass man bei dem Thema schnell angleitet. Soll doch jeder für sich entscheiden was er oder sie will. Ich kenne sogar Leute die ständig irgendwo rumlungern und liebend gerne in jedweder Form an sich fummeln lassen, hauptsache es gibt den Kick. *Wenn's schee macht..."
 
.. ähhhhhm, so gaaaanz glaub ich dir das jetzt mal nicht.
Stimmt aber (fast). Auf die Technik dieses Parsers bin ich eher durch Zufall gestoßen. Und er beruht darauf, dass die Leute, die das GRP nutzen, auch wissen, was sie tun. Das vereinfacht die Sache immens. Ein Beispiel: Das Auslösen der Animationen. Da wird nichts abgefragt. Das Script guckt einfach, ob der Name der Trägerin vorkommt. Ist das der Fall, schaut es, ob ein Befehlswort vorkommt. Wenn ja: Befehl erkannt. Wenn nein, könnte es eine Animation sein. Gibt's so eine Animation? Wenn ja, ausführen, wenn nicht. Pöh, dann eben nicht. ;)
Das eigentlich komplexe ist eigentlich nur das Ketten-Script, da habe ich lange dran herumgebasteln, bis das Laufen an der Kette so schön soft wird.

Das OpenCollar geht einen ganz anderen Weg: Es versucht, möglichst viele Funktionen zur Verfügung zu stellen. Dazu bedarf es eben viel Code.
 
Na ja, zum Teil doch. Schau Dir als Beispiel mal dieses Konstrukt an:
Code:
integer enabled(string token) {
    integer index = llListFindList(settings, [token]);
    if(index == -1) {
        return FALSE;
    } else {
        if(llList2String(settings, index + 1) == "on") {
            return TRUE;
        } else if(llList2String(settings, index + 1) == "off") {
            return FALSE;
        } else {
            return FALSE;
        }
    }
}
Code:
integer enabled(string token) {
    integer index=llListFindList(settings, [token]);
    if (index==-1) return FALSE;
    string found = llList2String(settings, index + 1);
    if(found == "on") return TRUE;
        else if (found == "off") return FALSE;
    return FALSE;
}
Zweimal dasselbe - aber einmal eben nur mit der Hälfte an Rechenzeitbedarf und weniger Code.

Man könnte es nochmals kürzen, aber dann geht ein wenig Eindeutigkeit verlohren:
Code:
 integer enabled(string token) {
    integer index=llListFindList(settings, [token]);
    if (index==-1) return FALSE;
    if (llList2String(settings, index + 1)== "on") return TRUE;
        else return FALSE;
}
Nachtrag: Der letzte Fall, nämlich der, dass weder ON noch OFF enthalten sind, wird ja bereits bei der Eingangsabfrage mit geklärt: Wenn der entsprechende Befehl nicht vorhanden ist, ist es wurscht, ob das folgende ON, OFF oder HUGENDUGEL ist. ;)
Und da nur dann TRUE zurückgegeben wird, wenn ON enthalten ist, kann der Rest auch flachfallen.

Noch eine, bin gerade so schön in Fahrt:

Code:
 integer enabled(string token) {
    integer index=llListFindList(settings, [token]);
    if (index==-1 || llList2String(settings, index + 1) != "on") return FALSE;
        else return TRUE;
}
DIE ist aber etwas unsicher (aber nur, wenn der Satz mit "on" beginnt *g*).
 
@ Sylvie

ja mag sein das ich in der Beziehung naiv sein mag / bin...habtte ich im Vorfeld ja schon eingeräumt..aber ich bleibe dabei....das collar ist nicht das Problem....das Problem ist der Master welcher sich nicht unter Beherrschung hat oder/ und die Sub die unter Paranoia leidet....
 
Nachtrag: Der letzte Fall, nämlich der, dass weder ON noch OFF enthalten sind, wird ja bereits bei der Eingangsabfrage mit geklärt: Wenn der entsprechende Befehl nicht vorhanden ist, ist es wurscht, ob das folgende ON, OFF oder HUGENDUGEL ist. ;)
Und da nur dann TRUE zurückgegeben wird, wenn ON enthalten ist, kann der Rest auch flachfallen.

Lach, hast Recht, bloss beim "zitieren" sah ich DEN text, vorher nicht

:shock:

Das wäre mein Einwand nämlich gewesen. ;)
 
@trish
Sicher, das stimmt schon - stellt auch niemand in Abrede.

@Bo
Es gibt halt viele Wege, Dinge zu Programmieren. Bei LSL muss man aber immer im Hinterkopf haben, dass alle "ll-Befehle" direkten Datenaustausch mit der Engine betreiben, "normale" Befehle dies aber nicht tun. Und im Original wird eben zweimal llList2String verwendet, obwohl einmal völlig ausreicht.
Zweiter Punkt sind die logischen Abfragen - eindeutige Fälle braucht man nicht gesondert abzufragen - sonst wären sie ja nicht eindeutig. Der Fall "Wenn ON da ist, dann TRUE, ansonsten FALSE" ist eine solche Eindeutigkeit. Ebenso der Fakt, dass das Original-Script ja auch immer FALSE ausgibt, wenn ON nicht enthalten ist.

So, und nun stelle Dir vor, dass alle meine Scripte auf diese Weise aufgebaut sind - dann gilt die Aussage über die Länge des Codes durchaus wieder.
 

Users who are viewing this thread

Zurück
Oben Unten