FarmSystem/LSL/raw/item_server.lsl
2025-02-11 02:47:50 -07:00

188 lines
No EOL
6.4 KiB
Text

#include "Common.lsl"
string API_SERVER;
integer g_iActive = 1;
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 {
state_entry() {
llSay(0, "Server '" + llGetObjectDesc() + "' is starting up...");
llMessageLinked(LINK_SET, 2, "", "");
llMessageLinked(LINK_SET, -1, "", "");
XteaKey(PSK);
}
link_message(integer s,integer n,string m,key i) {
if(n == 0x004f) {
API_SERVER = DecipherService(m, "api");
if(g_iRegistered)return;
// Register the server object ID
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);
}
}
touch_start(integer t) {
if(llDetectedKey(0) == llGetOwner()) {
g_iActive = 1-g_iActive;
if(g_iActive) {
llSay(0, "Server '" + llGetObjectDesc() + "' reactivating...");
llResetScript();
} 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");
g_kScriptRequest = llHTTPRequest(API_SERVER + "/zni/Del_Server_ID.php?NAME=" + llEscapeURL(llGetObjectDesc()) + "&PSK=" + llEscapeURL(SERVER_PSK), [], "");
}
}
}
timer() {
llGetNextEmail("", "");
}
on_rez(integer t) {
llResetScript();
}
email(string time, string address, string subject, string body, integer num_remain) {
if(subject == "RequestProductDelivery") {
//llSay(0, "EMAIL : " + body);
llMessageLinked(LINK_SET, 1, "", "");
list lPar = llParseString2List(body, [";;"], []);
string sPayload = xtea_decrypt_string(llList2String(lPar,1));
// 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;
// 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, "", "");
}
}
dataserver(key kID, string sData) {
if(kID == g_kPayload) {
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"
]));
}
}
}