123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766 |
- {{ define "lsl-bot-controller" }}
- <p>This is the master bot controller script, which allows controlling all agents, including creating new ones.</p>
- <p>Copy the below code to a script called <code>bot controller.lsl</code> and put it inside a cube.</p>
- <pre><code class="language-javascript">
- // Handles registration with the external database
- // Send inventory and deal with external commands
- // This combines the old listen channel with the new HTTP-based command, since we need to be able to clone avatars
- // to notecards (which was only present on the old code)
- string registrationURL = "http://{{.Host}}{{.ServerPort}}{{.URLPathPrefix}}/register-position/";
- string externalURL; // this is what we'll get from SL to get incoming connections
- string webServerURLupdateInventory = "http://{{.Host}}{{.ServerPort}}{{.URLPathPrefix}}/update-inventory/";
- key registrationRequest; // used to track down the request for registration
- key updateRequest; // used to track down the request for registration
- key serverKey; // for inventory updates
- key httpRequestKey;
- list npcNames;
- integer howManyNPCs = 0;
- string deleteAvatarURL = "http://{{.Host}}{{.ServerPort}}{{.URLPathPrefix}}/register-position/";
- key deleteRequest;
- key npc; // used on chat commands
- integer LSLSignaturePIN = {{.LSLSignaturePIN}};
- integer listenChannel = 10;
- init()
- {
- llSetText("Registering bot controller...", <1.0,0.0,0.0>, 1.0);
- llOwnerSay("Registering bot controller...");
- llSetTimerEvent(0.0);
-
- // release URLs before requesting a new one
- llReleaseURL(externalURL);
- externalURL = "";
- llRequestURL();
- }
- default
- {
- state_entry()
- {
- //llOwnerSay("On state_entry");
- llListen(listenChannel,"",NULL_KEY,"");
- llSetText("Listening on " + listenChannel, <0, 255, 0>, 1);
- llOwnerSay("Say /" + (string)listenChannel + " help for commands");
- llSetTimerEvent(3600.0); // this will hopefully force an update every hour
- }
-
- on_rez(integer what)
- {
- //llOwnerSay("On on_rez");
- init();
- }
- touch_start(integer total_number)
- {
- // llOwnerSay("On touch_start");
- // just re-register
-
- if (llDetectedKey(0) == llGetOwner() || llDetectedGroup(0))
- {
- if (llDetectedTouchFace(0) != 0)
- init();
- }
- }
-
- listen(integer channel, string name, key id, string msg)
- {
- if (msg != "")
- {
- list commands = llParseString2List(msg, [ " " ], []);
- string msg0 = llList2String(commands, 0);
- string msg1 = llList2String(commands, 1);
- string msg2 = llList2String(commands, 2);
- string msg3 = llList2String(commands, 3);
-
- if (msg0 == "create")
- {
- if (msg1 != "")
- {
- string notecardName = msg1;
- string FirstName = msg2;
- string LastName = msg3;
-
- if (FirstName == "") FirstName = "Jane";
- if (LastName == "") LastName = "Doe";
-
- npc = osNpcCreate(FirstName, LastName, llGetPos() + <5, 5, 0>, notecardName, OS_NPC_SENSE_AS_AGENT);
-
- npcNames += [npc];
- osNpcSetProfileImage(npc, "botimage"); // this texture MUST be inside the content for this to work!
- osNpcSetProfileAbout(npc, "Hello! I'm just a friendly bot passing by! Please ignore me!");
-
- llOwnerSay("Created npc " + (string) npc + " from notecard " + notecardName);
- }
- else
- {
- llOwnerSay("Usage: create <notecard-name> <FirstName> <LastName>");
- }
- }
- else if (msg0 =="createm")
- {
- // msg1 says number of NPCs to be created
- string notecardName = msg2;
- if (notecardName == "") notecardName = "appearance";
-
- // osOwnerSaveAppearance(notecardName);
- vector pos = llGetPos();
- integer i;
- npcNames = []; // reset list
- key newNPC;
- float angle;
- rotation npcCurrRot;
- rotation npcNewRot;
-
- for (i = 0; i < (integer)msg1; i++)
- {
- // add some randomness
- float xRand = llFrand(30) - 30;
- float yRand = llFrand(30) - 30;
- newNPC = osNpcCreate("John-" + (string)i, "Doe", pos + <xRand, yRand, 0>, notecardName);
- npcNames += [newNPC];
- llSleep(1);
- npcCurrRot = osNpcGetRot(newNPC);
- angle = llAtan2( llVecMag(pos % (pos + <xRand, yRand, 0>)), pos * (pos + <xRand, yRand, 0>) );
- npcNewRot = npcCurrRot * llEuler2Rot(<0.0, 0.0, angle>);
- osNpcSetRot(newNPC, npcNewRot);
- llOwnerSay("NPC <" + newNPC + "> created, old rot: "
- + (string)npcCurrRot + ", new rot: " + (string)npcNewRot);
- }
- }
- else if (msg0 == "remove" && npc != NULL_KEY)
- {
- integer npcToKill = llListFindList(npcNames, npc);
-
- if (npcToKill == -1) {
- llOwnerSay("Remove: NPC key '" + (string)npc + "' not found");
- } else {
- osNpcSay(npc, "You will pay for this with your liiiiiivvveeessss!!!.....");
- osNpcRemove(npc);
-
- // inform server to delete this bot from
- // database
- string myTimestamp = llGetTimestamp();
- deleteRequest = llHTTPRequest(deleteAvatarURL, [HTTP_METHOD, "POST", HTTP_MIMETYPE, "application/x-www-form-urlencoded"],
- "request=delete"
- + "&npc=" + (string)npc
- + "&timestamp=" + myTimestamp
- + "&signature=" + llMD5String((string)llGetKey() + myTimestamp, LSLSignaturePIN));
- }
- }
- else if (msg0 == "forceremove")
- {
- llInstantMessage(id, "Trying to remove " +
- msg1 + "(" + llKey2Name((key)msg1) + ")");
- osNpcRemove((key)msg1);
- string myTimestamp = llGetTimestamp();
- deleteRequest = llHTTPRequest(deleteAvatarURL, [HTTP_METHOD, "POST", HTTP_MIMETYPE, "application/x-www-form-urlencoded"],
- "request=delete"
- + "&npc=" + msg1
- + "&timestamp=" + myTimestamp
- + "&signature=" + llMD5String((string)llGetKey() + myTimestamp, LSLSignaturePIN));
- }
- else if (msg0 == "removeall")
- {
- integer i;
-
- for (i = 0; i < llGetListLength(npcNames); i++)
- {
- osNpcRemove(llList2Key(npcNames, i));
- string myTimestamp = llGetTimestamp();
- deleteRequest = llHTTPRequest(deleteAvatarURL, [HTTP_METHOD, "POST", HTTP_MIMETYPE, "application/x-www-form-urlencoded"],
- "request=delete"
- + "&npc=" + llList2String(npcNames, i)
- + "&timestamp=" + myTimestamp
- + "&signature=" + llMD5String((string)llGetKey() + myTimestamp, LSLSignaturePIN));
- }
- llOwnerSay("All NPCs removed");
- }
- else if (msg0 == "say" && npc != NULL_KEY)
- {
- integer npcToSay = llListFindList(npcNames, npc);
-
- if (npcToSay == -1) {
- llOwnerSay("Say: NPC key " + (string)npc + "not found");
- } else {
- osNpcSay(llList2Key(npcNames, npcToSay), "I am your worst Nightmare!!!!");
- }
- }
- else if (msg0 == "move")
- {
- integer npcToMove = llListFindList(npcNames, npc);
- if (msg1 != "" && msg2 != "" && npc != NULL_KEY && npcToMove != -1)
- {
- key npcMoving = llList2Key(npcNames, npcToMove);
-
- vector delta = <(integer)msg1, (integer)msg2, 0>;
-
- if (msg3 != "")
- {
- delta.z = (integer)msg3;
- }
-
- osNpcMoveTo(npcMoving, osNpcGetPos(npc) + delta);
- }
- else
- {
- llOwnerSay("Usage: move <x> <y> [<z>]");
- }
- }
- else if (msg0 == "moveto")
- {
- integer npcToMove = llListFindList(npcNames, npc);
-
- if (msg1 != "" && msg2 != "" && npc != NULL_KEY && npcToMove != -1)
- {
- vector pos = <(integer)msg1, (integer)msg2, 0>;
-
- if (msg3 != "")
- {
- pos.z = (integer)msg3;
- }
-
- osNpcMoveTo(npc, pos);
- }
- else
- {
- llOwnerSay("Usage: move <x> <y> [<z>]");
- }
- }
- else if (msg0 == "movetarget" && npc != NULL_KEY)
- {
- integer npcToMove = llListFindList(npcNames, npc);
-
- if (npcToMove == -1)
- {
- llOwnerSay("MoveTarget: NPC key " + (string)npc + " not found");
- } else {
- osNpcMoveToTarget(npc, llGetPos() + <9,9,5>, OS_NPC_FLY|OS_NPC_LAND_AT_TARGET);
- }
- }
- else if (msg0 == "movetargetnoland" && npc != NULL_KEY)
- {
- integer npcToMove = llListFindList(npcNames, npc);
-
- if (npcToMove == -1) {
- llOwnerSay("MoveTargetNoLand: NPC key " + (string)npc + " not found");
- } else {
- osNpcMoveToTarget(npc, llGetPos() + <9,9,5>, OS_NPC_FLY);
- }
- }
- else if (msg0 == "movetargetwalk" && npc != NULL_KEY)
- {
- integer npcToMove = llListFindList(npcNames, npc);
-
- if (npcToMove == -1) {
- llOwnerSay("MoveTargetWalk: NPC key " + (string)npc + " not found");
- } else {
- osNpcMoveToTarget(npc, llGetPos() + <9,9,0>, OS_NPC_NO_FLY);
- }
- }
- else if (msg0 == "rot" && npc != NULL_KEY)
- {
- integer npcToMove = llListFindList(npcNames, npc);
-
- if (npcToMove == -1) {
- llOwnerSay("Rot: NPC key " + (string)npc + " not found");
- } else {
- vector xyz_angles = <0,0,90>; // This is to define a 1 degree change
- vector angles_in_radians = xyz_angles * DEG_TO_RAD; // Change to Radians
- rotation rot_xyzq = llEuler2Rot(angles_in_radians); // Change to a Rotation
- rotation rot = osNpcGetRot(npc);
- osNpcSetRot(npc, rot * rot_xyzq);
- }
- }
- else if (msg0 == "rotabs" && msg1 != "")
- {
- integer npcToMove = llListFindList(npcNames, npc);
-
- if (npcToMove == -1) {
- llOwnerSay("Rotabs: NPC key " + (string)npc + " not found");
- } else {
- vector xyz_angles = <0, 0, (integer)msg1>;
- vector angles_in_radians = xyz_angles * DEG_TO_RAD; // Change to Radians
- rotation rot_xyzq = llEuler2Rot(angles_in_radians); // Change to a Rotation
- osNpcSetRot(npc, rot_xyzq);
- }
- }
- else if (msg0 == "animate" && npc != NULL_KEY)
- {
- integer npcToMove = llListFindList(npcNames, npc);
-
- if (npcToMove == -1) {
- llOwnerSay("Animate: NPC key " + (string)npc + " not found");
- } else {
- osAvatarPlayAnimation(npc, "stabbed+die_2");
- llSleep(3);
- osAvatarStopAnimation(npc, "stabbed+die_2");
- }
- }
- else if (msg0 == "getrot" && npc != NULL_KEY)
- {
- integer npcToMove = llListFindList(npcNames, npc);
-
- if (npcToMove == -1) {
- llOwnerSay("Get rotation: NPC key " + (string)npc + " not found");
- } else {
- llSay(0, "Rotation is: " + (string)osNpcGetRot(npc));
- }
- }
- else if (msg0 == "save" && msg1 != "" && npc != NULL_KEY)
- {
- integer npcToMove = llListFindList(npcNames, npc);
-
- if (npcToMove == -1) {
- llOwnerSay("Save: NPC key " + (string)npc + " not found");
- } else {
- osNpcSaveAppearance(npc, msg1);
- llOwnerSay("Saved appearance " + msg1 + " to " + npc);
- }
- }
- else if (msg0 == "load" && msg1 != "" && npc != NULL_KEY)
- {
- integer npcToMove = llListFindList(npcNames, npc);
-
- if (npcToMove == -1) {
- llOwnerSay("Load appearance: NPC key " + (string)npc + " not found");
- } else {
- osNpcLoadAppearance(npc, msg1);
- llOwnerSay("Loaded appearance " + msg1 + " to " + npc);
- }
- }
- else if (msg0 == "clone")
- {
- if (msg1 != "")
- {
- osOwnerSaveAppearance(msg1);
- llOwnerSay("Cloned your appearance to " + msg1);
- }
- else
- {
- llOwnerSay("Usage: clone <notecard-name-to-save>");
- }
- }
- else if (msg0 == "stop" && npc != NULL_KEY)
- {
- integer npcToMove = llListFindList(npcNames, npc);
-
- if (npcToMove == -1) {
- llOwnerSay("Stop: NPC key " + (string)npc + " not found");
- } else {
- osNpcStopMoveToTarget(npc);
- }
- }
- else if (msg0 == "sit" && msg1 != "" && npc != NULL_KEY)
- {
- integer npcToMove = llListFindList(npcNames, npc);
-
- if (npcToMove == -1) {
- llOwnerSay("Sit: NPC key " + (string)npc + " not found");
- } else {
- osNpcSit(npc, msg1, OS_NPC_SIT_NOW);
- }
- }
- else if (msg0 == "stand" && npc != NULL_KEY)
- {
- integer npcToMove = llListFindList(npcNames, npc);
-
- if (npcToMove == -1) {
- llOwnerSay("Stand: NPC key " + (string)npc + " not found");
- } else {
- osNpcStand(npc);
- }
- }
- else if (msg0 == "swarm")
- {
- // is list empty?
-
- if (npcNames == []) llOwnerSay("Swarm: no NPCs");
-
- // go through the list
- integer i;
- vector currPos = llGetPos();
- vector npcCurrPos;
- vector npcFuturePos;
- key currNPC;
-
- for (i = 0; i < llGetListLength(npcNames); i++)
- {
- currNPC = llList2Key(npcNames, i);
- npcCurrPos = osNpcGetPos(currNPC);
-
-
- // calculate intermediate point (quarter the distance)
- npcFuturePos = ((currPos - npcCurrPos) / 4.0) + npcCurrPos;
-
- osNpcMoveToTarget(currNPC, npcFuturePos, OS_NPC_NO_FLY);
- osNpcSay(currNPC, "Moving from " + (string)currPos + " to "
- + (string)npcFuturePos);
- }
- llOwnerSay("One moving interaction finished");
- }
- else if (msg0 == "help")
- {
- llOwnerSay("Commands are:");
- llOwnerSay("create <notecard-name> <FirstName> <LastName> - Create NPC from a stored notecard");
- llOwnerSay("createm <N> <notecard-name> - Create N NPCs from a notecard");
- llOwnerSay("remove - Remove current NPC");
- llOwnerSay("forceremove <uuid> - Remove NPC with key <uuid>");
- llOwnerSay("removeall - Remove all NPCs");
- llOwnerSay("clone <notecard-name> - Clone own appearance to a notecard");
- llOwnerSay("load <notecard-name> - Load appearance on notecard to current npc");
- llOwnerSay("save <notecard-name> - Save appearance of current NPC to notecard");
- llOwnerSay("animate");
- llOwnerSay("move");
- llOwnerSay("moveto <x> <y> <z> - move to absolute position");
- llOwnerSay("movetarget");
- llOwnerSay("movetargetnoland");
- llOwnerSay("movetargetwalk");
- llOwnerSay("rot");
- llOwnerSay("getrot");
- llOwnerSay("say");
- llOwnerSay("sit <target-uuid>");
- llOwnerSay("stop");
- llOwnerSay("stand");
- llOwnerSay("swarm");
- }
- else
- {
- llOwnerSay("I don't understand [" + msg + "]");
- }
- }
- }
-
- http_response(key request_id, integer status, list metadata, string body)
- {
- if (request_id == registrationRequest || request_id == updateRequest)
- {
- if (status == 200)
- {
- llOwnerSay(body);
- // new registration? switch to inventory reading
- if (request_id == registrationRequest)
- state read_inventory;
- // if it is just an update, no need to do anything else for now
- }
- else
- {
- llSetText("!!! BROKEN !!!", <1.0,0.0,0.0>, 1.0);
- llOwnerSay("Error " +(string)status + ": " + body);
- llSetTimerEvent(3600.0); // try registering again in an hour
- }
- }
- }
- http_request(key id, string method, string body)
- {
- //llOwnerSay("Entering http_request for registration...");
- if (method == URL_REQUEST_GRANTED)
- {
- externalURL = body;
- string myTimestamp = llGetTimestamp();
- string formRequest = "permURL=" + llEscapeURL(externalURL)
- + "&objecttype=" + llEscapeURL("Bot Controller")
- + "&timestamp=" + myTimestamp
- + "&signature=" + llMD5String((string)llGetKey() + myTimestamp, LSLSignaturePIN);
- // llOwnerSay("Registration URL is " + registrationURL + " Form request is: " + formRequest);
-
- registrationRequest = llHTTPRequest(registrationURL, [HTTP_METHOD, "POST", HTTP_MIMETYPE, "application/x-www-form-urlencoded"],
- formRequest);
-
- llSetTimerEvent(3600.0); // if the registration fails, try later
- }
- else if (method == URL_REQUEST_DENIED)
- {
- llSetText("!!! BROKEN !!!", <1.0,0.0,0.0>, 1.0);
- llOwnerSay("Something went wrong, no url. " + body);
- llSetTimerEvent(3600.0);
- }
- else if (method == "POST" || method == "GET")
- {
- // incoming request for bot to do things
- //llSay(0, "[Request from server:] " + body);
-
- list params = llParseStringKeepNulls(llUnescapeURL(body), ["&", "="], []);
- string response; // what we return
-
- // first parameter will always be be npc=
-
- key NPC = llList2String(params, 1);
- //if (osIsNpc(NPC))
- // llSay(0, "Sanity check: This is an NPC with key " + (string)NPC);
- //else
- // llSay(0, "Sanity check failed: Key " + (string)NPC + " is NOT an NPC");
-
- // llOwnerSay("List parsed: " + (string) params);
-
- // commands begin on the second parameter
- string commandTag = llList2String(params, 2);
- string command = llList2String(params, 3);
- if (commandTag == "command" && (osIsNpc(NPC) || command == "osNpcCreate" || command == "ping"))
- {
- if (command == "osNpcGetRot")
- {
- response = (string)osNpcGetRot(NPC);
- }
- else if (command == "osNpcSetRot")
- {
- osNpcSetRot(NPC, llList2Rot(params, 5));
- response = "Rotation set.";
- }
- else if (command == "osNpcGetPos")
- {
- response = (string)osNpcGetPos(NPC);
- }
- else if (command == "osNpcGetOwner")
- {
- response = (string)osNpcGetOwner(NPC);
- }
- else if (command == "osNpcMoveToTarget")
- {
- osNpcMoveToTarget(NPC, llList2Vector(params, 5), llList2Integer(params, 7));
- response = "Moving to target " + llList2String(params, 5);
- }
- else if (command == "osNpcStopMoveToTarget")
- {
- osNpcStopMoveToTarget(NPC);
- response = "Stopping.";
- }
- else if (command == "osNpcSit")
- {
- osNpcSit(NPC, llList2Key(params, 5), llList2Integer(params, 7));
- response = "Sitting on " +
- llKey2Name(llList2Key(params, 5))
- + " (" + llList2Key(params, 5) + ").";
- }
- else if (command == "osNpcStand")
- {
- osNpcStand(NPC);
- response = "Standing up.";
- }
- else if (command == "osNpcSay")
- {
- osNpcSay(NPC, llList2Integer(params, 5), llUnescapeURL(llList2String(params, 7)));
- response = "Saying \"" +
- llUnescapeURL(llList2String(params, 7)) + "\".";
- }
- else if (command == "osNpcShout")
- {
- osNpcShout(NPC, llList2Integer(params, 5), llUnescapeURL(llList2String(params, 7)));
- response = "Shouting \"" +
- llUnescapeURL(llList2String(params, 7)) + "\".";
- }
- else if (command == "osNpcWhisper")
- {
- osNpcWhisper(NPC, llList2Integer(params, 5), llUnescapeURL(llList2String(params, 7)));
- response = "Whispering \"" +
- llUnescapeURL(llList2String(params, 7)) + "\".";
- }
- else if (command == "osNpcPlayAnimation")
- {
- osNpcPlayAnimation(NPC, llList2String(params, 5));
- response = "Playing animation \"" +
- llList2String(params, 5) + "\".";
- }
- else if (command == "osNpcStopAnimation")
- {
- osNpcStopAnimation(NPC, llList2String(params, 5));
- response = "Stopping animation \"" +
- llList2String(params, 5) + "\".";
- }
- else if (command == "osNpcLoadAppearance")
- {
- osNpcLoadAppearance(NPC, llList2String(params, 5));
- response = "Loading appearance \"" +
- llList2String(params, 5) + "\".";
- }
- else if (command == "osNpcTouch")
- {
- osNpcTouch(NPC, llList2Key(params, 5), llList2Integer(params, 7));
- response = "Touching " + llKey2Name(llList2Key(params, 5))
- + " (" + llList2Key(params, 5) + ").";
- }
- else if (command == "osNpcCreate")
- {
- string FirstName = "My";
- string LastName = "Bot";
- string fullName = llList2String(params, 5);
- integer index = llSubStringIndex(fullName, " ");
- if (~index)
- FirstName = llDeleteSubString(fullName, index, -1);
- else FirstName = fullName;
-
- if (~index)
- LastName = llDeleteSubString(fullName, 0, index);
- else LastName = "Bot";
-
- // add some randomness
- float xRand = llFrand(30) - 30;
- float yRand = llFrand(30) - 30;
- vector pos = llGetPos();
-
- key newNPC = osNpcCreate(FirstName, LastName, pos + <xRand, yRand, 0>, llList2String(params, 7), OS_NPC_SENSE_AS_AGENT);
- llSleep(1);
- rotation npcCurrRot = osNpcGetRot(newNPC);
- float angle = llAtan2( llVecMag(pos % (pos + <xRand, yRand, 0>)), pos * (pos + <xRand, yRand, 0>) );
- rotation npcNewRot = npcCurrRot * llEuler2Rot(<0.0, 0.0, angle>);
- osNpcSetRot(newNPC, npcNewRot);
- osNpcSetProfileImage(newNPC, "botimage"); // this texture MUST be inside the content for this to work!
- osNpcSetProfileAbout(newNPC, "Hello! I'm just a friendly bot passing by! Please ignore me!");
- response = "New NPC: " + (string)newNPC;
- }
- else if (command == "osNpcRemove")
- {
- osNpcRemove(NPC);
- response = "Removing " + llKey2Name(NPC);
- // send command to web app to remove from database
- string myTimestamp = llGetTimestamp();
- deleteRequest = llHTTPRequest(deleteAvatarURL, [HTTP_METHOD, "POST", HTTP_MIMETYPE, "application/x-www-form-urlencoded"],
- "request=delete"
- + "&npc=" + NPC
- + "&timestamp=" + myTimestamp
- + "&signature=" + llMD5String((string)llGetKey() + myTimestamp, LSLSignaturePIN));
- }
- else if (command == "ping")
- {
- response = "pong";
- }
- else
- {
- response = "";
- llHTTPResponse(id, 405, "Unknown engine command " + command + ".");
- }
- }
- else if (!osIsNpc(NPC)) {
- llSay(0, "Call made for invalid NPC UUID");
- llHTTPResponse(id, 400, "Not an NPC");
- }
-
- if (response)
- {
- //llSay(0, "Sending back response for " +
- // command + " '" +
- // response + "'...");
- llHTTPResponse(id, 200, response);
- }
- else {
- llSay(0, "ERROR: No response or no command found!");
- llHTTPResponse(id, 404, "ERROR: No response or no command found!");
- }
- }
- else
- {
- llHTTPResponse(id, 405, "Method unsupported");
- }
- }
-
- changed(integer c)
- {
- // Region changed, get a new PermURL
- if (c & (CHANGED_REGION | CHANGED_OWNER | CHANGED_REGION_START | CHANGED_TELEPORT ) )
- {
- init();
- }
- // Deal with inventory changes
- else if (c & CHANGED_INVENTORY)
- state read_inventory;
- }
-
- timer()
- {
- llSetText("Trying to register bot controller...", <1.0,0.0,0.0>, 1.0);
- llOwnerSay("Trying to register bot controller...");
- llSetTimerEvent(0.0);
- init();
- }
- }
- state read_inventory
- {
- state_entry()
- {
- llSetText("Sending to webserver - 0%", <0.3, 0.7, 0.2>, 1.0);
- // now prepare this line for sending to web server
-
- string httpBody;
- string itemName;
- string myTimeStamp;
- integer i;
- integer length = llGetInventoryNumber(INVENTORY_ALL);
- serverKey = llGetKey();
-
- llSetTimerEvent(360.0); // timeout if the web server is too slow in responding
-
- // Now add the new items.
- // This needs two passes: on the first one, we'll skip textures
- // The second pass will add them later
- llSetText("Checking inventory...", <1.0,1.0,0.0>, 1.0);
-
- for (i = 0; i < length; i++)
- {
- itemName = llGetInventoryName(INVENTORY_ALL, i);
-
- if (llGetInventoryType(itemName) != INVENTORY_SCRIPT && llGetInventoryType(itemName) != INVENTORY_TEXTURE) // skip script, skip textures
- {
- myTimeStamp = llGetTimestamp();
-
- httpBody = "name=" + llEscapeURL(itemName) +
- "&timestamp=" + myTimeStamp +
- "&permissions=" + (string) llGetInventoryPermMask(itemName, MASK_NEXT) +
- "&itemType=" + (string) llGetInventoryType(itemName) +
- "&signature=" + llMD5String((string)serverKey + myTimeStamp, LSLSignaturePIN);
- llSleep(1.0);
-
- httpRequestKey = llHTTPRequest(webServerURLupdateInventory,
- [HTTP_METHOD, "POST",
- HTTP_MIMETYPE,"application/x-www-form-urlencoded"],
- httpBody);
- //llOwnerSay("Object " + (string) i + ": " + httpBody);
- if (httpRequestKey == NULL_KEY)
- llOwnerSay("Error contacting webserver on item #" + (string)i);
-
- llSetText("Sending to webserver - " + (string) ((integer)((float)i/(float)length*100)) + "%", <0.3, 0.7, 0.2>, 1.0);
- }
- }
- state default;
- }
-
- http_response(key request_id, integer status, list metadata, string body)
- {
- llSetText("", <0.0,0.0,0.0>, 1.0);
-
- if (request_id == httpRequestKey)
- {
- if (status != 200)
- {
- llOwnerSay("HTTP Error " + (string)status + ": " + body);
- }
- else
- {
- //llOwnerSay("Web-server reply: " + body);
- if (body == "closed")
- state default;
-
- }
- }
- }
-
- timer()
- {
- // HTTP server does not work, go to default state for now
- llOwnerSay("Web server did not reply after 6 minutes - not updated - try again later");
- llSetTimerEvent(0.0);
- init();
- }
-
- state_exit()
- {
- //llOwnerSay("state_exit inventory");
- llSetTimerEvent(0.0);
- }
- }
- </code></pre>
- {{ end }}
|