Post fixes

This commit is contained in:
Fred Beckhusen
2021-04-25 23:52:03 -05:00
parent 763d012024
commit f49f7b5412
30 changed files with 217 additions and 1645 deletions

View File

@@ -1,10 +1,16 @@
// :NAME:Advanced Tree Planter V3.0
// :SHOW:
// :CATEGORY:Tree
// :NAME:Advanced Tree Planter
// :AUTHOR:CyberGlo CyberStar
// :KEYWORDS:
// :CREATED:2021-04-26 23:30:44
// :EDITED:2021-04-26 22:30:44
// :ID:1130
// :NUM:2020
// :REV:3.0
// :WORLD:Second Life, Opensim
// :DESCRIPTION:This device will plant an entire forrest in the 0,0 to 256,256 range (can be changed). It will plant trees at different heights in accordance with the land height level.
// :CATEGORY:Tree
// :DESCRIPTION:
// This device will plant an entire forrest in the 0,0 to 256,256 range (can be changed). It will plant trees at different heights in accordance with the land height level.
// :CODE:
// This device will plant an entire forrest in the 0,0 to 256,256 range (can be changed). It will plant trees at different heights in accordance with the land height level.

View File

@@ -1,6 +1,12 @@
// :SHOW:
// :CATEGORY:Color
// :NAME:COlor Picker
// :NAME:Colorpicker
// :AUTHOR:Anonymous
// :KEYWORDS:
// :CREATED:2021-04-26 23:30:52
// :EDITED:2021-04-26 22:30:52
// :ID:1131
// :NUM:2021
// :REV:1.0
// :WORLD:Second Life, Opensim
// :DESCRIPTION:

View File

@@ -1,3 +1,17 @@
// :SHOW:
// :CATEGORY:DreamGrid
// :NAME:Dreamgrid Auto teleport sign
// :AUTHOR:Ferd Frederix
// :KEYWORDS:
// :CREATED:2021-04-26 23:31:25
// :EDITED:2021-04-26 22:31:25
// :ID:1132
// :NUM:2022
// :REV:1
// :WORLD:OpenSim
// :DESCRIPTION:
// Autoload Teleporter Board
// :CODE:
// (c) The owner of Avatar Jeff Kelley, 2010
//
// This script is licensed under Creative Commons BY-NC-SA

View File

@@ -4,6 +4,7 @@
// :AUTHOR:Pedlar Decosta
// :KEYWORDS:Ladder
// :CREATED:2015-07-15 10:04:12
// :EDITED:2021-04-26 22:31:25
// :ID:1081
// :NUM:1800
// :REV:2

View File

@@ -0,0 +1,3 @@
<Solution name="Giver with HTTP notice">
<Project name="Giver with HTTP notice" path="Giver with HTTP notice\Giver with HTTP notice.prj" active="true"/>
</Solution>

View File

@@ -0,0 +1,6 @@
<Project name="Giver with HTTP notice" guid="21db7bb6-6899-49df-96c2-967de0672748">
<Object name="Object" guid="271b6ddf-84f0-4fc1-b0bf-63a31e620eab" active="true">
<Script name="Script.lsl" guid="54e7417b-27b4-4e95-a98c-e456c45162a9">
</Script>
</Object>
</Project>

View File

@@ -0,0 +1,74 @@
// :SHOW:
// :CATEGORY:Giver
// :NAME:Giver with HTTP notice
// :AUTHOR:Ferd Frederix
// :KEYWORDS:
// :CREATED:2021-04-26 23:38:38
// :EDITED:2021-04-26 22:38:38
// :ID:1133
// :NUM:2023
// :REV:1
// :WORLD:Second Life
// :DESCRIPTION:
// Gves inventory and sends what it did to a HTTP server
// :CODE:
//
// Give with notice via HTTP
//
// Fill in your server and port, if necessary, port 80 is a default. It will connect to Apache with the parameter ?name=(Prim Name)
string SERVER = "http://outworldz.com";
// * This function cases the script to sleep for 3.0 seconds.
// * If inventory is missing from the prim's inventory then an error is shouted on DEBUG_CHANNEL.
// * Avatar must be, or have recently been, within the same Region as sending object.
// * Does not create a folder when avatar is a prim UUID.
// o The prim must be in the same region.
//Examples
// When a user clicks this object, this script will give a folder containing everything in the objects inventory
// This can serve as a unpacker script for boxed objects
default {
http_request(key id, string method, string body)
{
llOwnerSay("Someone just got " + llGetObjectName());
}
touch_start(integer total_number) {
llHTTPRequest(SERVER + "?Name=" + llGetObjectName(),[], "");
list inventory;
string name;
integer num = llGetInventoryNumber(INVENTORY_ALL);
integer i;
for (i = 0; i < num; ++i) {
name = llGetInventoryName(INVENTORY_ALL, i);
if(llGetInventoryPermMask(name, MASK_NEXT) & PERM_COPY)
inventory += name;
else
llSay(0, "Don't have permissions to give you \""+name+"\".");
}
//we don't want to give them this script
i = llListFindList(inventory, [llGetScriptName()]);
inventory = llDeleteSubList(inventory, i, i);
if (llGetListLength(inventory) < 1) {
llSay(0, "No items to offer.");
} else {
// give folder to agent, use name of object as name of folder we are giving
llGiveInventoryList(llDetectedKey(0), llGetObjectName(), inventory);
llHTTPRequest(SERVER,[],llGetObjectName());
}
}
}

View File

@@ -1,60 +0,0 @@
//
// Give with notice via HTTP
//
// Fill in your server and port, if necessary, port 80 is a default. It will connect to Apache with the parameter ?name=(Prim Name)
string SERVER = "http://outworldz.com";
// * This function cases the script to sleep for 3.0 seconds.
// * If inventory is missing from the prim's inventory then an error is shouted on DEBUG_CHANNEL.
// * Avatar must be, or have recently been, within the same Region as sending object.
// * Does not create a folder when avatar is a prim UUID.
// o The prim must be in the same region.
//Examples
// When a user clicks this object, this script will give a folder containing everything in the objects inventory
// This can serve as a unpacker script for boxed objects
default {
http_request(key id, string method, string body)
{
llOwnerSay("Someone just got " + llGetObjectName());
}
touch_start(integer total_number) {
llHTTPRequest(SERVER + "?Name=" + llGetObjectName(),[], "");
list inventory;
string name;
integer num = llGetInventoryNumber(INVENTORY_ALL);
integer i;
for (i = 0; i < num; ++i) {
name = llGetInventoryName(INVENTORY_ALL, i);
if(llGetInventoryPermMask(name, MASK_NEXT) & PERM_COPY)
inventory += name;
else
llSay(0, "Don't have permissions to give you \""+name+"\".");
}
//we don't want to give them this script
i = llListFindList(inventory, [llGetScriptName()]);
inventory = llDeleteSubList(inventory, i, i);
if (llGetListLength(inventory) < 1) {
llSay(0, "No items to offer.");
} else {
// give folder to agent, use name of object as name of folder we are giving
llGiveInventoryList(llDetectedKey(0), llGetObjectName(), inventory);
llHTTPRequest(SERVER,[],llGetObjectName());
}
}
}

View File

@@ -1,12 +0,0 @@
default
{
state_entry()
{
llSay(0, "Hello, Avatar!");
}
touch_start(integer total_number)
{
llSay(0, "Touched: "+(string)total_number);
}
}

View File

