/source/eggdrop/IM.lsl |
@@ -0,0 +1,578 @@ |
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2018 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// |
// An instant message sending module for Corrade Eggdrop. |
// |
/////////////////////////////////////////////////////////////////////////// |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
/////////////////////////////////////////////////////////////////////////// |
string wasKeyValueGet(string k, string data) { |
if(llStringLength(data) == 0) return ""; |
if(llStringLength(k) == 0) return ""; |
list a = llParseStringKeepNulls(data, ["&", "="], []); |
integer i = llListFindList(llList2ListStrided(a, 0, -1, 2), [ k ]); |
if(i != -1) return llList2String(a, 2*i+1); |
return ""; |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasKeyValueEncode(list data) { |
list k = llList2ListStrided(data, 0, -1, 2); |
list v = llList2ListStrided(llDeleteSubList(data, 0, 0), 0, -1, 2); |
data = []; |
do { |
data += llList2String(k, 0) + "=" + llList2String(v, 0); |
k = llDeleteSubList(k, 0, 0); |
v = llDeleteSubList(v, 0, 0); |
} while(llGetListLength(k) != 0); |
return llDumpList2String(data, "&"); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// http://was.fm/secondlife/wanderer |
vector wasCirclePoint(float radius) { |
float x = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2); |
float y = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2); |
if(llPow(x,2) + llPow(y,2) <= llPow(radius,2)) |
return <x, y, 0>; |
return wasCirclePoint(radius); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// escapes a string in conformance with RFC1738 |
string wasURLEscape(string i) { |
string o = ""; |
do { |
string c = llGetSubString(i, 0, 0); |
i = llDeleteSubString(i, 0, 0); |
if(c == "") jump continue; |
if(c == " ") { |
o += "+"; |
jump continue; |
} |
if(c == "\n") { |
o += "%0D" + llEscapeURL(c); |
jump continue; |
} |
o += llEscapeURL(c); |
@continue; |
} while(i != ""); |
return o; |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
list wasCSVToList(string csv) { |
list l = []; |
list s = []; |
string m = ""; |
do { |
string a = llGetSubString(csv, 0, 0); |
csv = llDeleteSubString(csv, 0, 0); |
if(a == ",") { |
if(llList2String(s, -1) != "\"") { |
l += m; |
m = ""; |
jump continue; |
} |
m += a; |
jump continue; |
} |
if(a == "\"" && llGetSubString(csv, 0, 0) == a) { |
m += a; |
csv = llDeleteSubString(csv, 0, 0); |
jump continue; |
} |
if(a == "\"") { |
if(llList2String(s, -1) != a) { |
s += a; |
jump continue; |
} |
s = llDeleteSubList(s, -1, -1); |
jump continue; |
} |
m += a; |
@continue; |
} while(csv != ""); |
// postcondition: length(s) = 0 |
return l + m; |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasListToCSV(list l) { |
list v = []; |
do { |
string a = llDumpList2String( |
llParseStringKeepNulls( |
llList2String( |
l, |
0 |
), |
["\""], |
[] |
), |
"\"\"" |
); |
if(llParseStringKeepNulls( |
a, |
[" ", ",", "\n", "\""], [] |
) != |
(list) a |
) a = "\"" + a + "\""; |
v += a; |
l = llDeleteSubList(l, 0, 0); |
} while(l != []); |
return llDumpList2String(v, ","); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// unescapes a string in conformance with RFC1738 |
string wasURLUnescape(string i) { |
return llUnescapeURL( |
llDumpList2String( |
llParseString2List( |
llDumpList2String( |
llParseString2List( |
i, |
["+"], |
[] |
), |
" " |
), |
["%0D%0A"], |
[] |
), |
"\n" |
) |
); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
list wasSetIntersect(list a, list b) { |
if(llGetListLength(a) == 0) return []; |
string i = llList2String(a, 0); |
a = llDeleteSubList(a, 0, 0); |
if(llListFindList(b, (list)i) == -1) |
return wasSetIntersect(a, b); |
return i + wasSetIntersect(a, b); |
} |
|
// configuration data |
string configuration = ""; |
// store message over state. |
string src_firstname = ""; |
string src_lastname = ""; |
string dst_firstname = ""; |
string dst_lastname = ""; |
string data = ""; |
|
default { |
state_entry() { |
llOwnerSay("[IM] Starting module..."); |
llSetTimerEvent(10); |
} |
link_message(integer sender, integer num, string message, key id) { |
if(id != "configuration") return; |
llOwnerSay("[IM] Got configuration..."); |
configuration = message; |
state listen_group; |
} |
timer() { |
llOwnerSay("[IM] Requesting configuration..."); |
llMessageLinked(LINK_THIS, 0, "configuration", NULL_KEY); |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
state_exit() { |
llSetTimerEvent(0); |
} |
} |
|
state listen_group { |
state_entry() { |
// DEBUG |
llOwnerSay("[IM] Waiting for group messages."); |
} |
link_message(integer sender, integer num, string message, key id) { |
// We only care about notifications now. |
if(id != "notification") |
return; |
|
// This script only processes group notifications. |
if(wasKeyValueGet("type", message) != "group" || |
(wasKeyValueGet("type", message) == "group" && |
wasURLUnescape(wasKeyValueGet("group", message)) != |
wasKeyValueGet("group", configuration))) |
return; |
|
// Get the message sender. |
src_firstname = wasURLUnescape( |
wasKeyValueGet( |
"firstname", |
message |
) |
); |
|
src_lastname = wasURLUnescape( |
wasKeyValueGet( |
"lastname", |
message |
) |
); |
|
// Get the sent message. |
data = wasURLUnescape( |
wasKeyValueGet( |
"message", |
message |
) |
); |
|
// Check if this is an eggdrop command. |
if(llGetSubString(data, 0, 0) != |
wasKeyValueGet("command", configuration)) |
return; |
|
// Check if the command matches the current module. |
list command = llParseString2List(data, [" "], []); |
if(llList2String(command, 0) != |
wasKeyValueGet("command", configuration) + "im") |
return; |
|
// Remove command. |
command = llDeleteSubList(command, 0, 0); |
|
// Retrieve the first and last name to remind. |
dst_firstname = llList2String(command, 0); |
command = llDeleteSubList(command, 0, 0); |
dst_lastname = llList2String(command, 0); |
command = llDeleteSubList(command, 0, 0); |
|
if(llStringLength(dst_firstname) == 0 || |
llStringLength(dst_lastname) == 0) { |
data = "Invalid avatar name, please use the full username!"; |
state tell; |
} |
|
// Retrieve the message to remind of. |
data = llDumpList2String(command, " "); |
if(llStringLength(message) == 0) { |
data = "No message to send supplied. . ."; |
state tell; |
} |
// Get roles of caller. |
state get_caller_roles; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
state_exit() { |
llSetTimerEvent(0); |
} |
} |
|
state get_caller_roles { |
state_entry() { |
// DEBUG |
llOwnerSay("[IM] Searching for caller..."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
configuration |
), |
wasKeyValueEncode( |
[ |
"command", "getmemberroles", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
configuration |
) |
), |
"firstname", src_firstname, |
"lastname", src_lastname, |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
) |
); |
llSetTimerEvent(60); |
} |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "getmemberroles") |
return; |
|
if(wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[IM] Unable to get member roles: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
); |
state listen_group; |
} |
|
// Dump the roles to a list. |
list roles = wasCSVToList( |
wasURLUnescape( |
wasKeyValueGet("data", body) |
) |
); |
|
if(llGetListLength( |
wasSetIntersect(roles, |
wasCSVToList( |
wasKeyValueGet( |
"admin roles", configuration |
) |
) |
) |
) == 0) { |
data = "You ain't got the cojones!"; |
state tell; |
} |
|
state get_avatar_key; |
} |
timer() { |
state listen_group; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
state_exit() { |
llSetTimerEvent(0); |
} |
} |
|
state get_avatar_key { |
state_entry() { |
// DEBUG |
llOwnerSay("[IM] Searching for avatar key..."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
configuration |
), |
wasKeyValueEncode( |
[ |
"command", "batchavatarnametokey", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
configuration |
) |
), |
"avatars", wasListToCSV([ |
dst_firstname + " " + dst_lastname |
]), |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
) |
); |
llSetTimerEvent(60); |
} |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "batchavatarnametokey") |
return; |
|
if(wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[IM] Unable to get avatar key: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
); |
data = "Avatar not found!"; |
state tell; |
} |
|
state im; |
} |
timer() { |
state listen_group; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
state_exit() { |
llSetTimerEvent(0); |
} |
} |
|
state im { |
state_entry() { |
// DEBUG |
llOwnerSay("[IM] Sending message..."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
configuration |
), |
wasKeyValueEncode( |
[ |
"command", "tell", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
configuration |
) |
), |
"entity", "avatar", |
"firstname", dst_firstname, |
"lastname", dst_lastname, |
"message", wasURLEscape(data), |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
) |
); |
llSetTimerEvent(60); |
} |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "tell") |
return; |
|
if(wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[IM] Unable to send message: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
); |
data = "Message could not be sent!"; |
state tell; |
} |
|
data = "Message sent!"; |
state tell; |
} |
timer() { |
state listen_group; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
state_exit() { |
llSetTimerEvent(0); |
} |
} |
|
state tell { |
state_entry() { |
// DEBUG |
llOwnerSay("[IM] Sending to group."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
configuration |
), |
wasKeyValueEncode( |
[ |
"command", "tell", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
configuration |
) |
), |
"entity", "group", |
"message", wasURLEscape(data) |
] |
) |
); |
state listen_group; |
} |
} |
/source/eggdrop/ban.lsl |
@@ -1,5 +1,5 @@ |
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2016 - License: CC BY 2.0 // |
// Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// |
// A module that bans group members using fuzzy name matching. |
@@ -17,9 +17,9 @@ |
if(i != -1) return llList2String(a, 2*i+1); |
return ""; |
} |
|
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2013 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasKeyValueEncode(list data) { |
list k = llList2ListStrided(data, 0, -1, 2); |
@@ -34,7 +34,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2011 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// http://was.fm/secondlife/wanderer |
vector wasCirclePoint(float radius) { |
@@ -46,7 +46,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// escapes a string in conformance with RFC1738 |
string wasURLEscape(string i) { |
@@ -70,7 +70,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
list wasCSVToList(string csv) { |
list l = []; |
@@ -109,7 +109,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasListToCSV(list l) { |
list v = []; |
@@ -117,18 +117,18 @@ |
string a = llDumpList2String( |
llParseStringKeepNulls( |
llList2String( |
l, |
l, |
0 |
), |
["\""], |
), |
["\""], |
[] |
), |
"\"\"" |
); |
if(llParseStringKeepNulls( |
a, |
a, |
[" ", ",", "\n", "\""], [] |
) != |
) != |
(list) a |
) a = "\"" + a + "\""; |
v += a; |
@@ -138,7 +138,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// unescapes a string in conformance with RFC1738 |
string wasURLUnescape(string i) { |
@@ -147,15 +147,15 @@ |
llParseString2List( |
llDumpList2String( |
llParseString2List( |
i, |
["+"], |
i, |
["+"], |
[] |
), |
), |
" " |
), |
["%0D%0A"], |
), |
["%0D%0A"], |
[] |
), |
), |
"\n" |
) |
); |
@@ -162,7 +162,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2017 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
list wasSetIntersect(list a, list b) { |
if(llGetListLength(a) == 0) return []; |
@@ -175,8 +175,6 @@ |
|
// configuration data |
string configuration = ""; |
// callback URL |
string URL = ""; |
// store message over state. |
string data = ""; |
// banee |
@@ -203,8 +201,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -223,70 +221,48 @@ |
// We only care about notifications now. |
if(id != "notification") |
return; |
|
|
// This script only processes group notifications. |
if(wasKeyValueGet("type", message) != "group") |
if(wasKeyValueGet("type", message) != "group" || |
(wasKeyValueGet("type", message) == "group" && |
wasURLUnescape(wasKeyValueGet("group", message)) != |
wasKeyValueGet("group", configuration))) |
return; |
|
|
// Get the sent message. |
data = wasURLUnescape( |
wasKeyValueGet( |
"message", |
"message", |
message |
) |
); |
|
|
// Check if this is an eggdrop command. |
if(llGetSubString(data, 0, 0) != |
if(llGetSubString(data, 0, 0) != |
wasKeyValueGet("command", configuration)) |
return; |
|
|
// Check if the command matches the current module. |
list command = llParseString2List(data, [" "], []); |
if(llList2String(command, 0) != |
if(llList2String(command, 0) != |
wasKeyValueGet("command", configuration) + "ban") |
return; |
|
|
// Remove command. |
command = llDeleteSubList(command, 0, 0); |
|
|
firstname = wasKeyValueGet("firstname", message); |
lastname = wasKeyValueGet("lastname", message); |
|
|
if(firstname == "" || lastname == "") { |
data = "And who would yarr be?"; |
state tell; |
} |
|
|
// Dump the rest of the message. |
data = llDumpList2String(command, " "); |
|
// Get an URL. |
state url; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
} |
|
state url { |
state_entry() { |
// DEBUG |
llOwnerSay("[Ban] Requesting URL..."); |
llRequestURL(); |
} |
http_request(key id, string method, string body) { |
if(method != URL_REQUEST_GRANTED) return; |
URL = body; |
// DEBUG |
llOwnerSay("[Ban] Got URL..."); |
// Get roles of caller. |
state get_caller_roles; |
} |
on_rez(integer num) { |
@@ -293,8 +269,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -307,46 +283,54 @@ |
llOwnerSay("[Ban] Searching for caller..."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
), |
wasKeyValueEncode( |
[ |
"command", "getmemberroles", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |
"firstname", firstname, |
"lastname", lastname, |
"callback", wasURLEscape(URL) |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
) |
); |
|
llSetTimerEvent(60); |
} |
http_request(key id, string method, string body) { |
llHTTPResponse(id, 200, "OK"); |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "getmemberroles") |
return; |
|
if(wasKeyValueGet("command", body) != "getmemberroles" || |
wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[Ban] Unable to get member roles: " + |
llOwnerSay("[Ban] Unable to get member roles: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
); |
llReleaseURL(URL); |
state listen_group; |
} |
|
|
// Dump the roles to a list. |
list roles = wasCSVToList( |
wasURLUnescape( |
@@ -353,9 +337,9 @@ |
wasKeyValueGet("data", body) |
) |
); |
|
|
if(llGetListLength( |
wasSetIntersect(roles, |
wasSetIntersect(roles, |
wasCSVToList( |
wasKeyValueGet( |
"admin roles", configuration |
@@ -364,34 +348,32 @@ |
) |
) == 0) { |
data = "You ain't got the cojones!"; |
llReleaseURL(URL); |
state tell; |
} |
|
|
list banee = llParseString2List(data, [" "], []); |
|
|
firstname = llList2String(banee, 0); |
banee = llDeleteSubList(banee, 0, 0); |
lastname = llList2String(banee, 0); |
banee = llDeleteSubList(banee, 0, 0); |
|
|
if(firstname == "" || lastname == "") { |
data = "Full name required."; |
state tell; |
} |
|
if(llGetListLength(banee) != 0 && |
|
if(llGetListLength(banee) != 0 && |
llToLower(llList2String(banee, 0)) == "nosoft") { |
soft = "False"; |
banee = llDeleteSubList(banee, 0, 0); |
} |
|
|
// GC |
banee = []; |
state get_banee_roles; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
@@ -398,8 +380,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -415,36 +397,43 @@ |
llOwnerSay("[Ban] Searching for banee..."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
), |
wasKeyValueEncode( |
[ |
"command", "getmemberroles", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |
"firstname", firstname, |
"lastname", lastname, |
"callback", wasURLEscape(URL) |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
) |
); |
llSetTimerEvent(60); |
} |
http_request(key id, string method, string body) { |
llHTTPResponse(id, 200, "OK"); |
if(wasKeyValueGet("command", body) != "getmemberroles" || |
wasKeyValueGet("success", body) != "True") { |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "getmemberroles") |
return; |
|
if(wasKeyValueGet("success", body) != "True") { |
if(wasKeyValueGet("status", body) == "19862") { |
// DEBUG |
llOwnerSay("[Ban] User not in group, but proceeding anyway..."); |
@@ -451,30 +440,27 @@ |
jump continue; |
} |
// DEBUG |
llOwnerSay("[Ban] Unable to get member roles: " + |
llOwnerSay("[Ban] Unable to get member roles: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
); |
llReleaseURL(URL); |
state listen_group; |
} |
|
|
@continue; |
string result = wasURLUnescape( |
wasKeyValueGet("data", body) |
); |
|
|
if(result != "" && llListFindList(wasCSVToList(result), (list)"Owners") != -1) { |
data = "Ejectee is an owner. I'm not gunna open the pod bay doors."; |
llReleaseURL(URL); |
state tell; |
} |
|
|
state ban; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
@@ -481,8 +467,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -498,21 +484,21 @@ |
llOwnerSay("[Ban] Banning..."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
), |
wasKeyValueEncode( |
[ |
"command", "ban", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |
@@ -526,19 +512,26 @@ |
) |
), |
"eject", "True", |
"callback", wasURLEscape(URL) |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
) |
); |
llSetTimerEvent(60); |
} |
http_request(key id, string method, string body) { |
llHTTPResponse(id, 200, "OK"); |
llReleaseURL(URL); |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "ban") |
return; |
|
if(wasKeyValueGet("command", body) != "ban" || |
wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[Ban] Unable to ban member: " + |
llOwnerSay("[Ban] Unable to ban member: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
@@ -545,13 +538,12 @@ |
); |
state listen_group; |
} |
|
|
data = "Hasta la vista, baby!"; |
|
|
state tell; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
@@ -558,8 +550,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -575,21 +567,21 @@ |
llOwnerSay("[Ban] Sending to group."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
), |
wasKeyValueEncode( |
[ |
"command", "tell", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |
@@ -598,10 +590,10 @@ |
] |
) |
); |
|
|
// reset variables. |
soft = "True"; |
|
|
state listen_group; |
} |
} |
/source/eggdrop/control.lsl |
@@ -1,5 +1,5 @@ |
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2016 - License: CC BY 2.0 // |
// Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// |
// An eggdrop-like group bot using Corrade. |
@@ -17,10 +17,52 @@ |
if(i != -1) return llList2String(a, 2*i+1); |
return ""; |
} |
|
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2013 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2014 Wizardry and Steamworks - License: CC BY 2.0 // |
/////////////////////////////////////////////////////////////////////////// |
string wasKeyValueDelete(string k, string data) { |
if(llStringLength(data) == 0) return ""; |
if(llStringLength(k) == 0) return ""; |
integer i = llListFindList( |
llList2ListStrided( |
llParseString2List(data, ["&", "="], []), |
0, -1, 2 |
), |
[ k ]); |
if(i != -1) return llDumpList2String( |
llDeleteSubList( |
llParseString2List(data, ["&"], []), |
i, i), |
"&"); |
return data; |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2014 Wizardry and Steamworks - License: CC BY 2.0 // |
/////////////////////////////////////////////////////////////////////////// |
string wasKeyValueSet(string k, string v, string data) { |
if(llStringLength(k) == 0) return ""; |
if(llStringLength(v) == 0) return ""; |
if(llStringLength(data) == 0) return k + "=" + v; |
integer i = llListFindList( |
llList2ListStrided( |
llParseString2List(data, ["&", "="], []), |
0, -1, 2 |
), |
[ k ]); |
if(i != -1) return llDumpList2String( |
llListReplaceList( |
llParseString2List(data, ["&"], []), |
[ k + "=" + v ], |
i, i), |
"&"); |
return data + "&" + k + "=" + v; |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasKeyValueEncode(list data) { |
list k = llList2ListStrided(data, 0, -1, 2); |
list v = llList2ListStrided(llDeleteSubList(data, 0, 0), 0, -1, 2); |
@@ -34,7 +76,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// escapes a string in conformance with RFC1738 |
string wasURLEscape(string i) { |
@@ -58,7 +100,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// unescapes a string in conformance with RFC1738 |
string wasURLUnescape(string i) { |
@@ -67,15 +109,15 @@ |
llParseString2List( |
llDumpList2String( |
llParseString2List( |
i, |
["+"], |
i, |
["+"], |
[] |
), |
), |
" " |
), |
["%0D%0A"], |
), |
["%0D%0A"], |
[] |
), |
), |
"\n" |
) |
); |
@@ -82,7 +124,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasListToCSV(list l) { |
list v = []; |
@@ -90,18 +132,18 @@ |
string a = llDumpList2String( |
llParseStringKeepNulls( |
llList2String( |
l, |
l, |
0 |
), |
["\""], |
), |
["\""], |
[] |
), |
"\"\"" |
); |
if(llParseStringKeepNulls( |
a, |
a, |
[" ", ",", "\n", "\""], [] |
) != |
) != |
(list) a |
) a = "\"" + a + "\""; |
v += a; |
@@ -110,9 +152,48 @@ |
return llDumpList2String(v, ","); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
/////////////////////////////////////////////////////////////////////////// |
list wasCSVToList(string csv) { |
list l = []; |
list s = []; |
string m = ""; |
do { |
string a = llGetSubString(csv, 0, 0); |
csv = llDeleteSubString(csv, 0, 0); |
if(a == ",") { |
if(llList2String(s, -1) != "\"") { |
l += m; |
m = ""; |
jump continue; |
} |
m += a; |
jump continue; |
} |
if(a == "\"" && llGetSubString(csv, 0, 0) == a) { |
m += a; |
csv = llDeleteSubString(csv, 0, 0); |
jump continue; |
} |
if(a == "\"") { |
if(llList2String(s, -1) != a) { |
s += a; |
jump continue; |
} |
s = llDeleteSubList(s, -1, -1); |
jump continue; |
} |
m += a; |
@continue; |
} while(csv != ""); |
// postcondition: length(s) = 0 |
return l + m; |
} |
|
// for notecard reading |
integer line = 0; |
|
|
// key-value data will be read into this list |
list tuples = []; |
string configuration = ""; |
@@ -144,7 +225,7 @@ |
key CORRADE = llList2Key( |
tuples, |
llListFindList( |
tuples, |
tuples, |
[ |
"corrade" |
] |
@@ -157,7 +238,7 @@ |
string GROUP = llList2String( |
tuples, |
llListFindList( |
tuples, |
tuples, |
[ |
"group" |
] |
@@ -170,7 +251,7 @@ |
string PASSWORD = llList2String( |
tuples, |
llListFindList( |
tuples, |
tuples, |
[ |
"password" |
] |
@@ -183,7 +264,7 @@ |
string VERSION = llList2String( |
tuples, |
llListFindList( |
tuples, |
tuples, |
[ |
"version" |
] |
@@ -201,8 +282,9 @@ |
state request_url_notifications; |
} |
if(data == "") jump continue; |
// No support for inline comments for this one! Needs parsing! |
integer i = llSubStringIndex(data, "#"); |
if(i != -1) data = llDeleteSubString(data, i, -1); |
if(i == 0) data = llDeleteSubString(data, i, -1); |
list o = llParseString2List(data, ["="], []); |
// get rid of starting and ending quotes |
string k = llDumpList2String( |
@@ -209,10 +291,10 @@ |
llParseString2List( |
llStringTrim( |
llList2String( |
o, |
o, |
0 |
), |
STRING_TRIM), |
), |
STRING_TRIM), |
["\""], [] |
), "\""); |
string v = llDumpList2String( |
@@ -219,10 +301,10 @@ |
llParseString2List( |
llStringTrim( |
llList2String( |
o, |
o, |
1 |
), |
STRING_TRIM), |
), |
STRING_TRIM), |
["\""], [] |
), "\""); |
if(k == "" || v == "") jump continue; |
@@ -261,8 +343,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -275,21 +357,21 @@ |
llOwnerSay("[Control] Releasing notifications..."); |
llInstantMessage( |
(key)wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
), |
wasKeyValueEncode( |
[ |
"command", "notify", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |
@@ -296,7 +378,7 @@ |
"action", "remove", |
"tag", wasURLEscape( |
wasKeyValueGet( |
"notification tag", |
"notification tag", |
configuration |
) |
), |
@@ -311,7 +393,7 @@ |
if(wasKeyValueGet("command", body) != "notify" || |
wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[Control] Unable to release tag: " + |
llOwnerSay("[Control] Unable to release tag: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
@@ -328,8 +410,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -345,21 +427,21 @@ |
llOwnerSay("[Control] Binding to notifications..."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
), |
wasKeyValueEncode( |
[ |
"command", "notify", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |
@@ -372,7 +454,7 @@ |
"URL", wasURLEscape(URL), |
"tag", wasURLEscape( |
wasKeyValueGet( |
"notification tag", |
"notification tag", |
configuration |
) |
), |
@@ -387,7 +469,7 @@ |
if(wasKeyValueGet("command", body) != "notify" || |
wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[Control] Unable to bind notifications: " + |
llOwnerSay("[Control] Unable to bind notifications: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
@@ -394,7 +476,7 @@ |
); |
llResetScript(); |
} |
state serve_configuration; |
state version_check; |
} |
timer() { |
llOwnerSay("[Control] Timeout binding notifications"); |
@@ -404,8 +486,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -415,7 +497,7 @@ |
} |
} |
|
state serve_configuration { |
state version_check { |
state_entry() { |
// DEBUG |
llOwnerSay("[Control] Checking version..."); |
@@ -429,13 +511,13 @@ |
"command", "version", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |
@@ -448,16 +530,12 @@ |
http_request(key id, string method, string body) { |
llHTTPResponse(id, 200, "OK"); |
llSetTimerEvent(0); |
if(wasKeyValueGet("command", body) != "version") { |
llMessageLinked(LINK_THIS, 0, body, "notification"); |
return; |
} |
|
|
if(wasKeyValueGet("success", body) != "True") { |
llOwnerSay("[Control] Version check failed..."); |
return; |
} |
|
|
list v = llParseString2List( |
wasKeyValueGet( |
"data", |
@@ -485,19 +563,18 @@ |
" for this template." |
); |
compatible = FALSE; |
//llReleaseURL(URL); |
return; |
} |
|
// Add the URL to the configuration so it can be used for all components. |
configuration = wasKeyValueSet("URL", URL, configuration); |
|
// DEBUG |
llOwnerSay("[Control] Version is compatible!"); |
compatible = TRUE; |
//llReleaseURL(URL); |
return; |
|
state serve_configuration; |
} |
link_message(integer sender, integer num, string message, key id) { |
if(message != "configuration") return; |
llMessageLinked(LINK_THIS, 0, configuration, "configuration"); |
} |
timer() { |
llOwnerSay("[Control] Timeout checking version..."); |
llResetScript(); |
@@ -506,8 +583,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -516,3 +593,91 @@ |
llSetTimerEvent(0); |
} |
} |
|
state serve_configuration { |
state_entry() { |
// DEBUG |
llOwnerSay("[Control] Serving configuration and passing callbacks..."); |
} |
http_request(key id, string method, string body) { |
llHTTPResponse(id, 200, "OK"); |
|
if(wasKeyValueGet("command", body) != "") { |
llMessageLinked(LINK_THIS, 0, body, "callback"); |
return; |
} |
|
// Check if this group message is from Corrade and passed through Discord. |
if(wasKeyValueGet("type", body) == "group" && |
llToUpper(wasKeyValueGet("agent", body)) == llToUpper(wasKeyValueGet("corrade", configuration)) && |
llSubStringIndex(wasURLUnescape(wasKeyValueGet("message", body)), "[Discord]:") != -1) { |
|
// Split message in Discord discriminator and message body. |
list messageSplit = llParseString2List( |
wasURLUnescape( |
wasKeyValueGet("message", body) |
), |
["[Discord]:"], |
[] |
); |
|
// Retrive the Discord discriminator. |
string did = llStringTrim( |
llList2String( |
messageSplit, |
0 |
), |
STRING_TRIM |
); |
|
|
// Retrieve a list of Discord discriminator that are allowed to send administrative commands. |
list admins = wasCSVToList(wasKeyValueGet("discord admin", configuration)); |
|
// If the sender is not amongst the administrative Discord discriminators, then strip the agent details. |
if(llListFindList(admins, [ did ]) == -1) { |
// DEBUG |
llOwnerSay("[Control] Non admin, issuing command, strip the agent details from the command."); |
|
body = wasKeyValueDelete("firstname", body); |
body = wasKeyValueDelete("lastname", body); |
body = wasKeyValueDelete("agent", body); |
} |
|
// Pack the message back without the Discord discriminator identifier. |
body = wasKeyValueSet( |
"message", |
wasURLEscape( |
llStringTrim( |
llList2String( |
messageSplit, |
1 |
), |
STRING_TRIM |
) |
), |
body |
); |
} |
|
llMessageLinked(LINK_THIS, 0, body, "notification"); |
} |
link_message(integer sender, integer num, string message, key id) { |
if(message != "configuration") return; |
|
llMessageLinked(LINK_THIS, 0, configuration, "configuration"); |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
state_exit() { |
llSetTimerEvent(0); |
} |
} |
/source/eggdrop/dice.lsl |
@@ -1,5 +1,5 @@ |
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2016 - License: CC BY 2.0 // |
// Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// |
// A dice roll with a configurable range. |
@@ -17,9 +17,9 @@ |
if(i != -1) return llList2String(a, 2*i+1); |
return ""; |
} |
|
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2013 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasKeyValueEncode(list data) { |
list k = llList2ListStrided(data, 0, -1, 2); |
@@ -34,7 +34,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2011 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// http://was.fm/secondlife/wanderer |
vector wasCirclePoint(float radius) { |
@@ -46,7 +46,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// escapes a string in conformance with RFC1738 |
string wasURLEscape(string i) { |
@@ -70,7 +70,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
list wasCSVToList(string csv) { |
list l = []; |
@@ -109,7 +109,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasListToCSV(list l) { |
list v = []; |
@@ -117,18 +117,18 @@ |
string a = llDumpList2String( |
llParseStringKeepNulls( |
llList2String( |
l, |
l, |
0 |
), |
["\""], |
), |
["\""], |
[] |
), |
"\"\"" |
); |
if(llParseStringKeepNulls( |
a, |
a, |
[" ", ",", "\n", "\""], [] |
) != |
) != |
(list) a |
) a = "\"" + a + "\""; |
v += a; |
@@ -138,7 +138,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// unescapes a string in conformance with RFC1738 |
string wasURLUnescape(string i) { |
@@ -147,15 +147,15 @@ |
llParseString2List( |
llDumpList2String( |
llParseString2List( |
i, |
["+"], |
i, |
["+"], |
[] |
), |
), |
" " |
), |
["%0D%0A"], |
), |
["%0D%0A"], |
[] |
), |
), |
"\n" |
) |
); |
@@ -163,8 +163,6 @@ |
|
// configuration data |
string configuration = ""; |
// callback URL |
string URL = ""; |
// store message over state. |
string data = ""; |
|
@@ -187,8 +185,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -207,58 +205,61 @@ |
// We only care about notifications now. |
if(id != "notification") |
return; |
|
|
// This script only processes group notifications. |
if(wasKeyValueGet("type", message) != "group") |
if(wasKeyValueGet("type", message) != "group" || |
(wasKeyValueGet("type", message) == "group" && |
wasURLUnescape(wasKeyValueGet("group", message)) != |
wasKeyValueGet("group", configuration))) |
return; |
|
|
// Get the sent message. |
data = wasURLUnescape( |
wasKeyValueGet( |
"message", |
"message", |
message |
) |
); |
|
|
// Check if this is an eggdrop command. |
if(llGetSubString(data, 0, 0) != |
if(llGetSubString(data, 0, 0) != |
wasKeyValueGet("command", configuration)) |
return; |
|
|
// Check if the command matches the current module. |
list command = llParseString2List(data, [" "], []); |
if(llList2String(command, 0) != |
if(llList2String(command, 0) != |
wasKeyValueGet("command", configuration) + "roll") |
return; |
|
|
// Remove command. |
command = llDeleteSubList(command, 0, 0); |
|
|
list range = wasCSVToList( |
wasKeyValueGet("roll range", configuration) |
); |
|
|
integer roll = llList2Integer(command, 0); |
if(roll < llList2Integer(range, 0) || roll > llList2Integer(range, 1)) { |
data = "Value should be within bounds [" + |
llList2String(range, 0) + |
"," + |
data = "Value should be within bounds [" + |
llList2String(range, 0) + |
"," + |
llList2String(range, 1) + |
"]."; |
state tell; |
} |
|
|
data = wasKeyValueGet( |
"firstname", |
"firstname", |
message |
) + |
" " + |
wasKeyValueGet( |
"lastname", |
"lastname", |
message |
) + " rolls a " + |
) + " rolls a " + |
(string)((integer)(llFrand(roll + 1))); |
|
|
state tell; |
} |
on_rez(integer num) { |
@@ -265,8 +266,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -279,21 +280,21 @@ |
llOwnerSay("[Dice] Sending to group."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
), |
wasKeyValueEncode( |
[ |
"command", "tell", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |
/source/eggdrop/eval.lsl |
@@ -1,5 +1,5 @@ |
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2016 - License: CC BY 2.0 // |
// Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// |
// A module that evaluates a mathematical expression for Corrade Eggdrop. |
@@ -17,9 +17,9 @@ |
if(i != -1) return llList2String(a, 2*i+1); |
return ""; |
} |
|
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2013 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasKeyValueEncode(list data) { |
list k = llList2ListStrided(data, 0, -1, 2); |
@@ -34,7 +34,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2011 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// http://was.fm/secondlife/wanderer |
vector wasCirclePoint(float radius) { |
@@ -46,7 +46,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// escapes a string in conformance with RFC1738 |
string wasURLEscape(string i) { |
@@ -70,7 +70,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
list wasCSVToList(string csv) { |
list l = []; |
@@ -109,7 +109,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasListToCSV(list l) { |
list v = []; |
@@ -117,18 +117,18 @@ |
string a = llDumpList2String( |
llParseStringKeepNulls( |
llList2String( |
l, |
l, |
0 |
), |
["\""], |
), |
["\""], |
[] |
), |
"\"\"" |
); |
if(llParseStringKeepNulls( |
a, |
a, |
[" ", ",", "\n", "\""], [] |
) != |
) != |
(list) a |
) a = "\"" + a + "\""; |
v += a; |
@@ -138,7 +138,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// unescapes a string in conformance with RFC1738 |
string wasURLUnescape(string i) { |
@@ -147,15 +147,15 @@ |
llParseString2List( |
llDumpList2String( |
llParseString2List( |
i, |
["+"], |
i, |
["+"], |
[] |
), |
), |
" " |
), |
["%0D%0A"], |
["%0D%0A"], |
[] |
), |
), |
"\n" |
) |
); |
@@ -168,7 +168,7 @@ |
if(llGetListLength(lst)<=1) return lst; |
return wasListReverse(llList2List(lst, 1, llGetListLength(lst))) + llList2List(lst,0,0); |
} |
|
|
////////////////////////////////////////////////////////// |
// Deletes elements delete from list input. |
////////////////////////////////////////////////////////// |
@@ -185,7 +185,7 @@ |
} while(delete = llDeleteSubList(delete, 0, 0)); |
return input; |
} |
|
|
////////////////////////////////////////////////////////// |
// Returns a list of operators and operands. |
////////////////////////////////////////////////////////// |
@@ -194,7 +194,7 @@ |
list result = llParseString2List(input, [], op); |
return wasSubtractSubList(result, [" "]); |
} |
|
|
////////////////////////////////////////////////////////// |
// Transforms an infix expression to a postfix expression. |
////////////////////////////////////////////////////////// |
@@ -235,9 +235,9 @@ |
@continue; |
} while(llGetListLength(infix) != 0); |
result += wasListReverse(opStack); |
return result; |
return result; |
} |
|
|
////////////////////////////////////////////////////////// |
// Evaluate a postfix expression. |
////////////////////////////////////////////////////////// |
@@ -326,8 +326,6 @@ |
|
// configuration data |
string configuration = ""; |
// callback URL |
string URL = ""; |
// store message over state. |
string data = ""; |
|
@@ -355,8 +353,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -375,33 +373,36 @@ |
// We only care about notifications now. |
if(id != "notification") |
return; |
|
|
// This script only processes group notifications. |
if(wasKeyValueGet("type", message) != "group") |
if(wasKeyValueGet("type", message) != "group" || |
(wasKeyValueGet("type", message) == "group" && |
wasURLUnescape(wasKeyValueGet("group", message)) != |
wasKeyValueGet("group", configuration))) |
return; |
|
|
// Get the sent message. |
data = wasURLUnescape( |
wasKeyValueGet( |
"message", |
"message", |
message |
) |
); |
|
|
// Check if this is an eggdrop command. |
if(llGetSubString(data, 0, 0) != |
if(llGetSubString(data, 0, 0) != |
wasKeyValueGet("command", configuration)) |
return; |
|
|
// Check if the command matches the current module. |
list command = llParseString2List(data, [" "], []); |
if(llList2String(command, 0) != |
if(llList2String(command, 0) != |
wasKeyValueGet("command", configuration) + "eval") |
return; |
|
|
// Remove command. |
command = llDeleteSubList(command, 0, 0); |
|
|
// Dump the rest of the message. |
data = (string)wasPostfixEval( |
wasInfixToPostfix( |
@@ -413,7 +414,7 @@ |
) |
) |
); |
|
|
state tell; |
} |
on_rez(integer num) { |
@@ -420,8 +421,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -434,21 +435,21 @@ |
llOwnerSay("[Eval] Sending to group."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
), |
wasKeyValueEncode( |
[ |
"command", "tell", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |
/source/eggdrop/fortune.lsl |
@@ -1,5 +1,5 @@ |
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2016 - License: CC BY 2.0 // |
// Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// |
// A fortune module for Corrade Eggdrop. |
@@ -17,9 +17,9 @@ |
if(i != -1) return llList2String(a, 2*i+1); |
return ""; |
} |
|
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2013 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasKeyValueEncode(list data) { |
list k = llList2ListStrided(data, 0, -1, 2); |
@@ -34,7 +34,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2011 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// http://was.fm/secondlife/wanderer |
vector wasCirclePoint(float radius) { |
@@ -46,7 +46,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// escapes a string in conformance with RFC1738 |
string wasURLEscape(string i) { |
@@ -70,7 +70,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
list wasCSVToList(string csv) { |
list l = []; |
@@ -109,7 +109,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasListToCSV(list l) { |
list v = []; |
@@ -117,18 +117,18 @@ |
string a = llDumpList2String( |
llParseStringKeepNulls( |
llList2String( |
l, |
l, |
0 |
), |
["\""], |
), |
["\""], |
[] |
), |
"\"\"" |
); |
if(llParseStringKeepNulls( |
a, |
a, |
[" ", ",", "\n", "\""], [] |
) != |
) != |
(list) a |
) a = "\"" + a + "\""; |
v += a; |
@@ -138,7 +138,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// unescapes a string in conformance with RFC1738 |
string wasURLUnescape(string i) { |
@@ -147,15 +147,15 @@ |
llParseString2List( |
llDumpList2String( |
llParseString2List( |
i, |
["+"], |
i, |
["+"], |
[] |
), |
), |
" " |
), |
["%0D%0A"], |
), |
["%0D%0A"], |
[] |
), |
), |
"\n" |
) |
); |
@@ -192,8 +192,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -229,8 +229,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -246,41 +246,44 @@ |
// We only care about notifications now. |
if(id != "notification") |
return; |
|
|
// This script only processes group notifications. |
if(wasKeyValueGet("type", message) != "group") |
if(wasKeyValueGet("type", message) != "group" || |
(wasKeyValueGet("type", message) == "group" && |
wasURLUnescape(wasKeyValueGet("group", message)) != |
wasKeyValueGet("group", configuration))) |
return; |
|
|
// Get the sent message. |
data = wasURLUnescape( |
wasKeyValueGet( |
"message", |
"message", |
message |
) |
); |
|
|
// Check if this is an eggdrop command. |
if(llGetSubString(data, 0, 0) != |
if(llGetSubString(data, 0, 0) != |
wasKeyValueGet("command", configuration)) |
return; |
|
|
// Check if the command matches the current module. |
list command = llParseString2List(data, [" "], []); |
if(llList2String(command, 0) != |
if(llList2String(command, 0) != |
wasKeyValueGet("command", configuration) + "fortune") |
return; |
|
|
// Remove command. |
command = llDeleteSubList(command, 0, 0); |
|
|
data = llList2String( |
nList, |
nList, |
(integer) |
llFrand( |
llGetListLength(nList) |
) |
); |
|
|
state tell; |
} |
on_rez(integer num) { |
@@ -287,8 +290,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -301,21 +304,21 @@ |
llOwnerSay("[Fortune] Sending to group."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
), |
wasKeyValueEncode( |
[ |
"command", "tell", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |
/source/eggdrop/heartbeat.lsl |
@@ -17,7 +17,7 @@ |
if(i != -1) return llList2String(a, 2*i+1); |
return ""; |
} |
|
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2013 Wizardry and Steamworks - License: CC BY 2.0 // |
/////////////////////////////////////////////////////////////////////////// |
@@ -117,18 +117,18 @@ |
string a = llDumpList2String( |
llParseStringKeepNulls( |
llList2String( |
l, |
l, |
0 |
), |
["\""], |
), |
["\""], |
[] |
), |
"\"\"" |
); |
if(llParseStringKeepNulls( |
a, |
a, |
[" ", ",", "\n", "\""], [] |
) != |
) != |
(list) a |
) a = "\"" + a + "\""; |
v += a; |
@@ -147,15 +147,15 @@ |
llParseString2List( |
llDumpList2String( |
llParseString2List( |
i, |
["+"], |
i, |
["+"], |
[] |
), |
), |
" " |
), |
["%0D%0A"], |
), |
["%0D%0A"], |
[] |
), |
), |
"\n" |
) |
); |
@@ -199,8 +199,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -219,45 +219,45 @@ |
// We only care about notifications now. |
if(id != "notification") |
return; |
|
|
// This script only processes group notifications. |
if(wasKeyValueGet("type", message) != "group" || |
(wasKeyValueGet("type", message) == "group" && |
wasURLUnescape(wasKeyValueGet("group", message)) != |
wasURLUnescape(wasKeyValueGet("group", message)) != |
wasKeyValueGet("group", configuration))) |
return; |
|
|
// Get the sent message. |
data = wasURLUnescape( |
wasKeyValueGet( |
"message", |
"message", |
message |
) |
); |
|
|
// Check if this is an eggdrop command. |
if(llGetSubString(data, 0, 0) != |
if(llGetSubString(data, 0, 0) != |
wasKeyValueGet("command", configuration)) |
return; |
|
|
// Check if the command matches the current module. |
list command = llParseString2List(data, [" "], []); |
if(llList2String(command, 0) != |
if(llList2String(command, 0) != |
wasKeyValueGet("command", configuration) + "heartbeat") |
return; |
|
|
// Remove command. |
command = llDeleteSubList(command, 0, 0); |
|
// Get an URL. |
state url; |
// Get heartbeat. |
state heartbeat; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -264,52 +264,27 @@ |
} |
} |
|
state url { |
state heartbeat { |
state_entry() { |
// DEBUG |
llOwnerSay("[Heartbeat] Requesting URL..."); |
llRequestURL(); |
} |
http_request(key id, string method, string body) { |
if(method != URL_REQUEST_GRANTED) return; |
URL = body; |
// DEBUG |
llOwnerSay("[Heartbeat] Got URL..."); |
state version; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
} |
|
state version { |
state_entry() { |
// DEBUG |
llOwnerSay("[Heartbeat] Getting heartbeat data..."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
), |
wasKeyValueEncode( |
[ |
"command", "getheartbeatdata", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |
@@ -317,22 +292,29 @@ |
[ |
"AverageCPUUsage", |
"AverageRAMUsage", |
"AverageNETUsage", |
"Uptime" |
] |
), |
"callback", wasURLEscape(URL) |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
) |
); |
llSetTimerEvent(60); |
} |
http_request(key id, string method, string body) { |
llHTTPResponse(id, 200, "OK"); |
llReleaseURL(URL); |
if(wasKeyValueGet("command", body) != "getheartbeatdata" || |
wasKeyValueGet("success", body) != "True") { |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "getheartbeatdata") |
return; |
|
if(wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[Heartbeat] Unable to get heartbeat data: " + |
llOwnerSay("[Heartbeat] Unable to get heartbeat data: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
@@ -339,7 +321,7 @@ |
); |
state listen_group; |
} |
|
|
list stats = wasCSVToList( |
wasURLUnescape( |
wasKeyValueGet( |
@@ -348,15 +330,15 @@ |
) |
) |
); |
|
|
string CPU = llList2String( |
stats, |
llListFindList( |
stats, |
stats, |
["AverageCPUUsage"] |
) + 1 |
); |
|
|
// AverageRAMUsage is returned in bytes, |
// so convert the value to MiB and round. |
string RAM = (string)llRound( |
@@ -363,26 +345,37 @@ |
llList2Float( |
stats, |
llListFindList( |
stats, |
stats, |
["AverageRAMUsage"] |
) + 1 |
) / 1024 / 1024 |
); |
|
|
// AverageNETUsage is returned in bytes, |
// so convert the value to MiB and round. |
string NET = (string)llRound( |
llList2Float( |
stats, |
llListFindList( |
stats, |
["AverageNETUsage"] |
) + 1 |
) / 1024 / 1024 |
); |
|
string uptime = llList2String( |
stats, |
llListFindList( |
stats, |
stats, |
["Uptime"] |
) + 1 |
); |
|
data = "RAM: " + RAM + "MiB" + " CPU: " + CPU + "%" + " Uptime: " + uptime; |
|
|
data = "RAM: " + RAM + "MiB" + " CPU: " + CPU + "%" + " NET: " + NET + "MiB" + " Uptime: " + uptime; |
|
state tell; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
@@ -389,8 +382,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -406,21 +399,21 @@ |
llOwnerSay("[Heartbeat] Sending to group."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
), |
wasKeyValueEncode( |
[ |
"command", "tell", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |
/source/eggdrop/help.lsl |
@@ -1,5 +1,5 @@ |
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2016 - License: CC BY 2.0 // |
// Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// |
// Help message for Corrade eggdrop. |
@@ -17,9 +17,9 @@ |
if(i != -1) return llList2String(a, 2*i+1); |
return ""; |
} |
|
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2013 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasKeyValueEncode(list data) { |
list k = llList2ListStrided(data, 0, -1, 2); |
@@ -34,7 +34,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2011 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// http://was.fm/secondlife/wanderer |
vector wasCirclePoint(float radius) { |
@@ -46,7 +46,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// escapes a string in conformance with RFC1738 |
string wasURLEscape(string i) { |
@@ -70,7 +70,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
list wasCSVToList(string csv) { |
list l = []; |
@@ -109,7 +109,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasListToCSV(list l) { |
list v = []; |
@@ -117,18 +117,18 @@ |
string a = llDumpList2String( |
llParseStringKeepNulls( |
llList2String( |
l, |
l, |
0 |
), |
["\""], |
), |
["\""], |
[] |
), |
"\"\"" |
); |
if(llParseStringKeepNulls( |
a, |
a, |
[" ", ",", "\n", "\""], [] |
) != |
) != |
(list) a |
) a = "\"" + a + "\""; |
v += a; |
@@ -138,7 +138,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// unescapes a string in conformance with RFC1738 |
string wasURLUnescape(string i) { |
@@ -147,15 +147,15 @@ |
llParseString2List( |
llDumpList2String( |
llParseString2List( |
i, |
["+"], |
i, |
["+"], |
[] |
), |
), |
" " |
), |
["%0D%0A"], |
), |
["%0D%0A"], |
[] |
), |
), |
"\n" |
) |
); |
@@ -163,8 +163,6 @@ |
|
// configuration data |
string configuration = ""; |
// callback URL |
string URL = ""; |
// store message over state. |
string data = ""; |
|
@@ -187,8 +185,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -207,58 +205,61 @@ |
// We only care about notifications now. |
if(id != "notification") |
return; |
|
|
// This script only processes group notifications. |
if(wasKeyValueGet("type", message) != "group") |
if(wasKeyValueGet("type", message) != "group" || |
(wasKeyValueGet("type", message) == "group" && |
wasURLUnescape(wasKeyValueGet("group", message)) != |
wasKeyValueGet("group", configuration))) |
return; |
|
|
string firstname = wasURLUnescape( |
wasKeyValueGet( |
"firstname", |
"firstname", |
message |
) |
); |
|
|
string agent = (key)wasURLUnescape( |
wasKeyValueGet( |
"agent", |
"agent", |
message |
) |
); |
|
|
// Get the sent message. |
data = wasURLUnescape( |
wasKeyValueGet( |
"message", |
"message", |
message |
) |
); |
|
|
// Check if this is an eggdrop command. |
if(llGetSubString(data, 0, 0) != |
if(llGetSubString(data, 0, 0) != |
wasKeyValueGet("command", configuration)) |
return; |
|
|
// Check if the command matches the current module. |
list command = llParseString2List(data, [" "], []); |
if(llList2String(command, 0) != |
if(llList2String(command, 0) != |
wasKeyValueGet("command", configuration) + "help") |
return; |
|
|
// Remove command. |
command = llDeleteSubList(command, 0, 0); |
|
if(llGetInventoryType(wasKeyValueGet("help card", configuration)) |
|
if(llGetInventoryType(wasKeyValueGet("help card", configuration)) |
!= INVENTORY_NOTECARD) { |
data = "Hmm. I have not notecard to hand out - contact my owner please?"; |
state tell; |
} |
|
|
// Hand out the notecard. |
llGiveInventory(agent, |
llGiveInventory(agent, |
wasKeyValueGet("help card", configuration) |
); |
|
|
data = "Sent you a help notecard " + firstname + ". Please check your inventory."; |
|
state tell; |
@@ -267,8 +268,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -281,21 +282,21 @@ |
llOwnerSay("[Help] Sending to group."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
), |
wasKeyValueEncode( |
[ |
"command", "tell", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |
/source/eggdrop/invite.lsl |
@@ -1,5 +1,5 @@ |
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2016 - License: CC BY 2.0 // |
// Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// |
// A module that invites people to the group members. |
@@ -17,9 +17,9 @@ |
if(i != -1) return llList2String(a, 2*i+1); |
return ""; |
} |
|
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2013 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasKeyValueEncode(list data) { |
list k = llList2ListStrided(data, 0, -1, 2); |
@@ -34,7 +34,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2011 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// http://was.fm/secondlife/wanderer |
vector wasCirclePoint(float radius) { |
@@ -46,7 +46,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// escapes a string in conformance with RFC1738 |
string wasURLEscape(string i) { |
@@ -70,7 +70,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
list wasCSVToList(string csv) { |
list l = []; |
@@ -109,7 +109,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasListToCSV(list l) { |
list v = []; |
@@ -117,18 +117,18 @@ |
string a = llDumpList2String( |
llParseStringKeepNulls( |
llList2String( |
l, |
l, |
0 |
), |
["\""], |
), |
["\""], |
[] |
), |
"\"\"" |
); |
if(llParseStringKeepNulls( |
a, |
a, |
[" ", ",", "\n", "\""], [] |
) != |
) != |
(list) a |
) a = "\"" + a + "\""; |
v += a; |
@@ -138,7 +138,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// unescapes a string in conformance with RFC1738 |
string wasURLUnescape(string i) { |
@@ -147,15 +147,15 @@ |
llParseString2List( |
llDumpList2String( |
llParseString2List( |
i, |
["+"], |
i, |
["+"], |
[] |
), |
), |
" " |
), |
["%0D%0A"], |
), |
["%0D%0A"], |
[] |
), |
), |
"\n" |
) |
); |
@@ -163,8 +163,6 @@ |
|
// configuration data |
string configuration = ""; |
// callback URL |
string URL = ""; |
// store message over state. |
string data = ""; |
string firstname = ""; |
@@ -189,8 +187,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -209,62 +207,40 @@ |
// We only care about notifications now. |
if(id != "notification") |
return; |
|
|
// This script only processes group notifications. |
if(wasKeyValueGet("type", message) != "group") |
if(wasKeyValueGet("type", message) != "group" || |
(wasKeyValueGet("type", message) == "group" && |
wasURLUnescape(wasKeyValueGet("group", message)) != |
wasKeyValueGet("group", configuration))) |
return; |
|
|
// Get the sent message. |
data = wasURLUnescape( |
wasKeyValueGet( |
"message", |
"message", |
message |
) |
); |
|
|
// Check if this is an eggdrop command. |
if(llGetSubString(data, 0, 0) != |
if(llGetSubString(data, 0, 0) != |
wasKeyValueGet("command", configuration)) |
return; |
|
|
// Check if the command matches the current module. |
list command = llParseString2List(data, [" "], []); |
if(llList2String(command, 0) != |
if(llList2String(command, 0) != |
wasKeyValueGet("command", configuration) + "invite") |
return; |
|
|
// Remove command. |
command = llDeleteSubList(command, 0, 0); |
|
|
// Dump the rest of the message. |
data = llDumpList2String(command, " "); |
|
// Get an URL. |
state url; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
} |
|
state url { |
state_entry() { |
// DEBUG |
llOwnerSay("[Invite] Requesting URL..."); |
llRequestURL(); |
} |
http_request(key id, string method, string body) { |
if(method != URL_REQUEST_GRANTED) return; |
URL = body; |
// DEBUG |
llOwnerSay("[Invite] Got URL..."); |
// Search for agent. |
state search; |
} |
on_rez(integer num) { |
@@ -271,8 +247,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -285,21 +261,21 @@ |
llOwnerSay("[Invite] Searching for agent."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
), |
wasKeyValueEncode( |
[ |
"command", "directorysearch", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |
@@ -313,41 +289,47 @@ |
] |
) |
),*/ |
"callback", wasURLEscape(URL) |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
) |
); |
llSetTimerEvent(60); |
} |
http_request(key id, string method, string body) { |
llHTTPResponse(id, 200, "OK"); |
if(wasKeyValueGet("command", body) != "directorysearch" || |
wasKeyValueGet("success", body) != "True") { |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "directorysearch") |
return; |
|
if(wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[Invite] Unable to search for agent: " + |
llOwnerSay("[Invite] Unable to search for agent: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
); |
llReleaseURL(URL); |
state listen_group; |
} |
|
|
list first_last = llParseString2List(data, [" "], []); |
firstname = llList2String(first_last, 0); |
lastname = llList2String(first_last, 1); |
|
|
list found_agent = wasCSVToList( |
wasURLUnescape( |
wasKeyValueGet("data", body) |
) |
); |
|
|
if(llToUpper( |
llList2String( |
found_agent, |
llListFindList( |
found_agent, |
found_agent, |
(list)"FirstName" |
) + 1 |
) |
@@ -362,14 +344,12 @@ |
) |
) != llToUpper(lastname)) { |
data = "Agent not found."; |
llReleaseURL(URL); |
state tell; |
} |
|
|
state invite; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
@@ -376,8 +356,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -393,21 +373,21 @@ |
llOwnerSay("[Invite] inviting..."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
), |
wasKeyValueEncode( |
[ |
"command", "invite", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |
@@ -415,19 +395,25 @@ |
"lastname", lastname, |
"soft", "True", |
"verify", "False", |
"callback", wasURLEscape(URL) |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
) |
); |
llSetTimerEvent(60); |
} |
http_request(key id, string method, string body) { |
llHTTPResponse(id, 200, "OK"); |
llReleaseURL(URL); |
if(wasKeyValueGet("command", body) != "invite" || |
wasKeyValueGet("success", body) != "True") { |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "invite") |
return; |
|
if(wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[Eject] Unable to invite agent: " + |
llOwnerSay("[Eject] Unable to invite agent: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
@@ -434,13 +420,12 @@ |
); |
state listen_group; |
} |
|
|
data = "Butters (Jym) was sent to pick them up!"; |
|
|
state tell; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
@@ -447,8 +432,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -464,21 +449,21 @@ |
llOwnerSay("[Invite] Sending to group."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
), |
wasKeyValueEncode( |
[ |
"command", "tell", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |
/source/eggdrop/jenkins.lsl |
@@ -0,0 +1,496 @@ |
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// |
// A module that builds Jenkins jobs. |
// |
/////////////////////////////////////////////////////////////////////////// |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
/////////////////////////////////////////////////////////////////////////// |
string wasKeyValueGet(string k, string data) { |
if(llStringLength(data) == 0) return ""; |
if(llStringLength(k) == 0) return ""; |
list a = llParseStringKeepNulls(data, ["&", "="], []); |
integer i = llListFindList(llList2ListStrided(a, 0, -1, 2), [ k ]); |
if(i != -1) return llList2String(a, 2*i+1); |
return ""; |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasKeyValueEncode(list data) { |
list k = llList2ListStrided(data, 0, -1, 2); |
list v = llList2ListStrided(llDeleteSubList(data, 0, 0), 0, -1, 2); |
data = []; |
do { |
data += llList2String(k, 0) + "=" + llList2String(v, 0); |
k = llDeleteSubList(k, 0, 0); |
v = llDeleteSubList(v, 0, 0); |
} while(llGetListLength(k) != 0); |
return llDumpList2String(data, "&"); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// http://was.fm/secondlife/wanderer |
vector wasCirclePoint(float radius) { |
float x = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2); |
float y = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2); |
if(llPow(x,2) + llPow(y,2) <= llPow(radius,2)) |
return <x, y, 0>; |
return wasCirclePoint(radius); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// escapes a string in conformance with RFC1738 |
string wasURLEscape(string i) { |
string o = ""; |
do { |
string c = llGetSubString(i, 0, 0); |
i = llDeleteSubString(i, 0, 0); |
if(c == "") jump continue; |
if(c == " ") { |
o += "+"; |
jump continue; |
} |
if(c == "\n") { |
o += "%0D" + llEscapeURL(c); |
jump continue; |
} |
o += llEscapeURL(c); |
@continue; |
} while(i != ""); |
return o; |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
list wasCSVToList(string csv) { |
list l = []; |
list s = []; |
string m = ""; |
do { |
string a = llGetSubString(csv, 0, 0); |
csv = llDeleteSubString(csv, 0, 0); |
if(a == ",") { |
if(llList2String(s, -1) != "\"") { |
l += m; |
m = ""; |
jump continue; |
} |
m += a; |
jump continue; |
} |
if(a == "\"" && llGetSubString(csv, 0, 0) == a) { |
m += a; |
csv = llDeleteSubString(csv, 0, 0); |
jump continue; |
} |
if(a == "\"") { |
if(llList2String(s, -1) != a) { |
s += a; |
jump continue; |
} |
s = llDeleteSubList(s, -1, -1); |
jump continue; |
} |
m += a; |
@continue; |
} while(csv != ""); |
// postcondition: length(s) = 0 |
return l + m; |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasListToCSV(list l) { |
list v = []; |
do { |
string a = llDumpList2String( |
llParseStringKeepNulls( |
llList2String( |
l, |
0 |
), |
["\""], |
[] |
), |
"\"\"" |
); |
if(llParseStringKeepNulls( |
a, |
[" ", ",", "\n", "\""], [] |
) != |
(list) a |
) a = "\"" + a + "\""; |
v += a; |
l = llDeleteSubList(l, 0, 0); |
} while(l != []); |
return llDumpList2String(v, ","); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// unescapes a string in conformance with RFC1738 |
string wasURLUnescape(string i) { |
return llUnescapeURL( |
llDumpList2String( |
llParseString2List( |
llDumpList2String( |
llParseString2List( |
i, |
["+"], |
[] |
), |
" " |
), |
["%0D%0A"], |
[] |
), |
"\n" |
) |
); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
list wasSetIntersect(list a, list b) { |
if(llGetListLength(a) == 0) return []; |
string i = llList2String(a, 0); |
a = llDeleteSubList(a, 0, 0); |
if(llListFindList(b, (list)i) == -1) |
return wasSetIntersect(a, b); |
return i + wasSetIntersect(a, b); |
} |
|
// configuration data |
string configuration = ""; |
// store message over state. |
string data = ""; |
// caller |
string firstname = ""; |
string lastname = ""; |
|
default { |
state_entry() { |
llOwnerSay("[Jenkins] Starting..."); |
llSetTimerEvent(10); |
} |
link_message(integer sender, integer num, string message, key id) { |
if(id != "configuration") return; |
llOwnerSay("[Jenkins] Got configuration..."); |
configuration = message; |
state listen_group; |
} |
timer() { |
llOwnerSay("[Jenkins] Requesting configuration..."); |
llMessageLinked(LINK_THIS, 0, "configuration", NULL_KEY); |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
state_exit() { |
llSetTimerEvent(0); |
} |
} |
|
state listen_group { |
state_entry() { |
// DEBUG |
llOwnerSay("[Jenkins] Waiting for group messages..."); |
} |
link_message(integer sender, integer num, string message, key id) { |
// We only care about notifications now. |
if(id != "notification") |
return; |
|
// This script only processes group notifications. |
if(wasKeyValueGet("type", message) != "group" || |
(wasKeyValueGet("type", message) == "group" && |
wasURLUnescape(wasKeyValueGet("group", message)) != |
wasKeyValueGet("group", configuration))) |
return; |
|
// Get the sent message. |
data = wasURLUnescape( |
wasKeyValueGet( |
"message", |
message |
) |
); |
|
// Check if this is an eggdrop command. |
if(llGetSubString(data, 0, 0) != |
wasKeyValueGet("command", configuration)) |
return; |
|
// Check if the command matches the current module. |
list command = llParseString2List(data, [" "], []); |
if(llList2String(command, 0) != |
wasKeyValueGet("command", configuration) + "jenkins") |
return; |
|
// Remove command. |
command = llDeleteSubList(command, 0, 0); |
|
firstname = wasKeyValueGet("firstname", message); |
lastname = wasKeyValueGet("lastname", message); |
|
if(firstname == "" || lastname == "") { |
data = "And who would yarr be?"; |
state tell; |
} |
|
// Dump the rest of the message. |
data = wasURLUnescape(llDumpList2String(command, " ")); |
if(data == "") { |
data = "Jenkins job name is required."; |
state tell; |
} |
|
// Get roles of caller. |
state get_caller_roles; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
} |
|
state get_caller_roles { |
state_entry() { |
// DEBUG |
llOwnerSay("[Jenkins] Searching for caller..."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
configuration |
), |
wasKeyValueEncode( |
[ |
"command", "getmemberroles", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
configuration |
) |
), |
"firstname", firstname, |
"lastname", lastname, |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
) |
); |
|
llSetTimerEvent(60); |
} |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "getmemberroles") |
return; |
|
if(wasKeyValueGet("command", body) != "getmemberroles" || |
wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[Jenkins] Unable to get member roles: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
); |
state listen_group; |
} |
|
// Dump the roles to a list. |
list roles = wasCSVToList( |
wasURLUnescape( |
wasKeyValueGet("data", body) |
) |
); |
|
if(llGetListLength( |
wasSetIntersect(roles, |
wasCSVToList( |
wasKeyValueGet( |
"admin roles", configuration |
) |
) |
) |
) == 0) { |
data = "You ain't got the cojones!"; |
state tell; |
} |
|
state jenkins; |
} |
timer() { |
state listen_group; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
state_exit() { |
llSetTimerEvent(0); |
} |
} |
|
state jenkins { |
state_entry() { |
string jenkins_url = "http://" + wasKeyValueGet( |
"jenkins user", |
configuration |
) + ":" + wasKeyValueGet( |
"jenkins password", |
configuration |
) + "@" + wasKeyValueGet( |
"jenkins host", |
configuration |
) + "/job/" + data + "/build"; |
// DEBUG |
llOwnerSay("[Jenkins] Queuing Jenkins CI build to URL: " + jenkins_url); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
configuration |
), |
wasKeyValueEncode( |
[ |
"command", "HTTP", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
configuration |
) |
), |
"action", "post", |
"type", "text", |
// "https://" + "user:pass" + "@" + jenkins CI host + "/job/" + job name + "/build" |
"URL", wasURLEscape(jenkins_url), |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
) |
); |
llSetTimerEvent(60); |
} |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "HTTP") |
return; |
|
if(wasKeyValueGet("command", body) != "HTTP" || |
wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[Jenkins] Unable to POST to Jenkins: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
); |
state listen_group; |
} |
|
data = "Job build scheduled!"; |
|
state tell; |
} |
timer() { |
state listen_group; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
state_exit() { |
llSetTimerEvent(0); |
} |
} |
|
state tell { |
state_entry() { |
// DEBUG |
llOwnerSay("[Jenkins] Sending to group."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
configuration |
), |
wasKeyValueEncode( |
[ |
"command", "tell", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
configuration |
) |
), |
"entity", "group", |
"message", wasURLEscape(data) |
] |
) |
); |
|
state listen_group; |
} |
} |
/source/eggdrop/joke-database.lsl |
@@ -5,7 +5,7 @@ |
// A database-based joke module for Corrade Eggdrop. |
// |
/////////////////////////////////////////////////////////////////////////// |
|
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
/////////////////////////////////////////////////////////////////////////// |
@@ -17,7 +17,7 @@ |
if(i != -1) return llList2String(a, 2*i+1); |
return ""; |
} |
|
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
@@ -32,7 +32,7 @@ |
} while(llGetListLength(k) != 0); |
return llDumpList2String(data, "&"); |
} |
|
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
@@ -44,7 +44,7 @@ |
return <x, y, 0>; |
return wasCirclePoint(radius); |
} |
|
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
@@ -68,7 +68,7 @@ |
} while(i != ""); |
return o; |
} |
|
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
@@ -107,7 +107,7 @@ |
// postcondition: length(s) = 0 |
return l + m; |
} |
|
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
@@ -117,18 +117,18 @@ |
string a = llDumpList2String( |
llParseStringKeepNulls( |
llList2String( |
l, |
l, |
0 |
), |
["\""], |
), |
["\""], |
[] |
), |
"\"\"" |
); |
if(llParseStringKeepNulls( |
a, |
a, |
[" ", ",", "\n", "\""], [] |
) != |
) != |
(list) a |
) a = "\"" + a + "\""; |
v += a; |
@@ -136,7 +136,7 @@ |
} while(l != []); |
return llDumpList2String(v, ","); |
} |
|
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
@@ -147,32 +147,32 @@ |
llParseString2List( |
llDumpList2String( |
llParseString2List( |
i, |
["+"], |
i, |
["+"], |
[] |
), |
), |
" " |
), |
["%0D%0A"], |
), |
["%0D%0A"], |
[] |
), |
), |
"\n" |
) |
); |
} |
|
|
// configuration data |
string configuration = ""; |
// callback URL |
string URL = ""; |
// store message over state. |
string firstname = ""; |
string lastname = ""; |
string group = ""; |
string data = ""; |
string jump_state = ""; |
integer joke_counter = 0; |
|
string action = ""; |
|
string statement = ""; |
string parameters = ""; |
|
default { |
state_entry() { |
llOwnerSay("[Joke] Starting module..."); |
@@ -182,8 +182,8 @@ |
if(id != "configuration") return; |
llOwnerSay("[Joke] Got configuration..."); |
configuration = message; |
jump_state = "create_database"; |
state url; |
action = "create_database"; |
state trampoline; |
} |
timer() { |
llOwnerSay("[Joke] Requesting configuration..."); |
@@ -193,8 +193,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -203,32 +203,161 @@ |
llSetTimerEvent(0); |
} |
} |
|
state url { |
|
state trampoline { |
state_entry() { |
if(action == "create_database") { |
statement = wasURLEscape("CREATE TABLE IF NOT EXISTS \"" + |
wasKeyValueGet("joke table", configuration) + |
"\" (data text(1023), name text(35), firstname text(31), lastname text(31), id integer NOT NULL PRIMARY KEY)"); |
state query; |
} |
|
if(action == "random") { |
statement = wasURLEscape("SELECT * FROM \"" + |
wasKeyValueGet("joke table", configuration) + |
"\" WHERE name=:group ORDER BY RANDOM() LIMIT 1"); |
parameters = wasURLEscape( |
wasListToCSV( |
[ |
"group", |
wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
) |
] |
) |
); |
|
state query; |
} |
|
if(action == "id") { |
statement = wasURLEscape("SELECT * FROM \"" + |
wasKeyValueGet("joke table", configuration) + |
"\" WHERE name=:group AND id=:id"); |
parameters = wasURLEscape( |
wasListToCSV( |
[ |
"group", |
wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"id", |
data |
] |
) |
); |
state query; |
} |
|
if(action == "search") { |
statement = wasURLEscape("SELECT * FROM \"" + |
wasKeyValueGet("joke table", configuration) + |
"\" WHERE name=:group AND data LIKE :data COLLATE NOCASE ORDER BY RANDOM() LIMIT 1"); |
parameters = wasURLEscape( |
wasListToCSV( |
[ |
"group", |
wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"data", |
wasURLEscape("%" + llDumpList2String(llParseString2List(data, [" "], []), "%") + "%") |
] |
) |
); |
state query; |
} |
|
if(action == "remove") { |
statement = wasURLEscape("DELETE FROM \"" + |
wasKeyValueGet("joke table", configuration) + |
"\" WHERE name=:name AND id=:id"); |
parameters = wasURLEscape( |
wasListToCSV( |
[ |
"name", |
wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"id", |
data |
] |
) |
); |
state query; |
} |
|
if(action == "add") { |
statement = wasURLEscape("INSERT INTO \"" + |
wasKeyValueGet("joke table", configuration) + |
"\" (name, data, firstname, lastname) VALUES (:name, :data, :firstname, :lastname)"); |
parameters = wasURLEscape( |
wasListToCSV( |
[ |
"name", |
wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"data", |
wasURLEscape(data), |
"firstname", |
wasURLEscape(firstname), |
"lastname", |
wasURLEscape(lastname) |
] |
) |
); |
state query; |
} |
|
if(action == "get_joke_id") { |
statement = wasURLEscape("SELECT MAX(id) AS LAST FROM \"" + |
wasKeyValueGet("joke table", configuration) + "\""); |
state query; |
} |
|
if(action == "by") { |
statement = wasURLEscape("SELECT * FROM \"" + |
wasKeyValueGet("joke table", configuration) + |
"\" WHERE name=:group AND firstname=:firstname AND lastname=:lastname ORDER BY RANDOM() LIMIT 1"); |
parameters = wasURLEscape( |
wasListToCSV( |
[ |
"group", |
wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"firstname", |
wasURLEscape(firstname), |
"lastname", |
wasURLEscape(lastname) |
] |
) |
); |
|
state query; |
} |
|
// DEBUG |
llOwnerSay("[Joke] Requesting URL..."); |
llRequestURL(); |
} |
http_request(key id, string method, string body) { |
if(method != URL_REQUEST_GRANTED) return; |
URL = body; |
// DEBUG |
llOwnerSay("[Joke] Got URL..."); |
if(jump_state == "create_database") |
state create_database; |
if(jump_state == "get") |
state get; |
if(jump_state == "add") |
state add; |
if(jump_state == "remove") |
state remove; |
if(jump_state == "count_jokes") |
state count_jokes; |
if(jump_state == "listen_group") |
state listen_group; |
|
// DEBUG |
llOwnerSay("[Joke] Jump table corrupted, please contact creator..."); |
llResetScript(); |
} |
@@ -236,161 +365,164 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
} |
|
state create_database { |
|
state query { |
state_entry() { |
// Check messge length. |
string message = wasKeyValueEncode( |
[ |
"command", "database", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
configuration |
) |
), |
"SQL", statement, |
"data", parameters, |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
); |
|
// GC - none of these are needed anymore. |
statement = ""; |
parameters = ""; |
|
// Message length check. |
if(llStringLength(message) > 1023) { |
data = "Message length exceeded 1023 characters."; |
state tell; |
} |
|
// DEBUG |
llOwnerSay("[Joke] Creating database: " + wasKeyValueGet("joke table", configuration)); |
llOwnerSay("[Joke] Executing action: " + action); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
wasKeyValueEncode( |
[ |
"command", "database", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
configuration |
) |
), |
"SQL", wasURLEscape("CREATE TABLE IF NOT EXISTS \"" + |
wasKeyValueGet("joke table", configuration) + |
"\" (data text(1023), name text(35), firstname text(31), lastname text(31), id integer NOT NULL PRIMARY KEY)"), |
"callback", wasURLEscape(URL) |
] |
) |
), |
message |
); |
// GC |
message = ""; |
llSetTimerEvent(60); |
} |
http_request(key id, string method, string body) { |
llHTTPResponse(id, 200, "OK"); |
llReleaseURL(URL); |
if(wasKeyValueGet("command", body) != "database" || |
wasKeyValueGet("success", body) != "True") { |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "database") |
return; |
|
if(wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[Joke] Unable modify database: " + |
llOwnerSay("[Joke] Unable query database: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) + |
" " + |
) |
); |
state listen_group; |
} |
|
if(action == "create_database") { |
llOwnerSay("[Joke] Database created!"); |
state listen_group; |
} |
|
if(action == "random" || action == "id" || action == "search" || action == "by") { |
list result = wasCSVToList( |
wasURLUnescape( |
wasKeyValueGet("data", body) |
) |
|
); |
llResetScript(); |
|
if(llGetListLength(result) != 10) { |
data = "No joke found. . ."; |
state tell; |
} |
|
data = llList2String( |
result, |
llListFindList(result, ["data"]) + 1 |
); |
|
firstname = llList2String( |
result, |
llListFindList(result, ["firstname"]) + 1 |
); |
|
lastname = llList2String( |
result, |
llListFindList(result, ["lastname"]) + 1 |
); |
|
string id = llList2String( |
result, |
llListFindList(result, ["id"]) + 1 |
); |
|
// Build data to be sent. |
data += " " + "[" + firstname + " " + lastname + "/" + id + "]"; |
|
state tell; |
} |
llOwnerSay("[Joke] Database created!"); |
jump_state = "count_jokes"; |
state url; |
} |
timer() { |
llResetScript(); |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
|
if(action == "remove") { |
data = "Joke " + data + " has been removed."; |
state tell; |
} |
} |
state_exit() { |
llSetTimerEvent(0); |
} |
} |
|
state count_jokes { |
state_entry() { |
// DEBUG |
llOwnerSay("[Joke] Counting jokes in database: " + wasKeyValueGet("joke table", configuration)); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
configuration |
), |
wasKeyValueEncode( |
[ |
"command", "database", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
configuration |
) |
), |
"SQL", wasURLEscape("SELECT COUNT(*) AS count FROM \"" + |
wasKeyValueGet("joke table", configuration) + "\""), |
"callback", wasURLEscape(URL) |
] |
) |
); |
llSetTimerEvent(60); |
} |
http_request(key id, string method, string body) { |
llHTTPResponse(id, 200, "OK"); |
llReleaseURL(URL); |
if(wasKeyValueGet("command", body) != "database" || |
wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[Joke] Unable modify database: " + |
if(action == "add") { |
action = "get_joke_id"; |
data = body; |
state trampoline; |
} |
|
if(action == "get_joke_id") { |
list result = wasCSVToList( |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) + |
" " + |
wasURLUnescape( |
wasKeyValueGet("data", body) |
) |
|
); |
llResetScript(); |
|
data = llList2String( |
result, |
llListFindList(result, ["LAST"]) + 1 |
); |
|
data = "Joke " + data + " has been stored."; |
state tell; |
} |
|
list result = wasCSVToList( |
wasURLUnescape( |
wasKeyValueGet("data", body) |
) |
); |
|
joke_counter = llList2Integer( |
result, |
llListFindList(result, ["count"]) + 1 |
) + 1; |
|
llOwnerSay("[Joke] There are " + (string)joke_counter + " jokes in the database."); |
|
// DEBUG |
llOwnerSay("[Joke] Jump table corrupted, please contact creator..."); |
state listen_group; |
} |
timer() { |
llResetScript(); |
state listen_group; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -399,7 +531,7 @@ |
llSetTimerEvent(0); |
} |
} |
|
|
state listen_group { |
state_entry() { |
// DEBUG |
@@ -409,54 +541,54 @@ |
// We only care about notifications now. |
if(id != "notification") |
return; |
|
|
// This script only processes group notifications. |
if(wasKeyValueGet("type", message) != "group" || |
(wasKeyValueGet("type", message) == "group" && |
wasURLUnescape(wasKeyValueGet("group", message)) != |
wasURLUnescape(wasKeyValueGet("group", message)) != |
wasKeyValueGet("group", configuration))) |
return; |
|
|
// Get the message sender. |
firstname = wasURLUnescape( |
wasKeyValueGet( |
"firstname", |
"firstname", |
message |
) |
); |
|
|
lastname = wasURLUnescape( |
wasKeyValueGet( |
"lastname", |
"lastname", |
message |
) |
); |
|
|
// Get the sent message. |
data = wasURLUnescape( |
wasKeyValueGet( |
"message", |
"message", |
message |
) |
); |
|
|
// Check if this is an eggdrop command. |
if(llGetSubString(data, 0, 0) != |
if(llGetSubString(data, 0, 0) != |
wasKeyValueGet("command", configuration)) |
return; |
|
|
// Check if the command matches the current module. |
list command = llParseString2List(data, [" "], []); |
if(llList2String(command, 0) != |
if(llList2String(command, 0) != |
wasKeyValueGet("command", configuration) + "joke") |
return; |
|
|
// Remove command. |
command = llDeleteSubList(command, 0, 0); |
|
|
// Remove action. |
string action = llList2String(command, 0); |
// Jump to the "add" state for adding |
action = llList2String(command, 0); |
// Jump to the "add" state for adding |
if(action == "add") { |
command = llDeleteSubList(command, 0, 0); |
data = llDumpList2String(command, " "); |
@@ -464,11 +596,11 @@ |
data = "The joke's too short to be funny."; |
state tell; |
} |
jump_state = "add"; |
state url; |
action = "add"; |
state trampoline; |
} |
|
// Jump to the "remove" state for removing |
|
// Jump to the "remove" state for removing |
if(action == "remove") { |
command = llDeleteSubList(command, 0, 0); |
data = llDumpList2String(command, " "); |
@@ -476,369 +608,59 @@ |
data = "Which one though? Please provide a joke id."; |
state tell; |
} |
jump_state = "remove"; |
state url; |
action = "remove"; |
state trampoline; |
} |
|
|
if(action == "by") { |
command = llDeleteSubList(command, 0, 0); |
firstname = llList2String(command, 0); |
command = llDeleteSubList(command, 0, 0); |
lastname = llList2String(command, 0); |
command = llDeleteSubList(command, 0, 0); |
data = llDumpList2String(command, " "); |
|
if(llStringLength(firstname) == 0 || |
llStringLength(lastname) == 0) { |
data = "First and Last name is required."; |
state tell; |
} |
|
action = "by"; |
state trampoline; |
} |
|
string index = llList2String(command, 0); |
command = llDeleteSubList(command, 0, 0); |
|
data = llDumpList2String(command, " "); |
if((integer)data <= 0) |
data = ""; |
jump_state = "get"; |
state url; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
|
if(index == "search") { |
action = "search"; |
state trampoline; |
} |
} |
} |
|
state get { |
state_entry() { |
// DEBUG |
llOwnerSay("[Joke] Retrieving from database."); |
if(data == "") { |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
configuration |
), |
wasKeyValueEncode( |
[ |
"command", "database", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
configuration |
) |
), |
"SQL", wasURLEscape("SELECT * FROM \"" + |
wasKeyValueGet("joke table", configuration) + |
"\" WHERE name=:group LIMIT 1 OFFSET :id"), |
"data", wasURLEscape( |
wasListToCSV( |
[ |
"group", |
wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"id", |
(string)( |
(integer)llFrand( |
joke_counter |
) + 1 |
) |
] |
) |
), |
"callback", wasURLEscape(URL) |
] |
) |
); |
llSetTimerEvent(60); |
return; |
|
if((integer)index <= 0) { |
action = "random"; |
state trampoline; |
} |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
configuration |
), |
wasKeyValueEncode( |
[ |
"command", "database", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
configuration |
) |
), |
"SQL", wasURLEscape("SELECT * FROM \"" + |
wasKeyValueGet("joke table", configuration) + |
"\" WHERE name=:group AND id=:id"), |
"data", wasURLEscape( |
wasListToCSV( |
[ |
"group", |
wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"id", |
data |
] |
) |
), |
"callback", wasURLEscape(URL) |
] |
) |
); |
llSetTimerEvent(60); |
|
data = index; |
action = "id"; |
state trampoline; |
} |
http_request(key id, string method, string body) { |
llHTTPResponse(id, 200, "OK"); |
llReleaseURL(URL); |
if(wasKeyValueGet("command", body) != "database" || |
wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[Joke] Unable retrieve from database: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
); |
state listen_group; |
} |
|
list result = wasCSVToList( |
wasURLUnescape( |
wasKeyValueGet("data", body) |
) |
); |
|
if(llGetListLength(result) != 10) { |
data = "No joke found. . ."; |
state tell; |
} |
|
data = llList2String( |
result, |
llListFindList(result, ["data"]) + 1 |
); |
|
string firstname = llList2String( |
result, |
llListFindList(result, ["firstname"]) + 1 |
); |
|
string lastname = llList2String( |
result, |
llListFindList(result, ["lastname"]) + 1 |
); |
|
string id = llList2String( |
result, |
llListFindList(result, ["id"]) + 1 |
); |
|
// Build data to be sent. |
data += " " + "[" + firstname + " " + lastname + "/" + id + "]"; |
|
state tell; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
state_exit() { |
llSetTimerEvent(0); |
} |
} |
|
state add { |
state_entry() { |
// DEBUG |
llOwnerSay("[Joke] Adding to database: " + (string)(joke_counter + 1)); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
configuration |
), |
wasKeyValueEncode( |
[ |
"command", "database", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
configuration |
) |
), |
"SQL", wasURLEscape("INSERT INTO \"" + |
wasKeyValueGet("joke table", configuration) + |
"\" (name, data, firstname, lastname, id) VALUES (:name, :data, :firstname, :lastname, :id)"), |
"data", wasURLEscape( |
wasListToCSV( |
[ |
"name", |
wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"data", |
wasURLEscape(data), |
"firstname", |
wasURLEscape(firstname), |
"lastname", |
wasURLEscape(lastname), |
"id", |
(string)(joke_counter + 1) |
] |
) |
), |
"callback", wasURLEscape(URL) |
] |
) |
); |
llSetTimerEvent(60); |
} |
http_request(key id, string method, string body) { |
llHTTPResponse(id, 200, "OK"); |
llReleaseURL(URL); |
if(wasKeyValueGet("command", body) != "database" || |
wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[Joke] Unable modify database: " + |
wasURLUnescape( |
wasKeyValueGet("data", body) |
) |
); |
state listen_group; |
} |
++joke_counter; |
data = "Joke " + (string)joke_counter + " has been stored."; |
state tell; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
state_exit() { |
llSetTimerEvent(0); |
} |
} |
|
state remove { |
state_entry() { |
// DEBUG |
llOwnerSay("[Joke] Removing from database."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
configuration |
), |
wasKeyValueEncode( |
[ |
"command", "database", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
configuration |
) |
), |
"SQL", wasURLEscape("DELETE FROM \"" + |
wasKeyValueGet("joke table", configuration) + |
"\" WHERE name=:name AND id=:id"), |
"data", wasURLEscape( |
wasListToCSV( |
[ |
"name", |
wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"id", |
data |
] |
) |
), |
"callback", wasURLEscape(URL) |
] |
) |
); |
llSetTimerEvent(60); |
} |
http_request(key id, string method, string body) { |
llHTTPResponse(id, 200, "OK"); |
llReleaseURL(URL); |
if(wasKeyValueGet("command", body) != "database" || |
wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[Joke] Unable modify database: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
); |
state listen_group; |
} |
--joke_counter; |
data = "Joke " + data + " has been removed."; |
state tell; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
state_exit() { |
llSetTimerEvent(0); |
} |
} |
|
state tell { |
state_entry() { |
// DEBUG |
@@ -845,21 +667,21 @@ |
llOwnerSay("[Joke] Sending to group."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
), |
wasKeyValueEncode( |
[ |
"command", "tell", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |
/source/eggdrop/motd.lsl |
@@ -1,11 +1,11 @@ |
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2016 - License: CC BY 2.0 // |
// Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// |
// A MOTD module for Corrade Eggdrop. |
// |
/////////////////////////////////////////////////////////////////////////// |
|
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
/////////////////////////////////////////////////////////////////////////// |
@@ -17,9 +17,9 @@ |
if(i != -1) return llList2String(a, 2*i+1); |
return ""; |
} |
|
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2013 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasKeyValueEncode(list data) { |
list k = llList2ListStrided(data, 0, -1, 2); |
@@ -32,9 +32,9 @@ |
} while(llGetListLength(k) != 0); |
return llDumpList2String(data, "&"); |
} |
|
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2011 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// http://was.fm/secondlife/wanderer |
vector wasCirclePoint(float radius) { |
@@ -44,9 +44,9 @@ |
return <x, y, 0>; |
return wasCirclePoint(radius); |
} |
|
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// escapes a string in conformance with RFC1738 |
string wasURLEscape(string i) { |
@@ -68,9 +68,9 @@ |
} while(i != ""); |
return o; |
} |
|
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
list wasCSVToList(string csv) { |
list l = []; |
@@ -107,9 +107,9 @@ |
// postcondition: length(s) = 0 |
return l + m; |
} |
|
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasListToCSV(list l) { |
list v = []; |
@@ -117,18 +117,18 @@ |
string a = llDumpList2String( |
llParseStringKeepNulls( |
llList2String( |
l, |
l, |
0 |
), |
["\""], |
), |
["\""], |
[] |
), |
"\"\"" |
); |
if(llParseStringKeepNulls( |
a, |
a, |
[" ", ",", "\n", "\""], [] |
) != |
) != |
(list) a |
) a = "\"" + a + "\""; |
v += a; |
@@ -136,9 +136,9 @@ |
} while(l != []); |
return llDumpList2String(v, ","); |
} |
|
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// unescapes a string in conformance with RFC1738 |
string wasURLUnescape(string i) { |
@@ -147,24 +147,22 @@ |
llParseString2List( |
llDumpList2String( |
llParseString2List( |
i, |
["+"], |
i, |
["+"], |
[] |
), |
), |
" " |
), |
["%0D%0A"], |
), |
["%0D%0A"], |
[] |
), |
), |
"\n" |
) |
); |
} |
|
|
// configuration data |
string configuration = ""; |
// callback URL |
string URL = ""; |
// store message over state. |
string firstname = ""; |
string lastname = ""; |
@@ -171,7 +169,8 @@ |
string group = ""; |
string data = ""; |
string jump_state = ""; |
|
integer membershipFee; |
|
default { |
state_entry() { |
llOwnerSay("[MOTD] Starting module..."); |
@@ -182,7 +181,7 @@ |
llOwnerSay("[MOTD] Got configuration..."); |
configuration = message; |
jump_state = "create_database"; |
state url; |
state trampoline; |
} |
timer() { |
llOwnerSay("[MOTD] Requesting configuration..."); |
@@ -192,8 +191,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -202,18 +201,9 @@ |
llSetTimerEvent(0); |
} |
} |
|
state url { |
|
state trampoline { |
state_entry() { |
// DEBUG |
llOwnerSay("[MOTD] Requesting URL..."); |
llRequestURL(); |
} |
http_request(key id, string method, string body) { |
if(method != URL_REQUEST_GRANTED) return; |
URL = body; |
// DEBUG |
llOwnerSay("[MOTD] Got URL..."); |
if(jump_state == "create_database") |
state create_database; |
if(jump_state == "greet") |
@@ -222,9 +212,13 @@ |
state get; |
if(jump_state == "set") |
state set; |
if(jump_state == "fee") |
state fee; |
if(jump_state == "pay") |
state pay; |
if(jump_state == "listen_group") |
state listen_group; |
|
|
// DEBUG |
llOwnerSay("[MOTD] Jump table corrupted, please contact creator..."); |
llResetScript(); |
@@ -233,14 +227,14 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
} |
|
|
state create_database { |
state_entry() { |
// DEBUG |
@@ -247,48 +241,54 @@ |
llOwnerSay("[MOTD] Creating database: " + wasKeyValueGet("motd table", configuration)); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
), |
wasKeyValueEncode( |
[ |
"command", "database", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |
"SQL", wasURLEscape("CREATE TABLE IF NOT EXISTS \"" + |
wasKeyValueGet("motd table", configuration) + |
"SQL", wasURLEscape("CREATE TABLE IF NOT EXISTS \"" + |
wasKeyValueGet("motd table", configuration) + |
"\" (name text unique collate nocase, data text)"), |
"callback", wasURLEscape(URL) |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
) |
); |
llSetTimerEvent(60); |
} |
http_request(key id, string method, string body) { |
llHTTPResponse(id, 200, "OK"); |
llReleaseURL(URL); |
if(wasKeyValueGet("command", body) != "database" || |
wasKeyValueGet("success", body) != "True") { |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "database") |
return; |
|
if(wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[MOTD] Unable modify database: " + |
llOwnerSay("[MOTD] Unable modify database: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) + |
" " + |
) + |
" " + |
wasURLUnescape( |
wasKeyValueGet("data", body) |
) |
|
|
); |
llResetScript(); |
} |
@@ -296,7 +296,6 @@ |
state listen_group; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
@@ -303,8 +302,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -313,8 +312,8 @@ |
llSetTimerEvent(0); |
} |
} |
|
|
|
|
state listen_group { |
state_entry() { |
// DEBUG |
@@ -324,7 +323,7 @@ |
// We only care about notifications now. |
if(id != "notification") |
return; |
|
|
// Get the group. |
group = wasURLUnescape( |
wasKeyValueGet( |
@@ -332,7 +331,15 @@ |
message |
) |
); |
|
|
// This script only processes group and membership notifications. |
// Esnure that the notification is meant for the configured group. |
if((wasKeyValueGet("type", message) != "membership" && wasKeyValueGet("type", message) != "group") || |
((wasKeyValueGet("type", message) == "membership" || wasKeyValueGet("type", message) == "group") && |
wasURLUnescape(wasKeyValueGet("group", message)) != |
wasKeyValueGet("group", configuration))) |
return; |
|
// Retrieve the membership notification. |
if(wasKeyValueGet("type", message) == "membership" && |
wasKeyValueGet("action", message) == "joined") { |
@@ -348,86 +355,92 @@ |
message |
) |
); |
jump_state = "greet"; |
state url; |
|
if(wasKeyValueGet("pay back", configuration) != "true") { |
jump_state = "greet"; |
state trampoline; |
} |
|
jump_state = "fee"; |
state trampoline; |
} |
|
// This script only processes group notifications. |
if(wasKeyValueGet("type", message) != "group") |
return; |
|
|
// Get the sent message. |
data = wasURLUnescape( |
wasKeyValueGet( |
"message", |
"message", |
message |
) |
); |
|
|
// Check if this is an eggdrop command. |
if(llGetSubString(data, 0, 0) != |
if(llGetSubString(data, 0, 0) != |
wasKeyValueGet("command", configuration)) |
return; |
|
|
// Check if the command matches the current module. |
list command = llParseString2List(data, [" "], []); |
if(llList2String(command, 0) != |
if(llList2String(command, 0) != |
wasKeyValueGet("command", configuration) + "motd") |
return; |
|
|
// Remove command. |
command = llDeleteSubList(command, 0, 0); |
|
|
// Dump the rest of the message. |
data = llDumpList2String(command, " "); |
|
|
// DEBUG |
//llOwnerSay("Remaining data: " + data); |
|
// Get the sent message. |
if(data == "") { |
jump_state = "get"; |
state url; |
state trampoline; |
} |
|
|
data = wasURLEscape(data); |
jump_state = "set"; |
state url; |
state trampoline; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
} |
|
|
state greet { |
state_entry() { |
// DEBUG |
llOwnerSay("[MOTD] Member joined, retrieving MOTD..."); |
llOwnerSay("[MOTD] Retrieving MOTD..."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
), |
wasKeyValueEncode( |
[ |
"command", "database", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |
"SQL", wasURLEscape("SELECT data FROM \"" + |
wasKeyValueGet("motd table", configuration) + |
wasKeyValueGet("motd table", configuration) + |
"\" WHERE name=:group"), |
"data", wasURLEscape( |
wasListToCSV( |
@@ -437,19 +450,25 @@ |
] |
) |
), |
"callback", wasURLEscape(URL) |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
) |
); |
llSetTimerEvent(60); |
} |
http_request(key id, string method, string body) { |
llHTTPResponse(id, 200, "OK"); |
llReleaseURL(URL); |
if(wasKeyValueGet("command", body) != "database" || |
wasKeyValueGet("success", body) != "True") { |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "database") |
return; |
|
if(wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[MOTD] Unable retrieve from database: " + |
llOwnerSay("[MOTD] Unable retrieve from database: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
@@ -456,7 +475,7 @@ |
); |
state listen_group; |
} |
|
|
data = llDumpList2String( |
llDeleteSubList( |
wasCSVToList( |
@@ -469,15 +488,14 @@ |
), |
"" |
); |
|
|
if(data == "") |
state listen_group; |
|
|
data = "Hello " + firstname + " " + lastname + "!" + " " + data; |
state tell; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
@@ -484,8 +502,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -494,7 +512,7 @@ |
llSetTimerEvent(0); |
} |
} |
|
|
state get { |
state_entry() { |
// DEBUG |
@@ -501,26 +519,26 @@ |
llOwnerSay("[MOTD] Retrieving from database."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
), |
wasKeyValueEncode( |
[ |
"command", "database", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |
"SQL", wasURLEscape("SELECT data FROM \"" + |
wasKeyValueGet("motd table", configuration) + |
wasKeyValueGet("motd table", configuration) + |
"\" WHERE name=:group"), |
"data", wasURLEscape( |
wasListToCSV( |
@@ -528,7 +546,7 @@ |
"group", |
wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
) |
@@ -535,19 +553,25 @@ |
] |
) |
), |
"callback", wasURLEscape(URL) |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
) |
); |
llSetTimerEvent(60); |
} |
http_request(key id, string method, string body) { |
llHTTPResponse(id, 200, "OK"); |
llReleaseURL(URL); |
if(wasKeyValueGet("command", body) != "database" || |
wasKeyValueGet("success", body) != "True") { |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "database") |
return; |
|
if(wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[MOTD] Unable retrieve from database: " + |
llOwnerSay("[MOTD] Unable retrieve from database: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
@@ -554,7 +578,7 @@ |
); |
state listen_group; |
} |
|
|
data = llDumpList2String( |
llDeleteSubList( |
wasCSVToList( |
@@ -567,16 +591,15 @@ |
), |
"" |
); |
|
|
if(data == "") { |
data = "Sorry, no MOTD is currently set."; |
state tell; |
} |
|
|
state tell; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
@@ -583,8 +606,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -593,62 +616,241 @@ |
llSetTimerEvent(0); |
} |
} |
|
|
state fee { |
state_entry() { |
// DEBUG |
llOwnerSay("[MOTD] Member joined, getting group membership fee..."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
configuration |
), |
wasKeyValueEncode( |
[ |
"command", "getgroupdata", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
configuration |
) |
), |
"data", "MembershipFee", |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
) |
); |
llSetTimerEvent(60); |
} |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "getgroupdata") |
return; |
|
if(wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[MOTD] Unable to get group data: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
); |
state listen_group; |
} |
|
list membership = wasCSVToList( |
wasURLUnescape( |
wasKeyValueGet( |
"data", |
body |
) |
) |
); |
|
membershipFee = llList2Integer( |
membership, |
llListFindList( |
membership, |
[ "MembershipFee" ] |
) + 1 |
); |
|
if(membershipFee <= 0) { |
// DEBUG |
llOwnerSay("The configured group does not have a membership fee!"); |
state listen_group; |
} |
|
jump_state = "pay"; |
state trampoline; |
} |
timer() { |
state listen_group; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
state_exit() { |
llSetTimerEvent(0); |
} |
} |
|
state pay { |
state_entry() { |
// DEBUG |
llOwnerSay("[MOTD] Paying back the entrance fee..."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
configuration |
), |
wasKeyValueEncode( |
[ |
"command", "pay", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
configuration |
) |
), |
"amount", membershipFee, |
"entity", "avatar", |
"firstname", wasURLEscape(firstname), |
"lastname", wasURLEscape(lastname), |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
) |
); |
llSetTimerEvent(60); |
} |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "pay") |
return; |
|
if(wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[MOTD] Unable to pay the entrance fee: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
); |
state listen_group; |
} |
|
// DEBUG |
llOwnerSay("[MOTD] Paid back the entrance fee."); |
|
jump_state = "greet"; |
state trampoline; |
} |
timer() { |
state listen_group; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
state_exit() { |
llSetTimerEvent(0); |
} |
} |
|
state set { |
state_entry() { |
// DEBUG |
llOwnerSay("[MOTD] Adding to database."); |
llOwnerSay("[MOTD] Adding to database..."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
), |
wasKeyValueEncode( |
[ |
"command", "database", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |
"SQL", wasURLEscape("REPLACE INTO \"" + |
wasKeyValueGet("motd table", configuration) + |
"\" (name, data) VALUES (:name, :data)"), |
wasKeyValueGet("motd table", configuration) + |
"\" (name, data) VALUES (:group, :message)"), |
"data", wasURLEscape( |
wasListToCSV( |
[ |
"name", |
"group", |
wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"data", |
wasURLEscape(data) |
"message", |
data |
] |
) |
), |
"callback", wasURLEscape(URL) |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
) |
); |
llSetTimerEvent(60); |
} |
http_request(key id, string method, string body) { |
llHTTPResponse(id, 200, "OK"); |
llReleaseURL(URL); |
if(wasKeyValueGet("command", body) != "database" || |
wasKeyValueGet("success", body) != "True") { |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "database") |
return; |
|
if(wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[MOTD] Unable modify database: " + |
llOwnerSay("[MOTD] Unable modify database: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
@@ -659,7 +861,6 @@ |
state tell; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
@@ -666,8 +867,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -676,7 +877,7 @@ |
llSetTimerEvent(0); |
} |
} |
|
|
state tell { |
state_entry() { |
// DEBUG |
@@ -683,21 +884,21 @@ |
llOwnerSay("[MOTD] Sending to group."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
), |
wasKeyValueEncode( |
[ |
"command", "tell", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |
/source/eggdrop/notice.lsl |
@@ -0,0 +1,530 @@ |
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// |
// A module that sends a group notice. |
// |
/////////////////////////////////////////////////////////////////////////// |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
/////////////////////////////////////////////////////////////////////////// |
string wasKeyValueGet(string k, string data) { |
if(llStringLength(data) == 0) return ""; |
if(llStringLength(k) == 0) return ""; |
list a = llParseStringKeepNulls(data, ["&", "="], []); |
integer i = llListFindList(llList2ListStrided(a, 0, -1, 2), [ k ]); |
if(i != -1) return llList2String(a, 2*i+1); |
return ""; |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasKeyValueEncode(list data) { |
list k = llList2ListStrided(data, 0, -1, 2); |
list v = llList2ListStrided(llDeleteSubList(data, 0, 0), 0, -1, 2); |
data = []; |
do { |
data += llList2String(k, 0) + "=" + llList2String(v, 0); |
k = llDeleteSubList(k, 0, 0); |
v = llDeleteSubList(v, 0, 0); |
} while(llGetListLength(k) != 0); |
return llDumpList2String(data, "&"); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// http://was.fm/secondlife/wanderer |
vector wasCirclePoint(float radius) { |
float x = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2); |
float y = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2); |
if(llPow(x,2) + llPow(y,2) <= llPow(radius,2)) |
return <x, y, 0>; |
return wasCirclePoint(radius); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// escapes a string in conformance with RFC1738 |
string wasURLEscape(string i) { |
string o = ""; |
do { |
string c = llGetSubString(i, 0, 0); |
i = llDeleteSubString(i, 0, 0); |
if(c == "") jump continue; |
if(c == " ") { |
o += "+"; |
jump continue; |
} |
if(c == "\n") { |
o += "%0D" + llEscapeURL(c); |
jump continue; |
} |
o += llEscapeURL(c); |
@continue; |
} while(i != ""); |
return o; |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
list wasCSVToList(string csv) { |
list l = []; |
list s = []; |
string m = ""; |
do { |
string a = llGetSubString(csv, 0, 0); |
csv = llDeleteSubString(csv, 0, 0); |
if(a == ",") { |
if(llList2String(s, -1) != "\"") { |
l += m; |
m = ""; |
jump continue; |
} |
m += a; |
jump continue; |
} |
if(a == "\"" && llGetSubString(csv, 0, 0) == a) { |
m += a; |
csv = llDeleteSubString(csv, 0, 0); |
jump continue; |
} |
if(a == "\"") { |
if(llList2String(s, -1) != a) { |
s += a; |
jump continue; |
} |
s = llDeleteSubList(s, -1, -1); |
jump continue; |
} |
m += a; |
@continue; |
} while(csv != ""); |
// postcondition: length(s) = 0 |
return l + m; |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasListToCSV(list l) { |
list v = []; |
do { |
string a = llDumpList2String( |
llParseStringKeepNulls( |
llList2String( |
l, |
0 |
), |
["\""], |
[] |
), |
"\"\"" |
); |
if(llParseStringKeepNulls( |
a, |
[" ", ",", "\n", "\""], [] |
) != |
(list) a |
) a = "\"" + a + "\""; |
v += a; |
l = llDeleteSubList(l, 0, 0); |
} while(l != []); |
return llDumpList2String(v, ","); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// unescapes a string in conformance with RFC1738 |
string wasURLUnescape(string i) { |
return llUnescapeURL( |
llDumpList2String( |
llParseString2List( |
llDumpList2String( |
llParseString2List( |
i, |
["+"], |
[] |
), |
" " |
), |
["%0D%0A"], |
[] |
), |
"\n" |
) |
); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
list wasSetIntersect(list a, list b) { |
if(llGetListLength(a) == 0) return []; |
string i = llList2String(a, 0); |
a = llDeleteSubList(a, 0, 0); |
if(llListFindList(b, (list)i) == -1) |
return wasSetIntersect(a, b); |
return i + wasSetIntersect(a, b); |
} |
|
// configuration data |
string configuration = ""; |
// store message over state. |
string data = ""; |
// callee |
string firstname = ""; |
string lastname = ""; |
|
// yhe notice parameters |
string noticeSubject = ""; |
string noticeMessage = ""; |
string noticeItem = ""; |
|
default { |
state_entry() { |
llOwnerSay("[Notice] Starting..."); |
llSetTimerEvent(10); |
} |
link_message(integer sender, integer num, string message, key id) { |
if(id != "configuration") return; |
llOwnerSay("[Notice] Got configuration..."); |
configuration = message; |
state listen_group; |
} |
timer() { |
llOwnerSay("[Notice] Requesting configuration..."); |
llMessageLinked(LINK_THIS, 0, "configuration", NULL_KEY); |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
state_exit() { |
llSetTimerEvent(0); |
} |
} |
|
state listen_group { |
state_entry() { |
// DEBUG |
llOwnerSay("[Notice] Waiting for group messages..."); |
} |
link_message(integer sender, integer num, string message, key id) { |
// We only care about notifications now. |
if(id != "notification") |
return; |
|
// This script only processes group notifications. |
if(wasKeyValueGet("type", message) != "group" || |
(wasKeyValueGet("type", message) == "group" && |
wasURLUnescape(wasKeyValueGet("group", message)) != |
wasKeyValueGet("group", configuration))) |
return; |
|
// Get the sent message. |
data = wasURLUnescape( |
wasKeyValueGet( |
"message", |
message |
) |
); |
|
// Check if this is an eggdrop command. |
if(llGetSubString(data, 0, 0) != |
wasKeyValueGet("command", configuration)) |
return; |
|
// Check if the command matches the current module. |
list command = llParseString2List(data, [" "], []); |
if(llList2String(command, 0) != |
wasKeyValueGet("command", configuration) + "notice") |
return; |
|
// Remove command. |
command = llDeleteSubList(command, 0, 0); |
|
firstname = wasKeyValueGet("firstname", message); |
lastname = wasKeyValueGet("lastname", message); |
|
if(firstname == "" || lastname == "") { |
data = "And who would yarr be?"; |
state tell; |
} |
|
// Tokenize the message. |
list noticeData = llParseString2List( |
llDumpList2String(command, " "), |
[], |
[ "(", ")" ] |
); |
|
// Build the notification data. |
noticeSubject = ""; |
noticeMessage = ""; |
noticeItem = ""; |
|
// Dyck parser. |
integer select = 0; |
list sym = []; |
do { |
string slice = llList2String(noticeData, 0); |
noticeData = llDeleteSubList(noticeData, 0, 0); |
|
// Opening bracket. |
if(slice == "(" && llGetListLength(sym) == 0) { |
++select; |
sym += slice; |
jump continue; |
} |
|
// Closing bracket lookahead. |
if(slice == ")" && ( |
llGetListLength(noticeData) == 0 || |
llList2String(noticeData, 0) == " ")) { |
sym = llDeleteSubList(sym, 0, 0); |
jump continue; |
} |
|
if(select == 1) { |
noticeSubject += slice; |
jump continue; |
} |
if(select == 2) { |
noticeMessage += slice; |
jump continue; |
} |
if(select == 3) { |
noticeItem += slice; |
jump continue; |
} |
|
@continue; |
} while(llGetListLength(noticeData) != 0); |
|
// Get roles of caller. |
state get_caller_roles; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
} |
|
state get_caller_roles { |
state_entry() { |
// DEBUG |
llOwnerSay("[Notice] Searching for caller..."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
configuration |
), |
wasKeyValueEncode( |
[ |
"command", "getmemberroles", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
configuration |
) |
), |
"firstname", firstname, |
"lastname", lastname, |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
) |
); |
llSetTimerEvent(60); |
} |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "getmemberroles") |
return; |
|
if(wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[Notice] Unable to get member roles: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
); |
state listen_group; |
} |
|
// Dump the roles to a list. |
list roles = wasCSVToList( |
wasURLUnescape( |
wasKeyValueGet("data", body) |
) |
); |
|
if(llGetListLength( |
wasSetIntersect(roles, |
wasCSVToList( |
wasKeyValueGet( |
"admin roles", configuration |
) |
) |
) |
) == 0) { |
data = "You ain't got the cojones!"; |
state tell; |
} |
|
state notice; |
} |
timer() { |
state listen_group; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
state_exit() { |
llSetTimerEvent(0); |
} |
} |
|
state notice { |
state_entry() { |
// DEBUG |
llOwnerSay("[Notice] Sending notice..."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
configuration |
), |
wasKeyValueEncode( |
[ |
"command", "notice", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
configuration |
) |
), |
"action", "send", |
"subject", wasURLEscape(noticeSubject), |
"message", wasURLEscape(noticeMessage), |
"item", wasURLEscape(noticeItem), |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
) |
); |
llSetTimerEvent(60); |
} |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "notice") |
return; |
|
if(wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[Notice] Unable to send notice: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
); |
state listen_group; |
} |
|
data = "Notice sent."; |
|
state tell; |
} |
timer() { |
state listen_group; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
state_exit() { |
llSetTimerEvent(0); |
} |
} |
|
state tell { |
state_entry() { |
// DEBUG |
llOwnerSay("[Notice] Sending to group."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
configuration |
), |
wasKeyValueEncode( |
[ |
"command", "tell", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
configuration |
) |
), |
"entity", "group", |
"message", wasURLEscape(data) |
] |
) |
); |
state listen_group; |
} |
} |
/source/eggdrop/reminders.lsl |
@@ -0,0 +1,797 @@ |
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2018 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// |
// A reminders module for Corrade Eggdrop. |
// |
/////////////////////////////////////////////////////////////////////////// |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
/////////////////////////////////////////////////////////////////////////// |
string wasKeyValueGet(string k, string data) { |
if(llStringLength(data) == 0) return ""; |
if(llStringLength(k) == 0) return ""; |
list a = llParseStringKeepNulls(data, ["&", "="], []); |
integer i = llListFindList(llList2ListStrided(a, 0, -1, 2), [ k ]); |
if(i != -1) return llList2String(a, 2*i+1); |
return ""; |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasKeyValueEncode(list data) { |
list k = llList2ListStrided(data, 0, -1, 2); |
list v = llList2ListStrided(llDeleteSubList(data, 0, 0), 0, -1, 2); |
data = []; |
do { |
data += llList2String(k, 0) + "=" + llList2String(v, 0); |
k = llDeleteSubList(k, 0, 0); |
v = llDeleteSubList(v, 0, 0); |
} while(llGetListLength(k) != 0); |
return llDumpList2String(data, "&"); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// http://was.fm/secondlife/wanderer |
vector wasCirclePoint(float radius) { |
float x = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2); |
float y = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2); |
if(llPow(x,2) + llPow(y,2) <= llPow(radius,2)) |
return <x, y, 0>; |
return wasCirclePoint(radius); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// escapes a string in conformance with RFC1738 |
string wasURLEscape(string i) { |
string o = ""; |
do { |
string c = llGetSubString(i, 0, 0); |
i = llDeleteSubString(i, 0, 0); |
if(c == "") jump continue; |
if(c == " ") { |
o += "+"; |
jump continue; |
} |
if(c == "\n") { |
o += "%0D" + llEscapeURL(c); |
jump continue; |
} |
o += llEscapeURL(c); |
@continue; |
} while(i != ""); |
return o; |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
list wasCSVToList(string csv) { |
list l = []; |
list s = []; |
string m = ""; |
do { |
string a = llGetSubString(csv, 0, 0); |
csv = llDeleteSubString(csv, 0, 0); |
if(a == ",") { |
if(llList2String(s, -1) != "\"") { |
l += m; |
m = ""; |
jump continue; |
} |
m += a; |
jump continue; |
} |
if(a == "\"" && llGetSubString(csv, 0, 0) == a) { |
m += a; |
csv = llDeleteSubString(csv, 0, 0); |
jump continue; |
} |
if(a == "\"") { |
if(llList2String(s, -1) != a) { |
s += a; |
jump continue; |
} |
s = llDeleteSubList(s, -1, -1); |
jump continue; |
} |
m += a; |
@continue; |
} while(csv != ""); |
// postcondition: length(s) = 0 |
return l + m; |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasListToCSV(list l) { |
list v = []; |
do { |
string a = llDumpList2String( |
llParseStringKeepNulls( |
llList2String( |
l, |
0 |
), |
["\""], |
[] |
), |
"\"\"" |
); |
if(llParseStringKeepNulls( |
a, |
[" ", ",", "\n", "\""], [] |
) != |
(list) a |
) a = "\"" + a + "\""; |
v += a; |
l = llDeleteSubList(l, 0, 0); |
} while(l != []); |
return llDumpList2String(v, ","); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// unescapes a string in conformance with RFC1738 |
string wasURLUnescape(string i) { |
return llUnescapeURL( |
llDumpList2String( |
llParseString2List( |
llDumpList2String( |
llParseString2List( |
i, |
["+"], |
[] |
), |
" " |
), |
["%0D%0A"], |
[] |
), |
"\n" |
) |
); |
} |
|
// configuration data |
string configuration = ""; |
// store message over state. |
string src_firstname = ""; |
string src_lastname = ""; |
string dst_firstname = ""; |
string dst_lastname = ""; |
string text = ""; |
string group = ""; |
string data = ""; |
|
// recent list of avatars |
list recent_firstnames = []; |
list recent_lastnames = []; |
|
// the action to execute |
string action = ""; |
// holds SQL statements and parameters |
string statement = ""; |
string parameters = ""; |
|
default { |
state_entry() { |
llOwnerSay("[Reminders] Starting module..."); |
llSetTimerEvent(10); |
} |
link_message(integer sender, integer num, string message, key id) { |
if(id != "configuration") return; |
llOwnerSay("[Reminders] Got configuration..."); |
configuration = message; |
action = "create"; |
state trampoline; |
} |
timer() { |
llOwnerSay("[Reminders] Requesting configuration..."); |
llMessageLinked(LINK_THIS, 0, "configuration", NULL_KEY); |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
state_exit() { |
llSetTimerEvent(0); |
} |
} |
|
|
state trampoline { |
state_entry() { |
if(action == "create") { |
statement = wasURLEscape("CREATE TABLE IF NOT EXISTS \"" + |
wasKeyValueGet("reminders table", configuration) + |
"\" (message TEXT(1023), name TEXT(35), src_firstname TEXT(31), src_lastname TEXT(31), dst_firstname TEXT(31), dst_lastname TEXT(31))"); |
state query; |
} |
|
if(action == "search") { |
statement = wasURLEscape("SELECT * FROM \"" + |
wasKeyValueGet("reminders table", configuration) + |
"\" WHERE name=:group AND dst_firstname=:firstname AND dst_lastname=:lastname LIMIT 1"); |
parameters = wasURLEscape( |
wasListToCSV( |
[ |
"group", |
wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"firstname", |
wasURLEscape(dst_firstname), |
"lastname", |
wasURLEscape(dst_lastname) |
] |
) |
); |
|
state query; |
} |
|
if(action == "commit") { |
statement = wasURLEscape("INSERT INTO \"" + |
wasKeyValueGet("reminders table", configuration) + |
"\" (name, dst_firstname, dst_lastname, src_firstname, src_lastname, message) VALUES (:name, :dst_firstname, :dst_lastname, :src_firstname, :src_lastname, :message)"); |
parameters = wasURLEscape( |
wasListToCSV( |
[ |
"name", |
wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"dst_firstname", |
wasURLEscape(dst_firstname), |
"dst_lastname", |
wasURLEscape(dst_lastname), |
"src_firstname", |
wasURLEscape(src_firstname), |
"src_lastname", |
wasURLEscape(src_lastname), |
"message", wasURLEscape(text) |
] |
) |
); |
|
state query; |
} |
|
if(action == "remove") { |
statement = wasURLEscape("DELETE FROM \"" + |
wasKeyValueGet("reminders table", configuration) + |
"\" WHERE name=:name AND src_firstname=:src_firstname AND src_lastname=:src_lastname AND dst_firstname=:dst_firstname AND dst_lastname=:dst_lastname AND message=:message"); |
parameters = wasURLEscape( |
wasListToCSV( |
[ |
"name", |
wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"src_firstname", |
wasURLEscape(src_firstname), |
"src_lastname", |
wasURLEscape(src_lastname), |
"dst_firstname", |
wasURLEscape(dst_firstname), |
"dst_lastname", |
wasURLEscape(dst_lastname), |
"message", |
wasURLEscape(text) |
] |
) |
); |
state query; |
} |
|
// DEBUG |
llOwnerSay("[Reminders] Jump table corrupted, please contact vendor..."); |
llResetScript(); |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
} |
|
state query { |
state_entry() { |
// Check messge length. |
string message = wasKeyValueEncode( |
[ |
"command", "database", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
configuration |
) |
), |
"SQL", statement, |
"data", parameters, |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
); |
|
// GC - none of these are needed anymore. |
statement = ""; |
parameters = ""; |
|
// DEBUG |
llOwnerSay("[Reminders] Executing action: " + action); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
configuration |
), |
message |
); |
// GC |
message = ""; |
llSetTimerEvent(60); |
} |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "database") |
return; |
|
if(wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[Reminders] Unable query database: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
); |
state listen_group; |
} |
|
// Process actions. |
if(action == "create") { |
llOwnerSay("[Reminders] Database created!"); |
state listen_group; |
} |
|
if(action == "search") { |
list result = wasCSVToList( |
wasURLUnescape( |
wasKeyValueGet("data", body) |
) |
); |
|
// DEBUG |
//llOwnerSay(llDumpList2String(result, ",")); |
|
// 12 CSV cells, 6 fields + 6 results |
if(llGetListLength(result) != 12) { |
// DEBUG |
llOwnerSay("[Reminders] No reminders for: " + dst_firstname + " " + dst_lastname); |
state search_trampoline; |
} |
|
data = llList2String( |
result, |
llListFindList(result, ["data"]) + 1 |
); |
|
src_firstname = llList2String( |
result, |
llListFindList(result, ["src_firstname"]) + 1 |
); |
|
src_lastname = llList2String( |
result, |
llListFindList(result, ["src_lastname"]) + 1 |
); |
|
dst_firstname = llList2String( |
result, |
llListFindList(result, ["dst_firstname"]) + 1 |
); |
|
dst_lastname = llList2String( |
result, |
llListFindList(result, ["dst_lastname"]) + 1 |
); |
|
text = llList2String( |
result, |
llListFindList(result, ["message"]) + 1 |
); |
|
// Build data to be sent. |
data = dst_firstname + |
" " + |
dst_lastname + |
": " + |
text + |
" " + |
"[" + |
src_firstname + |
" " + |
src_lastname + |
"]"; |
|
// DEBUG |
//llOwnerSay("BODY: " + wasURLUnescape(body)); |
//llOwnerSay("DATA: " + wasURLUnescape(data)); |
|
state remind; |
} |
|
if(action == "commit") { |
data = "Reminder for " + dst_firstname + " " + dst_lastname + " stored."; |
state tell; |
} |
|
if(action == "remove") { |
// DEBUG |
llOwnerSay("[Reminders] Reminder removed for " + dst_firstname + " " + dst_lastname); |
|
state search_trampoline; |
} |
|
// Don't announce creating table. |
if(action == "create") |
state listen_group; |
|
// DEBUG |
llOwnerSay("[Wiki] Jump table corrupted, please contact creator..."); |
state listen_group; |
} |
timer() { |
// DEBUG |
llOwnerSay("[Reminders] Query timed out..."); |
state listen_group; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
state_exit() { |
llSetTimerEvent(0); |
} |
} |
|
state listen_group { |
state_entry() { |
// DEBUG |
llOwnerSay("[Reminders] Waiting for group messages."); |
} |
timer() { |
if(!llGetListLength(recent_firstnames) || |
!llGetListLength(recent_lastnames)) |
return; |
|
// DEBUG |
llOwnerSay("[Reminders] Starting reminders sweep..."); |
|
// jump to process the recents list |
state search_trampoline; |
} |
link_message(integer sender, integer num, string message, key id) { |
// We only care about notifications now. |
if(id != "notification") |
return; |
|
// This script only processes group notifications. |
if(wasKeyValueGet("type", message) != "group" || |
(wasKeyValueGet("type", message) == "group" && |
wasURLUnescape(wasKeyValueGet("group", message)) != |
wasKeyValueGet("group", configuration))) |
return; |
|
// Get the message sender. |
src_firstname = wasURLUnescape( |
wasKeyValueGet( |
"firstname", |
message |
) |
); |
|
src_lastname = wasURLUnescape( |
wasKeyValueGet( |
"lastname", |
message |
) |
); |
|
// Add the agent to the recents list. |
if(llListFindList(recent_firstnames, (list)src_firstname) == -1 && |
llListFindList(recent_lastnames, (list)src_lastname) == -1) { |
recent_firstnames += src_firstname; |
recent_lastnames += src_lastname; |
} |
|
// alarm 5 |
llSetTimerEvent(10); |
|
// Get the sent message. |
data = wasURLUnescape( |
wasKeyValueGet( |
"message", |
message |
) |
); |
|
// Check if this is an eggdrop command. |
if(llGetSubString(data, 0, 0) != |
wasKeyValueGet("command", configuration)) |
return; |
|
// Check if the command matches the current module. |
list command = llParseString2List(data, [" "], []); |
if(llList2String(command, 0) != |
wasKeyValueGet("command", configuration) + "remind") |
return; |
|
// Remove command. |
command = llDeleteSubList(command, 0, 0); |
|
// Retrieve the first and last name to remind. |
dst_firstname = llList2String(command, 0); |
command = llDeleteSubList(command, 0, 0); |
dst_lastname = llList2String(command, 0); |
command = llDeleteSubList(command, 0, 0); |
|
if(llStringLength(dst_firstname) == 0 || |
llStringLength(dst_lastname) == 0) { |
data = "Invalid avatar name, please use the full username!"; |
state tell; |
} |
|
// Retrieve the message to remind of. |
text = llDumpList2String(command, " "); |
if(llStringLength(message) == 0) { |
data = "No message to remind of supplied. . ."; |
state tell; |
} |
|
state validate; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
state_exit() { |
llSetTimerEvent(0); |
} |
} |
|
state validate { |
state_entry() { |
// DEBUG |
llOwnerSay("[Reminders] Searching for agent."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
configuration |
), |
wasKeyValueEncode( |
[ |
"command", "getmembers", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
configuration |
) |
), |
"sift", wasURLEscape( |
wasListToCSV( |
[ |
"match", |
wasURLEscape("(?i),?\"([^\",$]*" + dst_firstname + " " + dst_lastname + "[^\",$]*)\",?") |
] |
) |
), |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
) |
); |
llSetTimerEvent(60); |
} |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "getmembers") |
return; |
|
if(wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[Reminders] Unable to get members: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
); |
state listen_group; |
} |
|
// Dump the members to a list. |
list members = wasCSVToList( |
wasURLUnescape( |
wasKeyValueGet("data", body) |
) |
); |
|
list name = llParseString2List( |
llList2String(members, 0), |
[" "], |
[] |
); |
|
dst_firstname = llList2String(name, 0); |
dst_lastname = llList2String(name, 1); |
|
if(llStringLength(dst_firstname) == 0 || |
llStringLength(dst_lastname) == 0) { |
data = "Invalid avatar name, please use the full username!"; |
state tell; |
} |
|
action = "commit"; |
state trampoline; |
} |
timer() { |
state listen_group; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
state_exit() { |
llSetTimerEvent(0); |
} |
} |
|
state search_trampoline { |
state_entry() { |
// pop |
if(!llGetListLength(recent_firstnames) || |
!llGetListLength(recent_lastnames)) { |
state listen_group; |
} |
dst_firstname = llList2String(recent_firstnames, 0); |
recent_firstnames = llDeleteSubList(recent_firstnames, 0, 0); |
dst_lastname = llList2String(recent_lastnames, 0); |
recent_lastnames = llDeleteSubList(recent_lastnames, 0, 0); |
|
// wend |
action = "search"; |
state trampoline; |
} |
} |
|
state remind { |
state_entry() { |
// DEBUG |
llOwnerSay("[Reminders] Reminding..."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
configuration |
), |
wasKeyValueEncode( |
[ |
"command", "tell", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
configuration |
) |
), |
"entity", "group", |
"message", wasURLEscape(data) |
] |
) |
); |
|
action = "remove"; |
state trampoline; |
} |
} |
|
state tell { |
state_entry() { |
// DEBUG |
llOwnerSay("[Reminders] Sending to group."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
configuration |
), |
wasKeyValueEncode( |
[ |
"command", "tell", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
configuration |
) |
), |
"entity", "group", |
"message", wasURLEscape(data) |
] |
) |
); |
state listen_group; |
} |
} |
/source/eggdrop/softban.lsl |
@@ -1,5 +1,5 @@ |
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2016 - License: CC BY 2.0 // |
// Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// |
// A module that bans group members using fuzzy name matching. |
@@ -12,7 +12,7 @@ |
string wasKeyValueGet(string k, string data) { |
if(llStringLength(data) == 0) return ""; |
if(llStringLength(k) == 0) return ""; |
list a = llParseStringKeepNulls(data, ["&", "="], []); |
list a = llParseString2List(data, ["&", "="], []); |
integer i = llListFindList(llList2ListStrided(a, 0, -1, 2), [ k ]); |
if(i != -1) return llList2String(a, 2*i+1); |
return ""; |
@@ -19,7 +19,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2013 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasKeyValueEncode(list data) { |
list k = llList2ListStrided(data, 0, -1, 2); |
@@ -34,7 +34,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2011 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// http://was.fm/secondlife/wanderer |
vector wasCirclePoint(float radius) { |
@@ -46,7 +46,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// escapes a string in conformance with RFC1738 |
string wasURLEscape(string i) { |
@@ -70,7 +70,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
list wasCSVToList(string csv) { |
list l = []; |
@@ -109,7 +109,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasListToCSV(list l) { |
list v = []; |
@@ -138,7 +138,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// unescapes a string in conformance with RFC1738 |
string wasURLUnescape(string i) { |
@@ -162,7 +162,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2017 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
list wasSetIntersect(list a, list b) { |
if(llGetListLength(a) == 0) return []; |
@@ -175,8 +175,6 @@ |
|
// configuration data |
string configuration = ""; |
// callback URL |
string URL = ""; |
// store message over state. |
string data = ""; |
// banee |
@@ -225,7 +223,10 @@ |
return; |
|
// This script only processes group notifications. |
if(wasKeyValueGet("type", message) != "group") |
if(wasKeyValueGet("type", message) != "group" || |
(wasKeyValueGet("type", message) == "group" && |
wasURLUnescape(wasKeyValueGet("group", message)) != |
wasKeyValueGet("group", configuration))) |
return; |
|
// Get the sent message. |
@@ -261,32 +262,7 @@ |
// Dump the rest of the message. |
data = llDumpList2String(command, " "); |
|
// Get an URL. |
state url; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
} |
|
state url { |
state_entry() { |
// DEBUG |
llOwnerSay("[Softban] Requesting URL..."); |
llRequestURL(); |
} |
http_request(key id, string method, string body) { |
if(method != URL_REQUEST_GRANTED) return; |
URL = body; |
// DEBUG |
llOwnerSay("[Softban] Got URL..."); |
// Get roles of callers. |
state get_caller_roles; |
} |
on_rez(integer num) { |
@@ -327,16 +303,23 @@ |
), |
"firstname", firstname, |
"lastname", lastname, |
"callback", wasURLEscape(URL) |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
) |
); |
llSetTimerEvent(60); |
} |
http_request(key id, string method, string body) { |
llHTTPResponse(id, 200, "OK"); |
if(wasKeyValueGet("command", body) != "getmemberroles" || |
wasKeyValueGet("success", body) != "True") { |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "getmemberroles") |
return; |
|
if(wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[Softban] Unable to get member roles: " + |
wasURLUnescape( |
@@ -343,7 +326,6 @@ |
wasKeyValueGet("error", body) |
) |
); |
llReleaseURL(URL); |
state listen_group; |
} |
|
@@ -364,7 +346,6 @@ |
) |
) == 0) { |
data = "You ain't got the cojones!"; |
llReleaseURL(URL); |
state tell; |
} |
|
@@ -390,7 +371,6 @@ |
state get_banee_roles; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
@@ -434,16 +414,23 @@ |
), |
"firstname", firstname, |
"lastname", lastname, |
"callback", wasURLEscape(URL) |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
) |
); |
llSetTimerEvent(60); |
} |
http_request(key id, string method, string body) { |
llHTTPResponse(id, 200, "OK"); |
if(wasKeyValueGet("command", body) != "getmemberroles" || |
wasKeyValueGet("success", body) != "True") { |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "getmemberroles") |
return; |
|
if(wasKeyValueGet("success", body) != "True") { |
if(wasKeyValueGet("status", body) == "19862") { |
// DEBUG |
llOwnerSay("[Softban] User not in group, but proceeding anyway..."); |
@@ -455,7 +442,6 @@ |
wasKeyValueGet("error", body) |
) |
); |
llReleaseURL(URL); |
state listen_group; |
} |
|
@@ -466,7 +452,6 @@ |
|
if(result != "" && llListFindList(wasCSVToList(result), (list)"Owners") != -1) { |
data = "Ejectee is an owner. I'm not gunna open the pod bay doors."; |
llReleaseURL(URL); |
state tell; |
} |
|
@@ -473,7 +458,6 @@ |
state ban; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
@@ -530,15 +514,22 @@ |
] |
) |
), |
"callback", wasURLEscape(URL) |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
) |
); |
llSetTimerEvent(60); |
} |
http_request(key id, string method, string body) { |
llHTTPResponse(id, 200, "OK"); |
llReleaseURL(URL); |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "softban") |
return; |
|
if(wasKeyValueGet("command", body) != "softban" || |
wasKeyValueGet("success", body) != "True") { |
// DEBUG |
@@ -555,7 +546,6 @@ |
state tell; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
/source/eggdrop/softunban.lsl |
@@ -1,5 +1,5 @@ |
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2016 - License: CC BY 2.0 // |
// Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// |
// A module that unbans group members using fuzzy name matching. |
@@ -17,9 +17,9 @@ |
if(i != -1) return llList2String(a, 2*i+1); |
return ""; |
} |
|
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2013 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasKeyValueEncode(list data) { |
list k = llList2ListStrided(data, 0, -1, 2); |
@@ -34,7 +34,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2011 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// http://was.fm/secondlife/wanderer |
vector wasCirclePoint(float radius) { |
@@ -46,7 +46,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// escapes a string in conformance with RFC1738 |
string wasURLEscape(string i) { |
@@ -70,7 +70,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
list wasCSVToList(string csv) { |
list l = []; |
@@ -109,7 +109,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasListToCSV(list l) { |
list v = []; |
@@ -117,18 +117,18 @@ |
string a = llDumpList2String( |
llParseStringKeepNulls( |
llList2String( |
l, |
l, |
0 |
), |
["\""], |
), |
["\""], |
[] |
), |
"\"\"" |
); |
if(llParseStringKeepNulls( |
a, |
a, |
[" ", ",", "\n", "\""], [] |
) != |
) != |
(list) a |
) a = "\"" + a + "\""; |
v += a; |
@@ -138,7 +138,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// unescapes a string in conformance with RFC1738 |
string wasURLUnescape(string i) { |
@@ -147,15 +147,15 @@ |
llParseString2List( |
llDumpList2String( |
llParseString2List( |
i, |
["+"], |
i, |
["+"], |
[] |
), |
), |
" " |
), |
["%0D%0A"], |
), |
["%0D%0A"], |
[] |
), |
), |
"\n" |
) |
); |
@@ -162,7 +162,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2017 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
list wasSetIntersect(list a, list b) { |
if(llGetListLength(a) == 0) return []; |
@@ -175,8 +175,6 @@ |
|
// configuration data |
string configuration = ""; |
// callback URL |
string URL = ""; |
// store message over state. |
string data = ""; |
// banee |
@@ -202,8 +200,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -222,70 +220,48 @@ |
// We only care about notifications now. |
if(id != "notification") |
return; |
|
|
// This script only processes group notifications. |
if(wasKeyValueGet("type", message) != "group") |
if(wasKeyValueGet("type", message) != "group" || |
(wasKeyValueGet("type", message) == "group" && |
wasURLUnescape(wasKeyValueGet("group", message)) != |
wasKeyValueGet("group", configuration))) |
return; |
|
|
// Get the sent message. |
data = wasURLUnescape( |
wasKeyValueGet( |
"message", |
"message", |
message |
) |
); |
|
|
// Check if this is an eggdrop command. |
if(llGetSubString(data, 0, 0) != |
if(llGetSubString(data, 0, 0) != |
wasKeyValueGet("command", configuration)) |
return; |
|
|
// Check if the command matches the current module. |
list command = llParseString2List(data, [" "], []); |
if(llList2String(command, 0) != |
if(llList2String(command, 0) != |
wasKeyValueGet("command", configuration) + "softunban") |
return; |
|
|
// Remove command. |
command = llDeleteSubList(command, 0, 0); |
|
|
firstname = wasKeyValueGet("firstname", message); |
lastname = wasKeyValueGet("lastname", message); |
|
|
if(firstname == "" || lastname == "") { |
data = "And who would yarr be?"; |
state tell; |
} |
|
|
// Dump the rest of the message. |
data = llDumpList2String(command, " "); |
|
// Get an URL. |
state url; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
} |
|
state url { |
state_entry() { |
// DEBUG |
llOwnerSay("[Softunban] Requesting URL..."); |
llRequestURL(); |
} |
http_request(key id, string method, string body) { |
if(method != URL_REQUEST_GRANTED) return; |
URL = body; |
// DEBUG |
llOwnerSay("[Softunban] Got URL..."); |
// Get roles of caller. |
state get_caller_roles; |
} |
on_rez(integer num) { |
@@ -292,8 +268,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -306,46 +282,52 @@ |
llOwnerSay("[Softunban] Searching for caller..."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
), |
wasKeyValueEncode( |
[ |
"command", "getmemberroles", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |
"firstname", firstname, |
"lastname", lastname, |
"callback", wasURLEscape(URL) |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
) |
); |
llSetTimerEvent(60); |
} |
http_request(key id, string method, string body) { |
llHTTPResponse(id, 200, "OK"); |
if(wasKeyValueGet("command", body) != "getmemberroles" || |
wasKeyValueGet("success", body) != "True") { |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "getmemberroles") |
return; |
|
if(wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[Softunban] Unable to get member roles: " + |
llOwnerSay("[Softunban] Unable to get member roles: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
); |
llReleaseURL(URL); |
state listen_group; |
} |
|
|
// Dump the roles to a list. |
list roles = wasCSVToList( |
wasURLUnescape( |
@@ -352,9 +334,9 @@ |
wasKeyValueGet("data", body) |
) |
); |
|
|
if(llGetListLength( |
wasSetIntersect(roles, |
wasSetIntersect(roles, |
wasCSVToList( |
wasKeyValueGet( |
"admin roles", configuration |
@@ -363,26 +345,24 @@ |
) |
) == 0) { |
data = "You ain't got the cojones!"; |
llReleaseURL(URL); |
state tell; |
} |
|
|
list banee = llParseString2List(data, [" "], []); |
|
|
firstname = llList2String(banee, 0); |
lastname = llList2String(banee, 1); |
|
|
if(firstname == "" || lastname == "") { |
data = "Full name required."; |
state tell; |
} |
|
|
// GC |
banee = []; |
state get_banee_roles; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
@@ -389,8 +369,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -406,36 +386,43 @@ |
llOwnerSay("[Softunban] Searching for banee..."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
), |
wasKeyValueEncode( |
[ |
"command", "getmemberroles", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |
"firstname", firstname, |
"lastname", lastname, |
"callback", wasURLEscape(URL) |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
) |
); |
llSetTimerEvent(60); |
} |
http_request(key id, string method, string body) { |
llHTTPResponse(id, 200, "OK"); |
if(wasKeyValueGet("command", body) != "getmemberroles" || |
wasKeyValueGet("success", body) != "True") { |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "getmemberroles") |
return; |
|
if(wasKeyValueGet("success", body) != "True") { |
if(wasKeyValueGet("status", body) == "19862") { |
// DEBUG |
llOwnerSay("[Softunban] User not in group, but proceeding anyway..."); |
@@ -442,31 +429,28 @@ |
jump continue; |
} |
// DEBUG |
llOwnerSay("[Softunban] Unable to get member roles: " + |
llOwnerSay("[Softunban] Unable to get member roles: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
); |
llReleaseURL(URL); |
state listen_group; |
} |
|
|
string result = wasURLUnescape( |
wasKeyValueGet("data", body) |
); |
|
|
if(result != "" && llListFindList(wasCSVToList(result), (list)"Owners") != -1) { |
data = "Ejectee is an owner. I'm not gonna open the pod bay doors."; |
llReleaseURL(URL); |
state tell; |
} |
|
|
@continue; |
|
state unban; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
@@ -473,8 +457,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -490,21 +474,21 @@ |
llOwnerSay("[Softunban] Unbanning..."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
), |
wasKeyValueEncode( |
[ |
"command", "softban", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |
@@ -516,19 +500,25 @@ |
] |
) |
), |
"callback", wasURLEscape(URL) |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
) |
); |
llSetTimerEvent(60); |
} |
http_request(key id, string method, string body) { |
llHTTPResponse(id, 200, "OK"); |
llReleaseURL(URL); |
if(wasKeyValueGet("command", body) != "softban" || |
wasKeyValueGet("success", body) != "True") { |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "softban") |
return; |
|
if(wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[Softunban] Unable to ban member: " + |
llOwnerSay("[Softunban] Unable to ban member: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
@@ -535,13 +525,12 @@ |
); |
state listen_group; |
} |
|
|
data = "They'll be bak!"; |
|
|
state tell; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
@@ -548,8 +537,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -565,21 +554,21 @@ |
llOwnerSay("[Softunban] Sending to group."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
), |
wasKeyValueEncode( |
[ |
"command", "tell", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |
@@ -588,7 +577,7 @@ |
] |
) |
); |
|
|
state listen_group; |
} |
} |
/source/eggdrop/spank.lsl |
@@ -1,5 +1,5 @@ |
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2016 - License: CC BY 2.0 // |
// Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// |
// A module that spanks group members using fuzzy name matching. . . |
@@ -17,9 +17,9 @@ |
if(i != -1) return llList2String(a, 2*i+1); |
return ""; |
} |
|
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2013 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasKeyValueEncode(list data) { |
list k = llList2ListStrided(data, 0, -1, 2); |
@@ -34,7 +34,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2011 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// http://was.fm/secondlife/wanderer |
vector wasCirclePoint(float radius) { |
@@ -46,7 +46,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// escapes a string in conformance with RFC1738 |
string wasURLEscape(string i) { |
@@ -70,7 +70,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
list wasCSVToList(string csv) { |
list l = []; |
@@ -109,7 +109,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasListToCSV(list l) { |
list v = []; |
@@ -117,18 +117,18 @@ |
string a = llDumpList2String( |
llParseStringKeepNulls( |
llList2String( |
l, |
l, |
0 |
), |
["\""], |
), |
["\""], |
[] |
), |
"\"\"" |
); |
if(llParseStringKeepNulls( |
a, |
a, |
[" ", ",", "\n", "\""], [] |
) != |
) != |
(list) a |
) a = "\"" + a + "\""; |
v += a; |
@@ -138,7 +138,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// unescapes a string in conformance with RFC1738 |
string wasURLUnescape(string i) { |
@@ -147,15 +147,15 @@ |
llParseString2List( |
llDumpList2String( |
llParseString2List( |
i, |
["+"], |
i, |
["+"], |
[] |
), |
), |
" " |
), |
["%0D%0A"], |
), |
["%0D%0A"], |
[] |
), |
), |
"\n" |
) |
); |
@@ -163,8 +163,6 @@ |
|
// configuration data |
string configuration = ""; |
// callback URL |
string URL = ""; |
// store message over state. |
string data = ""; |
|
@@ -187,8 +185,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -207,62 +205,40 @@ |
// We only care about notifications now. |
if(id != "notification") |
return; |
|
|
// This script only processes group notifications. |
if(wasKeyValueGet("type", message) != "group") |
if(wasKeyValueGet("type", message) != "group" || |
(wasKeyValueGet("type", message) == "group" && |
wasURLUnescape(wasKeyValueGet("group", message)) != |
wasKeyValueGet("group", configuration))) |
return; |
|
|
// Get the sent message. |
data = wasURLUnescape( |
wasKeyValueGet( |
"message", |
"message", |
message |
) |
); |
|
|
// Check if this is an eggdrop command. |
if(llGetSubString(data, 0, 0) != |
if(llGetSubString(data, 0, 0) != |
wasKeyValueGet("command", configuration)) |
return; |
|
|
// Check if the command matches the current module. |
list command = llParseString2List(data, [" "], []); |
if(llList2String(command, 0) != |
if(llList2String(command, 0) != |
wasKeyValueGet("command", configuration) + "spank") |
return; |
|
|
// Remove command. |
command = llDeleteSubList(command, 0, 0); |
|
|
// Dump the rest of the message. |
data = llDumpList2String(command, " "); |
|
// Get an URL. |
state url; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
} |
|
state url { |
state_entry() { |
// DEBUG |
llOwnerSay("[Spank] Requesting URL..."); |
llRequestURL(); |
} |
http_request(key id, string method, string body) { |
if(method != URL_REQUEST_GRANTED) return; |
URL = body; |
// DEBUG |
llOwnerSay("[Spank] Got URL..."); |
// Search for member. |
state search; |
} |
on_rez(integer num) { |
@@ -269,8 +245,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -283,21 +259,21 @@ |
llOwnerSay("[Spank] Searching for agent."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
), |
wasKeyValueEncode( |
[ |
"command", "getmembers", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |
@@ -309,19 +285,25 @@ |
] |
) |
), |
"callback", wasURLEscape(URL) |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
) |
); |
llSetTimerEvent(60); |
} |
http_request(key id, string method, string body) { |
llHTTPResponse(id, 200, "OK"); |
llReleaseURL(URL); |
if(wasKeyValueGet("command", body) != "getmembers" || |
wasKeyValueGet("success", body) != "True") { |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "getmembers") |
return; |
|
if(wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[Spank] Unable to get members: " + |
llOwnerSay("[Spank] Unable to get members: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
@@ -328,7 +310,7 @@ |
); |
state listen_group; |
} |
|
|
// Dump the members to a list. |
list spankees = wasCSVToList( |
wasURLUnescape( |
@@ -335,26 +317,25 @@ |
wasKeyValueGet("data", body) |
) |
); |
|
|
// Limit to two people to spank. |
if(llGetListLength(spankees) > 2) { |
data = "So many people, so few hands!"; |
return; |
state tell; |
} |
|
|
data = llList2CSV(spankees); |
|
|
if(data == "") { |
data = "I could not find anyone to spank (story of my life)."; |
state tell; |
} |
|
|
data = "/me spanks " + data; |
|
|
state tell; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
@@ -361,8 +342,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -378,21 +359,21 @@ |
llOwnerSay("[Spank] Sending to group."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
), |
wasKeyValueEncode( |
[ |
"command", "tell", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |
/source/eggdrop/survey.lsl |
@@ -0,0 +1,574 @@ |
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// |
// A fortune module for Corrade Eggdrop. |
// |
/////////////////////////////////////////////////////////////////////////// |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
/////////////////////////////////////////////////////////////////////////// |
string wasKeyValueGet(string k, string data) { |
if(llStringLength(data) == 0) return ""; |
if(llStringLength(k) == 0) return ""; |
list a = llParseStringKeepNulls(data, ["&", "="], []); |
integer i = llListFindList(llList2ListStrided(a, 0, -1, 2), [ k ]); |
if(i != -1) return llList2String(a, 2*i+1); |
return ""; |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasKeyValueEncode(list data) { |
list k = llList2ListStrided(data, 0, -1, 2); |
list v = llList2ListStrided(llDeleteSubList(data, 0, 0), 0, -1, 2); |
data = []; |
do { |
data += llList2String(k, 0) + "=" + llList2String(v, 0); |
k = llDeleteSubList(k, 0, 0); |
v = llDeleteSubList(v, 0, 0); |
} while(llGetListLength(k) != 0); |
return llDumpList2String(data, "&"); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// http://was.fm/secondlife/wanderer |
vector wasCirclePoint(float radius) { |
float x = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2); |
float y = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2); |
if(llPow(x,2) + llPow(y,2) <= llPow(radius,2)) |
return <x, y, 0>; |
return wasCirclePoint(radius); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// escapes a string in conformance with RFC1738 |
string wasURLEscape(string i) { |
string o = ""; |
do { |
string c = llGetSubString(i, 0, 0); |
i = llDeleteSubString(i, 0, 0); |
if(c == "") jump continue; |
if(c == " ") { |
o += "+"; |
jump continue; |
} |
if(c == "\n") { |
o += "%0D" + llEscapeURL(c); |
jump continue; |
} |
o += llEscapeURL(c); |
@continue; |
} while(i != ""); |
return o; |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
list wasCSVToList(string csv) { |
list l = []; |
list s = []; |
string m = ""; |
do { |
string a = llGetSubString(csv, 0, 0); |
csv = llDeleteSubString(csv, 0, 0); |
if(a == ",") { |
if(llList2String(s, -1) != "\"") { |
l += m; |
m = ""; |
jump continue; |
} |
m += a; |
jump continue; |
} |
if(a == "\"" && llGetSubString(csv, 0, 0) == a) { |
m += a; |
csv = llDeleteSubString(csv, 0, 0); |
jump continue; |
} |
if(a == "\"") { |
if(llList2String(s, -1) != a) { |
s += a; |
jump continue; |
} |
s = llDeleteSubList(s, -1, -1); |
jump continue; |
} |
m += a; |
@continue; |
} while(csv != ""); |
// postcondition: length(s) = 0 |
return l + m; |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasListToCSV(list l) { |
list v = []; |
do { |
string a = llDumpList2String( |
llParseStringKeepNulls( |
llList2String( |
l, |
0 |
), |
["\""], |
[] |
), |
"\"\"" |
); |
if(llParseStringKeepNulls( |
a, |
[" ", ",", "\n", "\""], [] |
) != |
(list) a |
) a = "\"" + a + "\""; |
v += a; |
l = llDeleteSubList(l, 0, 0); |
} while(l != []); |
return llDumpList2String(v, ","); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// unescapes a string in conformance with RFC1738 |
string wasURLUnescape(string i) { |
return llUnescapeURL( |
llDumpList2String( |
llParseString2List( |
llDumpList2String( |
llParseString2List( |
i, |
["+"], |
[] |
), |
" " |
), |
["%0D%0A"], |
[] |
), |
"\n" |
) |
); |
} |
|
// configuration data |
string configuration = ""; |
// callback URL |
string URL = ""; |
// store message over state. |
string data = ""; |
|
key queryID = NULL_KEY; |
string region = ""; |
|
string teleport_continue = ""; |
|
default { |
state_entry() { |
llOwnerSay("[Survey] Starting module..."); |
llSetTimerEvent(10); |
} |
link_message(integer sender, integer num, string message, key id) { |
if(id != "configuration") return; |
llOwnerSay("[Survey] Got configuration..."); |
configuration = message; |
state listen_group; |
} |
timer() { |
llOwnerSay("[Survey] Requesting configuration..."); |
llMessageLinked(LINK_THIS, 0, "configuration", NULL_KEY); |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
state_exit() { |
llSetTimerEvent(0); |
} |
} |
|
state listen_group { |
state_entry() { |
// DEBUG |
llOwnerSay("[Survey] Waiting for group messages..."); |
} |
link_message(integer sender, integer num, string message, key id) { |
// We only care about notifications now. |
if(id != "notification") |
return; |
|
// This script only processes group notifications. |
if(wasKeyValueGet("type", message) != "group" || |
(wasKeyValueGet("type", message) == "group" && |
wasURLUnescape(wasKeyValueGet("group", message)) != |
wasKeyValueGet("group", configuration))) |
return; |
|
// Get the sent message. |
data = wasURLUnescape( |
wasKeyValueGet( |
"message", |
message |
) |
); |
|
// Check if this is an eggdrop command. |
if(llGetSubString(data, 0, 0) != |
wasKeyValueGet("command", configuration)) |
return; |
|
// Check if the command matches the current module. |
list command = llParseString2List(data, [" "], []); |
if(llList2String(command, 0) != |
wasKeyValueGet("command", configuration) + "survey") |
return; |
|
// Remove command. |
command = llDeleteSubList(command, 0, 0); |
|
// Store the region name. |
region = llStringTrim( |
llDumpList2String( |
command, " " |
), |
STRING_TRIM |
); |
|
if(llStringLength(region) == 0) { |
data = "Must specify a region name"; |
state tell; |
} |
|
llOwnerSay("[Survey] Checking region..."); |
queryID = llRequestSimulatorData(region, DATA_SIM_STATUS); |
} |
dataserver(key query_id, string data) { |
if(query_id != queryID) |
return; |
|
if(data == "unknown") { |
data = "Region not found or in unknown state."; |
state tell; |
} |
|
if(data == "down") { |
data = "Region is down."; |
state tell; |
} |
|
if(data == "starting") { |
data = "Region is currently starting."; |
state tell; |
} |
|
if(data == "stopping") { |
data = "Region is stopping."; |
state tell; |
} |
|
if(data == "crashed") { |
data = "Region has crashed."; |
state tell; |
} |
|
// Teleport. |
teleport_continue = "stats_trampoline"; |
state teleport_trampoline; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
} |
|
state teleport_trampoline { |
state_entry() { |
// DEBUG |
llOwnerSay("Sleeping..."); |
llSetTimerEvent(3); |
} |
timer() { |
state teleport; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
state_exit() { |
llSetTimerEvent(0); |
} |
} |
|
state teleport { |
state_entry() { |
llOwnerSay("[Survey] Teleporting..."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
configuration |
), |
wasKeyValueEncode( |
[ |
"command", "teleport", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
configuration |
) |
), |
"entity", "region", |
"region", wasURLEscape(region), |
"position", wasURLEscape("<128, 128, 4096>"), |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
) |
); |
|
llSetTimerEvent(60); |
} |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "teleport") |
return; |
|
if(wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[Survey] Teleport failed: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
); |
state listen_group; |
} |
|
if(teleport_continue == "stats_trampoline") |
state stats_trampoline; |
|
if(teleport_continue == "tell") |
state tell; |
|
llOwnerSay("[Survey] Jump tables corrupt, please contact vendor."); |
llResetScript(); |
} |
timer() { |
data = "Teleport timed out..."; |
state tell; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
state_exit() { |
llSetTimerEvent(0); |
} |
} |
|
state stats_trampoline { |
state_entry() { |
// DEBUG |
llOwnerSay("Sleeping..."); |
llSetTimerEvent(3); |
} |
timer() { |
state stats; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
state_exit() { |
llSetTimerEvent(0); |
} |
} |
|
state stats { |
state_entry() { |
llSleep(10); |
llOwnerSay("[Survey] Getting region statistics..."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
configuration |
), |
wasKeyValueEncode( |
[ |
"command", "getregiondata", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
configuration |
) |
), |
"data", wasListToCSV( |
[ |
"Stats.LastLag", |
"Stats.Agents", |
"Stats.Dilation", |
"Stats.FPS", |
"Stats.ActiveScripts", |
"Stats.ScriptTime", |
"Stats.Objects", |
"Stats.PhysicsFPS", |
"Stats.ScriptTime" |
] |
), |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
) |
); |
|
llSetTimerEvent(300); |
} |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "getregiondata") |
return; |
|
if(wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[Survey] Stats failed: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
); |
state listen_group; |
} |
|
list stat = wasCSVToList( |
wasURLUnescape( |
wasKeyValueGet( |
"data", |
body |
) |
) |
); |
|
data = llDumpList2String(stat, " "); |
|
// Go home. |
region = wasKeyValueGet( |
"home region", |
configuration |
); |
teleport_continue = "tell"; |
state teleport_trampoline; |
} |
timer() { |
// Go home. |
region = wasKeyValueGet( |
"home region", |
configuration |
); |
data = "Fetching data timed out..."; |
teleport_continue = "tell"; |
state teleport_trampoline; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
state_exit() { |
llSetTimerEvent(0); |
} |
} |
|
state tell { |
state_entry() { |
// DEBUG |
llOwnerSay("[Survey] Sending to group."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
configuration |
), |
wasKeyValueEncode( |
[ |
"command", "tell", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
configuration |
) |
), |
"entity", "group", |
"message", wasURLEscape(data) |
] |
) |
); |
state listen_group; |
} |
} |
/source/eggdrop/unban.lsl |
@@ -1,5 +1,5 @@ |
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2016 - License: CC BY 2.0 // |
// Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// |
// A module that unbans group members using fuzzy name matching. |
@@ -17,9 +17,9 @@ |
if(i != -1) return llList2String(a, 2*i+1); |
return ""; |
} |
|
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2013 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasKeyValueEncode(list data) { |
list k = llList2ListStrided(data, 0, -1, 2); |
@@ -34,7 +34,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2011 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// http://was.fm/secondlife/wanderer |
vector wasCirclePoint(float radius) { |
@@ -46,7 +46,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// escapes a string in conformance with RFC1738 |
string wasURLEscape(string i) { |
@@ -70,7 +70,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
list wasCSVToList(string csv) { |
list l = []; |
@@ -109,7 +109,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasListToCSV(list l) { |
list v = []; |
@@ -117,18 +117,18 @@ |
string a = llDumpList2String( |
llParseStringKeepNulls( |
llList2String( |
l, |
l, |
0 |
), |
["\""], |
), |
["\""], |
[] |
), |
"\"\"" |
); |
if(llParseStringKeepNulls( |
a, |
a, |
[" ", ",", "\n", "\""], [] |
) != |
) != |
(list) a |
) a = "\"" + a + "\""; |
v += a; |
@@ -138,7 +138,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// unescapes a string in conformance with RFC1738 |
string wasURLUnescape(string i) { |
@@ -147,15 +147,15 @@ |
llParseString2List( |
llDumpList2String( |
llParseString2List( |
i, |
["+"], |
i, |
["+"], |
[] |
), |
), |
" " |
), |
["%0D%0A"], |
), |
["%0D%0A"], |
[] |
), |
), |
"\n" |
) |
); |
@@ -162,7 +162,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2017 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
list wasSetIntersect(list a, list b) { |
if(llGetListLength(a) == 0) return []; |
@@ -175,8 +175,6 @@ |
|
// configuration data |
string configuration = ""; |
// callback URL |
string URL = ""; |
// store message over state. |
string data = ""; |
// banee |
@@ -203,8 +201,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -223,70 +221,48 @@ |
// We only care about notifications now. |
if(id != "notification") |
return; |
|
|
// This script only processes group notifications. |
if(wasKeyValueGet("type", message) != "group") |
if(wasKeyValueGet("type", message) != "group" || |
(wasKeyValueGet("type", message) == "group" && |
wasURLUnescape(wasKeyValueGet("group", message)) != |
wasKeyValueGet("group", configuration))) |
return; |
|
|
// Get the sent message. |
data = wasURLUnescape( |
wasKeyValueGet( |
"message", |
"message", |
message |
) |
); |
|
|
// Check if this is an eggdrop command. |
if(llGetSubString(data, 0, 0) != |
if(llGetSubString(data, 0, 0) != |
wasKeyValueGet("command", configuration)) |
return; |
|
|
// Check if the command matches the current module. |
list command = llParseString2List(data, [" "], []); |
if(llList2String(command, 0) != |
if(llList2String(command, 0) != |
wasKeyValueGet("command", configuration) + "unban") |
return; |
|
|
// Remove command. |
command = llDeleteSubList(command, 0, 0); |
|
|
firstname = wasKeyValueGet("firstname", message); |
lastname = wasKeyValueGet("lastname", message); |
|
|
if(firstname == "" || lastname == "") { |
data = "And who would yarr be?"; |
state tell; |
} |
|
|
// Dump the rest of the message. |
data = llDumpList2String(command, " "); |
|
// Get an URL. |
state url; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
} |
|
state url { |
state_entry() { |
// DEBUG |
llOwnerSay("[Unban] Requesting URL..."); |
llRequestURL(); |
} |
http_request(key id, string method, string body) { |
if(method != URL_REQUEST_GRANTED) return; |
URL = body; |
// DEBUG |
llOwnerSay("[Unban] Got URL..."); |
// Get roles of caller. |
state get_caller_roles; |
} |
on_rez(integer num) { |
@@ -293,8 +269,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -307,46 +283,52 @@ |
llOwnerSay("[Unban] Searching for caller..."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
), |
wasKeyValueEncode( |
[ |
"command", "getmemberroles", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |
"firstname", firstname, |
"lastname", lastname, |
"callback", wasURLEscape(URL) |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
) |
); |
llSetTimerEvent(60); |
} |
http_request(key id, string method, string body) { |
llHTTPResponse(id, 200, "OK"); |
if(wasKeyValueGet("command", body) != "getmemberroles" || |
wasKeyValueGet("success", body) != "True") { |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "getmemberroles") |
return; |
|
if(wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[Unban] Unable to get member roles: " + |
llOwnerSay("[Unban] Unable to get member roles: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
); |
llReleaseURL(URL); |
state listen_group; |
} |
|
|
// Dump the roles to a list. |
list roles = wasCSVToList( |
wasURLUnescape( |
@@ -353,9 +335,9 @@ |
wasKeyValueGet("data", body) |
) |
); |
|
|
if(llGetListLength( |
wasSetIntersect(roles, |
wasSetIntersect(roles, |
wasCSVToList( |
wasKeyValueGet( |
"admin roles", configuration |
@@ -364,34 +346,32 @@ |
) |
) == 0) { |
data = "You ain't got the cojones!"; |
llReleaseURL(URL); |
state tell; |
} |
|
|
list banee = llParseString2List(data, [" "], []); |
|
|
firstname = llList2String(banee, 0); |
banee = llDeleteSubList(banee, 0, 0); |
lastname = llList2String(banee, 0); |
banee = llDeleteSubList(banee, 0, 0); |
|
|
if(firstname == "" || lastname == "") { |
data = "Full name required."; |
state tell; |
} |
|
if(llGetListLength(banee) != 0 && |
|
if(llGetListLength(banee) != 0 && |
llToLower(llList2String(banee, 0)) == "nosoft") { |
soft = "False"; |
banee = llDeleteSubList(banee, 0, 0); |
} |
|
|
// GC |
banee = []; |
state get_banee_roles; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
@@ -398,8 +378,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -415,36 +395,43 @@ |
llOwnerSay("[Unban] Searching for banee..."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
), |
wasKeyValueEncode( |
[ |
"command", "getmemberroles", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |
"firstname", firstname, |
"lastname", lastname, |
"callback", wasURLEscape(URL) |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
) |
); |
llSetTimerEvent(60); |
} |
http_request(key id, string method, string body) { |
llHTTPResponse(id, 200, "OK"); |
if(wasKeyValueGet("command", body) != "getmemberroles" || |
wasKeyValueGet("success", body) != "True") { |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "getmemberroles") |
return; |
|
if(wasKeyValueGet("success", body) != "True") { |
if(wasKeyValueGet("status", body) == "19862") { |
// DEBUG |
llOwnerSay("[Unban] User not in group, but proceeding anyway..."); |
@@ -451,31 +438,29 @@ |
jump continue; |
} |
// DEBUG |
llOwnerSay("[Unban] Unable to get member roles: " + |
llOwnerSay("[Unban] Unable to get member roles: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
); |
llReleaseURL(URL); |
|
state listen_group; |
} |
|
|
string result = wasURLUnescape( |
wasKeyValueGet("data", body) |
); |
|
|
if(result != "" && llListFindList(wasCSVToList(result), (list)"Owners") != -1) { |
data = "Ejectee is an owner. I'm not gonna open the pod bay doors."; |
llReleaseURL(URL); |
state tell; |
} |
|
|
@continue; |
|
state unban; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
@@ -482,8 +467,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -499,21 +484,21 @@ |
llOwnerSay("[Unban] Unbanning..."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
), |
wasKeyValueEncode( |
[ |
"command", "ban", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |
@@ -526,19 +511,25 @@ |
] |
) |
), |
"callback", wasURLEscape(URL) |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
) |
); |
llSetTimerEvent(60); |
} |
http_request(key id, string method, string body) { |
llHTTPResponse(id, 200, "OK"); |
llReleaseURL(URL); |
if(wasKeyValueGet("command", body) != "ban" || |
wasKeyValueGet("success", body) != "True") { |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "ban") |
return; |
|
if(wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[Unban] Unable to ban member: " + |
llOwnerSay("[Unban] Unable to ban member: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
@@ -545,13 +536,12 @@ |
); |
state listen_group; |
} |
|
|
data = "They'll be bak!"; |
|
|
state tell; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
@@ -558,8 +548,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -575,21 +565,21 @@ |
llOwnerSay("[Unban] Sending to group."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
), |
wasKeyValueEncode( |
[ |
"command", "tell", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |
@@ -598,10 +588,10 @@ |
] |
) |
); |
|
|
// reset variables. |
soft = "True"; |
|
|
state listen_group; |
} |
} |
/source/eggdrop/urbandictionary.lsl |
@@ -0,0 +1,388 @@ |
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// |
// A module that pulls information from an encyclopedia. |
// |
/////////////////////////////////////////////////////////////////////////// |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
/////////////////////////////////////////////////////////////////////////// |
string wasKeyValueGet(string k, string data) { |
if(llStringLength(data) == 0) return ""; |
if(llStringLength(k) == 0) return ""; |
list a = llParseStringKeepNulls(data, ["&", "="], []); |
integer i = llListFindList(llList2ListStrided(a, 0, -1, 2), [ k ]); |
if(i != -1) return llList2String(a, 2*i+1); |
return ""; |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasKeyValueEncode(list data) { |
list k = llList2ListStrided(data, 0, -1, 2); |
list v = llList2ListStrided(llDeleteSubList(data, 0, 0), 0, -1, 2); |
data = []; |
do { |
data += llList2String(k, 0) + "=" + llList2String(v, 0); |
k = llDeleteSubList(k, 0, 0); |
v = llDeleteSubList(v, 0, 0); |
} while(llGetListLength(k) != 0); |
return llDumpList2String(data, "&"); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// http://was.fm/secondlife/wanderer |
vector wasCirclePoint(float radius) { |
float x = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2); |
float y = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2); |
if(llPow(x,2) + llPow(y,2) <= llPow(radius,2)) |
return <x, y, 0>; |
return wasCirclePoint(radius); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// escapes a string in conformance with RFC1738 |
string wasURLEscape(string i) { |
string o = ""; |
do { |
string c = llGetSubString(i, 0, 0); |
i = llDeleteSubString(i, 0, 0); |
if(c == "") jump continue; |
if(c == " ") { |
o += "+"; |
jump continue; |
} |
if(c == "\n") { |
o += "%0D" + llEscapeURL(c); |
jump continue; |
} |
o += llEscapeURL(c); |
@continue; |
} while(i != ""); |
return o; |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
list wasCSVToList(string csv) { |
list l = []; |
list s = []; |
string m = ""; |
do { |
string a = llGetSubString(csv, 0, 0); |
csv = llDeleteSubString(csv, 0, 0); |
if(a == ",") { |
if(llList2String(s, -1) != "\"") { |
l += m; |
m = ""; |
jump continue; |
} |
m += a; |
jump continue; |
} |
if(a == "\"" && llGetSubString(csv, 0, 0) == a) { |
m += a; |
csv = llDeleteSubString(csv, 0, 0); |
jump continue; |
} |
if(a == "\"") { |
if(llList2String(s, -1) != a) { |
s += a; |
jump continue; |
} |
s = llDeleteSubList(s, -1, -1); |
jump continue; |
} |
m += a; |
@continue; |
} while(csv != ""); |
// postcondition: length(s) = 0 |
return l + m; |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasListToCSV(list l) { |
list v = []; |
do { |
string a = llDumpList2String( |
llParseStringKeepNulls( |
llList2String( |
l, |
0 |
), |
["\""], |
[] |
), |
"\"\"" |
); |
if(llParseStringKeepNulls( |
a, |
[" ", ",", "\n", "\""], [] |
) != |
(list) a |
) a = "\"" + a + "\""; |
v += a; |
l = llDeleteSubList(l, 0, 0); |
} while(l != []); |
return llDumpList2String(v, ","); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// unescapes a string in conformance with RFC1738 |
string wasURLUnescape(string i) { |
return llUnescapeURL( |
llDumpList2String( |
llParseString2List( |
llDumpList2String( |
llParseString2List( |
i, |
["+"], |
[] |
), |
" " |
), |
["%0D%0A"], |
[] |
), |
"\n" |
) |
); |
} |
|
// configuration data |
string configuration = ""; |
// store message over state. |
string data = ""; |
string query = ""; |
|
default { |
state_entry() { |
llOwnerSay("[Urban Dictionary] Starting module..."); |
llSetTimerEvent(10); |
} |
link_message(integer sender, integer num, string message, key id) { |
if(id != "configuration") return; |
llOwnerSay("[Urban Dictionary] Got configuration..."); |
configuration = message; |
state listen_group; |
} |
timer() { |
llOwnerSay("[Urban Dictionary] Requesting configuration..."); |
llMessageLinked(LINK_THIS, 0, "configuration", NULL_KEY); |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
state_exit() { |
llSetTimerEvent(0); |
} |
} |
|
state listen_group { |
state_entry() { |
// DEBUG |
llOwnerSay("[Urban Dictionary] Waiting for group messages..."); |
} |
link_message(integer sender, integer num, string message, key id) { |
// We only care about notifications now. |
if(id != "notification") |
return; |
|
// This script only processes group notifications. |
if(wasKeyValueGet("type", message) != "group" || |
(wasKeyValueGet("type", message) == "group" && |
wasURLUnescape(wasKeyValueGet("group", message)) != |
wasKeyValueGet("group", configuration))) |
return; |
|
// Get the sent message. |
data = wasURLUnescape( |
wasKeyValueGet( |
"message", |
message |
) |
); |
|
// Check if this is an eggdrop command. |
if(llGetSubString(data, 0, 0) != |
wasKeyValueGet("command", configuration)) |
return; |
|
// Check if the command matches the current module. |
list command = llParseString2List(data, [" "], []); |
if(llList2String(command, 0) != |
wasKeyValueGet("command", configuration) + "urbandictionary") |
return; |
|
// Remove command. |
command = llDeleteSubList(command, 0, 0); |
|
query = llDumpList2String(command, " "); |
|
state query_wikipedia; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
} |
|
state query_wikipedia { |
state_entry() { |
// DEBUG |
llOwnerSay("[Urban Dictionary] Querying..."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
configuration |
), |
wasKeyValueEncode( |
[ |
"command", "HTTP", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
configuration |
) |
), |
"action", "get", |
"type", "text", |
"URL", wasURLEscape("http://api.urbandictionary.com/v0/define?term=" + query), |
"sift", wasURLEscape( |
wasListToCSV( |
[ |
"select", |
"body", |
"JSONPath", |
wasURLEscape("$..list[*].definition"), |
"random", |
(string)llFloor(llFrand(2147483647)) |
] |
) |
), |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
) |
); |
|
llSetTimerEvent(60); |
} |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "HTTP") |
return; |
|
if(wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[Urban Dictionary] Unable to query: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
); |
state listen_group; |
} |
|
data = llDumpList2String( |
llParseString2List( |
wasKeyValueGet( |
"data", |
wasURLUnescape(body) |
), |
["\\r", "\n", "\\n", "[", "]", "\\\""], |
[] |
), |
"" |
); |
|
|
if(llStringLength(data) == 0) |
data = "No data returned, perhaps the site is down!"; |
|
state tell; |
} |
timer() { |
state listen_group; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
state_exit() { |
llSetTimerEvent(0); |
} |
} |
|
state tell { |
state_entry() { |
// DEBUG |
llOwnerSay("[Urban Dictionary] Sending to group..."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
configuration |
), |
wasKeyValueEncode( |
[ |
"command", "tell", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
configuration |
) |
), |
"entity", "group", |
"message", wasURLEscape(data) |
] |
) |
); |
state listen_group; |
} |
} |
/source/eggdrop/version.lsl |
@@ -1,5 +1,5 @@ |
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2016 - License: CC BY 2.0 // |
// Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// |
// A module that sends the current Corrade version to group chat. |
@@ -17,9 +17,9 @@ |
if(i != -1) return llList2String(a, 2*i+1); |
return ""; |
} |
|
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2013 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasKeyValueEncode(list data) { |
list k = llList2ListStrided(data, 0, -1, 2); |
@@ -34,7 +34,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2011 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// http://was.fm/secondlife/wanderer |
vector wasCirclePoint(float radius) { |
@@ -46,7 +46,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// escapes a string in conformance with RFC1738 |
string wasURLEscape(string i) { |
@@ -70,7 +70,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
list wasCSVToList(string csv) { |
list l = []; |
@@ -109,7 +109,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasListToCSV(list l) { |
list v = []; |
@@ -117,18 +117,18 @@ |
string a = llDumpList2String( |
llParseStringKeepNulls( |
llList2String( |
l, |
l, |
0 |
), |
["\""], |
), |
["\""], |
[] |
), |
"\"\"" |
); |
if(llParseStringKeepNulls( |
a, |
a, |
[" ", ",", "\n", "\""], [] |
) != |
) != |
(list) a |
) a = "\"" + a + "\""; |
v += a; |
@@ -138,7 +138,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// unescapes a string in conformance with RFC1738 |
string wasURLUnescape(string i) { |
@@ -147,15 +147,15 @@ |
llParseString2List( |
llDumpList2String( |
llParseString2List( |
i, |
["+"], |
i, |
["+"], |
[] |
), |
), |
" " |
), |
["%0D%0A"], |
), |
["%0D%0A"], |
[] |
), |
), |
"\n" |
) |
); |
@@ -162,7 +162,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2017 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
list wasSetIntersect(list a, list b) { |
if(llGetListLength(a) == 0) return []; |
@@ -175,8 +175,6 @@ |
|
// configuration data |
string configuration = ""; |
// callback URL |
string URL = ""; |
// store message over state. |
string data = ""; |
|
@@ -199,8 +197,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -219,59 +217,37 @@ |
// We only care about notifications now. |
if(id != "notification") |
return; |
|
|
// This script only processes group notifications. |
if(wasKeyValueGet("type", message) != "group") |
if(wasKeyValueGet("type", message) != "group" || |
(wasKeyValueGet("type", message) == "group" && |
wasURLUnescape(wasKeyValueGet("group", message)) != |
wasKeyValueGet("group", configuration))) |
return; |
|
|
// Get the sent message. |
data = wasURLUnescape( |
wasKeyValueGet( |
"message", |
"message", |
message |
) |
); |
|
|
// Check if this is an eggdrop command. |
if(llGetSubString(data, 0, 0) != |
if(llGetSubString(data, 0, 0) != |
wasKeyValueGet("command", configuration)) |
return; |
|
|
// Check if the command matches the current module. |
list command = llParseString2List(data, [" "], []); |
if(llList2String(command, 0) != |
if(llList2String(command, 0) != |
wasKeyValueGet("command", configuration) + "version") |
return; |
|
|
// Remove command. |
command = llDeleteSubList(command, 0, 0); |
|
// Get an URL. |
state url; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
} |
|
state url { |
state_entry() { |
// DEBUG |
llOwnerSay("[Version] Requesting URL..."); |
llRequestURL(); |
} |
http_request(key id, string method, string body) { |
if(method != URL_REQUEST_GRANTED) return; |
URL = body; |
// DEBUG |
llOwnerSay("[Version] Got URL..."); |
// Get version. |
state version; |
} |
on_rez(integer num) { |
@@ -278,8 +254,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -292,37 +268,43 @@ |
llOwnerSay("[Version] Getting version..."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
), |
wasKeyValueEncode( |
[ |
"command", "version", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |
"callback", wasURLEscape(URL) |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
) |
); |
llSetTimerEvent(60); |
} |
http_request(key id, string method, string body) { |
llHTTPResponse(id, 200, "OK"); |
llReleaseURL(URL); |
if(wasKeyValueGet("command", body) != "version" || |
wasKeyValueGet("success", body) != "True") { |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "version") |
return; |
|
if(wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[Version] Unable to get version: " + |
llOwnerSay("[Version] Unable to get version: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
@@ -329,13 +311,12 @@ |
); |
state listen_group; |
} |
|
|
data = "I'm a " + wasKeyValueGet("data", body); |
|
|
state tell; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
@@ -342,8 +323,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -359,21 +340,21 @@ |
llOwnerSay("[Version] Sending to group."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
), |
wasKeyValueEncode( |
[ |
"command", "tell", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |
/source/eggdrop/wiki.lsl |
@@ -1,5 +1,5 @@ |
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2016 - License: CC BY 2.0 // |
// Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// |
// A wiki module that can memorize strings and recall them by path. |
@@ -7,11 +7,11 @@ |
/////////////////////////////////////////////////////////////////////////// |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2014 - License: CC BY 2.0 // |
// Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
integer wasIsAlNum(string a) { |
if(a == "") return FALSE; |
integer x = llBase64ToInteger("AAAA" + |
integer x = llBase64ToInteger("AAAA" + |
llStringToBase64(llGetSubString(a, 0, 0))); |
return (x >= 65 && x <= 90) || (x >= 97 && x <= 122) || |
(x >= 48 && x <= 57); |
@@ -28,9 +28,9 @@ |
if(i != -1) return llList2String(a, 2*i+1); |
return ""; |
} |
|
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2013 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasKeyValueEncode(list data) { |
list k = llList2ListStrided(data, 0, -1, 2); |
@@ -45,7 +45,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// escapes a string in conformance with RFC1738 |
string wasURLEscape(string i) { |
@@ -69,7 +69,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
list wasCSVToList(string csv) { |
list l = []; |
@@ -108,7 +108,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
string wasListToCSV(list l) { |
list v = []; |
@@ -116,18 +116,18 @@ |
string a = llDumpList2String( |
llParseStringKeepNulls( |
llList2String( |
l, |
l, |
0 |
), |
["\""], |
), |
["\""], |
[] |
), |
"\"\"" |
); |
if(llParseStringKeepNulls( |
a, |
a, |
[" ", ",", "\n", "\""], [] |
) != |
) != |
(list) a |
) a = "\"" + a + "\""; |
v += a; |
@@ -137,7 +137,7 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0 // |
// Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
// unescapes a string in conformance with RFC1738 |
string wasURLUnescape(string i) { |
@@ -146,15 +146,15 @@ |
llParseString2List( |
llDumpList2String( |
llParseString2List( |
i, |
["+"], |
i, |
["+"], |
[] |
), |
), |
" " |
), |
["%0D%0A"], |
), |
["%0D%0A"], |
[] |
), |
), |
"\n" |
) |
); |
@@ -162,8 +162,6 @@ |
|
// configuration data |
string configuration = ""; |
// callback URL |
string URL = ""; |
// store message over state. |
string path = ""; |
string data = ""; |
@@ -181,7 +179,7 @@ |
llOwnerSay("[Wiki] Got configuration..."); |
configuration = message; |
action = "create"; |
state url; |
state trampoline; |
} |
timer() { |
llOwnerSay("[Wiki] Requesting configuration..."); |
@@ -191,8 +189,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -202,28 +200,18 @@ |
} |
} |
|
state url { |
state trampoline { |
state_entry() { |
// DEBUG |
llOwnerSay("[Wiki] Requesting URL..."); |
llRequestURL(); |
} |
http_request(key id, string method, string body) { |
if(method != URL_REQUEST_GRANTED) return; |
URL = body; |
// DEBUG |
llOwnerSay("[Wiki] Got URL."); |
|
if(action == "create") { |
statement = wasURLEscape("CREATE TABLE IF NOT EXISTS \"" + |
wasKeyValueGet("wiki table", configuration) + |
statement = wasURLEscape("CREATE TABLE IF NOT EXISTS \"" + |
wasKeyValueGet("wiki table", configuration) + |
"\" (path text unique collate nocase, data text)"); |
state query; |
} |
|
|
if(action == "get") { |
statement = wasURLEscape("SELECT data FROM \"" + |
wasKeyValueGet("wiki table", configuration) + |
wasKeyValueGet("wiki table", configuration) + |
"\" WHERE path=:path"); |
parameters = wasURLEscape( |
wasListToCSV( |
@@ -235,11 +223,11 @@ |
); |
state query; |
} |
|
|
if(action == "set") { |
if(data == "") { |
statement = wasURLEscape("DELETE FROM \"" + |
wasKeyValueGet("wiki table", configuration) + |
statement = wasURLEscape("DELETE FROM \"" + |
wasKeyValueGet("wiki table", configuration) + |
"\" WHERE path=:path"); |
parameters = wasURLEscape( |
wasListToCSV( |
@@ -252,7 +240,7 @@ |
state query; |
} |
statement = wasURLEscape("REPLACE INTO \"" + |
wasKeyValueGet("wiki table", configuration) + |
wasKeyValueGet("wiki table", configuration) + |
"\" (path, data) VALUES (:path, :data)"); |
parameters = wasURLEscape( |
wasListToCSV( |
@@ -266,13 +254,13 @@ |
); |
state query; |
} |
|
|
if(action == "dir") { |
if(path == "/") { |
path = ""; |
statement = wasURLEscape( |
"SELECT DISTINCT SUBSTR(path, 1, LENGTH(path) - LENGTH(LTRIM(SUBSTR(path,2), 'abcdefghijklmnopqrstuvwxyz'))) AS path FROM \"" + |
wasKeyValueGet("wiki table", configuration) + |
"SELECT DISTINCT SUBSTR(path, 1, LENGTH(path) - LENGTH(LTRIM(SUBSTR(path,2), 'abcdefghijklmnopqrstuvwxyz'))) AS path FROM \"" + |
wasKeyValueGet("wiki table", configuration) + |
"\" WHERE path LIKE '/%' LIMIT " + |
wasKeyValueGet("wiki results limit", configuration) |
); |
@@ -279,8 +267,8 @@ |
state query; |
} |
statement = wasURLEscape( |
"SELECT DISTINCT SUBSTR(REPLACE(path, :base, ''),1, LENGTH(REPLACE(path, :base, '')) - LENGTH(LTRIM(REPLACE(path, :base, ''), 'abcdefghijklmnopqrstuvwxyz'))) AS path FROM \"" + |
wasKeyValueGet("wiki table", configuration) + |
"SELECT DISTINCT SUBSTR(REPLACE(path, :base, ''),1, LENGTH(REPLACE(path, :base, '')) - LENGTH(LTRIM(REPLACE(path, :base, ''), 'abcdefghijklmnopqrstuvwxyz'))) AS path FROM \"" + |
wasKeyValueGet("wiki table", configuration) + |
"\" WHERE path LIKE :path LIMIT " + |
wasKeyValueGet("wiki results limit", configuration) |
); |
@@ -290,7 +278,7 @@ |
"path", |
wasURLEscape(path + "/" + "%"), |
"base", |
wasURLEscape("/" + |
wasURLEscape("/" + |
llDumpList2String( |
llParseString2List( |
path, |
@@ -298,7 +286,7 @@ |
[] |
), |
"/" |
) + |
) + |
"/" |
) |
] |
@@ -306,7 +294,7 @@ |
); |
state query; |
} |
|
|
if(action == "find") { |
if(data == "") { |
data = "Command requires two parameters: a path followed by a search term."; |
@@ -313,10 +301,10 @@ |
state tell; |
} |
if(path == "/") |
path = ""; |
path = ""; |
statement = wasURLEscape( |
"SELECT DISTINCT path FROM \"" + |
wasKeyValueGet("wiki table", configuration) + |
"SELECT DISTINCT path FROM \"" + |
wasKeyValueGet("wiki table", configuration) + |
"\" WHERE path LIKE :path AND ( data LIKE :data OR path LIKE :data ) COLLATE NOCASE LIMIT " + |
wasKeyValueGet("wiki search limit", configuration) |
); |
@@ -332,7 +320,7 @@ |
); |
state query; |
} |
|
|
// DEBUG |
llOwnerSay("[Wiki] Jump table corrupted, please contact creator..."); |
llResetScript(); |
@@ -341,8 +329,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -358,35 +346,38 @@ |
// We only care about notifications now. |
if(id != "notification") |
return; |
|
|
// This script only processes group notifications. |
if(wasKeyValueGet("type", message) != "group") |
if(wasKeyValueGet("type", message) != "group" || |
(wasKeyValueGet("type", message) == "group" && |
wasURLUnescape(wasKeyValueGet("group", message)) != |
wasKeyValueGet("group", configuration))) |
return; |
|
|
// Get the sent message. |
data = wasURLUnescape( |
wasKeyValueGet( |
"message", |
"message", |
message |
) |
); |
|
|
// Check if this is an eggdrop command. |
if(llGetSubString(data, 0, 0) != |
if(llGetSubString(data, 0, 0) != |
wasKeyValueGet("command", configuration)) |
return; |
|
|
// Check if the command matches the current module. |
list command = llParseString2List(data, [" "], []); |
if(llList2String(command, 0) != |
if(llList2String(command, 0) != |
wasKeyValueGet("command", configuration) + "wiki") |
return; |
|
|
// Remove command. |
command = llDeleteSubList(command, 0, 0); |
|
|
// Check for supported sub-commands. |
if(llList2String(command, 0) != "set" && |
if(llList2String(command, 0) != "set" && |
llList2String(command, 0) != "get" && |
llList2String(command, 0) != "dir" && |
llList2String(command, 0) != "find") { |
@@ -393,27 +384,27 @@ |
data = "Subcommands are: get, set, dir or find"; |
state tell; |
} |
|
|
// Get the sub-command and store it as a jump state. |
action = llList2String(command, 0); |
|
|
// Remove sub-command. |
command = llDeleteSubList(command, 0, 0); |
|
|
// Get the path parts. |
list path_parts = llParseString2List( |
llList2String(command, 0), ["/"], [] |
); |
|
|
// Dump the path and store it over states. |
path = llStringTrim( |
llDumpList2String( |
path_parts, |
path_parts, |
"/" |
), |
), |
STRING_TRIM |
); |
|
|
if(path != "") { |
integer i = llStringLength(path) - 1; |
do { |
@@ -424,24 +415,23 @@ |
} |
} while(--i > -1); |
} |
|
|
path = "/" + path; |
|
|
// Remove path. |
command = llDeleteSubList(command, 0, 0); |
|
|
// Dump the rest of the message. |
data = llDumpList2String(command, " "); |
|
// Get an URL. |
state url; |
|
state trampoline; |
} |
on_rez(integer num) { |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -456,35 +446,44 @@ |
"command", "database", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |
"SQL", statement, |
"data", parameters, |
"callback", wasURLEscape(URL) |
"callback", wasURLEscape( |
wasKeyValueGet( |
"URL", |
configuration |
) |
) |
] |
); |
|
// GC - none of these are needed anymore. |
statement = ""; |
parameters = ""; |
|
// Message length check. |
if(llStringLength(message) > 1023) { |
data = "Message length exceeded 1023 characters."; |
state tell; |
} |
|
// DEBUG |
llOwnerSay("[Wiki] Executing action: " + action); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
), |
message |
); |
// GC |
@@ -491,13 +490,14 @@ |
message = ""; |
llSetTimerEvent(60); |
} |
http_request(key id, string method, string body) { |
llHTTPResponse(id, 200, "OK"); |
llReleaseURL(URL); |
if(wasKeyValueGet("command", body) != "database" || |
wasKeyValueGet("success", body) != "True") { |
link_message(integer sender, integer num, string body, key id) { |
// Only process callbacks for the database command. |
if(id != "callback" || wasKeyValueGet("command", body) != "database") |
return; |
|
if(wasKeyValueGet("success", body) != "True") { |
// DEBUG |
llOwnerSay("[Wiki] Unable query database: " + |
llOwnerSay("[Wiki] Unable query database: " + |
wasURLUnescape( |
wasKeyValueGet("error", body) |
) |
@@ -504,9 +504,8 @@ |
); |
state listen_group; |
} |
|
|
// Process actions. |
|
if(action == "set") { |
if(data == "") { |
data = "Deleted from " + path; |
@@ -554,16 +553,16 @@ |
), |
"" |
); |
|
|
if(data == "") { |
data = "Sorry, that path contains no data."; |
state tell; |
} |
|
|
data = path + ": " + data; |
state tell; |
} |
|
|
if(action == "dir") { |
list paths = llList2ListStrided( |
llDeleteSubList( |
@@ -579,35 +578,35 @@ |
-1, |
2 |
); |
|
|
if(llGetListLength(paths) == 0) { |
data = "Sorry, that path contains no sub-paths."; |
state tell; |
} |
|
|
// Eliminate path component. |
if(path == "/") |
path = ""; |
|
|
list sibling = []; |
do { |
// Get the path part. |
string part = llList2String(paths, 0); |
|
|
// Remove the path component. |
string child = llStringTrim( |
llDumpList2String( |
llParseString2List( |
part, |
[path, "/"], |
[path, "/"], |
[] |
), |
"/" |
), |
STRING_TRIM |
|
|
); |
|
|
integer i = llSubStringIndex(child, "/"); |
if(i == -1) { |
sibling += path + "/" + child; |
@@ -619,24 +618,23 @@ |
@continue_dir; |
paths = llDeleteSubList(paths, 0, 0); |
} while(llGetListLength(paths) != 0); |
|
|
data = llList2CSV(sibling); |
// GC |
sibling = []; |
|
|
state tell; |
} |
|
|
// Don't announce creating table. |
if(action == "create") |
state listen_group; |
|
|
// DEBUG |
llOwnerSay("[Wiki] Jump table corrupted, please contact creator..."); |
state listen_group; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
@@ -643,8 +641,8 @@ |
llResetScript(); |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
@@ -660,21 +658,21 @@ |
llOwnerSay("[Wiki] Sending to group."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
"corrade", |
configuration |
), |
), |
wasKeyValueEncode( |
[ |
"command", "tell", |
"group", wasURLEscape( |
wasKeyValueGet( |
"group", |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
wasKeyValueGet( |
"password", |
"password", |
configuration |
) |
), |