TipJar vs. Vendor



huhu ihr suessen,

unglaublich das 2 so kleine Scripte tatsaechlich so abendfuellend sein koennen, doch ich hoffe alle hatten Spass.
Da waren zwischendurch auch einige konstruktive Anmerkungen, die ich hier ebenfalls erwaehnen moechte.
Nun aber erst mal die beiden Scripte, die fast identisch sind doch grund verschieden genutzt werden.
Zum Vergleich erst mal ganz ohne Kommentare.

Zum einen der TipJar:
Code:
integer Total = 0;

default
{
    state_entry()
    {
        llSetPayPrice(0, [5, 10, 20, 50]);
    }

    money(key id, integer payment)
    {
        Total += payment;
        llSetText(llKey2Name(id) + " zahlte " + (string)payment + "L$\nTotal: " + (string)Total + "L$", <0,1,0>, 1.0);
    }
}
Zum andern der Vendor:
Code:
integer Preis = 15;

default
{
    state_entry()
    {
        llSetPayPrice(PAY_HIDE, [Preis, PAY_HIDE, PAY_HIDE, PAY_HIDE]);
    }

    money(key id, integer payment)
    {
        if(payment == Preis)
        {
            llGiveInventory(id, llGetInventoryName(INVENTORY_OBJECT, 0));
        }
    }
}
Nun folgt der TipJar mit Kommentaren:
Der Befehl im state_entry bewirkt ein individuelles Bezahl-Menue, welches bei angegebenen Werten wiefolgt aussieht:
Zahlfeld TipJar.PNG

TipJar mit Kommentaren:
(Inworld im Script leserlicher)
Code:
// Globale Variable zum zusammen rechnen aller Zahlungseingaenge
integer Total = 0;

default
{
    state_entry() // Der state_entry Event wird beim speichern und resetten ausgefuehrt
    {
        // Individuelles Zahlfeld mit manueller Eingabe und allen 4 Bezahl-Button
        // Bei allen 5 Eintraegen handelt es sich um integer (Ganzzahl)
        llSetPayPrice(0, [5, 10, 20, 50]);
    }

    money(key id, integer payment) // Der money Event erkennt wer (key id) und wieviel (integer payment) einzahlt.
    {
        // Folgende Zeile rechnet den aktuellen Zahlungseingang mit der variable Total zusammen
        Total += payment;
 
        // Individueller Hovertext
        // Egal wie der Text aufgebaut wird, beim mixen von Text und Variablen muss auf die + Zeichen geachtet werden.
        // An welcher stelle zwischen den Gaensefuessen ein Leerschritt rein muss, wird im Hovertext ersichtlich.
        llSetText(llKey2Name(id) + " zahlte " + (string)payment + "L$\nTotal: " + (string)Total + "L$", <0,1,0>, 1.0);
    }
}
Als wir nun diesen Hovertext besprachen, kam die Frage auf, was ein unsichtbarer Hovertext fuer einen Sinn macht.
Aus konventioneller Sicht macht das absolut keinen Sinn.
Doch fuer Scripter ist diese Moeglichkeit hochinteressant.
Im Hovertext lassen sich versteckt bis zu 256 zeichen ablegen und mittels llGetPrimitiveParams wieder abrufen.
Ob das nun gewollt ist weiss ich nicht, jedenfalls haben die Lindens uns mit dieser Moeglichkeit eine enorme Speichererweiterung spendiert. ;)

Nun der Vendor:
Auch hier vewenden wir den gleichen Befehl im state_entry wie beim Tipjar, doch mit anderen Vorgaben.
Das PAY_HIDE versteckt alle ungenutzten Bezahlmoeglichkeiten und sieht folgendermassen aus:
Zahlfeld Vendor.PNG

Vendor mit Kommentaren:
(Inworld im Script leserlicher)
Code:
// Global angelegter Preis, um diese Variable nicht im Script suchen zu muessen
// Fuer andere Preise muss diese Zeile manuell angepasst werden.
integer Preis = 15;

default
{
    state_entry() // Der state_entry Event wird beim speichern und resetten ausgefuehrt
    {
        // Individuelles Zahlfeld mit nur einem einzigen Bezahl-Button ohne manueller Eingabemoeglichkeit
        // Der erste Bezahl-Button verwendet den global angelegten Preis.
        llSetPayPrice(PAY_HIDE, [Preis, PAY_HIDE, PAY_HIDE, PAY_HIDE]);
    }

    money(key id, integer payment) // Der money Event erkennt wer (key id) und wieviel (integer payment) einzahlt.
    {
        // Folgende Zeile vergleicht die aktuelle Einzahlung mit dem vorgegebenen Preis
        // Stimmt beides nicht ueberein, bekommt der Kunde gar nichts.
        if(payment == Preis)
        {
            // Dieser Befehl gibt dem einzahlenden (key id) das erste Objekt aus dem Inhalt des Vendors.
            // Man kann auch den Namen des Objects direkt bestimmen llGiveInventory(id, "Object-Name");
            // Doch bei der aktuellen Variante ist kein Eingriff im Script beim aendern des Objekts erforderlich.
            llGiveInventory(id, llGetInventoryName(INVENTORY_OBJECT, 0));
        }
    }
}
Bei diesem Script brachte Peter den Einwand, das ein Individuelles Bezahl-Menue auch gekuerzt angelegt werden kann.
llSetPayPrice(PAY_HIDE, [Preis]);
Hier bei verzichtet man lediglich auf die angabe PAY_HIDE fuer die ungenutzten Button und traegt in die Liste nur die Variable fuer den Preis ein.

