nyuuzyou/wikis huggingface dataset:
LlJsonSetValue/de

,"Z":9}]
 say("(11): " + output);
// overwriting an array with an object
 output = llJsonSetValue(input, ["X"], "10");
// {"X":10}
 say("(12): " + output);
// special case considerations:
// BUG-3692: (NOTE: Corrected in release 13.09.21.281328!)
// a bug where, instead of JSON_INVALID being returned, if the out of
// bounds index is at a lower level than the topmost (root) level, a
// non-compliant JSON text would be formed
 output = llJsonSetValue(input, [1, 7], "Disappearing Text");
// Note the "empty" second position that resulted in the returned array
// [9,,false,{"A":8,"Z":9}]
// (But now correctly shows JSON_INVALID)
 say("(13): " + output);
// though there is no way to directly delete a key-value-pair 
// nor remove a value from an array,
// the use of JSON_NULL may prove adequate
 output = llJsonSetValue(input, [3, "A"], JSON_NULL);
// [9,"<1,1,1>",false,{"A":null,"Z":9}]
 say("(14): " + output);
// if a JSON text object has been formed with llList2Json()
// that contains one or more duplicated "Keys", (allowable
// but NOT recommended!) ANY change
// made to that object will correct the condition,
// with all but the last such "Key" being removed
 output = llList2Json(JSON_OBJECT, ["A", 1, "A", 2, "A", 3, "B", 4, "B", 4]);
// both Keys "A" and "B" are duplicated
// {"A":1,"A":2,"A":3,"B":4,"B":4}
 say("(15): " + output);
// only the last value of the duplications is accessable though
// 3
 say("(16): " + llJsonGetValue(output, ["A"]));
// condition corrected by adding a key-value-pair...
// {"A":3,"B":4,"Z":5}
 say("(17): " + llJsonSetValue(output, ["Z"], "5"));
// ... or by changing a value
// {"A":5,"B":4}
 say("(18): " + llJsonSetValue(output, ["A"], "5"));
}
say(string message)
{
 llOwnerSay(message);
// llRegionSayTo(llGetOwner(), PUBLIC_CHANNEL, message);
// llWhisper(PUBLIC_CHANNEL, message);
}
default
{
 on_rez(integer start_param)
 {
 llResetScript();
 }
 state_entry()
 {
 init();
 }
 touch_end(integer num_detected)
 {
// copy 'TEST_STRING_JSON' from the following function call
// to the string 'input' in the function declaration
// and run a test on 'input' to not (!) modify 'TEST_STRING_JSON'
// but its copy instead
 run_json_test(TEST_STRING_JSON);
 }
}
</lsl>
|helpers
|also_functions=
|also_events
|also_tests
|also_articles=
|notes=
|permission
|negative_index
|sort=JsonSetValue
|cat1=List
|cat2=String
|cat3=Data Conversion
|cat4=JSON
|history = Veröffentlichungsdatum 20/05/2013 
}}
LlListReplaceList Test

[LLListReplaceListTest]
[VERSION] 0.1
[LENGTH] 00:05
[TESTERS] 1
[OVERVIEW] This test has been designed to cover the basic functionality of the LSL 
function, llListReplaceList.
[SETUP] Tester must be in an area where building is enabled.
[*]
[0030] Right-click on the ground, then select CREATE and rez a default cube
[0040] Right-click on the Cube, then select Edit.
[0050] In the Edit Window, select the Content Tab.
[0060] In the Content Window, Click "New Script"
[0070] In the Script window, copy and paste the following script replacing any original 
script and then select "Save". Wait for it to compile and save, Then Close Script Window.
[SCRIPT] ListReplaceListScript
[0080] Verify "New Script" appears in the Contents List
[0090] Close the Edit Window
[0100] Touch the Prim
[0110] Verify you hear the following lines from the prim:
[0120] a,b,2,3,4
[0130] 1,2,3,a,b
[0140] a,b
[0150] 1,2,3,4,a,b
[0160] 1,a,b,4
[0170] a,b
[0180] 3,a,b
[0190] After Verifying the test is complete, Please Clean up your work area.
[END]
[ListReplaceListScript]
default 
{ 
touch_start(integer total_number)
{
list foo = ["1", "2", "3", "4"];
list bar = ["a", "b"];
llSay(0,llList2CSV(llListReplaceList(foo,bar,0,0))); 
llSay(0,llList2CSV(llListReplaceList(foo,bar,-1,-1))); 
llSay(0,llList2CSV(llListReplaceList(foo,bar,0,-1))); 
llSay(0,llList2CSV(llListReplaceList(foo,bar,6,6))); 
llSay(0,llList2CSV(llListReplaceList(foo,bar,1,2))); 
llSay(0,llList2CSV(llListReplaceList(foo,bar,2,1))); 
llSay(0,llList2CSV(llListReplaceList(foo,bar,3,1))); 
} 
}
Category:QA Portal
Category:Quality Assurance
LlLoadURL Test

