/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. |
@@ -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("[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) { |
@@ -327,14 +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"); |
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 |
@@ -343,7 +328,6 @@ |
wasKeyValueGet("error", body) |
) |
); |
llReleaseURL(URL); |
state listen_group; |
} |
|
@@ -364,7 +348,6 @@ |
) |
) == 0) { |
data = "You ain't got the cojones!"; |
llReleaseURL(URL); |
state tell; |
} |
|
@@ -391,7 +374,6 @@ |
state get_banee_roles; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
@@ -435,16 +417,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("[Ban] User not in group, but proceeding anyway..."); |
@@ -456,7 +445,6 @@ |
wasKeyValueGet("error", body) |
) |
); |
llReleaseURL(URL); |
state listen_group; |
} |
|
@@ -467,7 +455,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; |
} |
|
@@ -474,7 +461,6 @@ |
state ban; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
@@ -526,15 +512,22 @@ |
) |
), |
"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 |
@@ -551,7 +544,6 @@ |
state tell; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
/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. |
@@ -19,8 +19,50 @@ |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// 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) { |
@@ -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 = []; |
@@ -110,6 +152,45 @@ |
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; |
|
@@ -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( |
@@ -394,7 +476,7 @@ |
); |
llResetScript(); |
} |
state serve_configuration; |
state version_check; |
} |
timer() { |
llOwnerSay("[Control] Timeout binding notifications"); |
@@ -415,7 +497,7 @@ |
} |
} |
|
state serve_configuration { |
state version_check { |
state_entry() { |
// DEBUG |
llOwnerSay("[Control] Checking version..."); |
@@ -448,10 +530,6 @@ |
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..."); |
@@ -485,23 +563,110 @@ |
" 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); |
|
state serve_configuration; |
} |
timer() { |
llOwnerSay("[Control] Timeout checking version..."); |
llResetScript(); |
} |
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 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"); |
} |
timer() { |
llOwnerSay("[Control] Timeout checking version..."); |
llResetScript(); |
} |
on_rez(integer num) { |
llResetScript(); |
} |
/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. |
@@ -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) { |
@@ -163,8 +163,6 @@ |
|
// configuration data |
string configuration = ""; |
// callback URL |
string URL = ""; |
// store message over state. |
string data = ""; |
string firstname = ""; |
@@ -211,7 +209,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. |
@@ -239,32 +240,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("[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) { |
@@ -313,16 +289,23 @@ |
] |
) |
),*/ |
"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: " + |
wasURLUnescape( |
@@ -329,7 +312,6 @@ |
wasKeyValueGet("error", body) |
) |
); |
llReleaseURL(URL); |
state listen_group; |
} |
|
@@ -362,7 +344,6 @@ |
) |
) != llToUpper(lastname)) { |
data = "Agent not found."; |
llReleaseURL(URL); |
state tell; |
} |
|
@@ -369,7 +350,6 @@ |
state invite; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
@@ -415,17 +395,23 @@ |
"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: " + |
wasURLUnescape( |
@@ -440,7 +426,6 @@ |
state tell; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
/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 |
@@ -163,16 +163,16 @@ |
|
// 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..."); |
@@ -204,102 +204,161 @@ |
} |
} |
|
state url { |
state trampoline { |
state_entry() { |
// DEBUG |
llOwnerSay("[Joke] Requesting URL..."); |
llRequestURL(); |
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; |
} |
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(); |
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; |
} |
on_rez(integer num) { |
llResetScript(); |
|
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; |
} |
changed(integer change) { |
if((change & CHANGED_INVENTORY) || |
(change & CHANGED_REGION_START) || |
(change & CHANGED_OWNER)) { |
llResetScript(); |
} |
} |
} |
|
state create_database { |
state_entry() { |
// DEBUG |
llOwnerSay("[Joke] Creating database: " + wasKeyValueGet("joke table", configuration)); |
llInstantMessage( |
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( |
"corrade", |
"group", |
configuration |
) |
), |
wasKeyValueEncode( |
"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( |
[ |
"command", "database", |
"group", wasURLEscape( |
"name", |
wasURLEscape( |
wasKeyValueGet( |
"group", |
configuration |
) |
), |
"password", wasURLEscape( |
"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( |
"password", |
"group", |
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) |
"data", |
wasURLEscape(data), |
"firstname", |
wasURLEscape(firstname), |
"lastname", |
wasURLEscape(lastname) |
] |
) |
); |
llSetTimerEvent(60); |
state query; |
} |
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) |
) + |
" " + |
wasURLUnescape( |
wasKeyValueGet("data", body) |
|
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) |
] |
) |
); |
|
); |
llResetScript(); |
state query; |
} |
llOwnerSay("[Joke] Database created!"); |
jump_state = "count_jokes"; |
state url; |
} |
timer() { |
|
// DEBUG |
llOwnerSay("[Joke] Jump table corrupted, please contact creator..."); |
llResetScript(); |
} |
on_rez(integer num) { |
@@ -312,21 +371,12 @@ |
llResetScript(); |
} |
} |
state_exit() { |
llSetTimerEvent(0); |
} |
} |
|
state count_jokes { |
state query { |
state_entry() { |
// DEBUG |
llOwnerSay("[Joke] Counting jokes in database: " + wasKeyValueGet("joke table", configuration)); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
configuration |
), |
wasKeyValueEncode( |
// Check messge length. |
string message = wasKeyValueEncode( |
[ |
"command", "database", |
"group", wasURLEscape( |
@@ -341,33 +391,110 @@ |
configuration |
) |
), |
"SQL", wasURLEscape("SELECT COUNT(*) AS count FROM \"" + |
wasKeyValueGet("joke table", configuration) + "\""), |
"callback", wasURLEscape(URL) |
"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] Executing action: " + action); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
configuration |
), |
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) |
) |
); |
|
if(llGetListLength(result) != 10) { |
data = "No joke found. . ."; |
state tell; |
} |
|
data = llList2String( |
result, |
llListFindList(result, ["data"]) + 1 |
); |
llResetScript(); |
|
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; |
} |
|
if(action == "remove") { |
data = "Joke " + data + " has been removed."; |
state tell; |
} |
|
if(action == "add") { |
action = "get_joke_id"; |
data = body; |
state trampoline; |
} |
|
if(action == "get_joke_id") { |
list result = wasCSVToList( |
wasURLUnescape( |
wasKeyValueGet("data", body) |
@@ -374,16 +501,21 @@ |
) |
); |
|
joke_counter = llList2Integer( |
data = llList2String( |
result, |
llListFindList(result, ["count"]) + 1 |
) + 1; |
llListFindList(result, ["LAST"]) + 1 |
); |
|
llOwnerSay("[Joke] There are " + (string)joke_counter + " jokes in the database."); |
data = "Joke " + data + " has been stored."; |
state tell; |
} |
|
// DEBUG |
llOwnerSay("[Joke] Jump table corrupted, please contact creator..."); |
state listen_group; |
} |
timer() { |
llResetScript(); |
state listen_group; |
} |
on_rez(integer num) { |
llResetScript(); |
@@ -455,7 +587,7 @@ |
command = llDeleteSubList(command, 0, 0); |
|
// Remove action. |
string action = llList2String(command, 0); |
action = llList2String(command, 0); |
// Jump to the "add" state for adding |
if(action == "add") { |
command = llDeleteSubList(command, 0, 0); |
@@ -464,8 +596,8 @@ |
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 |
@@ -476,354 +608,47 @@ |
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((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(); |
} |
} |
} |
|
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(llStringLength(firstname) == 0 || |
llStringLength(lastname) == 0) { |
data = "First and Last name is required."; |
state tell; |
} |
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); |
} |
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; |
action = "by"; |
state trampoline; |
} |
|
data = llList2String( |
result, |
llListFindList(result, ["data"]) + 1 |
); |
string index = llList2String(command, 0); |
command = llDeleteSubList(command, 0, 0); |
|
string firstname = llList2String( |
result, |
llListFindList(result, ["firstname"]) + 1 |
); |
data = llDumpList2String(command, " "); |
|
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; |
if(index == "search") { |
action = "search"; |
state trampoline; |
} |
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 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); |
if((integer)index <= 0) { |
action = "random"; |
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 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); |
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 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(); |
} |
@@ -834,10 +659,7 @@ |
llResetScript(); |
} |
} |
state_exit() { |
llSetTimerEvent(0); |
} |
} |
|
state tell { |
state_entry() { |
/source/eggdrop/motd.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 MOTD module for Corrade Eggdrop. |
@@ -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) { |
@@ -163,8 +163,6 @@ |
|
// configuration data |
string configuration = ""; |
// callback URL |
string URL = ""; |
// store message over state. |
string firstname = ""; |
string lastname = ""; |
@@ -171,6 +169,7 @@ |
string group = ""; |
string data = ""; |
string jump_state = ""; |
integer membershipFee; |
|
default { |
state_entry() { |
@@ -182,7 +181,7 @@ |
llOwnerSay("[MOTD] Got configuration..."); |
configuration = message; |
jump_state = "create_database"; |
state url; |
state trampoline; |
} |
timer() { |
llOwnerSay("[MOTD] Requesting configuration..."); |
@@ -203,17 +202,8 @@ |
} |
} |
|
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,6 +212,10 @@ |
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; |
|
@@ -268,17 +262,23 @@ |
"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: " + |
wasURLUnescape( |
@@ -296,7 +296,6 @@ |
state listen_group; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
@@ -333,6 +332,14 @@ |
) |
); |
|
// 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,13 +355,15 @@ |
message |
) |
); |
|
if(wasKeyValueGet("pay back", configuration) != "true") { |
jump_state = "greet"; |
state url; |
state trampoline; |
} |
|
// This script only processes group notifications. |
if(wasKeyValueGet("type", message) != "group") |
return; |
jump_state = "fee"; |
state trampoline; |
} |
|
// Get the sent message. |
data = wasURLUnescape( |
@@ -381,14 +390,18 @@ |
// 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(); |
@@ -405,7 +418,7 @@ |
state greet { |
state_entry() { |
// DEBUG |
llOwnerSay("[MOTD] Member joined, retrieving MOTD..."); |
llOwnerSay("[MOTD] Retrieving MOTD..."); |
llInstantMessage( |
wasKeyValueGet( |
"corrade", |
@@ -437,17 +450,23 @@ |
] |
) |
), |
"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: " + |
wasURLUnescape( |
@@ -477,7 +496,6 @@ |
state tell; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
@@ -535,17 +553,23 @@ |
] |
) |
), |
"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: " + |
wasURLUnescape( |
@@ -576,7 +600,6 @@ |
state tell; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
@@ -594,10 +617,183 @@ |
} |
} |
|
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", |
@@ -620,11 +816,11 @@ |
), |
"SQL", wasURLEscape("REPLACE INTO \"" + |
wasKeyValueGet("motd table", configuration) + |
"\" (name, data) VALUES (:name, :data)"), |
"\" (name, data) VALUES (:group, :message)"), |
"data", wasURLEscape( |
wasListToCSV( |
[ |
"name", |
"group", |
wasURLEscape( |
wasKeyValueGet( |
"group", |
@@ -631,22 +827,28 @@ |
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: " + |
wasURLUnescape( |
@@ -659,7 +861,6 @@ |
state tell; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
/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. |
@@ -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 |
@@ -224,7 +222,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. |
@@ -260,32 +261,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("[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) { |
@@ -326,16 +302,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("[Softunban] Unable to get member roles: " + |
wasURLUnescape( |
@@ -342,7 +325,6 @@ |
wasKeyValueGet("error", body) |
) |
); |
llReleaseURL(URL); |
state listen_group; |
} |
|
@@ -363,7 +345,6 @@ |
) |
) == 0) { |
data = "You ain't got the cojones!"; |
llReleaseURL(URL); |
state tell; |
} |
|
@@ -382,7 +363,6 @@ |
state get_banee_roles; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
@@ -426,16 +406,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("[Softunban] User not in group, but proceeding anyway..."); |
@@ -447,7 +434,6 @@ |
wasKeyValueGet("error", body) |
) |
); |
llReleaseURL(URL); |
state listen_group; |
} |
|
@@ -457,7 +443,6 @@ |
|
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; |
} |
|
@@ -466,7 +451,6 @@ |
state unban; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
@@ -516,17 +500,23 @@ |
] |
) |
), |
"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: " + |
wasURLUnescape( |
@@ -541,7 +531,6 @@ |
state tell; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
/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. . . |
@@ -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) { |
@@ -163,8 +163,6 @@ |
|
// configuration data |
string configuration = ""; |
// callback URL |
string URL = ""; |
// store message over state. |
string data = ""; |
|
@@ -209,7 +207,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. |
@@ -237,32 +238,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("[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) { |
@@ -309,17 +285,23 @@ |
] |
) |
), |
"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: " + |
wasURLUnescape( |
@@ -339,7 +321,7 @@ |
// Limit to two people to spank. |
if(llGetListLength(spankees) > 2) { |
data = "So many people, so few hands!"; |
return; |
state tell; |
} |
|
data = llList2CSV(spankees); |
@@ -354,7 +336,6 @@ |
state tell; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
/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. |
@@ -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("[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) { |
@@ -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("[Unban] 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; |
} |
|
@@ -391,7 +372,6 @@ |
state get_banee_roles; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
@@ -435,16 +415,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("[Unban] User not in group, but proceeding anyway..."); |
@@ -456,7 +443,7 @@ |
wasKeyValueGet("error", body) |
) |
); |
llReleaseURL(URL); |
|
state listen_group; |
} |
|
@@ -466,7 +453,6 @@ |
|
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; |
} |
|
@@ -475,7 +461,6 @@ |
state unban; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
@@ -526,17 +511,23 @@ |
] |
) |
), |
"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: " + |
wasURLUnescape( |
@@ -551,7 +542,6 @@ |
state tell; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
/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. |
@@ -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 = ""; |
|
@@ -221,7 +219,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. |
@@ -246,32 +247,7 @@ |
// 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) { |
@@ -310,17 +286,23 @@ |
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: " + |
wasURLUnescape( |
@@ -335,7 +317,6 @@ |
state tell; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |
/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,7 +7,7 @@ |
/////////////////////////////////////////////////////////////////////////// |
|
/////////////////////////////////////////////////////////////////////////// |
// 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; |
@@ -30,7 +30,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); |
@@ -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 = []; |
@@ -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) { |
@@ -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..."); |
@@ -202,18 +200,8 @@ |
} |
} |
|
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) + |
@@ -360,7 +348,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. |
@@ -433,8 +424,7 @@ |
// Dump the rest of the message. |
data = llDumpList2String(command, " "); |
|
// Get an URL. |
state url; |
state trampoline; |
} |
on_rez(integer num) { |
llResetScript(); |
@@ -468,16 +458,25 @@ |
), |
"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( |
@@ -491,11 +490,12 @@ |
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: " + |
wasURLUnescape( |
@@ -506,7 +506,6 @@ |
} |
|
// Process actions. |
|
if(action == "set") { |
if(data == "") { |
data = "Deleted from " + path; |
@@ -636,7 +635,6 @@ |
state listen_group; |
} |
timer() { |
llReleaseURL(URL); |
state listen_group; |
} |
on_rez(integer num) { |