Complete more functionality of the Next Engine for dialogs

This commit is contained in:
zontreck 2024-08-01 03:06:13 -07:00
parent 6e28878b6a
commit aa26ff7406

View file

@ -37,6 +37,43 @@ string EXIT_MENU = "-exit-";
string NEXT_MENU = "-->";
string SLURL(key kID){
return "secondlife:///app/agent/"+(string)kID+"/about";
}
integer IsLikelyUUID(string sID)
{
if(sID == (string)NULL_KEY)return TRUE;
if(llStringLength(sID)==32)return TRUE;
key kID = (key)sID;
if(kID)return TRUE;
if(llStringLength(sID) >25){
if(llGetSubString(sID,8,8)=="-" && llGetSubString(sID, 13,13) == "-" && llGetSubString(sID,18,18) == "-" && llGetSubString(sID,23,23)=="-") return TRUE;
}
return FALSE;
}
integer IsLikelyAvatarID(key kID)
{
if(!IsLikelyUUID(kID))return FALSE;
// Avatar UUIDs always have the 15th digit set to a 4
if(llGetSubString(kID,8,8) == "-" && llGetSubString(kID,14,14)=="4")return TRUE;
return FALSE;
}
integer IsListOfIDs(list lIDs)
{
integer i=0;
integer end = llGetListLength(lIDs);
for(i=0;i<end;i++){
if(IsLikelyUUID(llList2String(lIDs,i)))return TRUE;
}
return FALSE;
}
integer generateChannel(integer iPositive) {
integer iRand = llRound(llFrand(0xFFFF));
@ -70,38 +107,78 @@ string readMenu(string sName) {
return sMenu;
}
list g_lListeners = [];
integer STRIDE = 7;
integer STRIDE_ID = 0;
integer STRIDE_PATH = 1;
integer STRIDE_CHANNEL = 2;
integer STRIDE_TEXT = 3;
integer STRIDE_PAGE = 4;
integer STRIDE_HANDLE = 5;
integer STRIDE_TIMER = 6;
startListen(key kAv, integer iChannel, string sMenuName, string sMenuText) {
list g_lListeners = [];
integer MENU_TIMER = 30;
integer GENERAL_TIMER = 120;
startListen(key kAv, integer iChannel, string sMenuName, string sMenuText, integer iTimer) {
integer iIndex=llListFindList(g_lListeners, [kAv]);
if(iIndex == -1) {
integer iListener = llListen(iChannel, "", kAv, "");
g_lListeners += [kAv, sMenuName, iChannel, sMenuText, 0, iListener];
g_lListeners += [kAv, sMenuName, iChannel, sMenuText, 0, iListener, llGetUnixTime() + iTimer];
}else {
stopListen(kAv);
startListen(kAv, iChannel, sMenuName, sMenuText);
startListen(kAv, iChannel, sMenuName, sMenuText, iTimer);
}
}
stopListen(key kAv) {
integer iIndex = llListFindList(g_lListeners, [kAv]);
if(iIndex != -1) {
g_lListeners = llDeleteSubList(g_lListeners, iIndex, iIndex+5); // Stride is 6 - ID, path, channel, text, page, listen handle
g_lListeners = llDeleteSubList(g_lListeners, iIndex, iIndex+STRIDE-1); // Stride is 6 - ID, path, channel, text, page, listen handle
}
}
updatePage(key kID, integer iPage) {
integer iIndex = llListFindList(g_lListeners, [kID]);
if(iIndex!=-1) {
g_lListeners = llListReplaceList(g_lListeners, [iPage], iIndex+4, iIndex+4);
g_lListeners = llListReplaceList(g_lListeners, [iPage], iIndex+STRIDE_PAGE, iIndex+STRIDE_PAGE);
}
}
integer getListenTimer(key kID) {
integer iIndex = llListFindList(g_lListeners, [kID]);
if(iIndex != -1) {
integer iVal = llList2Integer(g_lListeners, iIndex+STRIDE_TIMER);
return iVal;
}else return -1;
}
integer getPageNumber(key kID) {
integer iIndex = llListFindList(g_lListeners, [kID]);
if(iIndex != -1) {
return llList2Integer(g_lListeners, iIndex + STRIDE_PAGE);
} else return -1;
}
updateTimer(key kID, integer iNewTimer) {
integer iIndex = llListFindList(g_lListeners, [kID]);
if(iIndex != -1) {
g_lListeners = llListReplaceList(g_lListeners, [llGetUnixTime() + iNewTimer], iIndex + STRIDE_TIMER, iIndex + STRIDE_TIMER);
}
}
string getMenuID(key kID) {
integer iIndex = llListFindList(g_lListeners, [kID]);
if(iIndex != -1) {
return llList2String(g_lListeners, iIndex + STRIDE_PATH);
} else return "";
}
integer getChannel(key kID) {
integer iIndex = llListFindList(g_lListeners, [kID]);
if(iIndex!=-1) {
return llList2Integer(g_lListeners, iIndex+2);
return llList2Integer(g_lListeners, iIndex+STRIDE_CHANNEL);
} else return -1;
}
@ -180,7 +257,7 @@ integer calcMaxPages(string sMenu) {
}
}
list getPage(string sMenu, integer iPage) {
string getPage(string sMenu, integer iPage, integer iCheckUUID) {
// Retrieve buttons and utility lists from JSON
list lButtons = llJson2List(llJsonGetValue(sMenu, ["buttons"]));
list lUtility = llJson2List(llJsonGetValue(sMenu, ["utility"]));
@ -216,7 +293,31 @@ list getPage(string sMenu, integer iPage) {
// Add navigation buttons
lPageButtons = getNavigatorButtons(iPage, totalPages) + lPageButtons;
return lPageButtons;
// Loop over the buttons, check if UUID, replace with a number instead if UUID
if(!iCheckUUID) jump returnMenu;
i =0;
integer end = llGetListLength(lPageButtons);
integer idNum = 0;
string sExtraText = "";
for(i=0;i<end;i++) {
string sButton = llList2String(lPageButtons, i);
if(IsLikelyAvatarID(sButton)) {
lPageButtons = llListReplaceList(lPageButtons, [(string)idNum], i,i);
idNum++;
sExtraText += SLURL(sButton) + "\n";
}
}
@returnMenu;
return llList2Json(JSON_OBJECT, ["text", sExtraText, "buttons", "~!~" + llDumpList2String(lPageButtons, "~!~") + "~!~"]);
}
AppendMenuButton(string sMenu, string sButton) {
string json = readMenu(sMenu);
AddMenuButton(json, sButton);
updateMenu(sMenu, json);
}
default
@ -224,14 +325,24 @@ default
state_entry() {
llLinksetDataDeleteFound("menus", "");
llMessageLinked(LINK_SET, LINK_SIGNAL_QUERY_MENU, "root", "");
llLinksetDataDeleteFound("colors", "");
// Query color menu buttons and color pairs. Stride 3 instead of 2
}
timer() {
integer iTimerActive=0;
integer i = 0;
integer end = llGetListLength(g_lListeners);
for(i=0;i<end;i+=STRIDE) {
key kID = llList2Key(g_lListeners, i + STRIDE_ID);
integer iTimer = getListenTimer(kID);
if(llGetUnixTime() > iTimer) {
stopListen(kID);
if(!iTimerActive){
llSetTimerEvent(0);
llRegionSayTo(kID, 0, "Listener Timed Out");
return;
}
}
}
@ -243,23 +354,83 @@ default
}
listen(integer c,string n,key i,string m) {
integer iIndex = llListFindList(g_lListeners, [i]);
// Get the listener handle
integer iListener = llList2Integer(g_lListeners, iIndex+5);
llListenRemove(iListener);
// Get the menu path
string sMenuID = getMenuID(i);
// Get the current page number
integer iPage = getPageNumber(i);
string sMenu = "";
if(sMenuID != "") readMenu(sMenuID);
integer iMaxPages = calcMaxPages(sMenu);
if(m == PREVIOUS_MENU) {
// Update the time remaining
updateTimer(i, MENU_TIMER);
iPage--;
if(iPage < 0) iPage=0;
string sPage = getPage(sMenuID, iPage, TRUE);
list lPageButtons = llParseString2List(llJsonGetValue(sPage, ["buttons"]), ["~!~"], []);
updatePage(i, iPage);
string sAppend = llJsonGetValue(sPage, ["text"]);
if(iMaxPages > 1) sAppend += "\n\nPage " + (string)iPage + "/" + (string)(iMaxPages-1);
llDialog(i, llJsonGetValue(sMenu, ["prompt"]) + sAppend, lPageButtons, getChannel(i));
} else if(m == NEXT_MENU) {
// Update the time remaining
updateTimer(i, MENU_TIMER);
iPage++;
if(iPage < iMaxPages-1) iPage=iMaxPages-1;
string sPage = getPage(sMenuID, iPage, TRUE);
list lPageButtons = llParseString2List(llJsonGetValue(sPage, ["buttons"]), ["~!~"], []);
updatePage(i, iPage);
string sAppend = llJsonGetValue(sPage, ["text"]);
if(iMaxPages > 1) sAppend += "\n\nPage " + (string)iPage + "/" + (string)(iMaxPages-1);
llDialog(i, llJsonGetValue(sMenu, ["prompt"]) + sAppend, lPageButtons, getChannel(i));
} else if(m == " ") {
// Update the time remaining
updateTimer(i, MENU_TIMER);
string sPage = getPage(sMenuID, iPage, TRUE);
list lPageButtons = llParseString2List(llJsonGetValue(sPage, ["buttons"]), ["~!~"], []);
updatePage(i, iPage);
string sAppend = llJsonGetValue(sPage, ["text"]);
if(iMaxPages > 1) sAppend += "\n\nPage " + (string)iPage + "/" + (string)(iMaxPages-1);
llDialog(i, llJsonGetValue(sMenu, ["prompt"]) + sAppend, lPageButtons, getChannel(i));
} else if(m == EXIT_MENU) {
stopListen(i);
} else {
// Stop listening, and send a signal
string sPage = getPage(sMenuID, iPage, FALSE);
}
}
link_message(integer s,integer n,string m,key i) {
if(n == LINK_SIGNAL_GEN_CHANNEL) {
integer iChan = generateChannel((integer)m);
startListen(i, iChan, "", "");
startListen(i, iChan, "", "", GENERAL_TIMER);
llMessageLinked(LINK_SET, LINK_SIGNAL_CHANNEL_BACK, (string)iChan, "");
} else if(n == LINK_SIGNAL_SHOW_MENU) {
string sMenu = readMenu(llJsonGetValue(m,["menu"]));
integer iChan = generateChannel(FALSE);
startListen(i, iChan, m, llJsonGetValue(sMenu, ["prompt"]));
startListen(i, iChan, m, llJsonGetValue(sMenu, ["prompt"]), MENU_TIMER);
// Show the dialog window now after constructing pages if needed.
integer maxPages = calcMaxPages(sMenu);
@ -267,12 +438,17 @@ default
integer iPage = 1;
if(jsonValueExists(m, ["page"])) iPage = (integer)llJsonGetValue(m,["page"]);
list lPageButtons = getPage(sMenu, iPage);
string sPage = getPage(sMenu, iPage, TRUE);
list lPageButtons = llParseString2List(llJsonGetValue(sPage, ["buttons"]), ["~!~"], []);
updatePage(i, iPage);
string sAppend = "";
string sAppend = llJsonGetValue(sPage, ["text"]);
if(maxPages>1) sAppend += "\n\nPage " + (string)iPage+"/" + (string)(maxPages-1);
//llOwnerSay("DEBUG\n" + llJsonGetValue(sMenu, ["prompt"]) + sAppend + "\n\n" + llJsonGetValue(sPage, ["buttons"]));
if(maxPages>1) sAppend = "\n\nPage " + (string)iPage+"/" + (string)maxPages;
llDialog(i, llJsonGetValue(sMenu, ["prompt"])+sAppend, lPageButtons, getChannel(i));
} else if(n == LINK_SIGNAL_REGISTER_MENU) {
string sMenuJson = llLinksetDataRead("menus." + (string)i);