From 623966b90752f6a3f20f759aa53376ed40c37d4d Mon Sep 17 00:00:00 2001 From: zontreck Date: Tue, 11 Feb 2025 02:47:50 -0700 Subject: [PATCH] Fix delivery problems --- LSL/external/ServiceCheck | 2 +- LSL/includes/Common.lsl | 14 +++++- LSL/raw/item_server.lsl | 96 +++++++++++++++++++++++++++++++++++---- LSL/raw/tree.lsl | 95 +++++++++++++++++++++++++++++++++++--- LSL/raw/water_well.lsl | 68 +++++++++++++++++++++++++-- 5 files changed, 255 insertions(+), 20 deletions(-) diff --git a/LSL/external/ServiceCheck b/LSL/external/ServiceCheck index 116681b..1e42931 160000 --- a/LSL/external/ServiceCheck +++ b/LSL/external/ServiceCheck @@ -1 +1 @@ -Subproject commit 116681ba4fe093f0206542313d1b2b431445a9ac +Subproject commit 1e429318811df423f874462358603e960c9d37c1 diff --git a/LSL/includes/Common.lsl b/LSL/includes/Common.lsl index 32268c1..689658a 100644 --- a/LSL/includes/Common.lsl +++ b/LSL/includes/Common.lsl @@ -187,9 +187,19 @@ string SERVER_PSK = "8597f-f19f0eec-cc526aa87-152ac84-326"; string g_sServerID = ""; -requestProductForDelivery(string sProduct, string sID) { +requestProductForDelivery(string sProduct, string sID, string sCallback) { llEmail(g_sServerID+"@lsl.secondlife.com", "RequestProductDelivery", "S;;" + xtea_encrypt_string(llList2Json(JSON_OBJECT, [ "item", sProduct, - "id", sID + "id", sID, + "callback", sCallback ])) + ";;X"); +} + +altRequestDelivery(string sURL, string sID, string sProduct) { + llHTTPRequest(sURL, [HTTP_METHOD, "POST", HTTP_MIMETYPE, "text/plain"], xtea_encrypt_string( + llList2Json(JSON_OBJECT, [ + "item", sProduct, + "id", sID + ]) + )); } \ No newline at end of file diff --git a/LSL/raw/item_server.lsl b/LSL/raw/item_server.lsl index 7008bf8..731a494 100644 --- a/LSL/raw/item_server.lsl +++ b/LSL/raw/item_server.lsl @@ -6,6 +6,10 @@ integer g_iRegistered=0; integer g_iError=0; string g_kPayload; string g_sItem; +string g_sURL; +key g_kCallback; +integer g_iFallback = 0; +key g_kScriptRequest; default { @@ -23,16 +27,78 @@ default { if(g_iRegistered)return; // Register the server object ID - llHTTPRequest(API_SERVER + "/zni/Put_Server_ID.php?NAME=" + llEscapeURL(llGetObjectDesc()) + "&PSK=" + llEscapeURL(SERVER_PSK), [HTTP_METHOD, "POST", HTTP_MIMETYPE, "application/json"], llList2Json(JSON_OBJECT, ["id", llGetKey()])); + g_kScriptRequest = llHTTPRequest(API_SERVER + "/zni/Put_Server_ID.php?NAME=" + llEscapeURL(llGetObjectDesc()) + "&PSK=" + llEscapeURL(SERVER_PSK), [HTTP_METHOD, "POST", HTTP_MIMETYPE, "application/json"], llList2Json(JSON_OBJECT, ["id", llGetKey()])); llMessageLinked(LINK_SET, 1, "", ""); } } + changed(integer iChange) { + if(iChange & CHANGED_REGION_START) { + llResetScript(); + } + } + + http_request(key kID, string sMethod, string sBody) + { + if(sMethod == URL_REQUEST_GRANTED) { + g_sURL = sBody; + + g_kScriptRequest = llHTTPRequest(API_SERVER + "/zni/Put_Server_URL.php", [HTTP_METHOD, "POST", HTTP_MIMETYPE, "application/x-www-form-urlencoded"], "NAME=" + llEscapeURL(llGetObjectDesc()) + "&KEYID=" + llEscapeURL(g_sURL)); + + llSay(0, "> Registered both Server ID for email, and server URL"); + } else if(sMethod == URL_REQUEST_DENIED) { + llSay(0, "/!\\ FATAL /!\\ \n\nSecond Life rejected the request for a new LSL URL. The sim is likely overloaded\n\n> Forwarding report to Red Queen"); + + llInstantMessage(llGetOwner(), "/!\\ URGENT /!\\ \n\nThe server could not obtain a URL!"); + + } else if(sMethod == "POST") { + if(kID == g_kScriptRequest) return; + // Alternative method for request + g_iFallback = 1; + string sPayload = xtea_decrypt_string(sBody); + // Check what object is being requested and by who + string sRequest = llJsonGetValue(sPayload, ["item"]); + string sID = llJsonGetValue(sPayload, ["id"]); + + // Forbid giving scripts + if(llGetInventoryType(sRequest) == INVENTORY_SCRIPT) return; + + // Deliver if we have the item + if(llGetInventoryType(sRequest) != INVENTORY_NONE) { + llGiveInventory(sID, sRequest); + g_iError=0; + } + else + { + // Log this as an error in delivery + g_iError=1; + } + + g_sItem = sRequest; + g_iFallback = 0; + + g_kPayload = llRequestUsername(sID); + + llSleep(0.25); + llMessageLinked(LINK_SET, 0, "", ""); + } + } + http_response(key k, integer s, list m, string b) { + if(k != g_kScriptRequest) return; + + //llSay(0, "HTTP RESPONSE: " + llDumpList2String([s,b], " ~ ")); + + if(k == g_kCallback) return; if(s == 200) { llMessageLinked(LINK_SET, 0, "", ""); llSay(0, "Server '" + llGetObjectDesc() +"' is now ready"); + if(g_sURL == "") { + // Register the server URL + g_kScriptRequest = llRequestURL(); + } + g_iRegistered=TRUE; llSetTimerEvent(1); @@ -48,7 +114,7 @@ default { } else { llMessageLinked(LINK_SET, 2, "", ""); llSay(0, "Server '" + llGetObjectDesc() + "' has been taken offline for maintenance. Any pending requests will still be processed, but any new ones will be blocked"); - llHTTPRequest(API_SERVER + "/zni/Del_Server_ID.php?NAME=" + llEscapeURL(llGetObjectDesc()) + "&PSK=" + llEscapeURL(SERVER_PSK), [], ""); + g_kScriptRequest = llHTTPRequest(API_SERVER + "/zni/Del_Server_ID.php?NAME=" + llEscapeURL(llGetObjectDesc()) + "&PSK=" + llEscapeURL(SERVER_PSK), [], ""); } } } @@ -71,6 +137,11 @@ default { // Check what object is being requested and by who string sRequest = llJsonGetValue(sPayload, ["item"]); string sID = llJsonGetValue(sPayload, ["id"]); + string sCallback = llJsonGetValue(sPayload, ["callback"]); // URL to callback on receipt + llSleep(20); + + if(~llSubStringIndex(sCallback, "http://")) + g_kCallback=llHTTPRequest(sCallback, [], ""); // Forbid giving scripts if(llGetInventoryType(sRequest) == INVENTORY_SCRIPT) return; @@ -87,6 +158,7 @@ default { } g_sItem = sRequest; + g_iFallback = 0; g_kPayload = llRequestUsername(sID); @@ -97,12 +169,20 @@ default { dataserver(key kID, string sData) { if(kID == g_kPayload) { - llSay(0x9CB9, llList2Json(JSON_OBJECT, [ - "user", sData, - "msg", "Delivery of item '" + g_sItem + "'", - "author", "Relay", - "title", "Farm Delivery Server" - ])); + if(!g_iFallback) + llSay(0x9CB9, llList2Json(JSON_OBJECT, [ + "user", sData, + "msg", "Delivery of item '" + g_sItem + "'", + "author", "Relay", + "title", "Farm Delivery Server" + ])); + else + llSay(0x9CB9, llList2Json(JSON_OBJECT, [ + "user", sData, + "msg", "Fallback delivery of item '" + g_sItem + "'", + "author", "Relay HTTP", + "title", "Farm Delivery Server" + ])); } } } \ No newline at end of file diff --git a/LSL/raw/tree.lsl b/LSL/raw/tree.lsl index e8c88a1..b67b50f 100644 --- a/LSL/raw/tree.lsl +++ b/LSL/raw/tree.lsl @@ -23,6 +23,9 @@ integer g_iRezzedObject; vector g_vInitialSapling = <0.59996, 0.56265, 1.01659>; vector g_vInitialTree = <0.77864, 0.90290, 1.38959>; vector g_vInitialStump = <0.14584, 0.14018, 0.05000>; +string g_sCallbackURL; +key g_kCallbackURLRequest; +integer g_iRemoveScripts=1; SCAN() { @@ -70,6 +73,9 @@ setText() { } integer g_iLastOwnerDev=1; +integer g_iDevListener; + +integer g_iWaitDelivery = 0; default { @@ -103,6 +109,8 @@ default #endif setText(); + + g_iDevListener = llListen(99, "", "", ""); } changed(integer c) { @@ -110,6 +118,7 @@ default if(!g_iLastOwnerDev)return; g_iLastOwnerDev=0; + llListenRemove(g_iDevListener); /*g_iTreeGrowth=0; @@ -149,18 +158,70 @@ default if(llList2String(lPar,0) == "GetServerID") { string sJson = llList2String(lPar,1); g_sServerID = llJsonGetValue(sJson, ["id"]); - requestProductForDelivery(SAPLING_NAME, g_kAv); + g_kCallbackURLRequest = llRequestURL(); + } else if(llList2String(lPar,0) == "Get_Server_URL") { + altRequestDelivery(llList2String(lPar,2), g_kAv, SAPLING_NAME); + llSleep(2); + if(!g_iRemoveScripts) { + llSay(0, "> Server acknowledged delivery"); + } g_iRequestedSapling=1; - if(g_iRezzedObject){ + if(g_iRezzedObject && g_iRemoveScripts){ llRemoveInventory("Service Daemon [AC]"); llRemoveInventory(llGetScriptName()); } } } + http_request(key kID, string sMethod, string sBody) { + + if(sMethod == URL_REQUEST_GRANTED && g_kCallbackURLRequest == kID) { + g_sCallbackURL = sBody; + if(!g_iRemoveScripts) { + llSay(0, "> Failsafe URL Obtained... Request Delivery [" + SAPLING_NAME + "]"); + llSay(0, "API SERVER: " + API_SERVER); + llSay(0, "SERVER ID: " + g_sServerID); + } + + requestProductForDelivery(SAPLING_NAME, g_kAv, g_sCallbackURL); + g_iWaitDelivery = 30; + llSetTimerEvent(2); + }else if(sMethod == "GET") { + llHTTPResponse(kID, 200, ""); + llReleaseURL(g_sCallbackURL); + + if(!g_iRemoveScripts) { + llSay(0, "> Server acknowledged delivery"); + } + + llSleep(2); + + g_iRequestedSapling=1; + if(g_iRezzedObject && g_iRemoveScripts){ + llRemoveInventory("Service Daemon [AC]"); + llRemoveInventory(llGetScriptName()); + } + } + + } + timer() { + if(g_iWaitDelivery) { + g_iWaitDelivery--; + + if(g_iWaitDelivery == 1) { + llReleaseURL(g_sCallbackURL); + llHTTPRequest(API_SERVER + "/Get_Server_URL.php?NAME=Farming", [], ""); + } + + + if(g_iTreeStage == 1 && g_iTreeGrowth == 100 && !g_iWaitDelivery) { + llSetTimerEvent(0); + return; + } + } if(llGetUnixTime() > g_iLastUsedWater+5) llWhisper(global_ingredients, xtea_encrypt_string(llList2Json(JSON_OBJECT, ["cmd", "query"]))); @@ -254,6 +315,7 @@ default llListenRemove(g_iListen); if(m == "Yes") { + g_kAv = i; llRezObject("Tree Log [AC]", llGetPos()+<0,0,0.5>, ZERO_VECTOR, ZERO_ROTATION, 1990); llSetLinkAlpha(g_iTreeStump, 1, ALL_SIDES); @@ -262,12 +324,33 @@ default llSetLinkPrimitiveParams(g_iTree, [PRIM_POS_LOCAL, ZERO_VECTOR, PRIM_SIZE, ZERO_VECTOR]); // Deliver 1 sapling, additional ones need to be bought - llHTTPRequest(API_SERVER + "/Get_Server_ID.php", [HTTP_MIMETYPE, "application/json", HTTP_METHOD, "POST"], xtea_encrypt_string(llList2Json(JSON_OBJECT, [ - "psk", SERVER_PSK, - "name", "Farming" - ]))); + llHTTPRequest(API_SERVER + "/Get_Server_ID.php?NAME=Farming", [], ""); //requestProductForDelivery("Tree A Sapling [AC]"); } + } else if(c == 99) { + if(m == "devmode_off") { + llSay(0, "Disabling developer mode"); + + llSetTimerEvent(2); + g_iLastOwnerDev=0; + + } else if(m == "water"){ + g_iTotalWater=0; + llSay(0, "Setting thirsty"); + } else if(m == "reset") { + g_iTreeGrowth = 0; + g_iTreeStage = 0; + } else if(m == "grow") { + g_iTreeGrowth = 100; + } else if(m == "freeze") { + llSetTimerEvent(0); + llSay(0, "State frozen"); + } else if(m == "test_sapling") { + llSay(0, "Initiating sapling delivery test..."); + g_kAv = i; + g_iRemoveScripts = 0; + llHTTPRequest(API_SERVER + "/Get_Server_ID.php?NAME=Farming", [], ""); + } } } } \ No newline at end of file diff --git a/LSL/raw/water_well.lsl b/LSL/raw/water_well.lsl index 541a8b5..8175b56 100644 --- a/LSL/raw/water_well.lsl +++ b/LSL/raw/water_well.lsl @@ -12,7 +12,7 @@ float g_fEmpty = -1.142; float g_fFull = -0.202; integer g_iRequestTime = 0; string WATER_WELL_NAME = "WoodStoneWaterWell"; -string VERSION = "1.0.0"; +string VERSION = "1.0.1"; integer g_iWaterPrim; integer g_iRoofPrim; integer g_iDestroyed = 0; @@ -50,6 +50,11 @@ SCAN() { } } +integer g_iDevListener; +integer g_iWaitDelivery = 0; +string g_sCallbackURL; +key g_kCallbackURLRequest; + default { state_entry() @@ -69,9 +74,33 @@ default updateLevel(); setText(); + g_iDevListener = llListen(99, "", "", ""); + } listen(integer c,string n,key i,string m) { + if(c==99) { + if(m == "devmode_off") { + g_iTotalWater=100; + llSetTimerEvent(1); + g_iLastFillTime=llGetUnixTime(); + if(g_iWellChannel != 0) { + llListenRemove(g_iWellListener); + } + g_iWellChannel = (integer)("0x" + llGetSubString(llGetKey(), 0, 5)); + g_iWellListener = llListen(g_iWellChannel, "", "", ""); + + setText(); + } else if(m == "empty") { + g_iTotalWater = 0; + setText(); + }else if(m == "freeze") { + llSetTimerEvent(0); + } else if(m == "reset") { + llResetScript(); + } + return; + } string sJson = xtea_decrypt_string(m); if(llJsonGetValue(sJson, ["cmd"]) == "alive" && llJsonGetValue(sJson, ["type"]) == "Bucket") { @@ -127,6 +156,21 @@ default } timer() { + if(g_iWaitDelivery) { + g_iWaitDelivery--; + + if(g_iWaitDelivery == 1) { + // Failed, request by fallback + llReleaseURL(g_sCallbackURL); + llHTTPRequest(API_SERVER + "/Get_Server_URL.php?NAME=Farming", [], ""); + } + + + if(g_iTotalWater >= 100 && !g_iWaitDelivery) { + llSetTimerEvent(0); + return; + } + } if(llGetUnixTime() > (g_iLastFillTime + 30)) { g_iLastFillTime = llGetUnixTime(); g_iTotalWater ++; @@ -187,6 +231,22 @@ default } } + http_request(key kID, string sMethod, string sBody) + { + if(kID == g_kCallbackURLRequest) { + if(sMethod == URL_REQUEST_GRANTED) { + requestProductForDelivery("Water Bucket [AC]", g_kAv, sBody); + g_sCallbackURL = sBody; + + g_iWaitDelivery = 30; + llSetTimerEvent(1); + } + } else { + llHTTPResponse(kID, 200, ""); + llReleaseURL(g_sCallbackURL); + } + } + http_response(key kID, integer iStatus, list lMeta, string sBody) { list lParams = llParseString2List(sBody, [";", ";;"], []); string sScript = llList2String(lParams,0); @@ -196,8 +256,10 @@ default if(sScript == "GetServerID") { string sJson = llList2String(lParams,1); g_sServerID = llJsonGetValue(sJson, ["id"]); - requestProductForDelivery("Water Bucket [AC]", g_kAv); - }else if(sScript == "Modify_ProductV2") { + g_kCallbackURLRequest = llRequestURL(); + } else if(sScript == "Get_Server_URL") { + altRequestDelivery(llList2String(lParams, 2), g_kAv, "Water Bucket [AC]"); + } else if(sScript == "Modify_ProductV2") { // Gives the version information string sJson = llList2String(lParams,1); if(llJsonGetValue(sJson, ["status"]) == "ok") {