@@ -1,95 +0,0 @@
default {
state_entry() {
llParticleSystem( [
PSYS_SRC_TEXTURE, llGetInventoryName(INVENTORY_TEXTURE, 0),
PSYS_PART_START_SCALE, <15.5,15.5, 0>, PSYS_PART_END_SCALE, <0,2.0, 0>,
PSYS_PART_START_COLOR, <.2,0,.2>, PSYS_PART_END_COLOR, <.5,1,1>,
PSYS_PART_START_ALPHA, 1.0, PSYS_PART_END_ALPHA, 0.0,
PSYS_SRC_BURST_PART_COUNT, 1,
PSYS_SRC_BURST_RATE, 0.01,
PSYS_PART_MAX_AGE, 3.4,
PSYS_SRC_MAX_AGE, 0.0,
PSYS_SRC_PATTERN, 8, // 1=DROP, 2=EXPLODE, 4=ANGLE, 8=ANGLE_CONE,
PSYS_SRC_ACCEL, <0.0,0.0,0.0>,
// PSYS_SRC_BURST_RADIUS, 0.0,
PSYS_SRC_BURST_SPEED_MIN, .01, PSYS_SRC_BURST_SPEED_MAX, 3.01,
PSYS_SRC_ANGLE_BEGIN, 1*DEG_TO_RAD, PSYS_SRC_ANGLE_END, 0*DEG_TO_RAD,
PSYS_SRC_OMEGA, <0,0,0>,
// PSYS_SRC_TARGET_KEY, llGetLinkKey(llGetLinkNum() + 1),
PSYS_PART_FLAGS, ( 0
| PSYS_PART_INTERP_COLOR_MASK
| PSYS_PART_INTERP_SCALE_MASK
| PSYS_PART_EMISSIVE_MASK
| PSYS_PART_FOLLOW_VELOCITY_MASK
// | PSYS_PART_WIND_MASK
// | PSYS_PART_BOUNCE_MASK
// | PSYS_PART_FOLLOW_SRC_MASK
// | PSYS_PART_TARGET_POS_MASK
// | PSYS_PART_TARGET_LINEAR_MASK
) ] );
}
}
// (particle appearance settings)
// TEXTURE, can be an "Asset UUID" key copied from a modable texture, or the name of a texture in the prim's inventory.
// SCALE, vector's x and y can be 0.0 to 4.0. z is ignored. Values smaller than 0.04 might not get rendered.
// END_SCALE requires the INTERP_SCALE_MASK
// COLOR, red,green,blue values from 0,0,0(black) to 1,1,1 (white)
// ALPHA, 0.0 = invisible, less than 0.1 may not get seen, 1.0 = solid/opaque
// END_COLOR and END_ALPHA both require INTERP_COLOR_MASK
// (emitter controls)
// BURST_PART_COUNT 1 to 4096
// BURST_RATE 0.0 to 60.0? # of seconds between bursts, smaller = faster
// PART_MAX_AGE, 0.0 to 30.0, particle lifespan in seconds
// SRC_MAX_AGE - emitter auto-off interval 0.0 never times out. 1.0 to 60.0.
// (placement and movement settings)
// PATTERN,
// DROP, no initial velocity, direction or distance from emitter
// EXPLODE, spray in all directions
// ANGLE, "fan" shape defined by ANGLE BEGIN and END values
// ANGLE_CONE, "ring" or "cone" shapes defined by ANGLE BEGIN and END values
// ACCEL, x,y,z 0.0 to 50.0? sets a constant force, (affects all patterns)
// RADIUS 0.0 to 50.0? distance from emitter to create new particles
// (Useless with DROP pattern and FOLLOW_SRC option)
// SPEED, 0.01 to 50.0? Sets range of starting velocities. (Useless with DROP pattern.)
// ANGLE_BEGIN & END, 0.0 (up) to PI (down), (Only useful with ANGLE patterns)
// OMEGA, x,y,z 0.0 to PI? Sets distance to rotate emitter nozzle between bursts
// (Only useful with ANGLE patterns)
// TARGET_KEY, "key", (requires a TARGET option below) can be many things :
// llGetOwner()
// llGetKey() target self
// llGetLinkKey(1) target parent prim
// llGetLinkKey(llGetLinkNum() + 1) target next prim in link set
// (on/off options that affect how particles look)
// EMISSIVE identical to "full bright" setting on prims
// FOLLOW_VELOCITY particle texture 'tilts' towards the direction it's moving
// INTERP_COLOR causes color and alpha to change over time
// INTERP_SCALE causes particle size to change over time
// (on/off options that affect how particles move)
// BOUNCE particles can't go below altitude of emitter
// WIND sim's wind will push particles around
// FOLLOW_SRC makes particles move (but not rotate) if their emitter moves, (disables RADIUS)
// TARGET_POS causes particles to home in on a target object
// TARGET_LINEAR forces a DROP pattern like behavior and disables wind.

View File

@@ -1,95 +0,0 @@
default {
state_entry() {
llParticleSystem( [
PSYS_SRC_TEXTURE, llGetInventoryName(INVENTORY_TEXTURE, 0),
PSYS_PART_START_SCALE, <15.5,15.5, 0>, PSYS_PART_END_SCALE, <0,2.0, 0>,
PSYS_PART_START_COLOR, <255,140,0>, PSYS_PART_END_COLOR, <.5,.2,0>,
PSYS_PART_START_ALPHA, 1.0, PSYS_PART_END_ALPHA, 0.0,
PSYS_SRC_BURST_PART_COUNT, 1,
PSYS_SRC_BURST_RATE, 0.01,
PSYS_PART_MAX_AGE, 3.4,
PSYS_SRC_MAX_AGE, 0.0,
PSYS_SRC_PATTERN, 8, // 1=DROP, 2=EXPLODE, 4=ANGLE, 8=ANGLE_CONE,
PSYS_SRC_ACCEL, <0.0,0.0,0.0>,
// PSYS_SRC_BURST_RADIUS, 0.0,
PSYS_SRC_BURST_SPEED_MIN, .01, PSYS_SRC_BURST_SPEED_MAX, 3.01,
PSYS_SRC_ANGLE_BEGIN, 1*DEG_TO_RAD, PSYS_SRC_ANGLE_END, 0*DEG_TO_RAD,
PSYS_SRC_OMEGA, <0,0,0>,
// PSYS_SRC_TARGET_KEY, llGetLinkKey(llGetLinkNum() + 1),
PSYS_PART_FLAGS, ( 0
| PSYS_PART_INTERP_COLOR_MASK
| PSYS_PART_INTERP_SCALE_MASK
| PSYS_PART_EMISSIVE_MASK
| PSYS_PART_FOLLOW_VELOCITY_MASK
// | PSYS_PART_WIND_MASK
// | PSYS_PART_BOUNCE_MASK
// | PSYS_PART_FOLLOW_SRC_MASK
// | PSYS_PART_TARGET_POS_MASK
// | PSYS_PART_TARGET_LINEAR_MASK
) ] );
}
}
// (particle appearance settings)
// TEXTURE, can be an "Asset UUID" key copied from a modable texture, or the name of a texture in the prim's inventory.
// SCALE, vector's x and y can be 0.0 to 4.0. z is ignored. Values smaller than 0.04 might not get rendered.
// END_SCALE requires the INTERP_SCALE_MASK
// COLOR, red,green,blue values from 0,0,0(black) to 1,1,1 (white)
// ALPHA, 0.0 = invisible, less than 0.1 may not get seen, 1.0 = solid/opaque
// END_COLOR and END_ALPHA both require INTERP_COLOR_MASK
// (emitter controls)
// BURST_PART_COUNT 1 to 4096
// BURST_RATE 0.0 to 60.0? # of seconds between bursts, smaller = faster
// PART_MAX_AGE, 0.0 to 30.0, particle lifespan in seconds
// SRC_MAX_AGE - emitter auto-off interval 0.0 never times out. 1.0 to 60.0.
// (placement and movement settings)
// PATTERN,
// DROP, no initial velocity, direction or distance from emitter
// EXPLODE, spray in all directions
// ANGLE, "fan" shape defined by ANGLE BEGIN and END values
// ANGLE_CONE, "ring" or "cone" shapes defined by ANGLE BEGIN and END values
// ACCEL, x,y,z 0.0 to 50.0? sets a constant force, (affects all patterns)
// RADIUS 0.0 to 50.0? distance from emitter to create new particles
// (Useless with DROP pattern and FOLLOW_SRC option)
// SPEED, 0.01 to 50.0? Sets range of starting velocities. (Useless with DROP pattern.)
// ANGLE_BEGIN & END, 0.0 (up) to PI (down), (Only useful with ANGLE patterns)
// OMEGA, x,y,z 0.0 to PI? Sets distance to rotate emitter nozzle between bursts
// (Only useful with ANGLE patterns)
// TARGET_KEY, "key", (requires a TARGET option below) can be many things :
// llGetOwner()
// llGetKey() target self
// llGetLinkKey(1) target parent prim
// llGetLinkKey(llGetLinkNum() + 1) target next prim in link set
// (on/off options that affect how particles look)
// EMISSIVE identical to "full bright" setting on prims
// FOLLOW_VELOCITY particle texture 'tilts' towards the direction it's moving
// INTERP_COLOR causes color and alpha to change over time
// INTERP_SCALE causes particle size to change over time
// (on/off options that affect how particles move)
// BOUNCE particles can't go below altitude of emitter
// WIND sim's wind will push particles around
// FOLLOW_SRC makes particles move (but not rotate) if their emitter moves, (disables RADIUS)
// TARGET_POS causes particles to home in on a target object
// TARGET_LINEAR forces a DROP pattern like behavior and disables wind.

