~Fiona's Script Library~

← Zurück zur Bibliothek

kick.lsl | 4.23 KB
Herunterladen
// Copyright 2025 Fiona Sweet - Free to use for any purpose
// StageGuard.lsl — OpenSim/LSL
// Put this in an invisible prim that surrounds your stage.
// Set the prim to PHANTOM. The script turns on volume-detect.

// =================== CONFIG ===================
list    ALLOWED = [
    // Add avatar UUIDs here (strings)
        "78e7a55f-5c3d-4e5f-9a20-2026adba8660", //Niki Stark
        "ededfb98-67d2-46ac-ab74-6a67f7660667" //Prim
];

integer ALLOW_OWNER   = FALSE;        // let the prim's owner always pass
integer ALLOW_ESTATE  = FALSE;        // let estate managers/owners pass (requires os* estate checks)
integer ALLOW_GROUP   = FALSE;       // if TRUE, allow avatars in the prim's group

vector  SAFE_POS      = <86.0, 151.0, 30.0>;  // where to send unauthorized avatars
integer SHOW_DEBUG    = FALSE;       // TRUE shows renter/allowed hint hovertext

string  DENY_MSG = "Sorry, the stage is restricted. Teleporting you back to the audience area.";

// Optional: if your grid doesn’t allow osTeleportAgent or you want a fallback,
// set USE_PUSH_FALLBACK = TRUE to gently push people out instead of teleporting.
integer USE_PUSH_FALLBACK = FALSE;
float   PUSH_STRENGTH = 10.0;
// ==============================================

// ---- internal state ----
integer gArmed = TRUE;      // touch to toggle on/off

integer isAllowed(key av)
{
    // skip non-avatars
    if (llGetAgentSize(av) == ZERO_VECTOR) return TRUE;

    // Owner bypass
    if (ALLOW_OWNER && av == llGetOwner()) return TRUE;

    // Estate manager/owner bypass (OpenSim OSSL)
    // Not all grids expose an API for this in LSL; commonly you’d whitelist staff in ALLOWED.
    // If you have osIsEstateManager, uncomment this block:
    // if (ALLOW_ESTATE && osIsEstateManager(av)) return TRUE;

    // Group check
    if (ALLOW_GROUP && llSameGroup(av)) return TRUE;

    // Explicit allow list
    if (~llListFindList(ALLOWED, [ (string)av ])) return TRUE;

    return FALSE;
}

teleportOut(key av)
{
    // Teleport (preferred)
    if (!USE_PUSH_FALLBACK)
    {
        // OSSL: requires sufficient threat level (usually estate powers).
        osTeleportAgent(av, SAFE_POS, ZERO_VECTOR);
        llInstantMessage(av, DENY_MSG);
        return;
    }

    // Fallback push (no OSSL)
    vector dir = llVecNorm(SAFE_POS - llGetPos());
    if (dir == ZERO_VECTOR) dir = <1,0,0>;
    llPushObject(av, dir * PUSH_STRENGTH, ZERO_VECTOR, FALSE);
    llInstantMessage(av, DENY_MSG);
}

refreshDebug()
{
    if (SHOW_DEBUG)
    {
        string txt = "StageGuard: " + (gArmed ? "ARMED" : "DISARMED")
                   + "\nAllowed: " + (string)llGetListLength(ALLOWED)
                   + (ALLOW_GROUP ? " + group" : "")
                   + (ALLOW_OWNER ? " + owner" : "")
                   + (ALLOW_ESTATE ? " + estate" : "");
        llSetText(txt, <1,1,0>, 1.0);
    }
    else llSetText("", ZERO_VECTOR, 0.0);
}

default
{
    state_entry()
    {
        // make sure we're a volume detector
        llVolumeDetect(TRUE);
        refreshDebug();
    }

    on_rez(integer p)
    {
        llResetScript();
    }

    // Touch to arm/disarm quickly (for builders)
    touch_start(integer n)
    {
        key who = llDetectedKey(0);
        // Only owner can toggle
        if (who != llGetOwner()) return;

        gArmed = !gArmed;
        llOwnerSay("StageGuard is now " + (gArmed ? "ARMED" : "DISARMED") + ".");
        refreshDebug();
    }

    // When someone enters the stage volume
    collision_start(integer n)
    {
        if (!gArmed) return;

        integer i;
        for (i = 0; i < n; ++i)
        {
            key av = llDetectedKey(i);

            // ignore non-avatars (objects)
            if (llGetAgentSize(av) == ZERO_VECTOR) 
                jump next;

            if (!isAllowed(av))
            {
                teleportOut(av);
            }

@next;
        }
    }

    // Keep sweeping while they remain in the volume (optional safety)
    collision(integer n)
    {
        if (!gArmed) return;

        integer i;
        for (i = 0; i < n; ++i)
        {
            key av = llDetectedKey(i);
            if (llGetAgentSize(av) == ZERO_VECTOR) 
                jump next2;

            if (!isAllowed(av))
            {
                teleportOut(av);
            }

@next2;
        }
    }
}