[LLLoadUrlTest]
[VERSION] 0.2
[LENGTH] 00:10
[TESTERS] 2
[OVERVIEW] This test has been designed to exercise the llLoadURL LSL function.
[SETUP] 2 non-god testers.
[*]
[0010] Tester 1: Create the following script in a box named Sue.
[SCRIPT] llLoadURLScript
[*]
[NOTE] Test Default Behavior
[*]
[0020] Tester 2: Click the box.
[0030] Tester 2: Verify you get a dialog at the top right of the screen.
[0040] Tester 2: Verify you can clearly see who owns the box, what the box is named, the 
description of the link, and the actual URL you will be taken to.
[0050] Tester 2: Click the button to open your web browser. Verify your default web 
browser loads the page advertised in the URL dialog.
[0060] Tester 2: Click the box again and verify you can close the dialog without launching 
the web page.
[*]
[NOTE] Test spam control
[*]
[0070] Tester 2: Click and hold the button. Verify you do not get spammed with URLs. They 
should only open another URL once every 10 seconds.
[*]
[NOTE] Mute
[*]
[0080] Tester 2: Mute the box. Click the box. Verify you do not get a URL dialog.
[0090] Tester 2: Unmute the box.
[0100] Tester 2: Mute Tester 1: Click the box. Verify you do not get a URL dialog.
[0110] Tester 2: Unmute Tester 1:
[*]
[NOTE] Only http:// and https:// are supported
[*]
[0120] Tester 1: Replace the URL in the script "http://Secondlife.com" 
with "https://Secondlife.com" and save
[0130] Tester 2: Click the link and verify it works.
[0140] Tester 1: Replace the URL with "ftp://ftp.idsoftware.com/"
[0150] Tester 2: Click the link and verify that your web browser is NOT opened.
[END]
[llLoadURLScript]
default 
{ 
 touch(integer total_number) 
 { 
 llLoadURL(llDetectedKey(0), "Second Life homepage", "http://Secondlife.com"); 
 } 
}
Category:QA Portal
Category:Quality Assurance
LlOnRegionReset

It would be nice if a shutdown notice from LL would trigger a scripted event. I'm using userlists which get lost when the region resets. If a noticed regionreset will trigger an event, it would be possible to take backup measures using httpreq.
Like the event will be set with LlSetResetEvent(integer secondstodisaster);
<lsl>
ResetEvent(string LLNotice) {
 llHTTPreq(migratedate(ALL));
}
</lsl>
:Where are you storing your data that is causing it to get lost? You're not using the event queue are you? -- Strife Onizuka 09:15, 6 June 2007 (PDT)
: Try to use the event Changed along with constant CHANGED_REGION and CHANGED_REGION_START. --Shadow Siamendes 10:10, 5 July 2012 (PDT)
LlOverParcel