In wie weit sich Kriminelle mit illegalen Viewern nun die Button und oder das manuelle Zahlfeld zurueck holen koennen, kann ich nicht sagen.
Darum verwende ich der volstaendigkeithalber ausschliesslich den kompletten Befehl und gehe sogar noch einen Schritt weiter.

Nun sehen wir im aktuellen Vendor Script, das eine Ausgabe des Objects nur dann erfolgt, wenn die Einzahlung mit dem Preis ueberein stimmt.
In der Wiki gehe ich sogar so weit, das ich mich fuer die Spende bedanke, wenn jemand versucht mich zu bescheissen.
http://wiki.secondlife.com/wiki/User:Daemonika_Nightfire/Scripts/Vendor#Default_Vendor
Der entsprechende Code dafuer sieht wiefolgt aus:
Code:
money(key id, integer payment)
    {
        // Absolut wichtig! Nur wenn die Zahlung mit dem Preis ueberein stimmt, sollte das Produkt ausgegeben werden!
        if(payment == prize)
        {
            llGiveInventory(id, object);
        }
        else if(payment != prize) // <--- *** Anti Hacker Option ***
        {
            // Sollte es dennoch jemand mit einem gehackten Viewer schaffen sich das manuelle Zahlfeld anzeigen zu lassen,
            // bedankt sich der Vendor hoeflich fuer die Spende und gibt kein Produkt aus.
            llShout(0,"Thanks for your donation, " + llKey2Name(id) + "!");
        }
    }
Das war es erst einmal wieder und ich bedanke mich bei allen Teilnehmern fuer die rege beteiligung, es hat Spass gemacht. :)

Natuerlich koennen auch hier wieder Fragen oder konstruktive Bemerkungen Einzug erhalten.
Schliesslich sind wir hier im Forum und nicht in der Wiki.



unglaublich das 2 so kleine Scripte tatsaechlich so abendfuellend sein koennen, doch ich hoffe alle hatten Spass.
Da waren zwischendurch auch einige konstruktive Anmerkungen, die ich hier ebenfalls erwaehnen moechte.
Nun aber erst mal die beiden Scripte, die fast identisch sind doch grund verschieden genutzt werden.
Zum Vergleich erst mal ganz ohne Kommentare.

Zum einen der TipJar:
Code:
integer Total = 0;

default
{
    state_entry()
    {
        llSetPayPrice(0, [5, 10, 20, 50]);
    }

    money(key id, integer payment)
    {
        Total += payment;
        llSetText(llKey2Name(id) + " zahlte " + (string)payment + "L$\nTotal: " + (string)Total + "L$", <0,1,0>, 1.0);
    }
}
Zum andern der Vendor:
Code:
integer Preis = 15;

default
{
    state_entry()
    {
        llSetPayPrice(PAY_HIDE, [Preis, PAY_HIDE, PAY_HIDE, PAY_HIDE]);
    }

    money(key id, integer payment)
    {
        if(payment == Preis)
        {
            llGiveInventory(id, llGetInventoryName(INVENTORY_OBJECT, 0));
        }
    }
}
Nun folgt der TipJar mit Kommentaren:
Der Befehl im state_entry bewirkt ein individuelles Bezahl-Menue, welches bei angegebenen Werten wiefolgt aussieht:
Zahlfeld TipJar.PNG

TipJar mit Kommentaren:
(Inworld im Script leserlicher)
Code:
// Globale Variable zum zusammen rechnen aller Zahlungseingaenge
integer Total = 0;

default
{
    state_entry() // Der state_entry Event wird beim speichern und resetten ausgefuehrt
    {
        // Individuelles Zahlfeld mit manueller Eingabe und allen 4 Bezahl-Button
        // Bei allen 5 Eintraegen handelt es sich um integer (Ganzzahl)
        llSetPayPrice(0, [5, 10, 20, 50]);
    }

    money(key id, integer payment) // Der money Event erkennt wer (key id) und wieviel (integer payment) einzahlt.
    {
        // Folgende Zeile rechnet den aktuellen Zahlungseingang mit der variable Total zusammen
        Total += payment;
 
        // Individueller Hovertext
        // Egal wie der Text aufgebaut wird, beim mixen von Text und Variablen muss auf die + Zeichen geachtet werden.
        // An welcher stelle zwischen den Gaensefuessen ein Leerschritt rein muss, wird im Hovertext ersichtlich.
        llSetText(llKey2Name(id) + " zahlte " + (string)payment + "L$\nTotal: " + (string)Total + "L$", <0,1,0>, 1.0);
    }
}
Als wir nun diesen Hovertext besprachen, kam die Frage auf, was ein unsichtbarer Hovertext fuer einen Sinn macht.
Aus konventioneller Sicht macht das absolut keinen Sinn.
Doch fuer Scripter ist diese Moeglichkeit hochinteressant.
Im Hovertext lassen sich versteckt bis zu 256 zeichen ablegen und mittels llGetPrimitiveParams wieder abrufen.
Ob das nun gewollt ist weiss ich nicht, jedenfalls haben die Lindens uns mit dieser Moeglichkeit eine enorme Speichererweiterung spendiert. ;)

Nun der Vendor:
Auch hier vewenden wir den gleichen Befehl im state_entry wie beim Tipjar, doch mit anderen Vorgaben.
Das PAY_HIDE versteckt alle ungenutzten Bezahlmoeglichkeiten und sieht folgendermassen aus:
Zahlfeld Vendor.PNG

Vendor mit Kommentaren:
(Inworld im Script leserlicher)
Code:
// Global angelegter Preis, um diese Variable nicht im Script suchen zu muessen
// Fuer andere Preise muss diese Zeile manuell angepasst werden.
integer Preis = 15;

default
{
    state_entry() // Der state_entry Event wird beim speichern und resetten ausgefuehrt
    {
        // Individuelles Zahlfeld mit nur einem einzigen Bezahl-Button ohne manueller Eingabemoeglichkeit
        // Der erste Bezahl-Button verwendet den global angelegten Preis.
        llSetPayPrice(PAY_HIDE, [Preis, PAY_HIDE, PAY_HIDE, PAY_HIDE]);
    }

    money(key id, integer payment) // Der money Event erkennt wer (key id) und wieviel (integer payment) einzahlt.
    {
        // Folgende Zeile vergleicht die aktuelle Einzahlung mit dem vorgegebenen Preis
        // Stimmt beides nicht ueberein, bekommt der Kunde gar nichts.
        if(payment == Preis)
        {
            // Dieser Befehl gibt dem einzahlenden (key id) das erste Objekt aus dem Inhalt des Vendors.
            // Man kann auch den Namen des Objects direkt bestimmen llGiveInventory(id, "Object-Name");
            // Doch bei der aktuellen Variante ist kein Eingriff im Script beim aendern des Objekts erforderlich.
            llGiveInventory(id, llGetInventoryName(INVENTORY_OBJECT, 0));
        }
    }
}
Bei diesem Script brachte Peter den Einwand, das ein Individuelles Bezahl-Menue auch gekuerzt angelegt werden kann.
llSetPayPrice(PAY_HIDE, [Preis]);
Hier bei verzichtet man lediglich auf die angabe PAY_HIDE fuer die ungenutzten Button und traegt in die Liste nur die Variable fuer den Preis ein.

In wie weit sich Kriminelle mit illegalen Viewern nun die Button und oder das manuelle Zahlfeld zurueck holen koennen, kann ich nicht sagen.
Darum verwende ich der volstaendigkeithalber ausschliesslich den kompletten Befehl und gehe sogar noch einen Schritt weiter.

Nun sehen wir im aktuellen Vendor Script, das eine Ausgabe des Objects nur dann erfolgt, wenn die Einzahlung mit dem Preis ueberein stimmt.
In der Wiki gehe ich sogar so weit, das ich mich fuer die Spende bedanke, wenn jemand versucht mich zu bescheissen.
http://wiki.secondlife.com/wiki/User:Daemonika_Nightfire/Scripts/Vendor#Default_Vendor
Der entsprechende Code dafuer sieht wiefolgt aus:
Code:
money(key id, integer payment)
    {
        // Absolut wichtig! Nur wenn die Zahlung mit dem Preis ueberein stimmt, sollte das Produkt ausgegeben werden!
        if(payment == prize)
        {
            llGiveInventory(id, object);
        }
        else if(payment != prize) // <--- *** Anti Hacker Option ***
        {
            // Sollte es dennoch jemand mit einem gehackten Viewer schaffen sich das manuelle Zahlfeld anzeigen zu lassen,
            // bedankt sich der Vendor hoeflich fuer die Spende und gibt kein Produkt aus.
            llShout(0,"Thanks for your donation, " + llKey2Name(id) + "!");
        }
    }
Das war es erst einmal wieder und ich bedanke mich bei allen Teilnehmern fuer die rege beteiligung, es hat Spass gemacht. :)

Natuerlich koennen auch hier wieder Fragen oder konstruktive Bemerkungen Einzug erhalten.
Schliesslich sind wir hier im Forum und nicht in der Wiki.
LG
Dae​
 

Kommentare