View File

@@ -1,6 +1,12 @@
// :SHOW:
// :CATEGORY:Sensor
// :NAME:Mafic Sensor
// :NAME:Magic Sensor
// :AUTHOR:CyberGlo Cyberstar
// :KEYWORDS:
// :CREATED:2021-04-26 23:40:28
// :EDITED:2021-04-26 22:40:28
// :ID:1134
// :NUM:2024
// :REV:1.0
// :WORLD:Second Life, Opensim
// :DESCRIPTION:

View File

@@ -1,12 +1,10 @@
//:Author: Unknown
//:CATEGORY: Mover
// :SHOW:1
// :CATEGORY:Mover
// :NAME:Move-From-Point-To-Point
// :AUTHOR:Unknown
// :KEYWORDS:
// :CREATED:2019-08-30 11:39:48
// :EDITED:2021-04-26 22:40:29
// :ID:1125
// :NUM:2012
// :REV:2
@@ -17,6 +15,7 @@
integer m_STEPS = 64;
motionTo(vector dest,rotation rot) {

View File

Before

Width:  |  Height:  |  Size: 183 KiB

After

Width:  |  Height:  |  Size: 183 KiB

View File

@@ -1,3 +1,17 @@
// :SHOW:1
// :CATEGORY:Train
// :NAME:Opensim Train
// :AUTHOR:Moundsa Mayo
// :KEYWORDS:
// :CREATED:2021-04-26 23:42:50
// :EDITED:2021-04-26 22:46:16
// :ID:1135
// :NUM:2025
// :REV:1
// :WORLD:Second Life
// :DESCRIPTION:
//
// :CODE:
SOME NOTES ABOUT THIS SCRIPT
I'm more of a script hacker than a script editor, and I decided to hack this script. I got rid of the Guide prims and got it to run ON the MESH TRACK! I did this by editing the script and replacing the value of gsSensorTargetName from Guide to Freight. Then I renamed each mesh track to Freight. I found this mostly worked just as well.

View File

@@ -1,8 +1,12 @@
// :SHOW:
// :SHOW:1
// :CATEGORY:Train
// :NAME:Opensim Train
// :AUTHOR:Moundsa Mayo
// :KEYWORDS:Opensim Train
// :CREATED:2021-04-26 23:42:50
// :EDITED:2021-04-26 22:42:50
// :ID:1135
// :NUM:2026
// :REV:2.6.0
// :WORLD:Opensim
// :DESCRIPTION:

View File

@@ -1,8 +1,12 @@
// :SHOW:
// :SHOW:1
// :CATEGORY:Meter
// :NAME:Visitor Display
// :NAME:Opensim VIsitors List
// :AUTHOR:Unknown
// :KEYWORDS:Visitor Display
// :CREATED:2021-04-26 23:42:50
// :EDITED:2021-04-26 22:42:50
// :ID:1136
// :NUM:2027
// :REV:1
// :WORLD:Opensim
// :DESCRIPTION:

View File

@@ -1,10 +1,16 @@
// :SHOW:
// :CATEGORY:Train
// :NAME:Opensim Train
// :NAME:OpensimTrain
// :AUTHOR:Moundsa Mayo
// :CREATED:
// :EDITED:
// :KEYWORDS:
// :CREATED:2021-04-26 23:42:51
// :EDITED:2021-04-26 22:42:51
// :ID:1137
// :NUM:2028
// :REV:2.6.0// :WORLD:OpensimSim
// :DESCRIPTION:this is setup for non-physical, phantom movement but can be modified for physical, etc.
// :WORLD:Second Life
// :DESCRIPTION:
// this is setup for non-physical, phantom movement but can be modified for physical, etc.
// :CODE:
// [VRCLocomotiveOpensourceScript]

View File

@@ -1,3 +1,17 @@
// :SHOW:1
// :CATEGORY:Train
// :NAME:OpensimTrain
// :AUTHOR:Anonymous
// :KEYWORDS:
// :CREATED:2021-04-26 23:46:30
// :EDITED:2021-04-26 22:47:31
// :ID:1137
// :NUM:2028
// :REV:1
// :WORLD:Second Life
// :DESCRIPTION:
// Train
// :CODE:
This script works under DREAMGRID! It lives in the root prim of the engine, which in my test case was a box prim of size <9.00000, 1.20000, 0.75029>. The image below shows this moves out from its usual position
The track I used was some mesh track I found elsewhere, all named "Guide". The reason I've been using it is that as mesh it was easy to just change the size and direction of it when building track. I'm glad this works BETWEEN regions, but you have to be driving it to make anything happen. Ultimately I want to have a "guided tour" vehicle running under the same principles but with a much expanded route across several regions. The old guided tour scripts were OK but couldn't go outside a single region.

View File

@@ -1,8 +1,12 @@
// :SHOW:
// :SHOW:1
// :CATEGORY:Region Traffic Monitor
// :NAME:Region Traffic Monitor Stats Retriever
// :NAME:Paramour Traffic Monitor
// :AUTHOR:Aine Caoimhe
// :KEYWORDS:Region Traffic Monitor
// :CREATED:2021-04-26 23:46:30
// :EDITED:2021-04-26 22:46:30
// :ID:1138
// :NUM:2029
// :REV:2.0
// :WORLD:Opensim, Second Life
// :DESCRIPTION:

View File

@@ -1,8 +1,12 @@
// :SHOW:
// :SHOW:1
// :CATEGORY:Region Traffic Monitor
// :NAME:Region Traffic Monitor Stats Retriever
// :NAME:Paramour Traffic Monitor
// :AUTHOR:Aine Caoimhe
// :KEYWORDS:Region Traffic Monitor
// :CREATED:2021-04-26 23:46:31
// :EDITED:2021-04-26 22:46:31
// :ID:1138
// :NUM:2030
// :REV:2.0
// :WORLD:Opensim, Second Life
// :DESCRIPTION:

View File

@@ -1,8 +1,12 @@
// :SHOW:
// :SHOW:1
// :CATEGORY:Region Traffic Monitor
// :NAME:Region Traffic Monitor Stats Retriever
// :NAME:Paramour Traffic Monitor
// :AUTHOR:Aine Caoimhe
// :KEYWORDS:Region Traffic Monitor
// :CREATED:2021-04-26 23:46:31
// :EDITED:2021-04-26 22:46:31
// :ID:1138
// :NUM:2031
// :REV:2.0
// :WORLD:Opensim, Second Life
// :DESCRIPTION:

View File

@@ -1,10 +1,16 @@
// :SHOW:
// :CATEGORY:Particles
// :NAME:Pawprints
// :NAME:PawPrints
// :AUTHOR:CyberGlo CyberStar
// :KEYWORDS:
// :CREATED:2021-04-26 23:46:31
// :EDITED:2021-04-26 22:46:31
// :ID:1139
// :NUM:2032
// :REV:1.0
// :WORLD:Second Life, Opensim
// :DESCRIPTION:
//drop this script in a prim with a texture and wear it on your foot.
// //drop this script in a prim with a texture and wear it on your foot.
// :CODE:
//PawPrints by CyberGlo CyberStar

View File

@@ -1,16 +0,0 @@
default {
attach(key attached) {
if (attached != NULL_KEY) {
llRequestPermissions(attached, PERMISSION_TRIGGER_ANIMATION);
} else {
llStopAnimation(llGetInventoryName(INVENTORY_ANIMATION, 0));
}
}
run_time_permissions(integer perms) {
if(perms & (PERMISSION_TRIGGER_ANIMATION))
{
llStartAnimation(llGetInventoryName(INVENTORY_ANIMATION, 0));
}
}
}

View File

@@ -1,6 +1,12 @@
// :AUTHOR:Anatova Akina
// :SHOW:
// :CATEGORY:Email
// :NAME:PostBox
// :NAME:PostBox by Ana
// :AUTHOR:Anatova Akina
// :KEYWORDS:
// :CREATED:2021-04-26 23:47:32
// :EDITED:2021-04-26 22:47:32
// :ID:1140
// :NUM:2033
// :REV:1.0
// :WORLD:Second Life,Opensim
// :DESCRIPTION:

View File

@@ -1,339 +0,0 @@
From the free script library at http://www.outworldz.com/
tl;dr - Too long; didn't read:
My scripts are not for sale at any price except zero. Give credit to the authors. Share your changes so we all benefit.
How to Use:
These scripts are LSL-Editor formatted, plain-text *.LSL files and images, CAD files, sculpts and other useful files. Almost all of them work in Second Life, but some are specific to OpenSim which is noted in the header.
The easiest way to use them is to open any .LSL file in a word processor - except for Microsoft notepad, which folds it all on one line. Try Wordpad.
LSL-Editor:
The library is organized in LSL-Editor format, which is a free and open source LSL debugger and editor that emulates OpensIm and Second Life. You can download it for Windows from Sourceforge at http://sourceforge.net/projects/lsleditor/
Licenses:
Please leave any author credits and any headers intact in any script you use or publish. About 600 people worked many thousands of hours of volunteer effort to make and debug these scripts.
Scripts by Ferd Frederix, aka Fred K. Beckhusen, are licensed as Creative Commons CC Attribution-NonCommercial-ShareAlike (CC BY-NC-SA)
This license lets others remix, tweak, and build upon my work non-commercially, as long as you credit my and license you new creations under identical terms.
However,OBJECTS made with these scripts may be sold with no restrictions, priovided my script license remains intact. All I ask is that you point others to http://www.outworldz.com and to not sell my scripts, unless it is for $0. Free means FREE. The simplest way to do this is to make the scripts be readable to anyone, include a notecard with this license, or display a credit in ads.
Additional Licenses located in the body of the scripts may apply.
Please help improve the work by sending any new scripts, bugs and improvements to fred@mitsi.com so that all can benefit.
AUTHOR CREDITS:
SCRIPTS AUTHOR
294 Ferd Frederix
58 Encog Dod
32 Ama Omega
26 Dana Moore
21 Davy Maltz
15 Void Singer
13 Xundra Snowpaw
12 Fred Kinsei
11 mangowylder
11 Becky Pippen
10 Ariane Brodie
8 Barney Boomslang
7 Pavcules Superior
6 Apotheus Silverman
5 Martin
4 Kelly Linden
4 Nitsuj Kidd
4 Shine Renoir
4 Timeless Prototype
4 Cory Linden
4 eltee Statosky
4 donjr Spiegelblatt
4 Fred Gandt
4 Hank Ramos
4 John Linden
3 Jamethiel Wickentower
3 Fritigern
3 Fritz Kakapo
3 fratserke
3 Ezhar Fairlight
3 Falados Kapuskas
3 DZ
3 Eloise Pasteur
3 Christopher Omega
3 CrystalShard Foo
3 Cubey Terra
3 Alondria LeFay
3 Aaron Perkins
3 Sparti Carroll
3 Stormy Roentgren
3 Tali Rosca
3 Newfie Pendragon
3 Mitzpatrick Fitzsimmons
3 Meiyo Sojourner
3 kagefumi
3 Jopsy Pendragon
3 Kyrah Abbatoir
2 Max Case
2 Kira Komarov
2 Kristy Fanshaw
2 LSL Wiki
2 Melnik Balogh
2 Malaer Sunchaser
2 neo Rebus
2 oddball.otoole
2 Renmiri Writer
2 Rolig Loon
2 Runay Roussel
2 Xah Lee
2 Xaviar Czervik
2 Vince Bosen
2 Xylor Baysklef
2 Zanlew Wu
2 Zara Vale
2 Adalace Jewell
2 Amanda Vanness
2 Andrew Linden
2 Angel Fluffy
2 Angrybeth Shortbread
2 Beer Dailey
2 BACANA
2 CHandra Page
2 DoteDote Edison
2 Doug Linden
2 Doc Nerd
2 Emma Nowhere
2 FLipperPA
2 Beatfox Xevious
2 Francis Chung
2 heskemo oyen
2 Holy Gavenkrantz
2 Innula Zenovka
2 jesse barnett
1 Jester Knox
1 Jimmy Roo
1 Joannah Cramer
1 John Hurliman
1 JohnG Linden
1 Johnson Earls
1 Joker Opus
1 Jonathan Shaftoe
1 Insouciant Yue
1 jab737
1 Jacek Antonelli
1 Jake Cellardoor
1 Jamie Galliard
1 janasadvertise
1 Jason Keegan
1 Jasper Flossberg
1 Jeffrey Gomez
1 Jesrad Seraph
1 Honoured Resident
1 Hydrais
1 Harry Rau
1 Heb Dexler
1 herina Bode
1 Frost White
1 Gattz Gilman
1 Gaynor Gritzi
1 Ged Larsen
1 generaal.joubert
1 Goodwill Epoch
1 Green Fate
1 Guzar Fonzarelli
1 Gwyneth Llewelyn
1 Francisco V. Saldana
1 Franics
1 Fixit Galatea
1 Fred Huffhines
1 Foolish Frost
1 Fractal Mandala
1 Francis
1 Fenrir Reitveld
1 Ferd Fredderix
1 falados
1 Emmas Seetan
1 eltee Statowsky
1 Eric Linden
1 Eric Rosenbaum
1 Evil Fool
1 Dolyn Foley
1 Dora Gustafson
1 Dustin Widget
1 Charles Allen
1 Charlie Omega
1 Chasingred3 Ixtab
1 Chris Knox
1 Bastian McConach
1 Archanox Underthorn
1 aria.dragonash
1 Anylyn Hax
1 Asia Snowfall
1 Avatar42 Farspire
1 Azurei Ash
1 Babbage Linden
1 Daemonika Nightfire
1 dakar Muliaina
1 Dale Innis
1 Dan Medici
1 Cid Jacobs
1 Clarknova Helvetic
1 Click Broadcaster
1 Connely Aura
1 Cron Stardust
1 Daniel C. Smith
1 deaz
1 Dedric Mauriac
1 denise
1 Destiny Niles
1 dgrovesjr
1 Digital Dharma
1 Bel Linden
1 Ben Linden
1 Beverly Larkin
1 BigJohn Jade
1 Bill Freese
1 Blind Paine
1 Bobbyb30 Swashbuckler
1 boogday kuu
1 Brilliant Scientist
1 Cailyn Miller
1 camperdave614
1 Catherine Omega
1 Cera Murakami
1 ChadStatosky
1 Chalice Yao
1 Angel
1 AmaOmega
1 Amethyst Rosencrans
1 Amanda Sandgrain
1 Adelle Fitzgerald
1 Aeron Kohime
1 Aki Kojima
1 Aki-Tools
1 Alfkin Small
1 Ali Virgo
1 Allen Firethorn
1 Zena Juran
1 Zepp Zaftig
1 Zetaphor
1 ZHugh Becquerel
1 Zonax Delorean
1 Virus Collector
1 vittorio.vais
1 Void
1 Xylor
1 Todd Borst
1 Tribal Toland
1 Trimming Hedges
1 Tyche Shepherd
1 Tyro Dreamscape
1 Unrevoked Clarity
1 Valect
1 Vegas Silverweb
1 Very Keynes
1 Wandering Yaffle
1 Wedensday Grimm
1 Wednesday Grimm
1 whcyc2002
1 Wietse Cassini
1 wiki.YAK.net
1 Wizardry and Steamworks
1 Wizardy and Steamworks
1 WolfWings Majestic
1 RvA Hax
1 Ryker Beck
1 Sapphire Bombay
1 Scorpse Ghost
1 Scot Titian
1 Seagel Neville
1 Seifert Surface
1 Sheena Desade
1 shesuka
1 pedro.mcmillan
1 phoenix Behemoth
1 Pjanoo Windlow
1 Plowboy Lifestyle
1 PN Scripts Collection
1 Poppet McGimsie
1 Psycotic
1 Psyke Phaeton
1 Qie Niangao
1 Regina Public Schools
1 Rickard Roentgen
1 robokitty9000
1 Stormy Roengren
1 Siggy Romulus
1 Sitting Lightcloud
1 Solo Mornington
1 Taylor
1 Teddy Wishbringer
1 thedmanedman
1 Thili Playfair
1 Timeless Montreal
1 Strife Onizuka
1 StrifeOnizuka
1 Sylar Lawksley
1 Tacusin Memo
1 Takat Su
1 Tal Chernov
1 oddyotoole
1 Olly Butters
1 OoPsGalatea
1 Open Source
1 Optikal
1 Ordinal Malaprop
1 Paintball Magic
1 Particle Script
1 Patch
1 Paul Preibisch
1 nick failight
1 Niklas Waller
1 Noland Brokken
1 nonnux White
1 Northwest Portland
1 Oddball Otoole
1 Meyermagic Salome
1 Michael R. Horton
1 Micheil Merlin
1 Miffy Fluffy
1 Mike Zidane
1 Minsk Oud
1 Mitz
1 Moopf
1 Moriash Moreau
1 Mulligan Silversmith
1 muziekfreak1980 miles
1 Nada Epoch
1 Nash Baldwin
1 NashBaldwin
1 Nebadon Izumi
1 Nekow42 Zarf
1 Lum Pfohl
1 Lymirah Gardner
1 MachineCode
1 Kenny Jackson
1 Kex Godel
1 Kimm Paulino
1 Kyrah Abattoir
1 Marcus Llewellyn
1 Meghan Eldrich
1 Melchoir Tokhes
1 MeLight Korvin
1 Kyrah Abbattoir
1 Lear Cale
1 Leopard Loveless
1 Lex Neva
1 Lillie Yifu
1 Lionel Forager
1 Lisbeth Cohen
1 Logan Bauer
1 Jposy Pendragon
1 jpvdgiessen
1 Jules
1 justi
1 Kanker Greenacre

View File

@@ -1,992 +0,0 @@
// Changed to OpenSim by Rebekka Revnik
// in the OpenSim.ini you have to uncomment the following line under [Network]:
// user_agent = "OpenSim LSL (Mozilla Compatible)"
// and restart your sim
// Script: Shoutcast - radio controller
// Version: 0.3 - released 10-2-2011
// Logic Scripts (Flennan Roffo)
// (c) 2010 - Flennan Roffo (Logic Scripts)
//
// This script is a remake of a couple of similar script:
// + LandOwnersRadio V2.0 by Scripter Coba (( menu driven / notecard config script to select the radio station and sets parcel music url ))
// + Raven radio infoboard by Jamie Otis (( worked at the basis of sis service [sis.slserver.com/sis.php] used Xy text display ))
// + currentPlaying by Darkie Minotaur (( used the /7.html info to fetch current song title info, displayed as float text ))
//
// Purpose:
// * Sets the parcel audio URL and displays the channel info
// * Uses Xytext to display the info.
// * Fetches song title info from the shoutcast url
///////////////////////////////////////////////////////////////////////////////////////
// Extra Features -- 0.1 release
// * On/Off option
// * Allows multiple menus (if options per menu > 12) using a prev/next button
// * Checks if your url is well-formatted
// * Will delete genres for which no stations exist
// * Will skip stations that have same url and same genre (you can however have an identical station url under different genres).
// * New notecard format
//////////////////////////////////////////////////////////////////////////////////////////
// Extra Features -- 0.2 release
// * Configurable button text
// * Gets parcel URL and automatically sets the genre/station and on/off status accordingly (<-- doesn't work)
//////////////////////////////////////////////////////////////////////////////////////////
// Update -- 0.3 release
// * Fixed bug (only first station in genre displayed in menu)
// * Auto reset script when config card updated
// Notes:
// * Expects url to be in the format: <ip>:<port>, where <ip> has the format: xxx.xxx.xxx.xxx (0 <= xxx <= 255)
// * Deletes entries in category (genre) for which no stations are configured with notice.
// * Skips stations which have identical url AND same category (genre).
//////////////////////////////////////////////////////////////////////////////////////////
// Upcoming release -- 0.4
// * Will add functions for remote controller(s) and remote display(s) using llRegionSay to communicate over a channel.
// * Should relax on the constraints about the input format of URL's (currently requires that URL has format: xxx.xxx.xxx.xxx/yyyy).
// * Fix button placement. Control buttons should be on the first line.
// * Implement script reset on change of owner.
// * Permit station to be put under multiple genres, using a comma-seperated list of genres in the section [STATION]
// (currently this is only possible by duplicating the entire line and change the genre.)
/////////////////////////////////////////////////////////////////////////////////////////
// Future plans:
// * Individual user preferences that can be stored on seperate note cards. A user has access to his own list of genres and stations and the system available genres/stations.
// * Feature for accessing online playlists (M3U, PLS, other formats) to play a list of songs provided by that playlist.
// * User provided url.
/////////////////////////////////////////////////////////////////////////////////////////
// BUGS & FEATURE REQUESTS
//
// Please inform the author, Logic Scripts (flennan.roffo) about any bugs or annoyances.
// Feature requests can also be submitted to the author.
/////////////////////////////////////////////////////////////////////////////////////////
// LICENCE INFO
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
///////////////////////////////////////////////////////////////////////////////////////////
string info_notecard="Radio Control info"; /////// EDITABLE \\\\\\
string config_notecard="Radio Control config"; /////// EDITABLE \\\\\\
string comment_char="#"; /////// EDITABLE \\\\\\
list sep_char_list= ["|"]; /////// EDITABLE \\\\\\
float update_time=5.0; /////// EDITABLE \\\\\\
string no_title_info="(no title info available)"; /////// EDITABLE \\\\\\
// not used currently - for showing info on current song title elsewhere in the region
integer broadcast_channel=-1234; /////// EDITABLE \\\\\\
// Buttons
string button_MAIN = "MAIN"; /////// EDITABLE \\\\\\
string button_HELP = "HELP"; /////// EDITABLE \\\\\\
string button_NEXT = ">>"; /////// EDITABLE \\\\\\
string button_PREV = "<<"; /////// EDITABLE \\\\\\
string button_ON = "ON"; /////// EDITABLE \\\\\\
string button_OFF = "OFF"; /////// EDITABLE \\\\\\
string button_login = "Login as DJ"; /////// EDITABLE \\\\\\
//////////////////////////////////
// Don't touch the variables below
/////////////////////////////////
// List of categories (=genres)
list category_list=[];
// List of stations. KEEP THESE LISTS IN SYNCH!
list station_category=[];
list station_name=[];
list station_desc=[];
list station_url=[];
// Last song title played
string last_title_info="";
integer radio_status=0; // 0 - OFF 1 - ON
string parcel_url="";
integer lineno=0;
key reqid=NULL_KEY;
key httpreq_id=NULL_KEY;
integer config_error=FALSE;
integer flag;
integer section=0;
// Access values. Note that users who are banned can not access the device even when access is public
integer owner_access=TRUE;
integer group_access=TRUE;
integer public_access=FALSE;
list banned_keys=[];
// Channels for menu and user input
integer menu_channel;
integer listen_handle;
// Menu
integer menu_type=0; // 0 - Main menu (genres) 1 - Station menu (stations)
integer menu_num=0; // When more menu options need to be selectable then can be displayed on a menu (12), this is the menu number - menu number 0 is the first menu.
// Genres and stations
integer category_index=0; // Current index in category_list (genre)
integer station_index=0; // Current index in station_* (station)
integer num_categories=0;
integer num_stations=0;
key User;
string ncname;
key ncid;
integer ncline;
string stream;
key texture;
integer picno = 28; // Link number for picture
key radiopic = "c9e427ae-cd25-4548-86b9-c3fd6bf1aaca"; // UUID for club picture
// Make request for title info using HTTP request
retrieve_titelinfo()
{
string url=llList2String(station_url,station_index);
if(User != NULL_KEY) url = stream;
httpreq_id=llHTTPRequest(url + "/7.html",[],"");
}
// Display a line on an Xytext device linked in
display_line(string line, string message)
{
// Setup XYtext Variables
integer DISPLAY_STRING = 204000;
// integer DISPLAY_EXTENDED = 204001; (not used)
// integer REMAP_INDICES = 204002; (not used)
// integer RESET_INDICES = 204003; (not used)
// integer SET_CELL_INFO = 204004; (not used)
// integer SET_FONT_TEXTURE = 204005; (not used)
// integer SET_THICKNESS = 204006; (not used)
// integer SET_COLOR = 204007; (not used)
llMessageLinked(LINK_SET,DISPLAY_STRING,message,line);
}
// Clear the Xytext display
clear_display()
{
// Clears the display
display_line("1","Radio Station ID");
display_line("2","Music Genre....");
display_line("3","Now Playing....");
}
// Make a menu / dialog
make_menu(key id)
{
menu_channel=random_channel();
if (radio_status == 0)
{
menu_type=0;
menu_num=0;
llDialog(id,"Menu: Status\n\nRadio is OFF", [ "ON", "HELP" ],menu_channel);
}
else
{
if (menu_type ==0)
{
llDialog(id,"Menu: Genres", category_menu(menu_num),menu_channel);
}
else
{
llDialog(id,"Menu: Stations\nGenre: " + llList2String(category_list,category_index), station_menu(menu_num),menu_channel);
}
}
if (listen_handle != 0) llListenRemove(listen_handle);
listen_handle=llListen(menu_channel,"",id,"");
}
// Make the menu option list for menu: catagories (genres)
list category_menu(integer num)
{
integer len=llGetListLength(category_list);
list menu=[];
if (len > 9) // If more then 9 items (12 minus the 3 buttons for MAIN/HELP and PREV, NEXT)
{
integer last_sub=(len-1)/9; // submenus start at 0. 9th entry is in submenu 0, 10th in 1, etc.
if (num > last_sub)
{
llWhisper(0,"error: wrong submenu number: " + (string) num + ".");
return [ "MAIN" ];
}
else
{
integer first=9*num;
while (--len >= first)
menu+=(list)llList2String(category_list,len);
if (num == 0)
menu+=(list)button_login;
else
menu+=(list)button_MAIN;
if (num == 0)
menu+=(list)button_OFF;
else
menu+=(list)button_PREV;
if (num != last_sub)
menu+=(list)button_NEXT;
}
}
else
{
while (--len >= 0)
menu+=(list)llList2String(category_list,len);
menu+=(list)button_OFF;
menu+=(list)button_login;
}
return menu; // order_buttons(menu);
}
// Returns the number of stations in a certain category
integer stations_in_category(integer cat)
{
integer count=0;
integer i;
integer len=llGetListLength(station_category);
string category=llList2String(category_list,cat);
for (i=0; i < len; i++)
if (category == llList2String(category_list,i))
count++;
return count;
}
// Not used currently -- to fix button placement
//list order_buttons(list buttons)
//{
// integer offset;
// list fixt;
// integer flag=0;
//
// while((offset = llGetListLength(buttons)))
// {
// if (offset > 3)
// flag=1;
// else
// flag=0;
//
// fixt = llList2List(buttons, offset = -3 * flag, -1);
// buttons = llDeleteSubList(buttons, offset, -1);
// }
// return fixt;
//}
// Returns a list of station names in a certain category (genre)
list station_list(integer category)
{
list s=[];
integer i;
string cname=llList2String(category_list,category_index);
for (i = 0; i < llGetListLength(station_name); i++)
if (llList2String(station_category,i) == cname)
s+=(list)llList2String(station_name,i);
return s;
}
// Returns the list of stations for the station menu, depending on the submenu number
list station_menu(integer num)
{
list stations=station_list(category_index);
integer len=llGetListLength(stations);
list menu=[];
if (len > 11) // 12 - 1 for MAIN menu
{
integer last_sub=(len-1)/9;
if (num >= last_sub)
{
llWhisper(0,"error: wrong submenu number: " + (string) num + ".");
return [ "MAIN" ];
}
else
{
integer first=9*num;
integer last=9*num+8;
menu+=(list)button_MAIN;
if (num > 0)
menu+=(list)button_PREV;
if (num < last_sub)
menu+=(list)button_NEXT;
if (len > last)
len =last;
while (--len >= first)
menu+=(list)llList2String(stations,len);
}
}
else
{
menu+=(list)button_MAIN;
while (--len >= 0)
menu+=(list)llList2String(stations,len);
}
return menu; // order_buttons(menu);
}
// Returns whether av with key id has access
integer has_access(key id)
{
if (llListFindList(banned_keys,(list)id) != -1)
return FALSE;
if (owner_access && id == llGetOwner())
return TRUE;
if (group_access && llSameGroup(id))
return TRUE;
if (public_access)
return TRUE;
return FALSE;
}
// Gets a random channel -- uses a wide range of big negative channel numbers seldomly used
integer random_channel()
{
integer min=-2147483647;
integer max=-1000;
return (integer) (min + llFrand(max-min));
}
// Check for the format of the url string -- is very selective about url format
// expects: xxx.xxx.xxx.xxx:xxxx (ip adress in number notation with port adress)
// Next release will relax on this constraint.
integer check_url(string url)
{
return TRUE;
integer pos=0;
if (llGetSubString(url,0,6) == "http://")
pos=7;
if (llGetSubString(url,0,7) == "https://")
pos=8;
if (pos==0) return FALSE;
string str_ip_port=llGetSubString(url,pos,-1);
list list_ip_port=llParseString2List(str_ip_port,[":"],[]); // split in ip-adress and port
list list_ip=llParseString2List(llList2String(list_ip_port,0),["."],[]); // split ip-adress elements
if (llGetListLength(list_ip_port) != 2 || llGetListLength(list_ip) != 4)
return FALSE;
integer i;
integer test;
for (i=0;i<4;i++)
{
test=llList2Integer(list_ip,i);
if (llList2String(list_ip,i) != (string)test)
return FALSE;
if (test < 0 || test > 255)
return FALSE;
}
test=llList2Integer(list_ip_port,1);
if (llList2String(list_ip_port,1) != (string)test)
return FALSE;
return TRUE;
}
// Returns a true value depending on the first character in input - anything else is assumed false.
integer true_value(string input)
{
string value=llToLower(llGetSubString(input,0,0));
if (value == "y" || value == "t" || value =="1")
return TRUE;
return FALSE;
}
// Return if more input should be processed (if not at EOF) - sets ConfigError if any config error found. Reading config card stops at the first error.
integer process_line(string dataline)
{
string line=llStringTrim(dataline,STRING_TRIM);
integer index=llSubStringIndex(line,comment_char);
if (index==0) // line starts with comment - ignore line
return TRUE;
if (index!=-1)
line=llStringTrim(llGetSubString(line,0,index-1),STRING_TRIM_TAIL); // skip everything after comment_char and trim tail
if (line=="") // Ignore blank lines
return TRUE;
if (llToLower(line) == "[access]")
{
section = 1;
return TRUE;
}
else if (llToLower(line) == "[banned]")
{
section = 2;
return TRUE;
}
else if (llToLower(line) == "[genre]")
{
section = 3;
return TRUE;
}
else if (llToLower(line) == "[station]")
{
section = 4;
return TRUE;
}
else if (llGetSubString(line,0,0) == "[" && llGetSubString(line,-1,-1) == "]")
{
llWhisper(0,"error: malformed section found at line " + (string)lineno + ".\n" + dataline);
config_error=TRUE;
return FALSE;
}
if (section == 0)
{
llWhisper(0,"error: no section found on line: " + (string) lineno);
config_error = TRUE;
return FALSE;
}
list breakup=llParseString2List(line,["="],[]);
string field=llStringTrim(llList2String(breakup,0),STRING_TRIM);
string values=llStringTrim(llList2String(breakup,1),STRING_TRIM);
if (section == 1) // access
{
field=llToLower(field);
if (field=="owner")
{
owner_access=true_value(values);
return TRUE;
}
else if (field=="group")
{
group_access=true_value(values);
return TRUE;
}
else if (field=="public")
{
public_access=true_value(values);
return TRUE;
}
else
{
llWhisper(0,"error: invalid option on line: " + (string)lineno + ".\n" + dataline);
config_error=TRUE;
return FALSE;
}
}
else if (section == 2) // ban list
{
key try=(key) field;
if (try)
{
banned_keys+=(list)((key) field);
return TRUE;
}
else
return FALSE;
}
else if (section == 3) // categories
{
if (llListFindList(category_list,(list)field) == -1)
{
category_list+=(list)field;
}
else
llWhisper(0,"genre: '" + field + "' already entered; double entry skipped.");
return TRUE;
}
else if (section == 4) // stations
{
list parse=llParseString2List(line,sep_char_list, []);
string category=llStringTrim(llList2String(parse,0),STRING_TRIM);
string name=llStringTrim(llList2String(parse,1),STRING_TRIM);
string desc=llStringTrim(llList2String(parse,2),STRING_TRIM);
string url=llStringTrim(llToLower(llList2String(parse,3)),STRING_TRIM);
if (!available_category(category))
{
llWhisper(0,"error: unknown genre on line: " + (string)lineno + ".\n" + dataline);
config_error=TRUE;
return FALSE;
}
if (check_url(url))
{
if (llListFindList(station_url,(list)url) == -1 || llListFindList(station_category,(list)category) == -1)
{
num_stations++;
station_category+=(list)category;
station_name+=(list)name;
station_desc+=(list)desc;
station_url+=(list)url;
return TRUE;
}
else
{
llWhisper(0,"This station is already entered under the same genre and same url and is skipped.\nStation: " + name + "\nGenre: '" + category + "'\nURL: " + url);
return TRUE;
}
}
else
{
llWhisper(0,"error: malformed url on line: " + (string)lineno + ".\n" + dataline);
config_error=TRUE;
return FALSE;
}
}
return FALSE;
}
// Sets the parcel URL and updates the display
set_parcel_url(string url)
{
parcel_url=url;
llSetParcelMusicURL(parcel_url);
if (parcel_url=="")
{
clear_display();
display_line("1","Radio is OFF");
display_line("2","");
display_line("3","");
User = NULL_KEY;
}
else
{
if(User == NULL_KEY)
{
llWhisper(0,"station now set to " + llList2String(station_desc,station_index) + ".");
display_line("1","Station: " + llList2String(station_desc,station_index));
display_line("2","Genre : " + llList2String(category_list,category_index));
}
display_line("3","Now playing.....");
llSetTimerEvent(update_time);
}
}
// Returns if a category (genre) exists.
integer available_category(string category)
{
integer i;
integer len=llGetListLength(category_list);
for (i=0;i<len;i++)
if (llToLower(category) == llToLower(llList2String(category_list,i)))
return TRUE;
return FALSE;
}
// Returns if a category (genre) is empty (i.e. there are no stations for this catagory (genre))
integer empty_category(string category)
{
integer i;
integer len=llGetListLength(station_category);
for (i=0; i < len; i++)
if (llToLower(category) == llToLower(llList2String(station_category,i)))
return FALSE;
return TRUE;
}
// Removes categories (genres) for which no station is known.
skip_empty_categories()
{
integer i=0;
while (i<llGetListLength(category_list))
{
if (empty_category(llList2String(category_list,i)))
{
llWhisper(0,"Warning: Genre '" + llList2String(category_list,i) + "' contains no stations and is deleted.");
category_list=llDeleteSubList(category_list,i,i);
}
else
i++;
}
num_categories=llGetListLength(category_list);
}
/////////////////////////////////////////////
// state default
////////////////////////////////////////////
default
{
state_entry()
{
flag=FALSE;
lineno=1;
config_error=FALSE;
num_stations=0;
num_categories=0;
radio_status=0;
menu_num=0;
menu_type=0;
User = NULL_KEY;
llSetLinkTexture(picno, radiopic, 3);
if (llGetInventoryType(config_notecard) == INVENTORY_NOTECARD)
{
reqid=llGetNotecardLine(config_notecard,lineno++);
llWhisper(0, "Reading config notecard...");
display_line("1","Reading configuration.");
display_line("2","Wait....");
display_line("3","");
}
else
{
llWhisper(0,"No config notecard '" + config_notecard + "' present.");
state offline;
}
}
on_rez(integer param)
{
llResetScript();
}
dataserver(key id, string data)
{
if (reqid==id)
{
if (data==EOF)
{
skip_empty_categories();
llWhisper(0,"Configuration ok.\n" + (string)num_categories + " genres and " + (string)num_stations + " stations.");
display_line("1","Configuration OK");
display_line("2","Genres : " + (string)num_categories);
display_line("3","Stations: " + (string)num_stations);
state menu;
}
else
{
if (process_line(data))
reqid=llGetNotecardLine(config_notecard,lineno++);
else if (config_error)
{
llWhisper(0,"errors found in configuration. please correct them.");
state offline;
}
}
}
}
touch_start(integer total_num)
{
}
changed(integer ch)
{
if (ch & CHANGED_INVENTORY)
llResetScript();
}
}
/////////////////////////////////////////////
// state offline
////////////////////////////////////////////
state offline
{
state_entry()
{
llWhisper(0,"Reset on owner touch or when notecard updated.");
}
touch_start(integer t)
{
if (llDetectedKey(0)==llGetOwner())
llResetScript();
}
changed(integer ch)
{
if (ch & CHANGED_INVENTORY)
llResetScript();
}
}
/////////////////////////////////////////////
// state menu
////////////////////////////////////////////
state menu
{
state_entry()
{
menu_type=0;
menu_num=0;
listen_handle=0;
if(User != NULL_KEY)
{
set_parcel_url(stream);
}
}
on_rez(integer param)
{
llResetScript();
}
touch_start(integer total_num)
{
key toucher=llDetectedKey(0);
if (has_access(toucher))
{
make_menu(toucher);
}
else
llWhisper(0,"sorry, no access.");
}
listen(integer chan, string name,key id,string msg)
{
integer index;
if(msg == button_login)
{
//if(User != NULL_KEY)
//{
// llWhisper(0, "Sorry, but the board is already in use.");
// return;
//}
string s = "@" + llKey2Name(id);
if(llGetInventoryType(s) != INVENTORY_NOTECARD)
{
llWhisper(0, "Only DJ's are allowed to log in.");
return;
}
User = id;
state login;
}
else if (menu_type == 0) // main menu
{
if (msg == button_MAIN)
{
menu_type=0;
menu_num =0;
make_menu(id);
}
else if (msg == button_NEXT)
{
menu_num++;
make_menu(id);
}
else if (msg == button_PREV)
{
menu_num--;
make_menu(id);
}
else if (msg == button_ON)
{
radio_status=1;
set_parcel_url(parcel_url);
display_line("1","Radio is ON");
menu_num=0;
User = NULL_KEY;
llRegionSay(-7848, "button_ON");
llWhisper(0,"Radio now turned on.");
make_menu(id);
}
else if (msg == button_OFF)
{
radio_status=0;
set_parcel_url("");
User = NULL_KEY;
llSetTimerEvent(0.0);
llRegionSay(-7848, "button_OFF");
llWhisper(0,"Radio now turned off.");
}
else if (msg == button_HELP)
{
if (llGetInventoryType(info_notecard) == INVENTORY_NOTECARD)
{
llGiveInventory(id,info_notecard);
}
else
llWhisper(0,"sorry, help not available.");
} else if (radio_status == 1)
{
index = llListFindList(category_list, (list)msg);
if (index == -1)
llWhisper(0,"error: genre not found: " + msg);
else
{
category_index=index;
llWhisper(0,"Genre now set to " + llList2String(category_list,category_index) + ".");
menu_type=1;
menu_num=0;
make_menu(id);
}
}
}
else if (menu_type == 1 && radio_status == 1) // station menu
{
if (msg == button_MAIN)
{
menu_type=0;
menu_num =0;
make_menu(id);
}
else if (msg == button_NEXT)
{
menu_num++;
make_menu(id);
}
else if (msg == button_PREV)
{
menu_num--;
make_menu(id);
}
else
{
index = llListFindList(station_name, (list)msg);
if (index == -1)
llWhisper(0,"error: station not found: " + msg);
else
{
station_index=index;
string new_url=llList2String(station_url,station_index);
User = NULL_KEY;
llSetLinkTexture(picno, radiopic, 3);
if (new_url != parcel_url)
{
set_parcel_url(new_url);
}
}
}
}
}
timer()
{
retrieve_titelinfo();
llSetTimerEvent(update_time);
}
http_response(key id, integer status, list meta, string body)
{
if (id == httpreq_id)
{
//llSay(0, body);
if (status == 200)
{
string feed = llGetSubString(body,llSubStringIndex(body, "<body>") + llStringLength("<body>"), llSubStringIndex(body,"</body>") - 1);
list feed_list = llParseString2List(feed,[","],[]);
string current_title_info= llList2String(feed_list,6);
integer length = llGetListLength(feed_list);
if(llList2String(feed_list,7))
{
integer a = 7;
for(; a<length; ++a)
{
current_title_info += ", " + llList2String(feed_list,a);
}
}
if (current_title_info != last_title_info)
{
last_title_info = current_title_info;
display_line("3","Title : " + current_title_info);
}
}
else
{
display_line("3","");
}
}
}
changed(integer ch)
{
if (ch & CHANGED_INVENTORY)
llResetScript();
}
}
state login
{
state_entry()
{
texture = NULL_KEY;
stream = "";
ncname = "@" + llKey2Name(User);
ncline = 0;
ncid = llGetNotecardLine(ncname, ncline++);
}
dataserver(key requested, string data)
{
if(requested == ncid)
{
if(data != EOF)
{
list l = llParseString2List(data, ["="], []);
string s1 = llToLower(llStringTrim(llList2String(l, 0), STRING_TRIM));
string s2 = llStringTrim(llList2String(l, 1), STRING_TRIM);
if(s1 == "texture") texture = (key)s2;
else if(s1 == "stream") stream = s2;
ncid = llGetNotecardLine(ncname, ncline++);
} else
{
//set_parcel_url(stream);
display_line("1","--> Live DJ <--");
display_line("2","Your DJ: " + llKey2Name(User));
if(texture != NULL_KEY) llSetLinkTexture(picno, texture, 3);
state menu;
}
}
}
}
//////////////////////////////
// end of script
//////////////////////////////

BIN
image.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 310 KiB