///////////////////////////////////////////////////////////////////////////
//  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;
    }
}
 

secondlife/scripted_agents/corrade/projects/in_world/eggdrop/im.txt ยท Last modified: 2022/11/24 07:45 by 127.0.0.1

Access website using Tor Access website using i2p Wizardry and Steamworks PGP Key


For the contact, copyright, license, warranty and privacy terms for the usage of this website please see the contact, license, privacy, copyright.