1. Bitte schaltet eure Ad Blocker aus. SLinfo kann nur betrieben werden, wenn es durch Werbung Einnahmen erzielt. Vielen Dank!!
    Information ausblenden
  2. 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.
    Information ausblenden
  3. 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.
    Information ausblenden

Visitor Detector

Dieses Thema im Forum "Fragen zu Scripting" wurde erstellt von Ezian Ecksol, 21. Juni 2008.

  1. Ezian Ecksol

    Ezian Ecksol Guest

    Irgendwo gabs einen Thread, da ging es um einen Besucher-Melder, den find ich allerdings nicht mehr. Mehrere Leute hatten mich per PM nach einem entsprechenden Script gefragt, here we go.

    Das Script einfach in ein beliebiges Prim werfen. Funktioniert in der vorliegenden Form für den Eigentümer eines Parcels.

    Nach dem Rezzen ist das Script an, und berechnet noch eine optimale Position für das Prim, bei dem der Scan-Kegel von 96m optimal für den Boden ausgenutzt wird - und teilt diese Position beim Start mit. Das Prim also ggf. per Edit einfach auf diese Stelle befördern.

    Per Touch kann der Eigentümer das Script aus- bzw. wieder anmachen.

    Das Script ignoriert Kurzzeit-Besucher, gibt dann nach Verstreichen der Kurz-Besucher-Zeit eine Meldung aus, die Zeit ist GMT. Beim Verlassen eines Besuchers des Grundstücks meldet sich das Script wieder mit der Verweildauer.

    Im Script-Kopf kann man folgende Werte einstellen:

    Erst nach dieser Zeit (in Sekunden) kommt eine Meldung , dass jemand aufs Grundstück gekommen ist. Verschwindet er vorher wieder (wie z.B. Grundstück-Überflieger), wird er nicht gemeldet. (Trotzdem wird aber die Gesamt-Zeit beim Verlassen des Grundstücks angezeigt)

    0: gibt die Meldungen direkt aus dem prim auf den offenen Chat aus. 1: benutzt llOwnerSay an den Prim-Eigentümer. OwnerSay geht verloren, wenn der Benutzer offline ist. 2: gibt die Meldungen per IM an den Eigentümer aus. IM funktioniert im Prinzip auch, wenn man offline ist. (zur Zeit wegen SL-Bugs allerdings manchmal nicht, außerdem können IMs derzeit teilweise erheblich zeitverzögert ankommen, während llOwnerSay eigentlich immer sofort arbeitet)

    Die Scan-Rate. mit 2 scannt er alle 2 Sekunden. Schnellere Werte erhöhen den Lag. Alle 5 Sekunden reicht sicher auch.

    Code:
    // Visitor-Detector 0.66
    // (c) Ezian Ecksol. Use, modify, steal or sale as you like. Keep credits.
    
    // modify these values: /////
    float ignore_time = 20.; // avatars visiting the parcel less than this time in seconds will be ignored
    integer print_method = 1; // 0=llSay, 1=llOwnerSay, 2=llInstantMessage
    float loop_time = 2.; // scanner checks every <loop_time> seconds
    //////////////////////////////////
    
    vector parcel0; vector parcel1;
    vector parcel_center; vector parcel_size;
    float detect_range = 96.;
    key owner;
    string parcel;
    list visitors_long;
    list visitors_short;
    integer active;
    
    string getparcelname(vector p) {
        return llList2String(llGetParcelDetails(p, [PARCEL_DETAILS_NAME]),0);
    }
    
    getparcelbounds() {
        vector pos = llGetPos();
        vector rpos;
        pos = <llRound(pos.x), llRound(pos.y), 0.>;
        string name = getparcelname(pos);
       
        rpos = pos;
        do { rpos.x -= 1.; } while ((getparcelname(rpos) == name) && (rpos.x>=0.));   
        parcel0.x = rpos.x + 1.;
        
        rpos = pos;
        do { rpos.y -= 1.; } while ((getparcelname(rpos) == name) && (rpos.y>=0.));    
        parcel0.y = rpos.y + 1.;
        
        rpos = pos;
        do { rpos.x += 1.; } while ((getparcelname(rpos) == name) && (rpos.x<256.));   
        parcel1.x = rpos.x;
        
        rpos = pos;
        do { rpos.y += 1.; } while ((getparcelname(rpos) == name) && (rpos.y<256.));   
        parcel1.y = rpos.y;
       
        parcel_center = (parcel1 + parcel0) / 2.;
        parcel_size = parcel1 - parcel0;
        float c = llPow(parcel_size.x/2.,2.)+llPow(parcel_size.y/2.,2.);
        float d = detect_range*detect_range;
        if (c > d)
            llOwnerSay("Your parcel is to large to be covered by a 96-m-scanner. Place the detector in the middle of the parcel at ground, but the corners are not covered.");  
        else { 
            vector dest = <parcel_center.x, parcel_center.y, llGround(parcel_center-llGetPos())+llSqrt(d-c)>;
            llOwnerSay("For optimal scanning range at ground, set position of object to: "+Vector2String(dest));
        }
    }
    
    
    string format_2dig(integer i) {
        if (i<10)
            return "0"+(string)i;
        else
            return (string)i;   
    }
    
    string format_timestamp(string ts) { 
        return parcel+", "+llGetSubString(ts, 0, 9)+", "+llGetSubString(ts, 11,18)+" GMT";
    }
    
    string format_seconds(integer s) {   
        integer m = s / 60;
        s %= 60;
       
        integer h = m / 60;
        m %= 60;
       
        return format_2dig(h)+":"+format_2dig(m)+":"+format_2dig(s); 
    }
    
    console(string txt) {
        if (print_method == 0)
            llSay(0, txt);
           
        else if (print_method == 1)
            llOwnerSay(txt);
           
        else
            llInstantMessage(owner, txt);
    }
    
    visitors_left(list v) {
        integer j = llGetListLength(v);
        if (j) {
            integer i;
            integer tu = llGetUnixTime();
            for (i=0; i<j; i+=3)
                console("<< "+llList2String(v, i)+" left "+parcel+" after "+format_seconds(tu-llList2Integer(v, i+1)));
        }
       
    }
    
    string Float2String(float num) {
        list s = llParseString2List((string)(llRound(num*10.)/10.), ["."], []);
        return llList2String(s, 0)+"."+llGetSubString(llList2String(s, 1), 0, 0);
    }
    
    string Vector2String(vector v) {
        return "<"+Float2String(v.x)+", "+Float2String(v.y)+", "+Float2String(v.z)+">";
    }
    
    activate(integer a) {
        active = a;
        if (a) {
            llOwnerSay("Scans every "+Float2String(loop_time)+"s. Ignores visitors staying less than "+Float2String(ignore_time)+"s.");
            llOwnerSay("Activated: "+format_timestamp(llGetTimestamp()));
            llSensorRepeat("", NULL_KEY, AGENT, detect_range, PI, loop_time);
       
        } else {
            llOwnerSay("Deactived.");
            llSensorRemove();   
        }
    }
    
    default {
    
        state_entry() {
            owner = llGetOwner();
            parcel = """+llList2String(llGetParcelDetails(llGetPos(), [PARCEL_DETAILS_NAME]),0)+"""; // +" in "+llGetRegionName();
           
            activate(TRUE);
            llOwnerSay("Touch to stop or start.");
           
            getparcelbounds();   
        }
       
        touch_start(integer n) {
            if (llDetectedKey(0) == owner)
                activate(!active);
        }
       
        on_rez(integer p) {
            llResetScript();
        }
       
        changed(integer c) {
            if (c & CHANGED_OWNER) llResetScript();   
        }
    
        sensor(integer n) {
            integer i; integer j;
            integer tu = llGetUnixTime();
            string ts = llGetTimestamp();
            string dname;
            list temp;
            list temp_short = visitors_short;
            list temp_long = visitors_long;
            visitors_short = [];
            visitors_long = [];
    
            for (i=0; i<n; ++i) {
               
                if (llOverMyLand(llDetectedKey(i))) {
                //vector dpos = llDetectedPos(i);
                //if ((dpos.x >= parcel0.x) && (dpos.x < parcel1.x) && (dpos.y >= parcel0.y) && (dpos.y < parcel1.y)) {
                    dname = llDetectedName(i);
               
                    j = llListFindList(temp_long, [dname]);     
                    if (j != -1) {
                        visitors_long += llList2List(temp_long, j, j+2);
                        temp_long = llDeleteSubList(temp_long, j, j+2);
       
                    } else {
                        j = llListFindList(temp_short, [dname]); 
                         
                        if (j != -1) {
                            temp = llList2List(temp_short, j, j+2);
                           
                            if ((tu-llList2Integer(temp, 1)) >= ignore_time) {
                                visitors_long += temp;
                                console(">> "+llList2String(temp, 0)+" entered "+format_timestamp(llList2String(temp, 2)));
    
                            } else {
                                visitors_short += temp;
                            }
                           
                        } else {
                            visitors_short += [dname, tu, ts];
                        }
                    }
                }
            }   
            visitors_left(temp_long);   
        }
       
        no_sensor() {
            visitors_left(visitors_long);
            visitors_short = [];
            visitors_long = [];   
        }
    
    }
     
  2. Schinder Toll

    Schinder Toll Aktiver Nutzer

    Beiträge:
    198
    Zustimmungen:
    0
    Punkte für Erfolge:
    0
    Hallo Ezian,
    ich hab das mal probiert, aber ich bekomme da einen Error:
    Code:
    [17:41]  Object: Scans every 2.0s. Ignores visitors staying less than 20.0s.
    [17:41]  Object: Activated: "xxbeliebigerOrtxx", 2008-06-23, 00:41:48 GMT
    [17:41]  Object: Touch to stop or start.
    [17:41]  Object [script:visitor_detect]: Script run-time error
    [17:41]  Object [script:visitor_detect]: Math Error
    Kannst Du sagen, woran das liegt ?
    Grüße
    ST
     
  3. Anette Thor

    Anette Thor Nutzer

    Beiträge:
    84
    Zustimmungen:
    0
    Punkte für Erfolge:
    0
    Bei mir genauso, ich habe mal geschaut aber ich finde den Fehler nicht ...ich dachte zuerst ein Variablen Wertigkeit wäre zu niedrig.
     
  4. Baertram Beerbaum

    Baertram Beerbaum Aktiver Nutzer

    Beiträge:
    471
    Zustimmungen:
    0
    Punkte für Erfolge:
    0
    math

    ohne das ich das ganze script jetzt durchgegangen bin,

    Math error hört sich nach division by Zero am. Also Teilen durch 0.

    Um heraus zu finden an welcher stelle der Fehler aufläuft, ist es hilfreich einige llSay 's unterzubringen. Ich mache das in jeder Funktion und jedem Event. Dann bekommt ihr den Überblick was noch richtig abläuft.

    Leider hat Linden [libary:a64cb4b5ca]Synonym für [LindenLab]. Wird im Zusammenhang mit der [Währung] [Lindendollar] oder auch als [Nachname] [Linden] für [Administratoren] in [SecondLife][/libary:a64cb4b5ca] ja den debugger vergessen.
     
  5. Ezian Ecksol

    Ezian Ecksol Guest

    Hm. Muss ich mir nochmal anschauen, bei mir läufts natürlich.

    Math Error kommt bei Division durch 0 oder Ziehen einer Wurzel durch eine negative Zahl.

    Kommentier doch einfach erstmal aus dem state_entry das hier aus: getparcelbounds() aus, indem du zwei Slashes davor schreibst, also "// getparcelbounds();"

    getparcelbounds() rechnet ein bisschen, um die optimale Position auszugeben, aber eigentlich ist der Programmteil für die eigentliche Funktion des Visitor Detectors völlig unwichtig.

    Und dann sagt mal, ob es ohne getparcelbounds geht, das grenzt dann die Suche ein :)
     
  6. Shirley Iuga

    Shirley Iuga Forumsgott/göttin

    Beiträge:
    7.507
    Zustimmungen:
    2
    Punkte für Erfolge:
    36
    So auf den ersten Blick (ohne testen) ist das Problem in Variable h in Parcelbounds():

    float h = llSqrt(llPow(detect_range/2.0,2.0)-c*c) - 0.4,


    Das Problem mit dem Mathefehler taucht dann auf, wenn c² > (detect_range/2)² ist.

    In diesem Fall (detect_range = 96m), wenn c größer als 48 ist.
     
  7. Ezian Ecksol

    Ezian Ecksol Guest

  8. Ezian Ecksol

    Ezian Ecksol Guest

  9. Ezian Ecksol

    Ezian Ecksol Guest

    [Push]

    Habe das Script jetzt oben in dem ersten Post korrigiert.

    Wie Shirley richtig gesehen hat, war ein Fehler in einer Formel drin, der bei meinem Test auf einem relativ kleinem Parcel nicht zum Tragen kam.

    Was bin ich immer wieder froh, dass es von Flugzeug-Software keine Release Candidates gibt. Sondern es Leute gibt, die Test-Software für die Flugtzeug-Software schreiben, und Dritte, die Test-Software für die Test-Software schreiben :) (eine rmeiner Bekannten).
     
  10. Iman Dryke

    Iman Dryke Guest

    Ezian, Du bist ein Schatz, das muss man schon sagen :D
     
  11. Schinder Toll

    Schinder Toll Aktiver Nutzer

    Beiträge:
    198
    Zustimmungen:
    0
    Punkte für Erfolge:
    0
    Hallo Ezian,
    das Ding funzt jetzt ! Super !
    Und Vielen Dank !
    Grüße
    ST
     
  12. Kottos Sperber

    Kottos Sperber Freund/in des Forums

    Beiträge:
    698
    Zustimmungen:
    7
    Punkte für Erfolge:
    18
    Eine Anmerkung: Es waere eventuell hilfreich abzufragen, ob der eingetroffene Gast der Eigner des Grundstuecks oder der Owner des Prims ist, in dem der script laeuft. Ich seh ja selber, ob ich mich auf meinem Grundstueck aufhalte oder nicht und muss nicht noch per script davon informiert werden.

    Auf die schnelle habe ich nichts finden koennen, wo eine Abfrage guenstig zu platzieren waere. Eventuell in der Funktion console, aber dorthin wird nur der komplette auszugebende Text uebergeben und nicht der key des Besuchers, den man dann mit getowner oder getlandowner vergleichen koennte.
     
  13. Ezian Ecksol

    Ezian Ecksol Guest

    Ja klar, das wa zu Testzwecken natürlich unpraktisch, und dann hab ich's vergessen :)

    Such mal diese Zeile im senso event:
    Code:
    if (llOverMyLand(llDetectedKey(i))) { 
    und ersetze sie hierdurch:
    Code:
    if ((llOverMyLand(llDetectedKey(i)) && (owner != llDetectedKey(i))) { 
    Ungetestet, sieht aber gut aus.
     
  14. Kottos Sperber

    Kottos Sperber Freund/in des Forums

    Beiträge:
    698
    Zustimmungen:
    7
    Punkte für Erfolge:
    18
    Hihi, genau an der Stelle hatte ich es inzwischen selbst geaendert. Ich habe nur llDetectedKey(i) einer Variablen zugewiesen, um den Doppelaufruf zu vermeiden.

    Und "parcel" und alle Ausgaben desbetreffend habe ich auch entfernt. Parcel ist bei mir leer, weil Parcelgroesse gleich Sim. Einen "Untertitel" habe ich gar nicht vergeben. Es wurden nur die "" ausgegeben.

    Aber sonst, gute Arbeit, Ez. Keep going.
     
  15. Schinder Toll

    Schinder Toll Aktiver Nutzer

    Beiträge:
    198
    Zustimmungen:
    0
    Punkte für Erfolge:
    0
    Eine Klammer fehlt, aber sonst läuft die Änderung:

    Code:
    if ((llOverMyLand(llDetectedKey(i))) && (owner != llDetectedKey(i))) {
    Super Teil !
    Grüße
    ST
     
  16. Doktor Schnyder

    Doktor Schnyder Superstar

    Beiträge:
    3.152
    Zustimmungen:
    0
    Punkte für Erfolge:
    0
    statt mit llsay oder llInstantMessage arbeite ich gerne mit llEmail.

    Das hat den Vorteil das die Nachrichten immer ankommen, egal ob man on oder offline ist.

    man kann es natürlich auch kombinieren.
     
  17. Ezian Ecksol

    Ezian Ecksol Guest

    Mach ich eigentlich auch normalerweise, hab das vorhin eben nur auf die Schnelle so hingeschrieben.

    Übrigens bin ich mir inzwischen ga nicht mehr sicher, ob der "Doppelaufruf" von llDetectedKey(bla) Zeit kostet, denn soweit ich irgendwo neulich gelesen habe, ist es so: Wir haben ja in LSL leider keine Arrays, nur diese beknackten Listen. Die einzigen Arrays sind diese llDetected...-Variablen. Die Werte, die da z.B. im Sensor-Event reinlaufen, werden in den Speicher der Virtual Machine des Scripts geschrieben, man kann man auch mit llGetFreeMemory gut beobachten. D.h. für mich, dass die llDetected...-Aufrufe nix kosten, sondern genauso wie Variablen-Zugriffe einfach nur auf den Stack der VM zugreifen. Ist aber nur so meine Theorie, und das nur mal am Rande.

    Ja, kann ja jeder gerne in diese Funze "console" reinbasteln. Ist ja OpenSource, d.h. darf gerne weiterentwickelt werden oder als Basis für irgendwas andres.
     
  18. Wired Georgia

    Wired Georgia Nutzer

    Beiträge:
    59
    Zustimmungen:
    0
    Punkte für Erfolge:
    6
    Hallo,

    ich hab mal den besuchermelder probiert. Kann es sein, das der auf Gruppen-Land nicht funktioniert?

    Ich habe auch probiert den der Gruppe zu deeden, auch scheinbar erfolglos.

    Oder was mache ich evtl. falsch?
     
  19. Finwe Fride

    Finwe Fride Aktiver Nutzer

    Beiträge:
    249
    Zustimmungen:
    0
    Punkte für Erfolge:
    0
    Nein der geht auf Gruppenland nicht, hatte Ezian auch gefragt, weil ich den gerne auf Gruppenland genutzt hätte :(
     
  20. Lucy Schlesinger

    Lucy Schlesinger Aktiver Nutzer

    Beiträge:
    186
    Zustimmungen:
    0
    Punkte für Erfolge:
    0
    Habt ihr mal
    Code:
    integer print_method = 0; // 0=llSay
    ausprobiert ?
    Weil llOwnerSay und llInstantMessage können nicht funktionieren,
    beides schickt die Nachricht an den Besitzer, wenn das Object gedeedet ist,
    dann schickt es die jeweilige Gruppe(nicht Gruppen IM) und da "verschwindet" die Nachricht dann im Datennirvana.
     

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies, um Inhalte zu personalisieren, diese deiner Erfahrung anzupassen und dich nach der Registrierung angemeldet zu halten.
    Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden