Initial Commit

This commit is contained in:
zontreck 2023-11-12 00:48:49 -07:00
parent 55ecc5b383
commit 83502bc972
15 changed files with 2251 additions and 0 deletions

4
README.md Normal file
View file

@ -0,0 +1,4 @@
Next Generation Core
=======
This project's initial aim is to create a set of replacement scripts for DHB. Any future targetting can be added as plugins. This project is, from the ground up, designed to be modular. You drop in the script(s) for the features your product supports, or that you want.

225
src/includes/common.lsl Normal file
View file

@ -0,0 +1,225 @@
#define MASTER_CODE "6acaf07f"
integer ACCESS_OWNER = 1;
integer ACCESS_SELF_OWN = 2;
integer ACCESS_WEARER = 3;
integer ACCESS_GROUP = 4;
integer ACCESS_PUBLIC = 5;
integer ACCESS_NO_ACCESS = 99;
integer LM_CHECK_SETTINGS_READY = 11;
integer LM_SETTINGS_READY = 10;
string ToLevelString(integer level)
{
string ret = "";
switch(level)
{
case ACCESS_OWNER:
{
ret = "Owner";
break;
}
case ACCESS_SELF_OWN:
{
ret = "Self Owner";
break;
}
case ACCESS_WEARER:
{
ret = "Wearer";
break;
}
case ACCESS_GROUP:
{
ret = "Group";
break;
}
case ACCESS_PUBLIC:
{
ret = "Public";
break;
}
default:
{
ret = "No Access";
break;
}
}
return ret;
}
writeSetting(string name, string value)
{
llMessageLinked(LINK_SET, 0, llList2Json(JSON_OBJECT, ["cmd", "write_setting", "name", name, "value", value]), "");
}
readSetting(string name, string defaultValue)
{
llMessageLinked(LINK_SET,0, llList2Json(JSON_OBJECT, ["cmd", "read_setting", "name",name, "default", defaultValue]), "");
}
deleteSetting(string name, string defaultValue)
{
llMessageLinked(LINK_SET,0,llList2Json(JSON_OBJECT, ["cmd", "delete_setting", "name", name, "default", defaultValue]), "");
}
#define ARIA "5556d037-3990-4204-a949-73e56cd3cb06"
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 bool(integer a){
if(a)return TRUE;
else return FALSE;
}
list g_lCheckboxes=["□","▣"];
string Checkbox(integer iValue, string sLabel) {
return llList2String(g_lCheckboxes, bool(iValue))+" "+sLabel;
}
string sSetor(integer a, string b, string c)
{
if(a)return b;
else return c;
}
key kSetor(integer a, key b, key c)
{
if(a)return b;
else return c;
}
integer iSetor(integer a, integer b, integer c)
{
if(a)return b;
else return c;
}
vector vSetor(integer a, vector b, vector c)
{
if(a)return b;
else return c;
}
list lSetor(integer a,list b, list c)
{
if(a)return b;
else return c;
}
string Uncheckbox(string sLabel)
{
integer iBoxLen = 1+llStringLength(llList2String(g_lCheckboxes,0));
return llGetSubString(sLabel,iBoxLen,-1);
}
string SLURL(key kID){
return "secondlife:///app/agent/"+(string)kID+"/about";
}
string OSLURL(key kID)
{
return llKey2Name(kID); // TODO: Replace with a SLURL of some kind pointing to the object inspect.
}
list StrideOfList(list src, integer stride, integer start, integer end)
{
list l = [];
integer ll = llGetListLength(src);
if(start < 0)start += ll;
if(end < 0)end += ll;
if(end < start) return llList2List(src, start, start);
while(start <= end)
{
l += llList2List(src, start, start);
start += stride;
}
return l;
}
string tf(integer a){
if(a)return "true";
return "false";
}
list g_lDSRequests;
key NULL=NULL_KEY;
UpdateDSRequest(key orig, key new, string meta){
if(orig == NULL){
g_lDSRequests += [new,meta];
}else {
integer index = HasDSRequest(orig);
if(index==-1)return;
else{
g_lDSRequests = llListReplaceList(g_lDSRequests, [new,meta], index,index+1);
}
}
}
string GetDSMeta(key id){
integer index=llListFindList(g_lDSRequests,[id]);
if(index==-1){
return "N/A";
}else{
return llList2String(g_lDSRequests,index+1);
}
}
integer HasDSRequest(key ID){
return llListFindList(g_lDSRequests, [ID]);
}
DeleteDSReq(key ID){
if(HasDSRequest(ID)!=-1)
g_lDSRequests = llDeleteSubList(g_lDSRequests, HasDSRequest(ID), HasDSRequest(ID)+1);
else return;
}
string MkMeta(list lTmp){
return llDumpList2String(lTmp, ":");
}
string SetMetaList(list lTmp){
return llDumpList2String(lTmp, ":");
}
string SetDSMeta(list lTmp){
return llDumpList2String(lTmp, ":");
}
list GetMetaList(key kID){
return llParseStringKeepNulls(GetDSMeta(kID), [":"],[]);
}

172
src/raw/Access.lsl Normal file
View file

@ -0,0 +1,172 @@
#include "src/includes/common.lsl"
string g_sMasterPassword = "";
list g_lOwners;
integer g_iSelfOwned = TRUE;
integer iSetor(integer Test, integer A, integer B)
{
if(Test)return A;
return B;
}
ResaveOwners()
{
llLinksetDataDeleteFound("access_owner", MASTER_CODE);
integer i=0;
integer end = llGetListLength(g_lOwners);
for(i=0;i<end;i++)
{
llLinksetDataWriteProtected("access_owner"+(string)i, llList2String(g_lOwners, i), MASTER_CODE);
}
}
integer g_iGroupEnabled=0;
integer g_iPublicEnabled=0;
integer calcAuthLevel(key kID)
{
if(llGetListLength(g_lOwners))
{
if(~llListFindList(g_lOwners, [(string)kID])) return ACCESS_OWNER;
if(kID == llGetOwner() && g_iSelfOwned) return ACCESS_SELF_OWN;
else if(kID == llGetOwner() && !g_iSelfOwned) return ACCESS_WEARER;
if(g_iGroupEnabled && llSameGroup(kID)) return ACCESS_GROUP;
if(g_iPublicEnabled) return ACCESS_PUBLIC;
return ACCESS_NO_ACCESS;
}else {
if(kID == llGetOwner())
return ACCESS_OWNER;
if(g_iGroupEnabled && llSameGroup(kID)) return ACCESS_GROUP;
if(g_iPublicEnabled) return ACCESS_PUBLIC;
return ACCESS_NO_ACCESS;
}
}
default
{
state_entry()
{
integer num_owners = llLinksetDataCountFound("access_owner");
integer i=0;
for(i=0;i<num_owners;i++)
{
g_lOwners += llLinksetDataReadProtected("access_owner"+(string)i, MASTER_CODE);
}
llListen(-9451, "", "", "");
}
listen(integer c,string n,key i,string m)
{
if(c == -9451)
{
if(g_sMasterPassword == "")return; // Ignore blank codes!
if(g_sMasterPassword == m)
{
llMessageLinked(LINK_SET, 0, llList2Json(JSON_OBJECT, ["cmd", "master_key_used"]), llGetOwnerKey(i));
}
}
}
link_message(integer s, integer n,string m,key i)
{
if(n == LM_SETTINGS_READY)
{
readSetting("access_password", "000000");
readSetting("access_selfown", "1");
readSetting("access_public", "0");
readSetting("access_group", "0");
return;
} else if(n == 0)
{
if(llJsonGetValue(m,["cmd"]) == "check_code")
{
integer RET = 0;
if(g_sMasterPassword == llJsonGetValue(m,["code"])){
RET = TRUE;
}else RET = FALSE;
llMessageLinked(LINK_SET, n, llList2Json(JSON_OBJECT, ["cmd", "check_code_back", "val", RET, "callback", llJsonGetValue(m,["callback"])]), i);
} else if(llJsonGetValue(m,["cmd"]) == "check_mode")
{
llMessageLinked(LINK_SET,n,llList2Json(JSON_OBJECT, ["cmd", "check_mode_back", "val", calcAuthLevel(i), "callback", llJsonGetValue(m,["callback"])]), i);
} else if(llJsonGetValue(m,["cmd"]) == "add_owner")
{
g_lOwners += llJsonGetValue(m,["id"]);
llLinksetDataWriteProtected("access_owner" + (string)(llGetListLength(g_lOwners)-1), llJsonGetValue(m,["id"]), MASTER_CODE);
} else if(llJsonGetValue(m,["cmd"]) == "rem_owner")
{
string sID = llJsonGetValue(m,["id"]);
integer index=llListFindList(g_lOwners, [sID]);
if(index == -1)
{
return;
}else{
g_lOwners = llDeleteSubList(g_lOwners, index,index);
ResaveOwners();
}
} else if(llJsonGetValue(m,["cmd"]) == "reset")
{
llResetScript();
} else if(llJsonGetValue(m,["cmd"]) == "set_master_password")
{
g_sMasterPassword = llJsonGetValue(m,["pwd"]);
llLinksetDataWriteProtected("access_password", g_sMasterPassword, MASTER_CODE);
} else if(llJsonGetValue(m,["cmd"]) == "set_self_own")
{
g_iSelfOwned = (integer)llJsonGetValue(m,["val"]);
llLinksetDataWriteProtected("access_selfown", (string)g_iSelfOwned, MASTER_CODE);
} else if(llJsonGetValue(m,["cmd"]) == "update_group")
{
g_iGroupEnabled = (integer)llJsonGetValue(m,["val"]);
llLinksetDataWriteProtected("access_group", (string)g_iGroupEnabled, MASTER_CODE);
} else if(llJsonGetValue(m,["cmd"]) == "update_public")
{
g_iPublicEnabled = (integer)llJsonGetValue(m,["val"]);
llLinksetDataWriteProtected("access_public", (string)g_iPublicEnabled, MASTER_CODE);
} else if(llJsonGetValue(m,["cmd"]) == "read_setting_back")
{
string sSetting = llJsonGetValue(m,["setting"]);
string sValue = llJsonGetValue(m,["value"]);
switch(sSetting)
{
case "access_password":
{
g_sMasterPassword = sValue;
break;
}
case "access_selfown":
{
g_iSelfOwned = (integer)sValue;
break;
}
case "access_group":
{
g_iGroupEnabled = (integer)sValue;
break;
}
case "access_public":
{
g_iPublicEnabled = (integer)sValue;
break;
}
}
}
}
}
}

12
src/raw/Debug.lsl Normal file
View file

@ -0,0 +1,12 @@
default
{
state_entry()
{
}
link_message(integer s,integer n,string m,key i)
{
llSay(0, llDumpList2String([n,m,i], " ~ "));
}
}

570
src/raw/Dialog Module.lsl Normal file
View file

@ -0,0 +1,570 @@
// ********************************************************************
//
// Menu Display Script
//
// Menu command format
// string = menuidentifier | display navigate? TRUE/FALSE | menuMaintitle~subtitle1~subtitle2~subtitle3 | button1~button2~button3 {| fixedbutton1~fixedbutton2~fixedbutton3 optional}
// key = menuuser key
//
// Return is in the format
// "menuidentifier | item"
//
// menusDescription [menuchannel, key, menu & parent, return link, nav?, titles, buttons, fixed buttons]
// menusActive [menuchannel, menuhandle, time, page]
//
// by SimonT Quinnell
//
// CHANGES
// 10/14/2010 - Timeout message now gets sent to the prim that called the menu, not LINK_THIS. Also includes menuidentifier
// 11/29/2010 - Fixed Bug in RemoveUser function. Thanks for Virtouse Lilienthal for pointing it out.
// 11/29/2010 - Tidied up a little and removed functions NewMenu and RemoveUser that are only called once
// 04/28/2014 - Clarified licence
// 03/20/2022 - ZNI CREATIONS: Updated to include a color menu
// 07/20/2023 - Aria's Creations: Updated to include a number input system
// 07/21/2023 - Aria's Creations: Updated to include a toggle for utility button appending.
//
// NOTE: This script is licenced using the Creative Commons Attribution-Share Alike 3.0 license
//
// ********************************************************************
#include "src/includes/common.lsl"
// ********************************************************************
// CONSTANTS
// ********************************************************************
// Link Commands
integer LINK_MENU_DISPLAY = 300;
integer LINK_MENU_CLOSE = 310;
integer LINK_MENU_RETURN = 320;
integer LINK_MENU_TIMEOUT = 330;
integer LINK_MENU_CHANNEL = 303; // Returns from the dialog module to inform what the channel is
integer LINK_MENU_ONLYCHANNEL = 302; // Sent with a ident to make a channel. No dialog will pop up, and it will expire just like any other menu if input is not received.
// Main Menu Details
string BACK = "<<";
string FOWARD = ">>";
string MANUAL_ENTRY = ">manual<";
list MENU_NAVIGATE_BUTTONS = [ " ", " ", "-exit-"];
float MENU_TIMEOUT_CHECK = 10.0;
integer MENU_TIMEOUT = 120;
integer MAX_TEXT = 510;
list NUMBER_PAD = ["1", "2", "3", "4", "5", "6", "7", "8", "9"];
//list NUMBER_PAD = ["7", "8", "9", "4", "5", "6", "1", "2", "3"];
list NUMBER_PAD_END_NO_RNG = ["C", "0", "Confirm"];
list NUMBER_PAD_END_RNG = ["Random", "0", "Confirm"];
string g_sNumPadCode;
integer STRIDE_DESCRIPTION = 14;
integer STRIDE_ACTIVE = 4;
integer DEBUG = FALSE;
// ********************************************************************
// Variables
// ********************************************************************
list menusDescription;
list menusActive;
// ********************************************************************
// Functions - General
// ********************************************************************
debug(string debug)
{
if (DEBUG) llSay(DEBUG_CHANNEL,"DEBUG:"+llGetScriptName()+":"+debug+" : Free("+(string)llGetFreeMemory()+")");
}
integer string2Bool (string test)
{
if (test == "TRUE") return TRUE;
else return FALSE;
}
// ********************************************************************
// Functions - Menu Helpers
// ********************************************************************
integer NewChannel()
{ // generates unique channel number
integer channel;
do channel = -(llRound(llFrand(999999)) + 99999);
while (~llListFindList(menusDescription, [channel]));
return channel;
}
string CheckTitleLength(string title)
{
if (llStringLength(title) > MAX_TEXT) title = llGetSubString(title, 0, MAX_TEXT-1);
return title;
}
list FillMenu(list buttons)
{ //adds empty buttons until the list length is multiple of 3, to max of 12
integer i;
list listButtons;
for(i=0;i<llGetListLength(buttons);i++)
{
string name = llList2String(buttons,i);
if (llStringLength(name) > 24) name = llGetSubString(name, 0, 23);
listButtons = listButtons + [name];
}
while (llGetListLength(listButtons) != 3 && llGetListLength(listButtons) != 6 && llGetListLength(listButtons) != 9 && llGetListLength(listButtons) < 12)
{
listButtons = listButtons + [" "];
}
buttons = llList2List(listButtons, 9, 11);
buttons = buttons + llList2List(listButtons, 6, 8);
buttons = buttons + llList2List(listButtons, 3, 5);
buttons = buttons + llList2List(listButtons, 0, 2);
return buttons;
}
RemoveMenu(integer channel, integer echo)
{
integer index = llListFindList(menusDescription, [channel]);
if (index != -1)
{
key menuId = llList2Key(menusDescription, index+1);
string menuDetails = llList2String(menusDescription, index+2);
integer menuLink = llList2Integer(menusDescription, index+3);
menusDescription = llDeleteSubList(menusDescription, index, index + STRIDE_DESCRIPTION - 1);
RemoveListen(channel);
if (echo) llMessageLinked(menuLink, LINK_MENU_TIMEOUT, menuDetails, menuId);
}
}
RemoveListen(integer channel)
{
integer index = llListFindList(menusActive, [channel]);
if (index != -1)
{
llListenRemove(llList2Integer(menusActive, index + 1));
menusActive = llDeleteSubList(menusActive, index, index + STRIDE_ACTIVE - 1);
}
}
// ********************************************************************
// Functions - Menu Main
// ********************************************************************
DisplayMenu(key id, integer channel, integer page, integer iTextBox)
{
string menuTitle;
list menuSubTitles;
list menuButtonsAll;
list menuButtonsTextAll;
list menuButtons;
list menuButtonsText; // This is companion menu text per-button
list menuNavigateButtons;
list menuFixedButtons;
integer max = 12;
// Populate values
integer index = llListFindList(menusDescription, [channel]);
integer iNumpad = 0;
menuButtonsAll = llParseString2List(llList2String(menusDescription, index+6), ["~"], []);
menuButtonsTextAll = llParseString2List(llList2String(menusDescription,index + 10), ["~"], []);
integer noUtil = (llList2String(menusDescription, index+9) == "NOUTIL");
BACK = llList2String(menusDescription, index+11);
FOWARD = llList2String(menusDescription, index+12);
MENU_NAVIGATE_BUTTONS = llParseString2List(llList2String(menusDescription, index+13), ["~"], []);
if (llList2String(menusDescription, index+7) != "") menuFixedButtons = llParseString2List(llList2String(menusDescription, index+7), ["~"], []);
if(llList2String(menuButtonsAll,0)=="colormenu" && llGetListLength(menuButtonsAll)==1){
menuButtonsAll = ["Dark Blue", "Blue", "Red", "Dark Red", "Green", "Dark Green", "Black", "White", ">custom<"];
}else if(llList2String(menuButtonsAll,0) == "numpadplz" && llGetListLength(menuButtonsAll) == 1)
{
iNumpad = 1;
if(g_sNumPadCode == "")
menuButtonsAll = NUMBER_PAD_END_RNG + NUMBER_PAD;
else menuButtonsAll = NUMBER_PAD_END_NO_RNG + NUMBER_PAD;
}
if(!noUtil){
// Set up the menu buttons
if (llList2Integer(menusDescription, index+4)) menuNavigateButtons= MENU_NAVIGATE_BUTTONS;
else if (llGetListLength(menuButtonsAll) > (max-llGetListLength(menuFixedButtons)) && !noUtil) menuNavigateButtons = [" ", " ", " "];
}
// FIXME: add sanity check for menu page
max = max - llGetListLength(menuFixedButtons) - llGetListLength(menuNavigateButtons);
integer start = page*max;
integer stop = (page+1)*max - 1;
if(!iTextBox && IsListOfIDs(menuButtonsAll))
{
integer x=0;
integer xe = llGetListLength(menuButtonsAll);
list lTitle=llParseString2List(llList2String(menusDescription, index+5),["~"],[]);
string sTitle = llList2String(lTitle,0);
for(x=0;x<xe;x++)
{
if(IsLikelyAvatarID(llList2String(menuButtonsAll,x))){
menuButtonsText += [(string)x + ". " + SLURL(llList2String(menuButtonsAll, x))];
menuButtonsAll[x] = (string)x;
} else {
if(IsLikelyUUID(llList2String(menuButtonsAll, x)))
{
menuButtonsText += [(string)x + ". " + llKey2Name(llList2String(menuButtonsAll, x))];
menuButtonsAll[x] = (string)x;
}
}
}
lTitle[0] = sTitle;
menusDescription[index+5] = llDumpList2String(lTitle,"~");
}
menuButtons = FillMenu(menuFixedButtons + llList2List(menuButtonsAll, start, stop));
if(llGetListLength(menuButtonsTextAll) > 0) {
menuButtonsText = llList2List(menuButtonsTextAll, start,stop);
menuButtonsAll = numberRange(start,stop);
integer x=0;
integer endx = llGetListLength(menuButtonsText);
for(x=0;x<endx;x++)
{
menuButtonsText = llListReplaceList(menuButtonsText, [llList2String(menuButtonsAll,x)+". " + llList2String(menuButtonsText,x)], x,x);
}
}
// Generate the title
list tempTitle = llParseString2List(llList2String(menusDescription, index+5), ["~"], []);
menuTitle = llList2String(tempTitle,0);
if (llGetListLength(tempTitle) > 1) menuSubTitles = llList2List(tempTitle, 1, -1);
if (llGetListLength(menuSubTitles) > 0)
{
integer i;
for(i=start;i<(stop+1);++i)
{
if (llList2String(menuSubTitles, i) != "") menuTitle += "\n"+llList2String(menuSubTitles, i);
}
}
menuTitle = CheckTitleLength(menuTitle);
if(!noUtil){
// Add navigate buttons if necessary
if (page > 0) menuNavigateButtons = llListReplaceList(menuNavigateButtons, [BACK], 0, 0);
if (llGetListLength(menuButtonsAll) > (page+1)*max) menuNavigateButtons = llListReplaceList(menuNavigateButtons, [FOWARD], 2, 2);
}
// Set up listen and add the row details
integer menuHandle = llListen(channel, "", id, "");
menusActive = [channel, menuHandle, llGetUnixTime(), page] + menusActive;
llSetTimerEvent(MENU_TIMEOUT_CHECK);
menuTitle += llDumpList2String(menuButtonsText, "\n") + sSetor(iNumpad,"\nNew Value: " + (string)g_sNumPadCode, "");
integer strlen = llStringLength(menuTitle);
//llSay(0, "Menu Content page length: "+(string)strlen);
if(strlen > 512)
{
llSay(0, "Unaltered menu text:\n" + menuTitle);
}
// Display menu
if(!iTextBox)
llDialog(id, menuTitle, menuNavigateButtons + menuButtons, channel);
else llTextBox(id, menuTitle, channel);
}
// ********************************************************************
// Event Handlers
// ********************************************************************
default
{
listen(integer channel, string name, key id, string message)
{
if (message == BACK)
{
integer index = llListFindList(menusActive, [channel]);
integer page = llList2Integer(menusActive, index+3)-1;
RemoveListen(channel);
DisplayMenu(id, channel, page, FALSE);
}
else if (message == FOWARD)
{
integer index = llListFindList(menusActive, [channel]);
integer page = llList2Integer(menusActive, index+3)+1;
RemoveListen(channel);
DisplayMenu(id, channel, page, FALSE);
}else if(message == MANUAL_ENTRY)
{
integer index = llListFindList(menusActive, [channel]);
integer page = llList2Integer(menusActive, index+3);
RemoveListen(channel);
DisplayMenu(id, channel, 0, TRUE);
}
else if (message == " ")
{
integer index = llListFindList(menusActive, [channel]);
integer page = llList2Integer(menusActive, index+3);
RemoveListen(channel);
DisplayMenu(id, channel, page, FALSE);
}
else
{
integer index = llListFindList(menusDescription, [channel]);
if(llList2String(menusDescription,index+6)=="colormenu")
{
switch(message)
{
case "Dark Blue":
{
message = "<0,0,0.5>";
break;
}
case "Blue":
{
message = "<0,0,1>";
break;
}
case "Red":
{
message = "<1,0,0>";
break;
}
case "Dark Red":
{
message = "<0.5,0,0>";
break;
}
case ">custom<":
{
llTextBox(id, "Enter the color using the format: <R,G,B> including the brackets.", channel);
return;
}
case "Green":
{
message = "<0,1,0>";
break;
}
case "Dark Green":
{
message = "<0,0.5,0>";
break;
}
case "Black":
{
message = "<0,0,0>";
break;
}
case "White":
{
message = "<1,1,1>";
break;
}
default:
{
break;
}
}
} else if(llGetSubString(llList2String(menusDescription,index+6),0, 8) == "numpadplz")
{
integer iReturn = 0;
switch(message)
{
case "Random":
{
g_sNumPadCode = (string)llRound(llFrand(0xFFFFFF));
break;
}
case "C":
{
g_sNumPadCode = "";
break;
}
case "Confirm":
{
if(g_sNumPadCode == "")
{
iReturn = 1;
message = "-1";
}else {
iReturn = 1;
message = g_sNumPadCode;
}
g_sNumPadCode = "";
break;
}
default:
{
g_sNumPadCode += message;
break;
}
}
if(!iReturn)
{
RemoveListen(channel);
DisplayMenu(id, channel, 0, FALSE);
return;
}
}
list lButtonOpts = llParseString2List(llList2String(menusDescription, index+6), ["~"], []);
integer iV = (integer)message;
if(message == "0" || iV>0)
{
string sBtn = llList2String(lButtonOpts, iV);
if(IsLikelyUUID(sBtn))
message = sBtn;
}
llMessageLinked(llList2Integer(menusDescription, index+3), LINK_MENU_RETURN, llList2Json(JSON_OBJECT, ["type", "menu_back", "id", llList2String(menusDescription, index+2), "extra", llList2String(menusDescription, index+8), "reply", message]), id);
//llMessageLinked(llList2Integer(menusDescription, index+3), LINK_MENU_RETURN, llList2String(menusDescription, index+2)+"|"+message, id);
RemoveMenu(channel, FALSE);
}
}
link_message(integer senderNum, integer num, string message, key id)
{
if (num == LINK_MENU_DISPLAY)
{ // Setup New Menu
list temp = llParseStringKeepNulls(message, ["|"], []);
integer iTextBox=0;
if(llList2String(temp,3)=="")iTextBox = 1;
integer channel = NewChannel();
//llSay(0, "DIALOG DEBUG : \n[ Item Count : "+(string)llGetListLength(temp)+" ]\n[ Items : "+llDumpList2String(temp, "~")+" ]\n[ Raw Request : "+message+" ]");
if (llGetListLength(temp) > 2)
{
menusDescription = [channel, id, llList2String(temp, 0), senderNum, string2Bool(llList2String(temp, 1)), llList2String(temp, 2), llList2String(temp, 3), llList2String(temp, 4), llList2String(temp, 5), llList2String(temp, 6), llList2String(temp,7), llList2String(temp,8), llList2String(temp,9), llList2String(temp,10)] + menusDescription;
//llSay(0, "DIALOG DEBUG : \n[ "+llDumpList2String(menusDescription, " ~ ")+" ]");
DisplayMenu(id, channel, 0, iTextBox);
}
else llSay (DEBUG_CHANNEL, "ERROR in "+llGetScriptName()+": Dialog Script. Incorrect menu format");
}
else if (num == LINK_MENU_CLOSE)
{ // Will remove all menus that have the user id.
integer index_id = llListFindList(menusDescription, [id]);
while (~index_id)
{
integer channel = llList2Integer(menusDescription, index_id-1);
RemoveMenu(channel, FALSE);
// Check for another menu by same user
index_id = llListFindList(menusDescription, [id]);
}
} else if(num == LINK_MENU_ONLYCHANNEL)
{
integer channel = NewChannel();
integer handle = llListen(channel, "", "", "");
menusActive = [channel, handle, llGetUnixTime(), 0] + menusActive;
menusDescription = [channel, id, message, senderNum, 0, " ", " ", " "]+menusDescription;
llMessageLinked(LINK_SET, LINK_MENU_CHANNEL, (string)channel, message);
}
}
timer()
{ // Check through timers and close if necessary
integer i;
list toRemove;
integer currentTime = llGetUnixTime();
integer length = llGetListLength(menusActive);
for(i=0;i<length;i+=STRIDE_ACTIVE)
{
if (currentTime - llList2Integer(menusActive, i+2) > MENU_TIMEOUT) toRemove = [llList2Integer(menusActive, i)] + toRemove;
}
length = llGetListLength(toRemove);
if (length > 0)
{
for(i=0;i<length;i++)
{
RemoveMenu(llList2Integer(toRemove, i), TRUE);
}
}
}
}
/*
string BACK = "<<";
string FORWARD = ">>";
list MENU_NAVIGATE_BUTTONS = [" ", " ", "-exit-"];
Menu(key kAv, string sText, list lButtons, string sIdent, string sExtra, list lCompanionText)
{
llMessageLinked(LINK_THIS, LINK_MENU_DISPLAY, llDumpList2String([sIdent, "TRUE", sText, llDumpList2String(lButtons, "~"), "", sExtra, "", llDumpList2String(lCompanionText, "~"), BACK, FORWARD, llDumpList2String(MENU_NAVIGATE_BUTTONS, "~")], "|"), kAv);
}
MenuNoUtility(key kAv, string sText, list lButtons, string sIdent, string sExtra, list lCompanionText)
{
llMessageLinked(LINK_THIS, LINK_MENU_DISPLAY, llDumpList2String([sIdent, "TRUE", sText, llDumpList2String(lButtons, "~"), "", sExtra, "NOUTIL", llDumpList2String(lCompanionText, "~"), BACK, FORWARD, llDumpList2String(MENU_NAVIGATE_BUTTONS, "~")], "|"), kAv);
}
GetArbitraryData(key kAv, string sText, string sIdent, string sExtra){
llMessageLinked(LINK_THIS, LINK_MENU_DISPLAY, llDumpList2String([sIdent, "FALSE", sText, "", "", sExtra, "", "", BACK, FORWARD, llDumpList2String(MENU_NAVIGATE_BUTTONS, "~")], "|"), kAv);
}
GetListenerChannel(string sIdent)
{
llMessageLinked(LINK_THIS, LINK_MENU_ONLYCHANNEL, sIdent, sIdent);
}
NumberPad(key kAv, string sText, string sIdent, string sExtra)
{
llMessageLinked(LINK_THIS, LINK_MENU_DISPLAY, llDumpList2String([sIdent, "TRUE", sText, "numpadplz", "", sExtra, "NOUTIL", "", BACK, FORWARD, llDumpList2String(MENU_NAVIGATE_BUTTONS, "~")], "|"), kAv);
}
link_message(integer s,integer n,string m,key i)
{
if(n == LINK_MENU_CHANNEL)
{
if(i == "ident")
{
//channel = m
}
}else if(n == LINK_MENU_RETURN)
{
if(llJsonGetValue(m, ["type"]) == "menu_back")
{
string sIdent = llJsonGetValue(m,["id"]);
key kAv = i;
string sReply = llJsonGetValue(m,["reply"]);
string sExtra = llJsonGetValue(m,["extra"]);
}
}
}
*/

629
src/raw/Leash.lsl Normal file
View file

@ -0,0 +1,629 @@
#include "src/includes/common.lsl"
/*
DISCLAIMER
Some code has been sourced from the OpenCollar project, some is my own personal code that may look similar to OpenCollar, because i was the one who contributed it in the first place.
*/
string LEASH_HOLDER = "[DHB]Leather Handle";
string LEASH_WALL_RING = "[DHB]Wall Ring";
string LEASH_POST = "[DHB]Leash Post";
string PLUGIN_NAME = "Leash";
// Link Commands
integer LINK_MENU_DISPLAY = 300;
integer LINK_MENU_CLOSE = 310;
integer LINK_MENU_RETURN = 320;
integer LINK_MENU_TIMEOUT = 330;
integer LINK_MENU_CHANNEL = 303; // Returns from the dialog module to inform what the channel is
integer LINK_MENU_ONLYCHANNEL = 302; // Sent with a ident to make a channel. No dialog will pop up, and it will expire just like any other menu if input is not received.
string g_sParticleTextureID="4cde01ac-4279-2742-71e1-47ff81cc3529";
string BACK = "<<";
string FORWARD = ">>";
list MENU_NAVIGATE_BUTTONS = [" ", " ", "-exit-"];
Menu(key kAv, string sText, list lButtons, string sIdent, string sExtra, list lCompanionText)
{
llMessageLinked(LINK_THIS, LINK_MENU_DISPLAY, llDumpList2String([sIdent, "TRUE", sText, llDumpList2String(lButtons, "~"), "", sExtra, "", llDumpList2String(lCompanionText, "~"), BACK, FORWARD, llDumpList2String(MENU_NAVIGATE_BUTTONS, "~")], "|"), kAv);
}
MenuNoUtility(key kAv, string sText, list lButtons, string sIdent, string sExtra, list lCompanionText)
{
llMessageLinked(LINK_THIS, LINK_MENU_DISPLAY, llDumpList2String([sIdent, "TRUE", sText, llDumpList2String(lButtons, "~"), "", sExtra, "NOUTIL", llDumpList2String(lCompanionText, "~"), BACK, FORWARD, llDumpList2String(MENU_NAVIGATE_BUTTONS, "~")], "|"), kAv);
}
GetArbitraryData(key kAv, string sText, string sIdent, string sExtra){
llMessageLinked(LINK_THIS, LINK_MENU_DISPLAY, llDumpList2String([sIdent, "FALSE", sText, "", "", sExtra, "", "", BACK, FORWARD, llDumpList2String(MENU_NAVIGATE_BUTTONS, "~")], "|"), kAv);
}
GetListenerChannel(string sIdent)
{
llMessageLinked(LINK_THIS, LINK_MENU_ONLYCHANNEL, sIdent, sIdent);
}
NumberPad(key kAv, string sText, string sIdent, string sExtra)
{
llMessageLinked(LINK_THIS, LINK_MENU_DISPLAY, llDumpList2String([sIdent, "TRUE", sText, "numpadplz", "", sExtra, "NOUTIL", "", BACK, FORWARD, llDumpList2String(MENU_NAVIGATE_BUTTONS, "~")], "|"), kAv);
}
call_menu(integer id, key kAv)
{
llMessageLinked(LINK_SET, 0, llList2Json(JSON_OBJECT, ["cmd", "check_mode", "callback", llList2Json(JSON_OBJECT, ["script", llGetScriptName(), "id", id])]), kAv);
}
Main(key kID, integer iAuth)
{
list lMenu = ["main..", "Length", Checkbox(g_iTurn, "Turn2Leasher"), "Post", "Tools..", "Color"];
if(kID != llGetOwner())
{
if(g_kLeashedTo)
lMenu += ["Grab Leash"];
else lMenu += ["Unleash"];
}else {
if(g_kLeashedTo) lMenu += ["Unleash"];
}
list lHelper = [];
string sText = "Leash Menu";
Menu(kID, sText, lMenu, "menu~Leash", SetDSMeta([iAuth]), lHelper);
}
list g_lLeashPoints = [];
LPSearch()
{
g_lLeashPoints = [];
integer ix=0;
integer end = llGetNumberOfPrims();
for(ix=LINK_ROOT; ix<=end;ix++)
{
list lPar = llGetLinkPrimitiveParams(ix, [PRIM_DESC]);
if(llList2String(lPar,0) == "leash point")
{
g_lLeashPoints += [ix];
}
}
}
integer g_iTurn;
key g_kLeashedTo;
integer g_iLeashedToAuth;
integer g_iLeashLength;
ToolsMenu(key kID, integer iAuth)
{
list lMenu = ["back..", "Leash Holder", "Leash Post", "Wall Ring"];
list lHelper = ["Go back to the leash menu", "Receive a leash holder", "Receive a rezzable leash post", "Receive a wall ring that can be rezzed"];
Menu(kID, "Leash Tools\n\n", lMenu, "menu~LeashTools", SetDSMeta([iAuth]), lHelper);
}
PostScan(key kAv, integer iAuth)
{
UpdateDSRequest(NULL, "postscan", SetDSMeta([kAv, iAuth]));
llSensor("", "", SCRIPTED, 20, PI);
}
PostMenu(key kID, integer iAuth, list lOptions)
{
list lMenu = ["back.."] + lOptions;
string sMenu = "What object do you want to attach the leash to?\n\n";
Menu(kID, sMenu, lMenu, "leash~post", SetDSMeta([iAuth]), []);
}
vector g_vLeashColor = <1.00000, 1.00000, 1.00000>;
vector g_vLeashSize = <0.04, 0.04, 1.0>;
integer g_iParticleGlow = TRUE;
float g_fParticleAge = 3.5;
vector g_vLeashGravity = <0.0,0.0,-1.0>;
integer g_iParticleCount = 1;
float g_fBurstRate = 0.0;
list CalculateParticles(key kParticleTarget)
{
integer iFlags = PSYS_PART_FOLLOW_VELOCITY_MASK | PSYS_PART_TARGET_POS_MASK | PSYS_PART_FOLLOW_SRC_MASK;
list lTemp = [
PSYS_PART_MAX_AGE,g_fParticleAge,
PSYS_PART_FLAGS,iFlags,
PSYS_PART_START_COLOR, g_vLeashColor,
//PSYS_PART_END_COLOR, g_vLeashColor,
PSYS_PART_START_SCALE,g_vLeashSize,
//PSYS_PART_END_SCALE,g_vLeashSize,
PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_DROP,
PSYS_SRC_BURST_RATE,g_fBurstRate,
PSYS_SRC_ACCEL, g_vLeashGravity,
PSYS_SRC_BURST_PART_COUNT,g_iParticleCount,
//PSYS_SRC_BURST_SPEED_MIN,fMinSpeed,
//PSYS_SRC_BURST_SPEED_MAX,fMaxSpeed,
PSYS_SRC_TARGET_KEY,kParticleTarget,
PSYS_SRC_MAX_AGE, 0,
PSYS_SRC_TEXTURE, g_sParticleTextureID
];
return lTemp;
}
StopParticles()
{
integer i=0;
integer end = llGetListLength(g_lLeashPoints);
for(i=0;i<end;i++)
{
llLinkParticleSystem(llList2Integer(g_lLeashPoints,i),[]);
}
}
RefreshParticles()
{
if(g_kLeashedTo)
{
integer i=0;
integer end = llGetListLength(g_lLeashPoints);
for(i=0;i<end;i++)
{
llLinkParticleSystem(llList2Integer(g_lLeashPoints,i), CalculateParticles(g_kLeashedTo));
}
}else {
StopParticles();
}
}
UpdateRLV()
{
if(g_kLeashedTo)
{
llOwnerSay("@fly=n,tplm=n,tplure=n,tploc=n,tplure:"+(string)g_kLeashedTo+"=add,fartouch=n,sittp=n");
}else {
llOwnerSay("@fly=y,tplm=y,tplure=y,tploc=y,clear=tplure,fartouch=y,sittp=y");
}
}
integer g_iTargetHandle;
vector g_vTargetPos;
integer g_iJustMoved = FALSE;
integer g_iTargetInRange;
integer g_iAwayCounter;
CheckLeashMovement()
{
if(g_kLeashedTo)
{
g_vTargetPos = llList2Vector(llGetObjectDetails(g_kLeashedTo, [OBJECT_POS]),0);
llTargetRemove(g_iTargetHandle);
llStopMoveToTarget();
g_iTargetHandle = llTarget(g_vTargetPos, (float)g_iLeashLength);
llSetTimerEvent(3);
}else {
llTargetRemove(g_iTargetHandle);
llStopMoveToTarget();
llSetTimerEvent(0);
}
}
default
{
state_entry()
{
// Load settings here
LPSearch();
}
timer()
{
vector vLeashedToPos = llList2Vector(llGetObjectDetails(g_kLeashedTo, [OBJECT_POS]), 0);
integer iIsInSimOrOutside = TRUE;
if(vLeashedToPos == ZERO_VECTOR || llVecDist(llGetPos(), vLeashedToPos) > 255) iIsInSimOrOutside=FALSE;
if(iIsInSimOrOutside && llVecDist(llGetPos(), vLeashedToPos) < (60 + g_iLeashLength))
{
if(!g_iTargetInRange)
{
g_iAwayCounter = -1;
llSetTimerEvent(3);
}
g_iTargetInRange = TRUE;
llTargetRemove(g_iTargetHandle);
g_vTargetPos = vLeashedToPos;
g_iTargetHandle = llTarget(g_vTargetPos, (float)g_iLeashLength);
} else {
if(g_iTargetInRange)
{
if(g_iAwayCounter <= llGetUnixTime())
{
llTargetRemove(g_iTargetHandle);
llStopMoveToTarget();
g_iTargetInRange=FALSE;
UpdateRLV();
g_iAwayCounter=-1;
} else if(g_iAwayCounter == -1)
{
g_iAwayCounter = llGetUnixTime()+ (5*60);
}
}else {
if(llGetUnixTime() > g_iAwayCounter)
{
deleteSetting("leash_leashedto", "");
llRegionSayTo(llGetOwner(), 0, "SAFETY UNLEASH\n\n[ The leash holder has been gone for more than five minutes ]");
}
}
}
}
at_target(integer iNum, vector vTarget, vector vMe)
{
llStopMoveToTarget();
llTargetRemove(g_iTargetHandle);
g_vTargetPos = llList2Vector(llGetObjectDetails(g_kLeashedTo, [OBJECT_POS]),0);
g_iTargetHandle = llTarget(g_vTargetPos, (float)g_iLeashLength);
if(g_iJustMoved)
{
vector vPointTo = llList2Vector(llGetObjectDetails(g_kLeashedTo, [OBJECT_POS]),0) - llGetPos();
float fAngle = llAtan2(vPointTo.x, vPointTo.y);
if(g_iTurn) llOwnerSay("@setrot:" + (string)fAngle + "=force");
g_iJustMoved=FALSE;
}
}
not_at_target(){
g_iJustMoved=1;
if(g_kLeashedTo)
{
vector vNewPos = llList2Vector(llGetObjectDetails(g_kLeashedTo, [OBJECT_POS]),0);
if(g_vTargetPos != vNewPos)
{
llTargetRemove(g_iTargetHandle);
g_vTargetPos = vNewPos;
g_iTargetHandle = llTarget(g_vTargetPos, (float)g_iLeashLength);
}
if(g_vTargetPos != ZERO_VECTOR)
{
llMoveToTarget(g_vTargetPos, 1.0);
}else {
llStopMoveToTarget();
llTargetRemove(g_iTargetHandle);
}
} else {
llStopMoveToTarget();
llTargetRemove(g_iTargetHandle);
}
}
sensor(integer iNum)
{
integer i=0;
list lMeta = GetMetaList("postscan");
DeleteDSReq("postscan");
list lResults = [];
for(i=0;i<iNum; i++)
{
lResults += [llDetectedKey(i)];
}
PostMenu(llList2String(lMeta,0), (integer)llList2String(lMeta,1), lResults);
}
no_sensor()
{
list lMeta = GetMetaList("postscan");
DeleteDSReq("postscan");
PostMenu((key)llList2String(lMeta,0), (integer)llList2String(lMeta,1), []);
}
link_message(integer s,integer n,string m,key i)
{
if(n==0)
{
if(llJsonGetValue(m,["cmd"]) == "reset")
{
llResetScript();
} else if(llJsonGetValue(m,["cmd"]) == "scan_plugins")
{
llMessageLinked(LINK_SET,0,llList2Json(JSON_OBJECT, ["cmd", "plugin_reply", "name", PLUGIN_NAME]), "");
} else if(llJsonGetValue(m,["cmd"]) == "pass_menu")
{
if(llJsonGetValue(m,["plugin"]) == PLUGIN_NAME)
call_menu(1, i);
} else if(llJsonGetValue(m,["cmd"]) == "check_mode_back")
{
integer access = (integer)llJsonGetValue(m,["val"]);
if(access != 99){
string sPacket = llJsonGetValue(m,["callback"]);
if(llGetScriptName() == llJsonGetValue(sPacket, ["script"]))
{
integer iMenu = (integer)llJsonGetValue(sPacket, ["id"]);
if(iMenu == 1)
Main(i, access);
else if(iMenu ==2)
NumberPad(i, "How long do you want the leash in meters?\nMax value: 50\nCurrent: "+(string)g_iLeashLength+"\n\n", "length", SetDSMeta([access]));
else if(iMenu ==3)
ToolsMenu(i, access);
else if(iMenu == 4)
PostScan(i, access);
else if(iMenu == 5)
Menu(i, "What color do you want to choose?\n\nCurrent Color: "+ (string)g_vLeashColor, ["colormenu"], "menu~LeashColor", SetDSMeta([access]), []);
}
}
else llRegionSayTo(i,0,"Access Denied");
} else if(llJsonGetValue(m,["cmd"]) == "read_setting_back")
{
string sSetting = llJsonGetValue(m,["setting"]);
string sValue = llJsonGetValue(m,["value"]);
switch(sSetting)
{
case "leash_turn":
{
g_iTurn = (integer)sValue;
break;
}
case "leash_leashedto":
{
if(sValue == "")
{
g_kLeashedTo = NULL_KEY;
g_iLeashedToAuth = 0;
}else {
g_kLeashedTo = llJsonGetValue(sValue, ["id"]);
g_iLeashedToAuth = (integer)llJsonGetValue(sValue, ["level"]);
}
break;
}
case "leash_length":
{
g_iLeashLength = (integer)sValue;
break;
}
case "leash_color":
{
g_vLeashColor = (vector)sValue;
break;
}
}
if(llSubStringIndex(sSetting, "leash")!=-1)
{
RefreshParticles();
UpdateRLV();
// Assert the Leash movement updates as well
CheckLeashMovement();
}
}
}else if(n == LINK_MENU_CHANNEL)
{
if(i == "ident")
{
//channel = m
}
}else if(n == LINK_MENU_RETURN)
{
if(llJsonGetValue(m, ["type"]) == "menu_back")
{
string sIdent = llJsonGetValue(m,["id"]);
key kAv = i;
string sReply = llJsonGetValue(m,["reply"]);
string sExtra = llJsonGetValue(m,["extra"]);
list lExtra = llParseString2List(sExtra, [":"],[]);
integer iAuth = (integer)llList2String(lExtra,0);
integer iRespring=1;
integer iMenu;
if(sReply == "-exit-")
{
return;
}
switch(sIdent)
{
case "menu~Leash":
{
iMenu = 1;
switch(sReply)
{
case "main..":
{
iRespring=0;
llMessageLinked(LINK_SET, 0, llList2Json(JSON_OBJECT, ["cmd", "pass_menu", "plugin", "Main"]), kAv);
break;
}
case "Length":
{
iMenu=2;
break;
}
case Checkbox(g_iTurn, "Turn2Leasher"):
{
g_iTurn=!g_iTurn;
writeSetting("leash_turn", (string)g_iTurn);
break;
}
case "Tools..":
{
iMenu=3;
break;
}
case "Post":
{
iMenu=4;
break;
}
case "Unleash":
{
if(iAuth <= g_iLeashedToAuth){
deleteSetting("leash_leashedto", "");
llRegionSayTo(llGetOwner(), 0, "You've been unleashed by " + SLURL(kAv));
}
break;
}
case "Grab Leash":
{
integer iLeash=1;
if(g_kLeashedTo)
{
if(!(iAuth <= g_iLeashedToAuth))
{
llRegionSayTo(kAv, 0, "The leash is currently held by " + SLURL(g_kLeashedTo)+". You lack the authority to take it from them.");
iLeash=0;
}
}
if(iLeash){
writeSetting("leash_leashedto", llList2Json(JSON_OBJECT, ["id", kAv, "level", iAuth]));
if(g_kLeashedTo)
llRegionSayTo(g_kLeashedTo, 0, SLURL(kAv)+" takes the leash from you");
llRegionSayTo(kAv,0,"You grab "+SLURL(llGetOwner()) +"'s leash");
llRegionSayTo(llGetOwner(), 0, "Your leash was grabbed by " + SLURL(kAv));
}
}
case "Color":
{
iMenu=5;
break;
}
}
break;
}
case "length":
{
iMenu = 1;
if(sReply != "-1"){
integer len = (integer)sReply;
if(len >= 50)
{
len = 50;
}
if(len <= 0) len = 1;
writeSetting("leash_length", (string)len);
}
break;
}
case "menu~LeashColor":
{
writeSetting("leash_color", sReply);
iMenu=1;
break;
}
case "menu~LeashTools":
{
iMenu=3;
switch(sReply)
{
case "back..":
{
iMenu=1;
break;
}
case "Leash Holder":
{
llGiveInventory(kAv, LEASH_HOLDER);
break;
}
case "Wall Ring":
{
llGiveInventory(kAv, LEASH_WALL_RING);
break;
}
case "Leash Post":
{
llGiveInventory(kAv, LEASH_POST);
break;
}
}
break;
}
case "leash~post":
{
iMenu=1;
switch(sReply)
{
case "back..":
{
iMenu=1;
break;
}
default:
{
// Leash to object
llRegionSayTo(kAv,0,"Leashing to " + llKey2Name(sReply)+" ...");
writeSetting("leash_leashedto", llList2Json(JSON_OBJECT, ["id", sReply, "level", iAuth]));
break;
}
}
break;
}
}
if(iRespring)
{
call_menu(iMenu, kAv);
}
}
} else if(n == LM_SETTINGS_READY)
{
readSetting("leash_leashedto", "");
readSetting("leash_length", "5");
readSetting("leash_turn", "0");
readSetting("leash_color", "<1,1,1>");
}
}
}

429
src/raw/Menu.lsl Normal file
View file

@ -0,0 +1,429 @@
#include "src/includes/common.lsl"
// Link Commands
integer LINK_MENU_DISPLAY = 300;
integer LINK_MENU_CLOSE = 310;
integer LINK_MENU_RETURN = 320;
integer LINK_MENU_TIMEOUT = 330;
integer LINK_MENU_CHANNEL = 303; // Returns from the dialog module to inform what the channel is
integer LINK_MENU_ONLYCHANNEL = 302; // Sent with a ident to make a channel. No dialog will pop up, and it will expire just like any other menu if input is not received.
string BACK = "<<";
string FORWARD = ">>";
list MENU_NAVIGATE_BUTTONS = [" ", " ", "-exit-"];
Menu(key kAv, string sText, list lButtons, string sIdent, string sExtra, list lCompanionText)
{
llMessageLinked(LINK_THIS, LINK_MENU_DISPLAY, llDumpList2String([sIdent, "TRUE", sText, llDumpList2String(lButtons, "~"), "", sExtra, "", llDumpList2String(lCompanionText, "~"), BACK, FORWARD, llDumpList2String(MENU_NAVIGATE_BUTTONS, "~")], "|"), kAv);
}
MenuNoUtility(key kAv, string sText, list lButtons, string sIdent, string sExtra, list lCompanionText)
{
llMessageLinked(LINK_THIS, LINK_MENU_DISPLAY, llDumpList2String([sIdent, "TRUE", sText, llDumpList2String(lButtons, "~"), "", sExtra, "NOUTIL", llDumpList2String(lCompanionText, "~"), BACK, FORWARD, llDumpList2String(MENU_NAVIGATE_BUTTONS, "~")], "|"), kAv);
}
GetArbitraryData(key kAv, string sText, string sIdent, string sExtra){
llMessageLinked(LINK_THIS, LINK_MENU_DISPLAY, llDumpList2String([sIdent, "FALSE", sText, "", "", sExtra, "", "", BACK, FORWARD, llDumpList2String(MENU_NAVIGATE_BUTTONS, "~")], "|"), kAv);
}
GetListenerChannel(string sIdent)
{
llMessageLinked(LINK_THIS, LINK_MENU_ONLYCHANNEL, sIdent, sIdent);
}
NumberPad(key kAv, string sText, string sIdent, string sExtra)
{
llMessageLinked(LINK_THIS, LINK_MENU_DISPLAY, llDumpList2String([sIdent, "TRUE", sText, "numpadplz", "", sExtra, "NOUTIL", "", BACK, FORWARD, llDumpList2String(MENU_NAVIGATE_BUTTONS, "~")], "|"), kAv);
}
integer g_iLocked= FALSE;
Main(key kID, integer level)
{
list lMenu = ["Access", "Help..", Checkbox(g_iLocked, "Locked")] + g_lPlugins;
list lMenuHelper = ["Set or remove owners", "Core help"];
string sText = "Welcome!\n\nDHB Replacement Scripts by " + SLURL ("5556d037-3990-4204-a949-73e56cd3cb06")+"\nYour Access Level is: " + ToLevelString(level)+"\n\n";
Menu(kID, sText, lMenu, "menu~Main", SetDSMeta([level]), lMenuHelper);
}
string g_sVersion = "1.0.111123.1753";
HelpMenu(key kID, integer level)
{
list lMenu = ["main..", "Restart"];
list lMenuHelper = ["Go back to the main menu", "Resets and restarts all scripts"];
string sText = "DHB Replacement Scripts\nHelp\n\nVersion: " + g_sVersion+"\n\nFree Memory: "+(string)llGetFreeMemory()+"\n\n";
Menu(kID, sText, lMenu, "menu~help", SetDSMeta([level]), lMenuHelper);
}
AccessMenu(key kID, integer level)
{
integer iSelfOwned = (integer)llLinksetDataReadProtected("access_selfown", MASTER_CODE);
integer iGroup = (integer)llLinksetDataReadProtected("access_group", MASTER_CODE);
integer iPublic = (integer)llLinksetDataReadProtected("access_public", MASTER_CODE);
list lMenu = ["main..", "Set Passwd", "Add Owner", "Rem Owner", "List Owners", Checkbox(iSelfOwned, "SelfOwn"), Checkbox(iGroup, "Group"), Checkbox(iPublic, "Public"), "Get MasterKey"];
list lHelper = ["Returns to the main menu", "Set the master key password", "Add a new owner", "Remove a existing owner", "List owners", "Toggle self owned status"];
string sText = "Access Settings Menu\nCurrent Master Password: " + llLinksetDataReadProtected("access_password", MASTER_CODE) + "\n\n";
Menu(kID, sText, lMenu, "menu~Access", SetDSMeta([level]), lHelper);
}
RemoveOwnerMenu(key kID, integer level)
{
list lMenu = ["cancel"];
string sText = "Who do you want to remove? \n\n";
integer ix=0;
integer endx = llLinksetDataCountFound("access_owner");
for(ix=0;ix<endx;ix++)
{
lMenu += [llLinksetDataReadProtected("access_owner"+(string)ix, MASTER_CODE)];
}
Menu(kID, sText, lMenu, "menu~remowner", SetDSMeta([level]), []);
}
call_menu(integer id, key kAv)
{
llMessageLinked(LINK_SET, 0, llList2Json(JSON_OBJECT, ["cmd", "check_mode", "callback", llList2Json(JSON_OBJECT, ["script", llGetScriptName(), "id", id])]), kAv);
}
list g_lPlugins = [];
key g_kLockedBy = NULL_KEY;
integer g_iLockedAuth = 0;
updateRLV()
{
if(g_iLocked)
{
llOwnerSay("@detach=n");
} else {
llOwnerSay("@detach=y");
}
}
default
{
state_entry()
{
llSetTimerEvent(10);
updateRLV();
}
timer()
{
llSetTimerEvent(0);
llMessageLinked(LINK_SET,0,llList2Json(JSON_OBJECT, ["cmd", "scan_plugins"]), "");
}
touch_start(integer t)
{
call_menu(1, llDetectedKey(0));
}
changed(integer c)
{
if(c&CHANGED_INVENTORY)
{
g_lPlugins=[];
llSetTimerEvent(5);
}
}
dataserver(key kID, string sData)
{
if(HasDSRequest(kID) != -1)
{
list lMeta = GetMetaList(kID);
DeleteDSReq(kID);
if(llList2String(lMeta,0) == "decodeAvatar")
{
if(sData != (string)NULL_KEY)
{
llMessageLinked(LINK_SET, 0, llList2Json(JSON_OBJECT, ["cmd", "add_owner", "id", sData]), "");
llRegionSayTo(llList2String(lMeta,2), 0, "Owner Added: " + SLURL(sData));
call_menu(2, llList2String(lMeta,2));
} else {
llRegionSayTo(llList2String(lMeta,2), 0, "Input invalid, avatar was not found. Try again");
call_menu(4, llList2String(lMeta,2));
}
}
}
}
link_message(integer s,integer n,string m,key i)
{
if(n == LINK_MENU_CHANNEL)
{
if(i == "ident")
{
//channel = m
}
} else if(n == LM_SETTINGS_READY)
{
readSetting("locked", "");
}else if(n == LINK_MENU_RETURN)
{
if(llJsonGetValue(m, ["type"]) == "menu_back")
{
string sIdent = llJsonGetValue(m,["id"]);
key kAv = i;
string sReply = llJsonGetValue(m,["reply"]);
string sExtra = llJsonGetValue(m,["extra"]);
list lExtra = llParseStringKeepNulls(sExtra, [":"], []);
integer level = (integer)llList2String(lExtra,0); // Auth Level
integer iRespring = 1;
integer iMenu = 0;
integer iSelfOwned = (integer)llLinksetDataReadProtected("access_selfown", MASTER_CODE);
integer iGroup = (integer)llLinksetDataReadProtected("access_group", MASTER_CODE);
integer iPublic = (integer)llLinksetDataReadProtected("access_public", MASTER_CODE);
if(sReply == "-exit-")
{
return;
}
switch(sIdent)
{
case "menu~Main":
{
iMenu = 1;
switch(sReply)
{
case "Access":
{
if(level <= ACCESS_WEARER)
{
iMenu = 2;
}
break;
}
case "Help..":
{
if(level <= ACCESS_WEARER)
{
iMenu = 6;
}
break;
}
case Checkbox(g_iLocked, "Locked"):
{
if(g_iLockedAuth >= level || !g_iLocked)
{
g_iLocked=!g_iLocked;
g_iLockedAuth = level;
g_kLockedBy = kAv;
updateRLV();
llLinksetDataWriteProtected("locked", llList2Json(JSON_OBJECT, ["by", kAv, "level", level]), MASTER_CODE);
}else {
llRegionSayTo(kAv, 0, "You lack the necessary permissions to unlock. Your level is " + ToLevelString(level) +"; and the locker's authority level is: "+ ToLevelString(g_iLockedAuth));
}
break;
}
default:
{
iRespring=0;
llMessageLinked(LINK_SET,0,llList2Json(JSON_OBJECT, ["cmd", "pass_menu", "plugin", sReply, "ray_id", llGenerateKey(), "from", iMenu]), kAv);
break;
}
}
break;
}
case "menu~Access":
{
iMenu=2;
switch(sReply)
{
case "main..":
{
iMenu=1;
break;
}
case "Set Passwd":
{
iMenu=3;
break;
}
case "Add Owner":
{
iMenu = 4;
break;
}
case "List Owners":
{
integer ix=0;
integer endx = llLinksetDataCountFound("access_owner");
llRegionSayTo(kAv, 0, "Owner X. " + SLURL(llGetOwner()));
for(ix=0;ix<endx;ix++)
{
llRegionSayTo(kAv, 0, "Owner "+(string)ix+". " + SLURL(llLinksetDataReadProtected("access_owner"+(string)ix, MASTER_CODE)));
}
break;
}
case "Rem Owner":
{
iMenu=5;
break;
}
case Checkbox(iSelfOwned, "SelfOwn"):
{
iSelfOwned = !iSelfOwned;
llMessageLinked(LINK_SET, 0, llList2Json(JSON_OBJECT, ["cmd", "set_self_own", "val", iSelfOwned]), kAv);
break;
}
case Checkbox(iGroup, "Group"):
{
iGroup = !iGroup;
llMessageLinked(LINK_SET, 0, llList2Json(JSON_OBJECT, ["cmd", "update_group", "val", iGroup]), kAv);
break;
}
case Checkbox(iPublic, "Public"):
{
iPublic = !iPublic;
llMessageLinked(LINK_SET, 0, llList2Json(JSON_OBJECT, ["cmd", "update_public", "val", iPublic]), kAv);
break;
}
case "Get MasterKey":
{
llGiveInventory(kAv, "Master Key");
break;
}
}
break;
}
case "menu~help":
{
iMenu=6;
switch(sReply)
{
case "main..":
{
iMenu=1;
break;
}
case "Restart":
{
iRespring=0;
llMessageLinked(LINK_SET,0, llList2Json(JSON_OBJECT, ["cmd", "reset"]), "");
break;
}
}
break;
}
case "access~passwd":
{
iMenu = 2;
if(sReply != "-1") // Cancel
{
llMessageLinked(LINK_SET, 0, llList2Json(JSON_OBJECT, ["cmd", "set_master_password", "pwd", sReply]), kAv);
}
break;
}
case "access~addowner":
{
iRespring=0;
key kDecode = decodeAvatarInput(sReply, kAv);
if(kDecode != NULL_KEY)
{
iRespring=1;
iMenu = 2;
llMessageLinked(LINK_SET, 0, llList2Json(JSON_OBJECT, ["cmd", "add_owner", "id", kDecode]), kAv);
llRegionSayTo(kAv, 0, "Owner Added: " + SLURL(sReply));
}
break;
}
case "menu~remowner":
{
iMenu=2;
llMessageLinked(LINK_SET ,0, llList2Json(JSON_OBJECT, ["cmd", "rem_owner", "id", sReply]), "");
llRegionSayTo(kAv, 0, "Owner Removed: " + SLURL(sReply));
break;
}
}
if(iRespring){
call_menu(iMenu, kAv);
}
}
} else {
if(llJsonGetValue(m,["cmd"]) == "check_mode_back")
{
integer access = (integer)llJsonGetValue(m,["val"]);
if(access != 99){
string sPacket = llJsonGetValue(m,["callback"]);
if(llGetScriptName() == llJsonGetValue(sPacket, ["script"]))
{
integer iMenu = (integer)llJsonGetValue(sPacket, ["id"]);
if(iMenu == 1)
Main(i, access);
if(iMenu == 2)
AccessMenu(i, access);
if(iMenu == 3)
NumberPad(i, "What should the new master password be?\n\nCurrent Value: " + llLinksetDataReadProtected("access_password", MASTER_CODE), "access~passwd", SetDSMeta([access]));
if(iMenu == 4)
GetArbitraryData(i, "Who do you want to add as owner?\n\nAccepts: SLURL, UUID, Legacy Name", "access~addowner", SetDSMeta([access]));
if(iMenu == 5)
RemoveOwnerMenu(i, access);
if(iMenu == 6)
HelpMenu(i, access);
}
}
else llRegionSayTo(i,0,"Access Denied");
} else if(llJsonGetValue(m,["cmd"]) == "reset")
{
llResetScript();
} else if(llJsonGetValue(m,["cmd"]) == "plugin_reply")
{
g_lPlugins += [llJsonGetValue(m,["name"])];
} else if(llJsonGetValue(m, ["cmd"]) == "pass_menu")
{
if(llJsonGetValue(m,["plugin"]) == "Main")
{
call_menu(1, i);
}
} else if(llJsonGetValue(m,["cmd"]) == "read_setitng_back")
{
string sSetting = llJsonGetValue(m,["setting"]);
string sValue = llJsonGetValue(m,["value"]);
switch(sSetting)
{
case "locked":
{
if(sValue == "")
{
llOwnerSay("@detach=y");
g_iLocked=0;
}else {
g_iLocked=1;
g_iLockedAuth = (integer)llJsonGetValue(sValue, ["level"]);
g_kLockedBy = llJsonGetValue(sValue, ["by"]);
}
break;
}
}
}
}
}
}

55
src/raw/Settings.lsl Normal file
View file

@ -0,0 +1,55 @@
#include "src/includes/common.lsl"
string sSetor(integer test, string a, string b)
{
if(test)return a;
return b;
}
default
{
state_entry()
{
llMessageLinked(LINK_SET, 10, "", "");
}
changed(integer c)
{
if(c&CHANGED_INVENTORY)
{
llSleep(2);
llMessageLinked(LINK_SET, 10, "", "");
}
}
link_message(integer s,integer n,string m,key i)
{
if(n == 0)
{
if(llJsonGetValue(m,["cmd"]) == "reset")
{
llResetScript();
} else if(llJsonGetValue(m,["cmd"]) == "write_setting")
{
llLinksetDataWriteProtected(llJsonGetValue(m,["name"]), llJsonGetValue(m,["value"]), MASTER_CODE);
llMessageLinked(LINK_SET, 0, llList2Json(JSON_OBJECT, ["cmd", "read_setting_back", "setting", llJsonGetValue(m,["name"]), "value", llJsonGetValue(m,["value"])]), "");
} else if(llJsonGetValue(m,["cmd"]) == "read_setting")
{
string reply = llLinksetDataReadProtected(llJsonGetValue(m,["name"]), MASTER_CODE);
llMessageLinked(LINK_SET, 0, llList2Json(JSON_OBJECT, ["cmd", "read_setting_back", "setting", llJsonGetValue(m,["name"]), "value", sSetor((reply==""), llJsonGetValue(m,["default"]), reply)]), "");
} else if(llJsonGetValue(m,["cmd"]) == "delete_setting")
{
llLinksetDataDeleteProtected(llJsonGetValue(m,["name"]), MASTER_CODE);
llMessageLinked(LINK_SET, 0, llList2Json(JSON_OBJECT, ["cmd", "read_setting_back", "setting", llJsonGetValue(m,["name"]), "value", llJsonGetValue(m,["default"])]), "");
}
} else if(n == 11)
{
llMessageLinked(LINK_SET, 10, "", "");
}
}
}

1
src/scripts/Access.lsl Normal file
View file

@ -0,0 +1 @@
#include "src/raw/Access.lsl"

1
src/scripts/Debug.lsl Normal file
View file

@ -0,0 +1 @@
#include "src/raw/Debug.lsl"

View file

@ -0,0 +1 @@
#include "src/raw/Dialog Module.lsl"

1
src/scripts/Leash.lsl Normal file
View file

@ -0,0 +1 @@
#include "src/raw/Leash.lsl"

1
src/scripts/Menu.lsl Normal file
View file

@ -0,0 +1 @@
#include "src/raw/Menu.lsl"

1
src/scripts/Settings.lsl Normal file
View file

@ -0,0 +1 @@
#include "src/raw/Settings.lsl"

149
src/spare/template.lsl Normal file
View file

@ -0,0 +1,149 @@
#include "ZNICommon.lsl"
string PLUGIN_NAME = "Example";
// Link Commands
integer LINK_MENU_DISPLAY = 300;
integer LINK_MENU_CLOSE = 310;
integer LINK_MENU_RETURN = 320;
integer LINK_MENU_TIMEOUT = 330;
integer LINK_MENU_CHANNEL = 303; // Returns from the dialog module to inform what the channel is
integer LINK_MENU_ONLYCHANNEL = 302; // Sent with a ident to make a channel. No dialog will pop up, and it will expire just like any other menu if input is not received.
string BACK = "<<";
string FORWARD = ">>";
list MENU_NAVIGATE_BUTTONS = [" ", " ", "-exit-"];
Menu(key kAv, string sText, list lButtons, string sIdent, string sExtra, list lCompanionText)
{
llMessageLinked(LINK_THIS, LINK_MENU_DISPLAY, llDumpList2String([sIdent, "TRUE", sText, llDumpList2String(lButtons, "~"), "", sExtra, "", llDumpList2String(lCompanionText, "~"), BACK, FORWARD, llDumpList2String(MENU_NAVIGATE_BUTTONS, "~")], "|"), kAv);
}
MenuNoUtility(key kAv, string sText, list lButtons, string sIdent, string sExtra, list lCompanionText)
{
llMessageLinked(LINK_THIS, LINK_MENU_DISPLAY, llDumpList2String([sIdent, "TRUE", sText, llDumpList2String(lButtons, "~"), "", sExtra, "NOUTIL", llDumpList2String(lCompanionText, "~"), BACK, FORWARD, llDumpList2String(MENU_NAVIGATE_BUTTONS, "~")], "|"), kAv);
}
GetArbitraryData(key kAv, string sText, string sIdent, string sExtra){
llMessageLinked(LINK_THIS, LINK_MENU_DISPLAY, llDumpList2String([sIdent, "FALSE", sText, "", "", sExtra, "", "", BACK, FORWARD, llDumpList2String(MENU_NAVIGATE_BUTTONS, "~")], "|"), kAv);
}
GetListenerChannel(string sIdent)
{
llMessageLinked(LINK_THIS, LINK_MENU_ONLYCHANNEL, sIdent, sIdent);
}
NumberPad(key kAv, string sText, string sIdent, string sExtra)
{
llMessageLinked(LINK_THIS, LINK_MENU_DISPLAY, llDumpList2String([sIdent, "TRUE", sText, "numpadplz", "", sExtra, "NOUTIL", "", BACK, FORWARD, llDumpList2String(MENU_NAVIGATE_BUTTONS, "~")], "|"), kAv);
}
call_menu(integer id, key kAv)
{
llMessageLinked(LINK_SET, 0, llList2Json(JSON_OBJECT, ["cmd", "check_mode", "callback", llList2Json(JSON_OBJECT, ["script", llGetScriptName(), "id", id])]), kAv);
}
Main(key kID, integer iAuth)
{
list lMenu = ["main.."];
list lHelper = [];
string sText = "Example Menu";
Menu(kID, sText, lMenu, "menu~example", SetDSMeta([iAuth]), lHelper);
}
default
{
state_entry()
{
// Load settings here
}
link_message(integer s,integer n,string m,key i)
{
if(n==0)
{
if(llJsonGetValue(m,["cmd"]) == "reset")
{
llResetScript();
} else if(llJsonGetValue(m,["cmd"]) == "scan_plugins")
{
llMessageLinked(LINK_SET,0,llList2Json(JSON_OBJECT, ["cmd", "plugin_reply", "name", PLUGIN_NAME]), "");
} else if(llJsonGetValue(m,["cmd"]) == "pass_menu")
{
if(llJsonGetValue(m,["plugin"]) == PLUGIN_NAME)
call_menu(1, i);
} else if(llJsonGetValue(m,["cmd"]) == "check_mode_back")
{
integer access = (integer)llJsonGetValue(m,["val"]);
if(access != 99){
string sPacket = llJsonGetValue(m,["callback"]);
if(llGetScriptName() == llJsonGetValue(sPacket, ["script"]))
{
integer iMenu = (integer)llJsonGetValue(sPacket, ["id"]);
if(iMenu == 1)
Main(i, access);
}
}
else llRegionSayTo(i,0,"Access Denied");
}
}else if(n == LINK_MENU_CHANNEL)
{
if(i == "ident")
{
//channel = m
}
}else if(n == LINK_MENU_RETURN)
{
if(llJsonGetValue(m, ["type"]) == "menu_back")
{
string sIdent = llJsonGetValue(m,["id"]);
key kAv = i;
string sReply = llJsonGetValue(m,["reply"]);
string sExtra = llJsonGetValue(m,["extra"]);
list lExtra = llParseString2List(sExtra, [":"],[]);
integer iAuth = (integer)llList2String(lExtra,0);
integer iRespring=1;
integer iMenu;
if(sReply == "-exit-")
{
return;
}
switch(sIdent)
{
case "menu~example":
{
iMenu = 1;
switch(sReply)
{
case "main..":
{
iRespring=0;
llMessageLinked(LINK_SET, 0, llList2Json(JSON_OBJECT, ["cmd", "pass_menu", "plugin", "Main"]), kAv);
break;
}
}
break;
}
}
if(iRespring)
{
call_menu(iMenu, kAv);
}
}
}
}
}