== It would be great to check if an agent is over a parcel. ==
llOverParcel(key agent, vektor posision); - Should return TRUE or FALSE
agent = Key of an detected agent
position = Vector in the parcel
<lsl>
 if (llOverParcel(llDetectedKey(0), llGetPos()) == TRUE)
 } 
 llInstantMessage(llDetectedKey(0), "Welcome on my rented land!");
 {
</lsl>
See function llOverMyLand
LlOwnerSay Test

[LLOwnerSayTest]
[VERSION] 0.2
[LENGTH] 00:05
[TESTERS] 2
[OVERVIEW] This test has been designed to exercise the llOwnerSay LSL function.
[SETUP] This test requires 2 users and rezzable land
[*]
[0010] Tester 1: Create a new script containing the following:
[SCRIPT] llOwnerSayScript
[0020] Tester 1: Create 2 new boxes on the ground, Named Object1 and Object2.
[0030] Tester 1: Place the script in both boxes.
[0040] Tester 1: Sets Object2 to sell Original
[0050] Tester 2: Purchase the box.
[0060] Either user touches each box.
[*]
[NOTE] Expected Results:
[*]
[0070] Tester 1: Verify you should only hear "This message should only be sent to owner" 
from Object1.
[0080] Tester 2: Verify you should only hear "This message should only be sent to owner" 
from Object2.
[0090] Verify Both Users should hear "message sent to owner" from each box.
[END]
[llOwnerSayScript]
default 
{ 
touch_start(integer total_number) 
{ 
llOwnerSay("This message should only be sent to owner"); 
llSay(0,"message sent to owner"); 
} 
} 
Category:QA Portal
Category:Quality Assurance
LlParseString2List/ja

{{LSL_Function/ja
|func_id=214|func_sleep=0.0|func_energy=10.0
|func=llParseString2List|return_type=list
|p1_type=string|p1_name=src|p2_type=list|p2_name=separators|p3_type=list|p3_name=spacers
|func_footnote
|func_desc
|return_text=src を区切ってリストにし、separators を破棄して、spacers を維持し、空となった要素を全て取り除いたもの
|spec
|caveats=
*空の文字列は (separators や spacers が隣接したり、末尾にあったりした場合に作られる) は全て削除されます。
**(例えばリストの並びを保持したい等) 空文字列の要素を保持したい場合は、代わりに を使ってください。
*引数の separators と spacers はそれぞれ先頭 8 要素だけが有効です。それを超えた分は無視されます。(これが問題になる場合は、以下の 便利なスニペット の項を参照してください。)
*separators と spacers の要素は全て string 型でなければいけません。それ以外のデータ型は無視されます。
*separators は spacers よりも優先的に扱われます。マッチングは src の先頭から開始されます。src のマッチング位置において、separators の各要素、次いで spacers の各要素とマッチングが行なわれ、それから次のマッチング位置へ移動します。
*separators と spacers で要素の重複があっても、動作に支障はありません。
* 戻り値の要素は全て string 型です。他のデータ型として扱うならば で明示的に型キャストしてください。llList2* 関数による暗黙の型キャストをあてにしないでください。 (これは通常デフォルト値を返却するため)
*戻り値を直接処理するのでないならば、戻り値を必ず変数へ格納してください。
|constants
|examples=default
{
 state_entry()
 {
 // 以下のように出力されます:
 // <A><crazy><fox><.><Saw><the><moon><.><.>
 string my_string = "A crazy fox. Saw the moon..";
 list my_list = llParseString2List(my_string,[" "],["."]);
 llOwnerSay("<" + llDumpList2String(my_list,"><") + ">");
 
 // 以下のように出力されます:
 // <A><crazy><fox><.><><><Saw><the><moon><.><><.><>
 my_list = llParseStringKeepNulls(my_string,[" "],["."]);
 llOwnerSay("<" + llDumpList2String(my_list,"><") + ">");
 }
}
|helpers=
8 個以上のspacers や separators を扱う例:'''
{
}
|also_functions=
|also_events
|also_tests
|also_articles=
|notes=何かを separator として指定すると、指定された separator が見つかった位置で文字列を区切り、separator を削除することになります。
一方、何かを spacer として指定すると、spacer が見つかった位置で文字列を区切りますが、spacer はそこに置き去りにされ、結果に含まれることになります。
string myString = "What Are You Looking At?";
llSay(0, (string)llParseString2List(myString, ["W", "A", "Y", "L", "A"], [] ));
//出力: hat re ou ooking t?
 
llSay(0, (string)llParseString2List(myString, [], ["W", "A", "Y", "L", "A"] ) );
//出力: What Are You Looking At?
separators の要素に " " を使うと、英文は単語に切り分けられます。
spacers に何も指定したくない場合は [] としてください。
空の文字列を separator または spacer として指定すると、何も起こりません。
|permission
|negative_index
|sort=ParseString2List
|cat1=List
|cat2=String
|cat3=Data Conversion
|cat4
}}
LlParseStringKeepNulls/fr

{{LSL_Function/fr
|func_id=285|func_sleep=0.0|func_energy=10.0
|func=llParseStringKeepNulls|return_type=list
|p1_type=string|p1_name=src|p1_desc=string source
|p2_type=list|p2_name=séparateurs_supprimés|p2_desc=list de séparateurs supprimés
|p3_type=list|p3_name=séparateurs_conservés|p3_desc=list de séparateurs conservés
|func_footnote
|func_desc
|return_text=correspondant au string src converti en list, sans conserver les séparateurs_supprimés et en gardant les séparateurs_conservés et en gardant par ailleurs les valeurs nulles générées.
|spec
|caveats=
* Seuls les 8 premiers séparateurs de chaque list sont utilisés, les autres sont ignorés.
* Tous les séparateurs doivent être des strings, les autres types de séparateurs seront ignorés.
* Les séparateurs_supprimés sont analysés avant les séparateurs_conservés. Le string est analysé de gauche à droite, la comparaison est faite avec le list des séparateurs_supprimés, puis avec le list des séparateurs_conservés.
* Les doublons sont ignorés.
* Tous les éléments renvoyés sont des strings. Utilisez les options de conversion explicite sur un llList2String pour convertir une donnée dans un autre type. Ne faites pas confiance aux fonctionnalités de conversion des autres llList2* (car elles retournent généralement leur valeur par défaut sur un string).
|constants
|examples=<lsl>default
{
 state_entry()
 {
 // cette partie dira :
 // <Un><renard><fous><.><Regarde><la><lune><.><.>
 string my_string = "Un renard fou. Regarde la lune..";
 list my_list = llParseString2List(my_string,[" "],["."]);
 llOwnerSay("<" + llDumpList2String(my_list,"><") + ">");
 
 // cette partie dira:
 // <Un><renard><fous><.><><><Regarde><la><lune><.><.><>
 my_list = llParseStringKeepNulls(my_string,[" "],["."]);
 llOwnerSay("<" + llDumpList2String(my_list,"><") + ">");
 }
}</lsl>
|helpers=
Exemples pour utiliser plus de 8 séparateurs:
{
}
|also_functions=
|also_events
|also_tests
|also_articles
|notes
|permission
|negative_index
|sort=ParseStringKeepNulls
|cat1=List/fr
|cat2=String/fr
|cat3=Data Conversion/fr
|cat4
}}
LlParseStringKeepNulls/ja

{{LSL_Function/ja
|func_id=285|func_sleep=0.0|func_energy=10.0
|func=llParseStringKeepNulls|return_type=list|p1_type=string|p1_name=src|p2_type=list|p2_name=separators|p3_type=list|p3_name=spacers
|func_footnote
|func_desc
|return_text=src を区切ってリストにし、separators を破棄して、spacers を維持し、空となった要素はそのままにしたもの
|spec=
戻り値で空文字列の要素が保持される点を除けば、 と同じ動作をします。Null もしくは空の要素を含む (そしてその空要素をを取り除くとデータの配置や要素のインデックスがぐちゃぐちゃになる) リストを切り分ける場合に有用です。
llParseStringKeepNulls("", ["~"], []) は [""] を返します。
|caveats=
*引数の separators と spacers はそれぞれ先頭 8 要素だけが有効です。それを超えた分は無視されます。(これが問題になる場合は、以下の 便利なスニペット の項を参照してください。)
*separators と spacers の要素は全て string 型でなければいけません。それ以外のデータ型は無視されます。
*separators は spacers よりも優先的に扱われます。マッチングは src の先頭から開始されます。src のマッチング位置において、separators の各要素、次いで spacers の各要素とマッチングが行なわれ、それから次のマッチング位置へ移動します。
*separators と spacers で要素の重複があっても、動作に支障はありません。
*戻り値の要素は全て string 型です。他のデータ型として扱うならば で取り出した文字列を明示的に型キャストしてください。llList2* 関数による暗黙の型キャストをあてにしないでください。 (これは通常デフォルト値を返却するため)
**これを忘れて、リストに切り分けた文字列から直接vectorやrotationの値を取り出そうとする事が、しばしばバグの原因となります。
*戻り値を直接処理するのでないならば、戻り値を必ず変数へ格納してください。
|constants
|examples=default
{
 state_entry()
 {
 // 以下のように出力されます:
 // <A><crazy><fox><.><Saw><the><moon><.><.>
 string my_string = "A crazy fox. Saw the moon..";
 list my_list = llParseString2List(my_string,[" "],["."]);
 llOwnerSay("<" + llDumpList2String(my_list,"><") + ">");
 
 // 以下のように出力されます:
 // <A><crazy><fox><.><><><Saw><the><moon><.><><.><>
 my_list = llParseStringKeepNulls(my_string,[" "],["."]);
 llOwnerSay("<" + llDumpList2String(my_list,"><") + ">");
 }
}
|helpers=
separator/spacer の数の制限を回避するか、非常に大きなものにする代替関数
{
}
|also_functions=
|also_events
|also_tests
|also_articles
|notes
|sort=ParseStringKeepNulls
|cat1=List
|cat2=String
|cat3=Data Conversion
|cat4
}}
LlPatrolPoints debugging

<lsl>
float speed = 5.0;
float wanderRadius = 15.0;
//add your coordinate points here
list points = [
<40, 30, 10>, 
<40, 20, 10>,
<40, 20, 10>];
debugMsg(string msg)
{
 //llOwnerSay(msg); //comment this line out to turn off debug messages
}
setup()
{
 llDeleteCharacter();
 llResetScript();
}
doStuff()
{
 llPatrolPoints(points, []);
}
default
{
 state_entry()
 {
 llCreateCharacter([CHARACTER_DESIRED_SPEED, speed, CHARACTER_ORIENTATION, VERTICAL, CHARACTER_RADIUS, 0.2, CHARACTER_LENGTH, 0.5]);
 doStuff(); //either replace this with your functionality or replace the function doStuff()
 }
 
 //touch_start(integer total_number)
 //{
 // setup(); //comment this handler line out when done testing unless touch events desired
 //}
 
 on_rez(integer start_param)
 { 
 setup(); 
 }
 
 path_update(integer update, list none)
 {
 if (update == 0) //near goal
 {
 debugMsg("");
 }
 else if (update == 1) //goal reached
 {
 debugMsg("");
 }
 else //errors
 {
 debugMsg("");
 }
 }
}
</lsl>
Get coordinate points (add to a prim, touch prim to get closest good pathfinding coordinate):
<lsl>
default
{
 state_entry()
 {
 // llSay(0, "Hello, Avatar!");
 }
 touch_start(integer total_number)
 {
 llOwnerSay((string)llGetClosestNavPoint(llGetPos(), []));
 }
}
</lsl>
LlRequestPermissions(llGetOwner(), PERMISSION REFUND);

Currently, any script that processes payment TO an avatar needs DEBIT permission to be able to refund the paying avatar if the amount payed was incorrect or something else went wrong. Apart from the problem that PERMISSION_DEBIT is currently limitless, meaning a vendor processing L$ 10 payments needs permission to llGiveMoney(to_some_avatar, unlimited_amount), there is also conceptually a big difference between REFUNDING money or GIVING money. I don't think a function llRefundMoney is needed, but it would be very good if the difference could be expressed in permissions. You could consider changing the color of the dialog box for request DEBIT permission from blue to red (after all, it's abuse sensitive.. blue can be a bit misleading). You could then have a yellow box for request REFUND permission. You would then restrict llGiveMoney, when called under REFUND permission, to
a) Only be called from within a money event context
b) Limit the amount given to the amount received in the money event.
Furthermore I suggest you add a 'budget' parameter to DEBIT permission, so any scripts that need to give money at will to operate can be restricted in their money-giving abilities.
For an illustration of the problems we currently have with DEBIT_PERMISSION, here are possible fraud scenarios:
Disguised-request-debit fraud
* Create an object for which it makes sense that it needs DEBIT permission, a slots machine, sploderball or vendor machine will do
* Create an algorithm to steal as much money as possible and let it run periodically
Users will give the DEBIT permission because it is expected that the object will ask for it. We need to have a budget parameter here so the dialog can say: .. wants to: Take a maximum of L$ 25 from you. Is this ok?
Request-debit-on-payment fraud
* Create a nice looking object that says: "Freebie: L$ 0"
* Do not set it 'For Sale', but instead llSetPayPrice(0, [DEFAULT,HIDDEN,HIDDEN,HIDDEN]);
* Create a money event and llSetPayText("Buy");
* Inside the money event, do a llRequestPermissions(id, [PERMISSION_DEBIT]);
The user will see: 
* An object marked "Freebie: L$ 0" 
* Upon rightclick, a pie menu item marked "Buy"
* Upon selection of the menu item, a dialog that says "Pay L$ to object "Freebie" owned by OddesE Oh?" with button "L$ 0"
* Upon payment, another dialog that says "Object "Freebie" owned by OddesE Oh wants to: Take L$ from you. Is this ok?" with buttons "Yes" and "No".
How many users do you trust with your money and this series of events?
LlRequestSimulatorData Test

[LLRequestSimulatorDataTest]
[VERSION] 0.3
[LENGTH] 00:10
[TESTERS] 1
[OVERVIEW] This test has been designed to exercise the llRequestSimulatorData LSL function.
[SETUP] This test requires 1 Tester and rezzable land
[*]
[0010] Create a new script containing the following:
[SCRIPT] llRequestSimulatorDataScript
[0020] Create a box on the ground, Named SimDataTest
[0030] Place the Script in the Box
[0040] Type /1 and then a sim name, Example: "/1 Ahern" minus the quotations, This will 
have you say on channel 1 "Ahern" so that the object with this script hears it and responds.
[0050] Verify the script responds with correct information. Example: "SimDataTest: Ahern 
(PG) (255232, 256512) is up" and "SimDataTest: Gibson (MATURE) (254976, 256000) is up"
[0060] Remember to clear up after your tests.
[END]
[llRequestSimulatorDataScript]
<lsl>string gSimName; 
key gStatusQuery;
string gStatus;
string gRating;
key SimPos;
default
{
 state_entry() 
 { 
 llListen(1, "", "", ""); 
 } 
 listen(integer channel, string name, key id, string mesg) 
 { 
 gSimName = mesg; 
 gStatusQuery = llRequestSimulatorData(gSimName, DATA_SIM_STATUS); 
 gRating = llRequestSimulatorData(gSimName, DATA_SIM_RATING);
 SimPos = llRequestSimulatorData(gSimName, DATA_SIM_POS);
 }
 
 dataserver(key queryId, string data) 
 {
 if (queryId == gStatusQuery)
 {
 gStatus = data;
 }
 else if (queryId == gRating)
 {
 gRating = data;
 } 
 else 
 {
 vector SimPos? = (vector) data; 
 llSay(0, gSimName + " (" + gRating + ") " + "(" + 
 (string)((integer) SimPos?.x) + ", " + 
 (string)((integer) SimPos?.y) + ") is " + gStatus); 
 }
 }
}</lsl>
Category:QA Portal
Category:Quality Assurance
LlRequestUpgrade

This article is a feature request, not an actually existing function (yet)
== Summary ==
llRequestUpgrade(key objecttypeid, integer currentversion, list params)
This command sends a request for an upgrade.
== Upgrading ==
Sometimes you don't want to help everyone who has purchased an item you created with an upgrade of that item. In these cases you might want to build in a feature in the object so that it can replace itself for an upgraded version. This is exactly what this command does. It sends a request to the server for an upgraded version of this object and if an upgrade is available, it destroys itself and it is then replaced with an upgraded version.
However, there are several things that may happen, depending on how the upgrade was made available. For this, there would be a command like llPublishUpgradableObject which takes a key and object name as parameter. For example:
=== The publishing script ===
key typeid = "18b03c24-809b-2c19-68d9-fac357e98d29";
default
{
 state_entry()
 {
 llPublishUpgradableObject(typeid, "some_upgradable_object");
 }
 upgrade_request(key requester, integer currentversion, list params)
 {
 if (currentversion < 1)
 {
 llUpgradeError(Requester, "Sorry, your current version is too old. Cannot migrate the settings of your current version to the new one");
 }
 else if (currentversion == 1)
 {
 llConfirmUpgrade(requester, 100, param);
 }
 else
 {
 llConfirmUpgrade(requester, 0, param);
 }
 }
}
=== The requesting object script (old version of the object) ===
integer version = 1;
key mytypeid = "18b03c24-809b-2c19-68d9-fac357e98d29";
default
{
 state_entry()
 {
 llSetText("Version 1...", <1,1,1>, 1);
 }
 touch_start(integer num)
 {
 list params;
 params += "some value to pass to new version of object";
 params += "another value to pass to new version of object";
 llRequestUpgrade(mytypeid, version, params);
 }
}
=== The upgraded object script ===
integer version = 3;
key mytypeid = "18b03c24-809b-2c19-68d9-fac357e98d29";
default
{
 state_entry()
 {
 llSetText("Version 3!", <1,1,1>, 1);
 }
 touch_start(integer num)
 {
 list params;
 params += "some value to pass to new version of object";
 params += "another value to pass to new version of object";
 llRequestUpgrade(mytypeid, version, params);
 }
 upgraded(integer oldversion, list params)
 {
 if (oldversion == 1)
 {
 // Do stuff to migrate settings from version 1...
 } else {
 // Do stuff to migrate settings from version 2...
 }
 }
}
I think the example should make it clear, except perhaps for the second parameter to the llConfirmUpgrade command. Sometimes you might want to support an update for an object, but don't want to do it for nothing. It might have been a difficult job to support the upgrade from that version to the new one. For this, there would be a money parameter. If the value to this parameter is greater than 0, the user will receive a dialog, asking if the user wants to pay the amount of linden dollars passed.
== Author ==
Original author: Xoren Raymaker
This request might need some tweaking.. I'm interested what you think of it and what your ideas are.
Category:Feature Requests