52 Commits

Author SHA1 Message Date
c42b1f028c update version check url 2026-03-02 08:01:44 +01:00
lickx
c58c4634ba Add creatorkit, closes #110 2026-02-22 04:26:43 +01:00
lickx
8659213ab2 Use sane default if leash length is 0
This should never happen tho
2026-02-15 13:49:13 +01:00
lickx
bcfe397138 Handle outfit changes in a failsafe way 2026-02-10 16:53:56 +01:00
lickx
f9ee2bc9e7 Don't process FloatText prim during hide/unhide 2026-02-02 09:22:43 +01:00
lickx
5e3301d021 Correct channel on oc_grabbypost 2026-02-01 10:30:35 +01:00
lickx
522d1a4f9c Bump device version for the updater check 2026-02-01 10:29:10 +01:00
lickx
1a06aa0b30 Correct the font y 2026-02-01 10:27:38 +01:00
lickx
e34bf53933 Redo how stealth works
Also remove redundant @detach (it is handled by rlvsys)
2026-02-01 10:24:57 +01:00
lickx
1fd6a90089 Rename Owner's HUD -> Remote 2026-01-27 15:03:28 +01:00
lickx
746653149b Update README.md 2026-01-14 12:40:12 +01:00
lickx
e95bea06d5 Normalize heel
If slider for heel and platform are fully to the right,
each is 10cm height difference
2025-12-25 16:23:27 +01:00
lickx
63f9c3ec97 Cleanup 2025-05-29 04:42:01 +02:00
lickx
550bfcacdf Post-merge changes 2025-05-19 06:59:06 +02:00
lickx
eaa5a6f1e3 Correct repo to check for the device version 2025-05-11 19:56:31 +02:00
lickx
e9d54fc60b Merge branch 'master' into tamai 2025-05-11 16:00:39 +02:00
lickx
0396e3bb62 Closes #108 2025-04-29 08:15:04 +02:00
lickx
eafa30a5f7 Replace script engine info with OS version info 2025-04-24 18:14:13 +02:00
lickx
41274d4020 Make it compile (now tested) 2025-04-24 18:03:10 +02:00
lickx
442d7b5fed Type is more reliable than Key for inv checking 2025-04-24 17:15:26 +02:00
lickx
57468cc10a On 2nd thought, always be verbose 2025-04-24 16:59:59 +02:00
lickx
4b6355a222 On runaway, rewrite card without owners, or else remove it
Untested
2025-04-24 16:50:04 +02:00
lickx
adec57490c Hint to unlock before overwrite the .settings card 2025-04-24 16:31:47 +02:00
lickx
4a021b7ed6 Unfortunately minimum version will be 0.9.3.1
Due to http://opensimulator.org/mantis/view.php?id=9127
which affects the most recent 0.9.3 release.
2025-04-23 21:02:42 +02:00
lickx
38b6eb9523 Lower minimum requirement to current release 2025-04-23 14:45:13 +02:00
lickx
8d05f56064 Comment out the llGetVisualParams code
Until next OpenSim release (0.9.3.1?) where it will be included
2025-04-19 19:05:37 +02:00
lickx
233679ca30 Oops forgot something 2025-04-17 16:24:37 +02:00
lickx
bec1074718 Detect RLV less frequent on startup 2025-04-17 15:48:44 +02:00
lickx
205460c44c Various small updates 2025-04-16 07:58:06 +02:00
lickx
bb1d46fc9f llGetVisualParams replaces inaccurate heel/platform detection 2025-04-16 07:54:22 +02:00
lickx
1aa899f895 Use yyyy.mm version from now on
The comparison never took into acount the pointversion (day) anyway
2025-04-16 07:53:36 +02:00
lickx
19d5891fab More refinement for llGetVisualParams 2025-04-16 07:52:28 +02:00
lickx
7fa14d3ed2 Removed due to licensing unclarity
Despite being available on most free font sites,
we can't have ambiguous licensed files in the repo
2025-04-16 05:00:36 +02:00
lickx
a68cb59770 Implement *real* heel+platform height
This feature will only show noticable results in OpenSim master (0.9.3.1)
For older OpenSim, heel and platform height will make no difference

You may have to readjust your offsets in the Animations->Pose menu,
and then Settings->Save from the main menu.
2025-04-15 08:27:56 +02:00
lickx
3930ba371d 2025.01.06 for Tamai 2025-01-06 15:21:26 +01:00
lickx
b488938ac4 Line endings 2024-10-04 04:16:59 +02:00
lickx
76336ec3ca Store on/off state, for when re-attaching/relogging 2024-07-23 20:03:46 +02:00
lickx
5d1a7bc4b5 Merge pull request #103 from lickx/101-oc_settings-use-linkset-data-for-storage-instead-of-notecardprimtextures
101 oc settings use linkset data for storage instead of notecardprimtextures
2024-07-08 14:47:46 +02:00
lickx
4fd317673d Merge branch 'master' into 101-oc_settings-use-linkset-data-for-storage-instead-of-notecardprimtextures 2024-07-08 14:46:15 +02:00
lickx
d08ccc5135 Merge pull request #104 from lickx/102-trim-led-code-for-optimization
Do away with LED code (issue #102)
2024-06-28 04:39:18 +02:00
lickx
0393a837d0 Update opensim-patches.md 2024-05-31 11:45:04 +02:00
lickx
b51fba378d Do away with LED code (issue #102) 2024-05-29 17:25:11 +02:00
lickx
e74599a50c Delete old notecard before saving the new one 2024-05-18 17:01:08 +02:00
lickx
1e5943497e Now multiple values per token work correct
I had to duplicate some code from SetSetting to LoadLinksetData

Also DelSetting will now remove the LSD for the token given
2024-05-13 17:45:01 +02:00
lickx
64d017517d Same here. And always load from LSD when state lost 2024-05-13 16:38:05 +02:00
lickx
7503c95555 One correction I forgot to commit 2024-05-13 16:20:55 +02:00
lickx
583f3de5a1 Let oc_settings use linksetdata #101
Includes a 'Dump LSD' command in the Settings dialog, to show what's
currently stored. You can compare to the 'Print' to see if everything
is correct.

On 'Load Card', linksetdata will be cleared before loading, at least for
now. This is maybe not desirable in the final release, otherwise one can
purge all owners too easily.
2024-05-13 15:10:55 +02:00
lickx
86004ac483 Workaround for AIS3 and RLVa 2024-03-17 10:29:43 +01:00
lickx
db623bef74 Save memory, minor improvements 2024-03-16 06:03:59 +01:00
lickx
f0ca350b6d Re-apply restrictions on login 2024-02-17 15:39:55 +01:00
lickx
5b6ecd549f Update AO comparison 2023-12-03 02:44:15 +01:00
lickx
2bf8ee180f Update AO comparison 2023-12-03 02:41:25 +01:00
33 changed files with 329 additions and 641 deletions

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
*.lsl text eol=lf

View File

@@ -1,10 +1,6 @@
### Welcome to OsCollar
OsCollar is a set of gadgets for submission roleplay for use in the OpenSim metaverse
Grid and sim owners might want to read [opensim patches](doc/opensim-patches.md)
For help and chatter, join us on [Matrix](https://matrix.to/#/#oscollar:matrix.org)
OsCollar is a set of gadgets for submission roleplay for use in OpenSim grids
#### Finding your way around this repo
@@ -16,26 +12,29 @@ For help and chatter, join us on [Matrix](https://matrix.to/#/#oscollar:matrix.o
> res: Resource of creative content.
> anims: Motions and Animations as .bvh and .avm binaries.
> creatorkit: Sample collar for creators to use as a base
> models: 3D Models as .dae and .blend binaries.
> sounds: Sounds as .wav and .aup binaries.
> textures: Images as .png and .xcf binaries.
> src: Source code of the OsCollar role play device.
> ao: The source code for the animation overrider.
> ao: The source code for the animation overrider HUD.
> apps: Fun features you can add to your device
> device: Everything you need for a full featured device
> extensions: Enhanced features that can be added to a device
> installer: The source code for the updater aka patch
> remote: The source code for the remote control HUD.
> remote: The source code for the Remote HUD.
> spares: Spares and snippets for research and development.
> web: Files for the updater check within the Help/About menu
```
#### Requirements
Simulator: OpenSim 0.9.1.0 or newer
XEngine or YEngine (YEngine strongly recommended!)
Simulator 0.9.3.1 or newer
Note that as soon as YEngine becomes the default in a forthcoming OpenSim release, we will drop XEngine support. High quality grids already have set YEngine as default, or at least give simowners the option to enable it.
- Teleporting to a sim running older versions of OpenSim may result in loss of settings (linkset data) and loss of functionality (non-running scripts)
- Teleporting to a hypergrid sim may result in scripts to stop running and/or reset, unless the destination sim is patched
UUIDs referenced by code and notecards refer to assets on the OsGrid.org asset server
To avoid problems, only use this on your home grid meeting the minimal requirements or better.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 85 KiB

View File

@@ -1,6 +1,8 @@
Recommended patches for OpenSim
You wouldn't believe how often I got a "bug report" for what is actually a bug in OpenSim itself. Unfortunately the core devs don't see the urgency to address these problems in mainstream OpenSim, so you'll have to patch the OpenSim sourcecode yourself!
Often we get a "bug report" for what is actually a known bug in OpenSim itself. Unfortunately the core devs don't see the urgency to address these problems, so you'll have to patch the OpenSim sourcecode yourself!
Alternatively, run my own [OpenSim fork](https://github.com/lickx/opensim-lickx) in which this all is fixed
[Mantis 8366](http://opensimulator.org/mantis/view.php?id=8366)
This fixes state being lost or even non-working scripts for any hypergrid visitors you receive at your sim. If you have been wondering why your collar (and other scripted attachments) lost any and all settings when hypergridding, this is it. The destination sim will have to apply these patches.
@@ -8,8 +10,9 @@ This fixes state being lost or even non-working scripts for any hypergrid visito
[Mantis 8366](http://opensimulator.org/mantis/view.php?id=8366) and [Mantis 9052](http://opensimulator.org/mantis/view.php?id=9052)
After a TP to the hypergrid, your attachments won't be set to the active group tag for that grid, which is needed if you allow access from that group on the collar. The destination sim will have to apply these patches.
[Mantis 6311](http://opensimulator.org/mantis/view.php?id=6311) [Patch here](https://github.com/lickx/opensim-lickx/wiki/6311)
This affects RLVa, when declining a folder given to your shared #RLV folder by a scripted object/trap. Accepting seems to be working now since OpenSim 0.9.2, decline will only work correctly after this patch is applied.
[Mantis 6311](http://opensimulator.org/mantis/view.php?id=6311)
This affects RLVa, when declining a folder given to your shared #RLV folder by a scripted object/trap. Accepting works since OpenSim 0.9.2, decline will only work correctly after a patch is applied. Basically the object url in a inventory offer message HAS to start with http://slurl because RLVa is hardcoded like that. http://slurl.yourgrid.com is fine for example.
[Mantis 8250](http://opensimulator.org/mantis/view.php?id=8250)
If your leashed sub has been bunny hopping or is stuck when walking up or down a hill, stairs, or other kind of slope, this patch fixes that leash weirdness.

Binary file not shown.

View File

@@ -15,8 +15,4 @@ Free software for 3D assets creation:
* [Blender](https://blender.org/)
License:
* The official OpenCollar logos and derivatives are trademark and property of their respective owners and may not be used without prior express permission.
* Button textures, which are generally prefixed with button_ in their name, may only be used with express permission.
* All other textures and binaries contributed to this repository, with exception of those stated above, are licensed under a [Creative Commons Attribution-ShareAlike 4.0 International Public License](https://creativecommons.org/licenses/by-sa/4.0/)
* All textures and binaries contributed to this repository are licensed under a [Creative Commons Attribution-ShareAlike 4.0 International Public License](https://creativecommons.org/licenses/by-sa/4.0/)

Binary file not shown.

View File

@@ -19,7 +19,7 @@
// Debug(string sStr) { llOwnerSay("Debug ["+llGetScriptName()+"]: " + sStr); }
string g_sVersion = "2023.09.06";
string g_sVersion = "2025.12";
integer g_iInterfaceChannel = -12587429;
integer g_iHUDChannel = -1812221819;
@@ -83,12 +83,6 @@ integer g_iRlvListener;
integer RLV_MAX_CHECKS = 5;
integer g_iRLVOn = FALSE;
integer g_iShoeChannel;
integer g_iShoeListener;
integer g_iShoesWorn;
float g_fHeelOffset = -0.1;
integer g_iOffsetAdjustHandle;
integer g_iTimerRlvDetect;
integer g_iTimerChangeStand;
integer g_iTimerDialogTimeout;
@@ -281,18 +275,11 @@ ToggleSitAnywhere()
if (g_iSitAnywhereOn) {
if (g_iChangeInterval) g_iTimerChangeStand = llGetUnixTime() + g_iChangeInterval;
SwitchStand();
if (g_iRLVOn) {
llOwnerSay("@adjustheight:1;0;0.0=force");
llListenRemove(g_iOffsetAdjustHandle);
}
if (g_iRLVOn) llOwnerSay("@adjustheight:1;0;0.0=force");
} else {
g_iTimerChangeStand = 0;
llSetAnimationOverride("Standing",g_sSitAnywhereAnim);
if (g_iRLVOn) {
AdjustSitOffset();
llOwnerSay("Use /2offset <float> to adjust SitAnywhere offset in meters");
g_iOffsetAdjustHandle = llListen(2, "", (string)g_kWearer, "");
}
if (g_iRLVOn) AdjustSitOffset();
}
g_iSitAnywhereOn = !g_iSitAnywhereOn;
DoStatus();
@@ -301,10 +288,9 @@ ToggleSitAnywhere()
AdjustSitOffset()
{
if (g_iShoesWorn)
llOwnerSay("@adjustheight:1;0;"+(string)(g_fSitOffset+g_fHeelOffset)+"=force");
else
llOwnerSay("@adjustheight:1;0;"+(string)g_fSitOffset+"=force");
list l = llGetVisualParams(g_kWearer, ["heel_height", "platform_height"]);
float fHeelOffset = (llList2Float(l, 0) + llList2Float(l, 1)) / 100.0;
llOwnerSay("@adjustheight:1;0;"+(string)(g_fSitOffset+fHeelOffset)+"=force");
}
Notify(key kID, string sStr, integer iAlsoNotifyWearer)
@@ -357,7 +343,7 @@ list SortButtons(list lButtons, list lStaticButtons)
MenuAO(key kID)
{
string sPrompt = "\n𝐎 𝐒 𝐂 𝐨 𝐥 𝐥 𝐚 𝐫 AO\t"+g_sVersion;
string sPrompt = "\nOsCollar - AO\t"+g_sVersion;
list lButtons = ["LOCK"];
if (g_iLocked) lButtons = ["UNLOCK"];
if (kID == g_kWearer) lButtons += ["Collar Menu"];
@@ -501,11 +487,13 @@ Command(key kID, string sCommand)
MenuLoad(kID,0);
return;
} else if (sCommand == "on") {
if ((llGetPermissions() & PERMISSION_OVERRIDE_ANIMATIONS) == 0) llRequestPermissions(g_kWearer, PERMISSION_OVERRIDE_ANIMATIONS);
SetAnimOverride();
g_iAO_ON = TRUE;
if (g_iChangeInterval) g_iTimerChangeStand = llGetUnixTime() + g_iChangeInterval;
DoStatus();
} else if (sCommand == "off") {
if ((llGetPermissions() & PERMISSION_OVERRIDE_ANIMATIONS) == 0) llRequestPermissions(g_kWearer, PERMISSION_OVERRIDE_ANIMATIONS);
llResetAnimationOverride("ALL");
g_iAO_ON = FALSE;
g_iTimerChangeStand = 0;
@@ -610,8 +598,6 @@ default
state_entry()
{
if (llGetInventoryType("oc_installer_sys") == INVENTORY_SCRIPT) return;
string sObjectName = osReplaceString(llGetObjectName(), "\\d+\\.\\d+\\.?\\d+", g_sVersion, -1, 0);
if (sObjectName != llGetObjectName()) llSetObjectName(sObjectName);
g_kWearer = llGetOwner();
RestoreSettings();
g_iInterfaceChannel = -llAbs((integer)("0x" + llGetSubString(g_kWearer,30,-1)));
@@ -631,7 +617,7 @@ default
g_iRlvListener = llListen(519274, "", (string)g_kWearer, "");
g_iRlvChecks = 0;
llOwnerSay("@versionnew=519274");
llSetTimerEvent(5.0);
llSetTimerEvent(30.0);
}
on_rez(integer iStart)
@@ -651,14 +637,7 @@ default
attach(key kID)
{
if (kID == NULL_KEY) {
llResetAnimationOverride("ALL");
if (g_iRLVOn) {
// de-register worn and unworn events (if it gets through)
llOwnerSay("@notify:"+(string)g_iShoeChannel+";worn legally shoes=rem");
llOwnerSay("@notify:"+(string)g_iShoeChannel+";unworn legally shoes=rem");
}
}
if (kID == NULL_KEY) llResetAnimationOverride("ALL");
else if (llGetAttached() <= 30) {
llOwnerSay("Sorry, this device can only be attached to the HUD.");
llRequestPermissions(kID, PERMISSION_ATTACH);
@@ -686,6 +665,7 @@ default
} else if (sButton == "Power") {
if (g_iAO_ON) Command(g_kWearer, "off");
else if (g_iReady) Command(g_kWearer, "on");
StoreSettings();
} else if (sButton == "Device") {
llRegionSayTo(llGetOwner(), g_iHUDChannel, "menu");
}
@@ -722,51 +702,7 @@ default
} else if (iChannel == 519274) {
g_iRLVOn = TRUE;
llListenRemove(g_iRlvListener);
g_iShoeChannel = (9999 + llRound(llFrand(9999999.0)));
llListenRemove(g_iShoeListener);
g_iShoeListener = llListen(g_iShoeChannel, "", (string)g_kWearer, "");
// get initial state of shoes worn or not:
llOwnerSay("@getoutfit="+(string)g_iShoeChannel);
} else if (iChannel==g_iShoeChannel) {
if (sMessage == "/unworn legally shoes") {
g_iShoesWorn = FALSE;
if (g_iSitAnywhereOn) AdjustSitOffset();
} else if (sMessage == "/worn legally shoes") {
g_iShoesWorn = TRUE;
if (g_iSitAnywhereOn) AdjustSitOffset();
} else if (llGetSubString(sMessage, 0, 6) != "/notify") {
// @getoutfit result (a string of 1's and 0's)
string sFlagShoes = llGetSubString(sMessage, 4, 4);
if (sFlagShoes == "1" || sFlagShoes == "0")
{
g_iShoesWorn = (integer)llGetSubString(sMessage, 4, 4);
if (g_iSitAnywhereOn) AdjustSitOffset();
// Register to be notified of worn and unworn
llOwnerSay("@notify:"+(string)g_iShoeChannel+";worn legally shoes=add");
llOwnerSay("@notify:"+(string)g_iShoeChannel+";unworn legally shoes=add");
}
}
} else if (iChannel == 2) {
list lCmd = llParseString2List(sMessage, [" "], []);
if (llStringTrim(llList2String(lCmd, 0), STRING_TRIM) != "offset") return;
string sParam1 = llStringTrim(llList2String(lCmd, 1), STRING_TRIM);
float fValue;
if (llGetListLength(lCmd) == 3) { // /2offset + 0.05
float fParam2 = (float)llList2String(lCmd, 2);
if (sParam1 == "+") fValue = g_fSitOffset + fParam2;
else if (sParam1 == "-") fValue = g_fSitOffset - fParam2;
else fValue = (float)sParam1; // ignore param 2
} else if (llGetListLength(lCmd) == 2) { // /2offset +0.05
float fParam2 = (float)llGetSubString(sParam1, 1, -1);
string sMod = llGetSubString(sParam1, 0, 0);
if (sMod == "+") fValue = g_fSitOffset + fParam2;
else if (sMod == "-") fValue = g_fSitOffset - fParam2;
else fValue = (float)sParam1;
}
g_fSitOffset = fValue;
StoreSettings();
AdjustSitOffset();
llOwnerSay("New SitAnywhere offset "+llGetSubString((string)g_fSitOffset, 0, 4)+" stored");
llSetTimerEvent(5.0);
} else if (llListFindList(g_lMenuIDs,[kID, iChannel]) != -1) {
integer iMenuIndex = llListFindList(g_lMenuIDs, [kID]);
string sMenuType = llList2String(g_lMenuIDs, iMenuIndex+4);
@@ -840,10 +776,6 @@ default
} else if (llListFindList(["Walking","Sitting on Ground","Sitting"], [sMenuType]) != -1) {
if (sMessage == "BACK") {
g_lAnims2Choose = [];
if (sMenuType == "Sitting on Ground" && g_iSitAnywhereOn) {
ToggleSitAnywhere();
DoStatus();
}
MenuAO(kID);
} else if (sMessage == "▲" || sMessage == "▼") {
if (sMessage == "▲") g_fSitOffset += 0.025;
@@ -941,6 +873,7 @@ default
llListenRemove(g_iRlvListener);
g_iRlvChecks = 0;
g_iRLVOn = FALSE;
llSetTimerEvent(5.0);
}
}
}
@@ -1013,4 +946,4 @@ default
if (llGetColor(0) != g_vAOoncolor) DetermineColors();
} else if (iChange & CHANGED_LINK) llResetScript();
}
}
}

View File

@@ -219,7 +219,7 @@ ChatCamParams(integer iChannel, key kID)
{
g_vCamPos = llGetCameraPos();
g_rCamRot = llGetCameraRot();
string sPosLine = osReplaceString((string)g_vCamPos, " ", "", -1, 0) + " " + osReplaceString((string)g_rCamRot, " ", "", -1, 0);
string sPosLine = llReplaceSubString((string)g_vCamPos, " ", "", 0) + " " + llReplaceSubString((string)g_rCamRot, " ", "", 0);
//if not channel 0, say to whole region. else just say locally
if (iChannel > 0)
llRegionSayTo(kID, iChannel, sPosLine);

View File

@@ -22,7 +22,7 @@
// Debug(string sStr) { llOwnerSay("Debug ["+llGetScriptName()+"]: " + sStr); }
string g_sAppVersion = "2023.03.29";
string g_sAppVersion = "2026.02";
string g_sParentMenu = "Apps";
string g_sSubMenu = "Label";
@@ -68,7 +68,7 @@ list g_lFonts;
string g_sFontTexture = "font_System 01";
integer x = 45;
integer y = 19;
integer y = 20;
integer g_iNumFaces = 6;

View File

@@ -69,14 +69,11 @@ integer MENUNAME_RESPONSE = 3001;
integer RLV_CMD = 6000;
integer RLV_OFF = 6100;
integer RLV_VERSION = 6003;
integer RLV_SHOES = 6108;
integer RLV_NOSHOES = 6109;
integer ANIM_START = 7000;
integer ANIM_STOP = 7001;
integer ANIM_LIST_REQUEST = 7002;
integer ANIM_LIST_RESPONSE =7003;
float g_fStandHover = 0.0;
integer g_iShoesWorn = FALSE;
integer REGION_TELEPORT = 10051;
@@ -91,8 +88,6 @@ key g_kWearer = NULL_KEY;
list g_lMenuIDs;
integer g_iMenuStride = 3;
float g_fHeelOffset = -0.1;
Dialog(key kID, string sPrompt, list lChoices, list lUtilityButtons, integer iPage, integer iAuth, string sName)
{
key kMenuID = llGenerateKey();
@@ -212,10 +207,11 @@ SetHover(string sStr)
} else g_lHeightAdjustments += [g_sCurrentPose, fNewHover];
@next;
if (g_sCurrentPose == g_sCrawlWalk) g_fPoseMoveHover = fNewHover;
if (g_iShoesWorn)
llMessageLinked(LINK_RLV, RLV_CMD, "adjustheight:1;0;"+(string)(fNewHover+g_fHeelOffset)+"=force", g_kWearer);
else
llMessageLinked(LINK_RLV, RLV_CMD, "adjustheight:1;0;"+(string)fNewHover+"=force", g_kWearer);
list l = llGetVisualParams(g_kWearer, ["heel_height", "platform_height"]);
float fHeelOffset = (llList2Float(l, 0) + llList2Float(l, 1)) / 100.0;
llMessageLinked(LINK_RLV, RLV_CMD, "adjustheight:1;0;"+(string)(fNewHover+fHeelOffset)+"=force", g_kWearer);
string sSettings;
integer i;
for (i = 0; i < llGetListLength(g_lHeightAdjustments); i += 2) {
@@ -263,7 +259,10 @@ PlayAnim(string sAnim)
integer index = llListFindList(g_lHeightAdjustments, [sAnim]);
float fOffset = 0.0;
if (index != -1) fOffset += llList2Float(g_lHeightAdjustments, index+1);
if (g_iShoesWorn) fOffset += g_fHeelOffset;
list l = llGetVisualParams(g_kWearer, ["heel_height", "platform_height"]);
fOffset += (llList2Float(l, 0) + llList2Float(l, 1)) / 100.0;
llMessageLinked(LINK_RLV, RLV_CMD, "adjustheight:1;0;"+(string)fOffset+"=force", g_kWearer);
}
llStartAnimation(sAnim);
@@ -321,20 +320,6 @@ CreateAnimList()
llMessageLinked(LINK_SET, ANIM_LIST_RESPONSE, llDumpList2String(g_lPoseList+g_lOtherAnims,"|"), "");
}
// Case insensitive match of sName against any inventory item of type iType
// Returns actual inventory name when matched
// Returns empty string if no match
string MatchInventoryName(string sName, integer iType)
{
integer i = 0;
while (i < llGetInventoryNumber(iType)) {
string sItemName = llGetInventoryName(iType, i);
if (llSubStringIndex(llToLower(sItemName), llToLower(sName)) == 0) return sItemName;
i++;
}
return "";
}
UserCommand(integer iNum, string sStr, key kID)
{
if (iNum == CMD_EVERYONE) return;
@@ -440,25 +425,16 @@ UserCommand(integer iNum, string sStr, key kID)
if (llList2String(lParams,2) == "") llMessageLinked(LINK_DIALOG, NOTIFY, "1"+"Crawl mode deactivated.", kID);
}
} else llMessageLinked(LINK_DIALOG, NOTIFY, "0"+"Only owners or the wearer can change crawl settings.",kID);
} else if (sCommand == "heeloffset") {
if ((iNum == CMD_OWNER) || (kID == g_kWearer)) {
if (sValue == "reset" || sValue != "") {
g_fHeelOffset = -0.1;
llMessageLinked(LINK_SAVE, LM_SETTING_DELETE, g_sSettingToken+"heeloffset", "");
llMessageLinked(LINK_DIALOG, NOTIFY, "0"+"heeloffset has been reset to "+llGetSubString((string)g_fHeelOffset, 0, 4), g_kWearer);
} else {
g_fHeelOffset = (float)sValue;
llMessageLinked(LINK_SAVE, LM_SETTING_SAVE, g_sSettingToken+"heeloffset="+(string)g_fHeelOffset, "");
llMessageLinked(LINK_DIALOG, NOTIFY, "0"+"heeloffset changed to "+llGetSubString((string)g_fHeelOffset, 0, 4), g_kWearer);
}
} else llMessageLinked(LINK_DIALOG, NOTIFY, "0"+"Only owners or the wearer can change the heel offset.", kID);
} else if (sStr == "resetposes") {
// this will wipe out all custom-set height adjustments!
g_lHeightAdjustments = [];
llMessageLinked(LINK_SAVE, LM_SETTING_DELETE, "offset_hovers", "");
llMessageLinked(LINK_DIALOG, NOTIFY, "0"+"All height adjustments for poses have been reset.", kID);
} else {
// Check if given command is a pose in inv, and if so play it
if (llStringLength(sStr) > 63) return; // inv item names can only have up to 63 chars
if (llGetInventoryType(sStr) != INVENTORY_ANIMATION) {
sStr = MatchInventoryName(sStr, INVENTORY_ANIMATION);
if (sStr == "") return; // no match in aNy cAsE
} // else sStr is an exact match
if (llGetInventoryType(sStr) != INVENTORY_ANIMATION) return;
// else sStr is an exact match:
if (iNum <= g_iLastRank || g_iAnimLock == FALSE || g_sCurrentPose == "") {
StopAnim(g_sCurrentPose,(g_sCurrentPose != ""));
g_sCurrentPose = sStr;
@@ -566,7 +542,7 @@ default
else if (sToken == "crawl") {
g_iCrawl = (integer)sValue;
checkCrawl();
} else if (sToken == "heeloffset") g_fHeelOffset = (float)sValue;
}
} else if (llGetSubString(sToken, 0, i) == "offset_") {
sToken = llGetSubString(sToken, i+1, -1);
if (sToken == "AllowHover") {
@@ -658,8 +634,6 @@ default
else if (sStr == "LINK_REQUEST") llMessageLinked(LINK_ALL_OTHERS, LINK_UPDATE, "LINK_ANIM", "");
} else if (iNum == REBOOT && sStr == "reboot") llResetScript();
else if (iNum == RLV_VERSION) g_iRLV_ON = TRUE;
else if (iNum == RLV_SHOES) g_iShoesWorn = TRUE;
else if (iNum == RLV_NOSHOES) g_iShoesWorn = FALSE;
else if (iNum == RLV_OFF) g_iRLV_ON = FALSE;
else if (iNum == REGION_TELEPORT) RefreshAnim();
}
@@ -697,7 +671,9 @@ default
fHover = 0.0;
integer index = llListFindList(g_lHeightAdjustments, [g_sCurrentPose]);
if (index != -1) fHover = llList2Float(g_lHeightAdjustments, index+1);
if (g_iShoesWorn) fHover += g_fHeelOffset;
list l = llGetVisualParams(g_kWearer, ["heel_height", "platform_height"]);
fHover += ((llList2Float(l, 0) + llList2Float(l, 1)) / 100.0);
llMessageLinked(LINK_RLV, RLV_CMD, "adjustheight:1;0;"+(string)fHover+"=force", g_kWearer);
}
StartAnim(llList2String(g_lAnims,0));

View File

@@ -20,10 +20,11 @@
// Debug(string sStr) { llOwnerSay("Debug ["+llGetScriptName()+"]: " + sStr); }
string g_sWearerID;
list g_lOwner; // 2 max
list g_lTrust; // 4 max
list g_lBlock; // 8 per prim with name 'blocklist'
list g_lTempOwner; // 1 max
list g_lOwner;
list g_lTrust;
list g_lBlock;
list g_lTempOwner;
integer g_iMaxUsers = 45;
key g_kGroup = NULL_KEY;
integer g_iGroupEnabled;
@@ -74,9 +75,6 @@ list g_lMenuIDs;
integer g_iMenuStride = 3;
integer g_iFirstRun;
integer g_iIsLED;
list g_lBlocklistPrims; // list of links with name 'blocklist'
string g_sSettingToken = "auth_";
@@ -101,12 +99,11 @@ Dialog(string sID, string sPrompt, list lChoices, list lUtilityButtons, integer
AuthMenu(key kAv, integer iAuth)
{
string sPrompt = "\nAccess & Authorization\n\n";
string sPrompt = "\nAccess & Authorization";
integer iPercentage = llRound(((float)llGetListLength(g_lOwner+g_lTrust+g_lBlock)/(float)g_iMaxUsers)*100.0);
sPrompt += "\n\nYou are using "+(string)iPercentage+"% of your global access list storage.";
list lButtons;
if (llGetListLength(g_lBlocklistPrims) > 0)
lButtons = ["+ Owner", "+ Trust", "+ Block", " Owner", " Trust", " Block"];
else
lButtons = ["+ Owner", "+ Trust", " Owner", " Trust"];
lButtons += ["+ Owner", "+ Trust", "+ Block", " Owner", " Trust", " Block"];
if (g_kGroup==NULL_KEY) lButtons += ["Group ☐"];
else lButtons += ["Group ☑"];
if (g_iOpenAccess) lButtons += ["Public ☑"];
@@ -171,8 +168,6 @@ RemovePerson(string sPersonID, string sToken, key kCmdr, integer iPromoted)
else if (sToken == "tempowner") g_lTempOwner = lPeople;
else if (sToken == "trust") g_lTrust = lPeople;
else if (sToken == "block") g_lBlock = lPeople;
if (sToken == "block") SaveBlocklist();
else SaveAuthorized();
} else
llMessageLinked(LINK_DIALOG, NOTIFY, "0"+"\""+NameURI(sPersonID) + "\" is not in "+sToken+" list.", kCmdr);
}
@@ -183,17 +178,12 @@ AddUniquePerson(string sPersonID, string sToken, key kID)
if (llListFindList(g_lTempOwner,[(string)kID]) != -1 && llListFindList(g_lOwner,[(string)kID]) == -1 && sToken != "tempowner")
llMessageLinked(LINK_DIALOG,NOTIFY, "0"+"%NOACCESS%", kID);
else {
if (sToken == "owner") {
if (llGetListLength(g_lOwner) >= 2) {
llMessageLinked(LINK_DIALOG,NOTIFY,"0"+"\n\nThe maximum of 2 owners has already been reached\n", kID);
return;
} else lPeople = g_lOwner;
}
if (llGetListLength(g_lOwner+g_lTrust+g_lBlock) >= g_iMaxUsers) {
llMessageLinked(LINK_DIALOG,NOTIFY,"0"+"\n\nSorry, we have reached a limit!\n\nYou now have 60 people on your combined global access lists. This means in order to add anyone else to a list, you will have to remove someone from either the Owner, Trust, or Block list.\n",kID);
return;
} else if (sToken == "owner") lPeople = g_lOwner;
else if (sToken=="trust") {
if (llGetListLength(g_lTrust) >= 4) {
llMessageLinked(LINK_DIALOG,NOTIFY, "0"+"\n\nThe maximum of 4 trusted people has already been reached\n", kID);
return;
} else lPeople = g_lTrust;
lPeople = g_lTrust;
if (llListFindList(g_lOwner,[sPersonID]) != -1) {
llMessageLinked(LINK_DIALOG,NOTIFY, "0"+"\n\nOops!\n\n"+NameURI(sPersonID)+" is already Owner! You should really trust them.\n", kID);
return;
@@ -248,8 +238,6 @@ AddUniquePerson(string sPersonID, string sToken, key kID)
} else if (sToken == "trust") g_lTrust = lPeople;
else if (sToken == "tempowner") g_lTempOwner = lPeople;
else if (sToken == "block") g_lBlock = lPeople;
if (sToken == "block") SaveBlocklist();
else SaveAuthorized();
}
}
@@ -266,170 +254,24 @@ SayOwners()
else sMsg += ".";
} else if (iCount == 2 && g_iVanilla == FALSE)
sMsg += NameURI(llList2String(g_lOwner,0)) + " and " + NameURI(llList2Key(g_lOwner,1)) + ".";
if (sMsg == "You belong to ") sMsg += "yourself.";
llMessageLinked(LINK_DIALOG,NOTIFY, "0"+sMsg, g_sWearerID);
}
}
SaveAuthorized()
{
// face layout: g_lOwner[0], g_lOwner[1], g_lTempOwner[0], g_kGroup, g_lTrust[0], g_lTrust[1], g_lTrust[2], g_lTrust[3]
string TEXTURE_NOTHING = TEXTURE_BLANK;
float fLimitRange = (float)g_iLimitRange;
float fRunawayDisable = (float) g_iRunawayDisable;
float fVanilla = (float)g_iVanilla;
float fHardVanilla = (float)g_iHardVanilla;
string sFirstOwner = TEXTURE_NOTHING;
string sSecondOwner = TEXTURE_NOTHING;
integer iFace;
if (llGetListLength(g_lOwner) == 1) {
sFirstOwner = llList2String(g_lOwner, 0);
} else if (llGetListLength(g_lOwner) > 1) {
sFirstOwner = llList2String(g_lOwner, 0);
sSecondOwner = llList2String(g_lOwner, 1);
}
llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_TEXTURE, 0, sFirstOwner, <1,1,0>, <fLimitRange,fRunawayDisable,0>, 0]);
llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_TEXTURE, 1, sSecondOwner, <1,1,0>, <fVanilla,fHardVanilla,0>, 0]);
float fOpenAccess = (float)g_iOpenAccess;
if (llGetListLength(g_lTempOwner) > 0) {
llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_TEXTURE, 2, llList2String(g_lTempOwner, 0), <fOpenAccess,1,0>, <0,0,0>, 0]);
} else {
llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_TEXTURE, 2, TEXTURE_NOTHING, <1,1,0>, <fOpenAccess,0,0>, 0]);
}
string sGroup = TEXTURE_NOTHING;
if (g_kGroup != NULL_KEY) sGroup = (string)g_kGroup;
if (g_iGroupEnabled) {
llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_TEXTURE, 3, sGroup, <1,1,0>, <1,1,0>, 0]);
} else {
llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_TEXTURE, 3, TEXTURE_NOTHING, <1,1,0>, <0,0,0>, 0]);
}
for (iFace = 4; iFace < llGetNumberOfPrims(); iFace++) {
if (llGetListLength(g_lTrust) > (iFace-4)) {
llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_TEXTURE, iFace, llList2String(g_lTrust, (iFace-4)), <1,1,0>, <0,0,0>, 0]);
} else {
llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_TEXTURE, iFace, TEXTURE_NOTHING, <1,1,0>, <0,0,0>, 0]);
}
}
}
LoadAuthorized()
{
// face layout: g_lOwner[0], g_lOwner[1], g_lTempOwner[0], g_kGroup, g_lTrust[0], g_lTrust[1], g_lTrust[2], g_lTrust[3]
// Note that Linden Lab disabled the ability to get the texture key using PRIM_TEXTURE if you don't own the texture,
// which we don't (since they're just keys). So in SL it would then return NULL_KEY, however OpenSim is not that idiotic.
list l;
vector v;
list lExclude = ["", TEXTURE_BLANK, TEXTURE_PLYWOOD, TEXTURE_TRANSPARENT];
g_lOwner = [];
l = llGetLinkPrimitiveParams(LINK_THIS, [PRIM_TEXTURE, 0]);
if (llListFindList(lExclude, [llList2Key(l, 0)]) == -1) g_lOwner += [llList2Key(l, 0)];
v = llList2Vector(l, 2);
g_iLimitRange = (integer)v.x;
g_iRunawayDisable = (integer)v.y;
l = llGetLinkPrimitiveParams(LINK_THIS, [PRIM_TEXTURE, 1]);
if (llListFindList(lExclude, [llList2Key(l, 0)]) == -1) g_lOwner += [llList2Key(l, 0)];
v = llList2Vector(l, 2);
g_iVanilla = (integer)v.x;
g_iHardVanilla = (integer)v.y;
if (llGetListLength(g_lOwner)) {
llMessageLinked(LINK_SAVE, LM_SETTING_SAVE, g_sSettingToken + "owner=" + llDumpList2String(g_lOwner, ","), "");
llMessageLinked(LINK_ALL_OTHERS, LM_SETTING_RESPONSE, g_sSettingToken + "owner=" + llDumpList2String(g_lOwner, ","), "");
} else
llMessageLinked(LINK_SAVE, LM_SETTING_DELETE, g_sSettingToken + "owner", "");
g_lTempOwner = [];
l = llGetLinkPrimitiveParams(LINK_THIS, [PRIM_TEXTURE, 2]);
if (llListFindList(lExclude, [llList2Key(l, 0)]) == -1) g_lTempOwner += [llList2Key(l, 0)];
v = llList2Vector(l, 2);
g_iOpenAccess = (integer)v.x;
if (llGetListLength(g_lTempOwner)) {
llMessageLinked(LINK_SAVE, LM_SETTING_SAVE, g_sSettingToken + "tempowner="+llList2Key(g_lTempOwner, 0), "");
llMessageLinked(LINK_ALL_OTHERS, LM_SETTING_RESPONSE, g_sSettingToken + "tempowner="+llList2Key(g_lTempOwner, 0), "");
} else
llMessageLinked(LINK_SAVE, LM_SETTING_DELETE, g_sSettingToken + "tempowner", "");
l = llGetLinkPrimitiveParams(LINK_THIS, [PRIM_TEXTURE, 3]);
if (llListFindList(lExclude, [llList2Key(l, 0)]) == -1) g_kGroup = llList2Key(l, 0);
else g_kGroup = NULL_KEY;
v = llList2Vector(l, 2);
if (g_kGroup != NULL_KEY && v.x > 0) {
if (llList2Key(llGetObjectDetails(llGetKey(), [OBJECT_GROUP]), 0) == g_kGroup) g_iGroupEnabled = TRUE;
else g_iGroupEnabled = FALSE;
} else g_iGroupEnabled = FALSE;
if (g_kGroup != NULL_KEY) {
llMessageLinked(LINK_SAVE, LM_SETTING_SAVE, g_sSettingToken + "group="+(string)g_kGroup, "");
llMessageLinked(LINK_ALL_OTHERS, LM_SETTING_RESPONSE, g_sSettingToken + "group="+(string)g_kGroup, "");
} else
llMessageLinked(LINK_SAVE, LM_SETTING_DELETE, g_sSettingToken + "group", "");
g_lTrust = [];
integer iFace;
for (iFace = 4; iFace < 8; iFace++) {
l = llGetLinkPrimitiveParams(LINK_THIS, [PRIM_TEXTURE, iFace]);
if (llListFindList(lExclude, [llList2Key(l, 0)]) == -1) g_lTrust += [llList2Key(l, 0)];
}
if (llGetListLength(g_lTrust)) {
llMessageLinked(LINK_SAVE, LM_SETTING_SAVE, g_sSettingToken + "trust=" + llDumpList2String(g_lTrust, ","), "");
llMessageLinked(LINK_ALL_OTHERS, LM_SETTING_RESPONSE, g_sSettingToken + "trust=" + llDumpList2String(g_lTrust, ","), "");
} else
llMessageLinked(LINK_SAVE, LM_SETTING_DELETE, g_sSettingToken + "trust" + llDumpList2String(g_lTrust, ","), "");
}
LoadBlocklist()
{
if (llGetListLength(g_lBlocklistPrims) == 0) return;
list lExclude = ["", TEXTURE_BLANK, TEXTURE_PLYWOOD, TEXTURE_TRANSPARENT];
g_lBlock = [];
integer iPrim;
for (iPrim = 0; iPrim < llGetListLength(g_lBlocklistPrims); iPrim++) {
integer iFace;
integer iLink = llList2Integer(g_lBlocklistPrims, iPrim);
for (iFace = 0; iFace < 8; iFace++) {
list lParams = llGetLinkPrimitiveParams(iLink, [PRIM_TEXTURE, iFace]);
string sTexture = llList2String(lParams, 0);
if (llListFindList(lExclude, [sTexture]) == -1) g_lBlock += [(key)sTexture];
}
}
}
GatherBlocklistPrims()
{
g_lBlocklistPrims = [];
integer i;
for (i = LINK_ROOT; i < llGetNumberOfPrims()+1; i++) {
if (llGetLinkName(i) == "blocklist") g_lBlocklistPrims += [i];
}
}
SaveBlocklist()
{
if (llGetListLength(g_lBlocklistPrims) == 0) return;
integer iPrim;
for (iPrim = 0; iPrim < llGetListLength(g_lBlocklistPrims); iPrim++) {
integer iFace;
integer iLink = llList2Integer(g_lBlocklistPrims, iPrim);
for (iFace = 0; iFace < 8; iFace++) {
integer idx = (iPrim*8) + iFace;
if (llGetListLength(g_lBlock)-1 < idx) {
// no more people, pad with TEXTURE_BLANK
llSetLinkPrimitiveParamsFast(iLink, [
PRIM_TEXTURE, iFace, TEXTURE_BLANK, <1,1,0>, <0,0,0>, 0,
PRIM_COLOR, <1,1,1>, 0.0]);
else if (iCount) {
integer iMax = 9;
if (g_iVanilla) iMax = 8;
while (index < iCount-1 && index < iMax) {
sMsg += NameURI(llList2String(g_lOwner,index))+", ";
index+=1;
}
if (iCount > (iMax+1)) {
sMsg += NameURI(llList2String(g_lOwner,index));
if (g_iVanilla) sMsg += ", yourself";
sMsg += " and others.";
} else {
// use blocked person's key as texture
llSetLinkPrimitiveParamsFast(iLink, [
PRIM_TEXTURE, iFace, llList2String(g_lBlock, idx), <1,1,0>, <0,0,0>, 0,
PRIM_COLOR, <1,1,1>, 0.0]);
if (g_iVanilla) sMsg += NameURI(llList2String(g_lOwner,index))+" and yourself.";
else sMsg += "and "+NameURI(llList2String(g_lOwner,index))+".";
}
}
if (sMsg == "You belong to ") sMsg += "yourself.";
llMessageLinked(LINK_DIALOG,NOTIFY, "0"+sMsg, g_sWearerID);
}
}
@@ -554,7 +396,6 @@ UserCommand(integer iAuth, string sStr, key kID, integer iRemenu)
if (g_iVanilla) sStr = "enabled.";
llMessageLinked(LINK_DIALOG, NOTIFY, "0"+"Vanilla is currently "+sStr, kID);
}
SaveAuthorized();
} else llMessageLinked(LINK_DIALOG, NOTIFY, "0"+"%NOACCESS%", kID);
@next;
if (iRemenu) AuthMenu(kID, iAuth);
@@ -607,7 +448,6 @@ UserCommand(integer iAuth, string sStr, key kID, integer iRemenu)
llMessageLinked(LINK_DIALOG,NOTIFY, "1"+"Group unset.", kID);
llMessageLinked(LINK_RLV, RLV_CMD, "setgroup=y", "auth");
}
SaveAuthorized();
} else llMessageLinked(LINK_DIALOG, NOTIFY, "0"+"%NOACCESS%", kID);
if (iRemenu) AuthMenu(kID, Auth(kID));
} else if (sCommand == "public") {
@@ -621,7 +461,6 @@ UserCommand(integer iAuth, string sStr, key kID, integer iRemenu)
llMessageLinked(LINK_SAVE, LM_SETTING_DELETE, g_sSettingToken + "public", "");
llMessageLinked(LINK_DIALOG, NOTIFY, "1"+"The %DEVICETYPE% is closed to the public.", kID);
}
SaveAuthorized();
} else llMessageLinked(LINK_DIALOG, NOTIFY, "0"+"%NOACCESS%", kID);
if (iRemenu) AuthMenu(kID, Auth(kID));
} else if (sCommand == "limitrange") {
@@ -635,7 +474,6 @@ UserCommand(integer iAuth, string sStr, key kID, integer iRemenu)
llMessageLinked(LINK_SAVE, LM_SETTING_SAVE, g_sSettingToken + "limitrange=" + (string) g_iLimitRange, "");
llMessageLinked(LINK_DIALOG, NOTIFY, "1"+"Public access range is simwide.", kID);
}
SaveAuthorized();
} else llMessageLinked(LINK_DIALOG, NOTIFY, "0"+"%NOACCESS%", kID);
if (iRemenu) AuthMenu(kID, Auth(kID));
} else if (sMessage == "runaway"){
@@ -672,9 +510,7 @@ RunAway()
g_lTempOwner = [];
llMessageLinked(LINK_ALL_OTHERS, LM_SETTING_RESPONSE, g_sSettingToken + "tempowner=", "");
llMessageLinked(LINK_SAVE, LM_SETTING_DELETE, g_sSettingToken + "tempowner", "");
SaveAuthorized();
g_lBlock = [];
SaveBlocklist();
llMessageLinked(LINK_ALL_OTHERS, CMD_OWNER, "clear", g_sWearerID);
llMessageLinked(LINK_ALL_OTHERS, CMD_OWNER, "runaway", g_sWearerID);
llMessageLinked(LINK_DIALOG, NOTIFY, "0"+"Runaway finished.", g_sWearerID);
@@ -712,21 +548,13 @@ default
if (llGetStartParameter()==825) llSetRemoteScriptAccessPin(0);
else g_iFirstRun = TRUE;
g_sWearerID = llGetOwner();
if (llSubStringIndex(llGetObjectDesc(),"LED") == 0) g_iIsLED = TRUE;
LoadAuthorized();
GatherBlocklistPrims();
LoadBlocklist();
llMessageLinked(LINK_ALL_OTHERS,LINK_UPDATE,"LINK_REQUEST","");
if (g_iIsLED == FALSE) PieSlice();
PieSlice();
}
link_message(integer iSender, integer iNum, string sStr, key kID)
{
if (iNum == CMD_ZERO) {
if (g_iIsLED) {
llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_FULLBRIGHT, ALL_SIDES, TRUE, PRIM_BUMP_SHINY, ALL_SIDES, PRIM_SHINY_NONE, PRIM_BUMP_NONE, PRIM_GLOW, ALL_SIDES, 0.4]);
llSetTimerEvent(0.5);
}
integer iAuth = Auth(kID);
if (kID == g_sWearerID && sStr == "runaway") {
if (g_iRunawayDisable)
@@ -768,25 +596,15 @@ default
else if (sToken == "hardvanilla") g_iHardVanilla = (integer)sValue;
} else if (sStr == "settings=sent") {
if (g_iFirstRun) {
LoadAuthorized();
LoadBlocklist();
SayOwners();
g_iFirstRun = FALSE;
}
}
} else if (iNum == AUTH_REQUEST) {
if (g_iIsLED) {
llSetLinkPrimitiveParamsFast(LINK_THIS,[PRIM_FULLBRIGHT, ALL_SIDES, TRUE, PRIM_BUMP_SHINY, ALL_SIDES, PRIM_SHINY_NONE, PRIM_BUMP_NONE, PRIM_GLOW, ALL_SIDES, 0.4]);
llSetTimerEvent(0.5);
}
llMessageLinked(iSender, AUTH_REPLY, "AuthReply|"+(string)kID+"|"+(string)Auth(kID), llGetSubString(sStr,0,35));
} else if (iNum == DIALOG_RESPONSE) {
integer iMenuIndex = llListFindList(g_lMenuIDs, [kID]);
if (iMenuIndex != -1) {
if (g_iIsLED) {
llSetLinkPrimitiveParamsFast(LINK_THIS,[PRIM_FULLBRIGHT, ALL_SIDES, TRUE, PRIM_BUMP_SHINY, ALL_SIDES, PRIM_SHINY_NONE, PRIM_BUMP_NONE, PRIM_GLOW, ALL_SIDES, 0.4]);
llSetTimerEvent(0.5);
}
list lMenuParams = llParseString2List(sStr, ["|"], []);
key kAv = llList2Key(lMenuParams, 0);
string sMessage = llList2String(lMenuParams, 1);
@@ -850,19 +668,5 @@ default
} else if (iNum == REBOOT && sStr == "reboot") llResetScript();
}
timer ()
{
llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_FULLBRIGHT, ALL_SIDES, FALSE, PRIM_BUMP_SHINY, ALL_SIDES, PRIM_SHINY_HIGH, PRIM_BUMP_NONE, PRIM_GLOW, ALL_SIDES, 0.0]);
llSetTimerEvent(0.0);
}
changed(integer iChange)
{
if (iChange & CHANGED_LINK) {
LoadAuthorized();
GatherBlocklistPrims();
LoadBlocklist();
}
}
}

View File

@@ -78,8 +78,6 @@ list g_lColors = [
"Midnight",<0.00000, 0.10588, 0.21176>
];
integer g_iIsLED;
string NameURI(key kID)
{
return "secondlife:///app/agent/"+(string)kID+"/about";
@@ -89,13 +87,13 @@ string SubstitudeVars(string sMsg)
{
if (sMsg == "%NOACCESS%") return "Access denied.";
if (llSubStringIndex(sMsg, "%PREFIX%") != -1)
sMsg = osReplaceString(sMsg, "%PREFIX%", g_sPrefix, -1, 0);
sMsg = llReplaceSubString(sMsg, "%PREFIX%", g_sPrefix, 0);
if (llSubStringIndex(sMsg, "%CHANNEL%") != -1)
sMsg = osReplaceString(sMsg, "%CHANNEL%", (string)g_iListenChan, -1, 0);
sMsg = llReplaceSubString(sMsg, "%CHANNEL%", (string)g_iListenChan, 0);
if (llSubStringIndex(sMsg, "%DEVICETYPE%") != -1)
sMsg = osReplaceString(sMsg, "%DEVICETYPE%", g_sDeviceType, -1, 0);
sMsg = llReplaceSubString(sMsg, "%DEVICETYPE%", g_sDeviceType, 0);
if (llSubStringIndex(sMsg, "%WEARERNAME%") != -1)
sMsg = osReplaceString(sMsg, "%WEARERNAME%", g_sWearerName, -1, 0);
sMsg = llReplaceSubString(sMsg, "%WEARERNAME%", g_sWearerName, 0);
return sMsg;
}
@@ -225,14 +223,12 @@ Dialog(key kRecipient, string sPrompt, list lMenuItems, list lUtilityButtons, in
integer iChan = llRound(llFrand(10000000)) + 100000;
while (llListFindList(g_lMenus, [iChan]) != -1) iChan=llRound(llFrand(10000000)) + 100000;
integer iListener = llListen(iChan, "", kRecipient, "");
if (g_iIsLED) llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_FULLBRIGHT, ALL_SIDES, TRUE, PRIM_BUMP_SHINY, ALL_SIDES, PRIM_SHINY_NONE, PRIM_BUMP_NONE, PRIM_GLOW, ALL_SIDES, 0.4]);
if (llGetListLength(lMenuItems+lUtilityButtons) > 0){
list lNavButtons;
if (iNumitems > iMyPageSize) lNavButtons=["◄","►"];
llDialog(kRecipient, sThisPrompt, PrettyButtons(lButtons, lUtilityButtons, lNavButtons), iChan);
}
else llTextBox(kRecipient, sThisPrompt, iChan);
if (g_iIsLED) llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_FULLBRIGHT, ALL_SIDES, FALSE, PRIM_BUMP_SHINY, ALL_SIDES, PRIM_SHINY_HIGH, PRIM_BUMP_NONE, PRIM_GLOW, ALL_SIDES, 0.0]);
llSetTimerEvent(g_iReapeat);
integer ts = llGetUnixTime() + g_iTimeOut;
g_lMenus += [iChan, kID, iListener, ts, kRecipient, sPrompt, llDumpList2String(lMenuItems, "|"), llDumpList2String(lUtilityButtons, "|"), iPage, iWithNums, iAuth,extraInfo];
@@ -360,10 +356,9 @@ default
{
if (llGetStartParameter() == 825) llSetRemoteScriptAccessPin(0);
g_kWearer = llGetOwner();
if (llSubStringIndex(llGetObjectDesc(),"LED") == 0) g_iIsLED = TRUE;
g_sPrefix = llToLower(llGetSubString(llKey2Name(g_kWearer),0,1));
g_sWearerName = NameURI(g_kWearer);
if (g_iIsLED == FALSE) PieSlice();
PieSlice();
llSetLinkPrimitiveParamsFast(LINK_THIS,[PRIM_NAME,g_sDeviceName]);
}

View File

@@ -164,6 +164,7 @@ integer CheckCommandAuth(key kCmdGiver, integer iAuth)
SetLength(integer iIn)
{
if (iIn == 0) iIn = 3; // i had a rare edge case where this happened
g_iLength = iIn;
if (g_kLeashedTo != NULL_KEY) {
llTargetRemove(g_iTargetHandle);

View File

@@ -379,8 +379,8 @@ default
llMessageLinked(LINK_DIALOG, NOTIFY, "0"+"If you would like to stop the animation early, say /" + (string)g_iStopChan + g_sStopString + " to stop.", g_kPartner);
string sText = llList2String(g_lAnimSettings, g_iCmdIndex * 4 + 3);
if (sText != "" && g_iVerbose) {
sText = osReplaceString(sText, "_PARTNER_", g_sPartnerName, -1, 0);
sText = osReplaceString(sText, "_SELF_", "%WEARERNAME%", -1, 0);
sText = llReplaceSubString(sText, "_PARTNER_", g_sPartnerName, 0);
sText = llReplaceSubString(sText, "_SELF_", "%WEARERNAME%", 0);
llMessageLinked(LINK_DIALOG, SAY, "0"+sText, "");
}
if (g_fTimeOut > 0.0) {

View File

@@ -197,21 +197,17 @@ WearFolder(string sStr, key kID)
llMessageLinked(LINK_DIALOG, NOTIFY, "1"+"Changing outfit!", kID);
string sOutfit = llGetSubString(sStr, llStringLength(g_sPathPrefix), -2);
llMessageLinked(LINK_ROOT, ATTACHMENT_RESPONSE, "CollarCommand|"+(string)g_iAuth+"|ZHAO_ao load "+sOutfit, kID);
// always lock collar during outfit change
llOwnerSay("@detach=n");
// lock the core folder if exists
// Protect against detaching:
llOwnerSay("@detach=n"); // this collar
if (g_sCoreFolder != "") llOwnerSay("@detachallthis:"+g_sCoreFolder+"=n");
// unwear everything that's not locked:
// Remove everything except protected:
llOwnerSay("@remoutfit=force,detach=force");
// wear clothes/parts from the core folder that are not already worn:
if (g_sCoreFolder != "") llOwnerSay("@attachallover:"+g_sCoreFolder+"=force");
// wear the chosen outfit:
llOwnerSay("@attachallover:"+sStr+"=force");
// cleanup: unlock core folder if exists
llSleep(1.5);
// Unprotect:
if (g_sCoreFolder != "") llOwnerSay("@detachallthis:"+g_sCoreFolder+"=y");
// cleanup: unlock the collar, only if it was locked temporarily
if (g_iLocked == FALSE) llOwnerSay("@detach=y");
llSleep(1.5); // delay for SSA
if (g_iLocked == FALSE) llOwnerSay("@detach=y"); // this collar (if it was unlocked)
// Wear the outfit:
llOwnerSay("@attachallover:"+sStr+"=force");
}
doRestrictions()
@@ -565,6 +561,7 @@ default
else if (sStr=="restrictions_blurred") g_iBlurredRestricted=FALSE;
else if (sStr=="restrictions_dazed") g_iDazedRestricted=FALSE;
else if (sStr=="restrictions_dress") g_iDressRestricted=FALSE;
doRestrictions();
} else if (iNum == LM_SETTING_RESPONSE) {
list lParams = llParseString2List(sStr, ["="], []);
string sToken = llList2String(lParams, 0);
@@ -581,6 +578,7 @@ default
else if (sToken=="restrictions_blurred") g_iBlurredRestricted=(integer)sValue;
else if (sToken=="restrictions_dazed") g_iDazedRestricted=(integer)sValue;
else if (sToken=="restrictions_dress") g_iDressRestricted=(integer)sValue;
doRestrictions();
} else if (sToken==g_sSettingToken+"corefolder") {
if (sValue=="none") g_sCoreFolder = "";
else g_sCoreFolder = sValue;
@@ -651,6 +649,7 @@ default
listen(integer iChan, string sName, key kID, string sMsg)
{
llSetTimerEvent(0.0);
llListenRemove(g_iListener);
if (iChan == g_iFolderRLV) {
if (llStringLength(sMsg) == 1023) llMessageLinked(LINK_DIALOG,NOTIFY,"0"+"\n\nATTENTION: Either some of the names of your outfit folders are too long, or there are too many folders in your Outfits directory. This could lead to gaps in your outfits folder index. For best operability, please consider reducing the overall amount of subfolders within the Outfits directory and use shorter names.\n",g_kWearer);
string sPrompt;
@@ -677,4 +676,4 @@ default
llListenRemove(g_iListener);
llSetTimerEvent(0.0);
}
}
}

View File

@@ -73,8 +73,6 @@ integer RLV_OFF = 6100;
integer RLV_ON = 6101;
integer RLV_QUERY = 6102;
integer RLV_RESPONSE = 6103;
integer RLV_SHOES = 6108;
integer RLV_NOSHOES = 6109;
integer DIALOG = -9000;
integer DIALOG_RESPONSE = -9001;
@@ -101,14 +99,8 @@ list g_lBaked;
key g_kSitter = NULL_KEY;
key g_kSitTarget = NULL_KEY;
integer g_iShoeNotify = TRUE;
integer g_iShoeListener;
integer g_iShoeChannel;
integer g_iShoesWorn = FALSE;
integer CMD_ADDSRC = 11;
integer CMD_REMSRC = 12;
integer g_iIsLED;
DoMenu(key kID, integer iAuth)
{
@@ -350,33 +342,19 @@ default
on_rez(integer param)
{
if (g_kWearer != llGetOwner()) llResetScript();
if (llSubStringIndex(llGetObjectDesc(),"LED") == 0) g_iIsLED = TRUE;
g_iRlvActive = FALSE;
g_iViewerCheck = FALSE;
g_iRLVOn = FALSE;
g_lBaked = [];
llMessageLinked(LINK_ALL_OTHERS,LINK_UPDATE,"LINK_RLV","");
if (g_iIsLED == FALSE) PieSlice();
PieSlice();
}
state_entry()
{
if (llGetStartParameter()==825) llSetRemoteScriptAccessPin(0);
llOwnerSay("@clear");
g_kWearer = llGetOwner();
if (llSubStringIndex(llGetObjectDesc(),"LED") == 0) g_iIsLED = TRUE;
if (g_iIsLED == FALSE) PieSlice();
}
attach(key kID)
{
if (kID == NULL_KEY && g_iRLVOn) {
// Detach, so de-register worn and unworn events (if it gets through)
if (g_iRlvActive) {
llOwnerSay("@notify:"+(string)g_iShoeChannel+";worn legally shoes=rem");
llOwnerSay("@notify:"+(string)g_iShoeChannel+";unworn legally shoes=rem");
}
}
PieSlice();
}
listen(integer iChan, string sName, key kID, string sMsg)
@@ -398,29 +376,6 @@ default
g_iRlvaVersion = (llList2Integer(lVersionSplit,0) * 100) + llList2Integer(lVersionSplit, 1);
setRlvState();
return;
} else if (iChan == g_iShoeChannel) {
//if (llGetSubString(sMsg, 0, 6) == "/notify") {
// llOwnerSay("shoe channel: got notify result: "+sMsg);
//} else
if (sMsg == "/unworn legally shoes") {
g_iShoesWorn = FALSE;
llMessageLinked(LINK_ANIM, RLV_NOSHOES, "", "");
} else if (sMsg == "/worn legally shoes") {
g_iShoesWorn = TRUE;
llMessageLinked(LINK_ANIM, RLV_SHOES, "", "");
} else if (llGetSubString(sMsg, 0, 6) != "/notify") {
// @getoutfit result (a string of 1's and 0's)
string sFlagShoes = llGetSubString(sMsg, 4, 4);
if (sFlagShoes == "1" || sFlagShoes == "0")
{
g_iShoesWorn = (integer)llGetSubString(sMsg, 4, 4);
if (g_iShoesWorn) llMessageLinked(LINK_ANIM, RLV_SHOES, "", "");
else llMessageLinked(LINK_ANIM, RLV_NOSHOES, "", "");
// Register to be notified of worn and unworn
llOwnerSay("@notify:"+(string)g_iShoeChannel+";worn legally shoes=add");
llOwnerSay("@notify:"+(string)g_iShoeChannel+";unworn legally shoes=add");
}
}
}
}
@@ -435,10 +390,6 @@ default
else if (iNum == DIALOG_RESPONSE) {
integer iMenuIndex = llListFindList(g_lMenuIDs, [kID]);
if (iMenuIndex != -1) {
if (g_iIsLED) {
llSetLinkPrimitiveParamsFast(LINK_THIS,[PRIM_FULLBRIGHT,ALL_SIDES,TRUE,PRIM_BUMP_SHINY,ALL_SIDES,PRIM_SHINY_NONE,PRIM_BUMP_NONE,PRIM_GLOW,ALL_SIDES,0.4]);
llSensorRepeat("N0thin9","abc",ACTIVE,0.1,0.1,0.22);
}
list lMenuParams = llParseString2List(sStr, ["|"], []);
key kAv = llList2Key(lMenuParams, 0);
string sMsg = llList2String(lMenuParams, 1);
@@ -521,10 +472,6 @@ default
while (numBaked--)
llOwnerSay("@"+llList2String(g_lBaked, numBaked)+"=n");
} else if (g_iRlvActive) {
if (g_iIsLED) {
llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_FULLBRIGHT, ALL_SIDES, TRUE, PRIM_BUMP_SHINY, ALL_SIDES, PRIM_SHINY_NONE, PRIM_BUMP_NONE, PRIM_GLOW, ALL_SIDES, 0.4]);
llSensorRepeat("N0thin9", "abc", ACTIVE, 0.1, 0.1, 0.22);
}
if (iNum == RLV_CMD) {
list lCommands = llParseString2List(llToLower(sStr), [","], []);
while (llGetListLength(lCommands) > 0) {
@@ -584,12 +531,6 @@ default
}
}
no_sensor()
{
llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_FULLBRIGHT, ALL_SIDES, FALSE, PRIM_BUMP_SHINY, ALL_SIDES, PRIM_SHINY_HIGH, PRIM_BUMP_NONE, PRIM_GLOW, ALL_SIDES, 0.0]);
llSensorRemove();
}
timer()
{
if (g_iWaitRelay) {
@@ -610,12 +551,6 @@ default
if (kSource != NULL_KEY) llShout(RELAY_CHANNEL, "ping," + (string)kSource + ",ping,ping");
else rebakeSourceRestrictions(kSource);
}
if (g_iShoeNotify) {
g_iShoeChannel = (9999 + llRound(llFrand(9999999.0)));
llListenRemove(g_iShoeListener);
g_iShoeListener = llListen(g_iShoeChannel, "", (string)g_kWearer, "");
llOwnerSay("@getoutfit="+(string)g_iShoeChannel);
}
if (llGetStartParameter() == 0) llMessageLinked(LINK_DIALOG, NOTIFY, "0"+"RLV ready!", g_kWearer);
}
} else {

View File

@@ -93,6 +93,7 @@ integer SettingExists(string sToken)
list SetSetting(list lCache, string sToken, string sValue)
{
llLinksetDataWrite(sToken, sValue);
integer idx = llListFindList(lCache, [sToken]);
if (idx != -1) return llListReplaceList(lCache, [sValue], idx+1, idx+1);
idx = GroupIndex(lCache, sToken);
@@ -108,6 +109,7 @@ string GetSetting(string sToken)
DelSetting(string sToken)
{
llLinksetDataDelete(sToken);
integer i = llGetListLength(g_lSettings) - 1;
if (SplitToken(sToken, 1) == "all") {
sToken = SplitToken(sToken, 0);
@@ -176,7 +178,7 @@ PrintSettings(key kID, string sDebug)
list lOut;
string sLinkNr = (string)llGetLinkNumber();
string sLinkName = llGetLinkName(LINK_THIS);
list lSay = ["/me \nTo copy/paste the settings below in the .settings notecard (in the '"+sLinkName+"' prim, link nr. "+sLinkNr+"), make sure the device is unlocked!\n----- 8< ----- 8< ----- 8< -----\n"];
list lSay = ["/me \nYou can copy/paste the settings below in a notecard to be loaded as backup (in the '"+sLinkName+"' prim, link nr. "+sLinkNr+")\n----- 8< ----- 8< ----- 8< -----\n"];
if (sDebug == "debug")
lSay = ["/me Settings Debug:\n"];
lSay += Add2OutList(g_lSettings, sDebug);
@@ -200,25 +202,30 @@ PrintSettings(key kID, string sDebug)
}
}
SaveSettings(key kID)
integer SaveCard(key kID)
{
integer iRet = FALSE;
list lOut = Add2OutList(g_lSettings, "save");
try
{
if (llGetInventoryType(g_sCard)==INVENTORY_NOTECARD)
llRemoveInventory(g_sCard);
osMakeNotecard(g_sCard, lOut);
llMessageLinked(LINK_DIALOG, NOTIFY, "0"+"Settings saved.", kID);
iRet = TRUE;
}
catch (scriptexception ex)
{
string msg = yExceptionMessage(ex);
if (osStringStartsWith(msg, "ossl permission error", TRUE))
llMessageLinked(LINK_DIALOG, NOTIFY, "0"+"Saving is not enabled on this region. Use 'Print' instead, then copy & paste to replace the contents of the settings notecard.", kID);
else
if (osStringStartsWith(msg, "ossl permission error", TRUE)) {
llMessageLinked(LINK_DIALOG, NOTIFY, "0"+"Could not save the '.settings' notecard. Use 'Print' instead, then copy & paste/replace the output into a notecard called '.settings' within the storage prim - link number "+(string)llGetLinkNumber()+", link name "+llGetObjectName()+" (the %DEVICETYPE% may need to be unlocked for doing this)", kID);
} else
throw;
}
return iRet;
}
LoadSetting(string sData, integer iLine)
ParseCardLine(string sData, integer iLine)
{
string sID;
string sToken;
@@ -249,12 +256,77 @@ LoadSetting(string sData, integer iLine)
for (i = 0; i < llGetListLength(lData); i += 2) {
sToken = llList2String(lData, i);
sValue = llList2String(lData, i+1);
if (sValue != "" && sID != "auth_")
g_lSettings = SetSetting(g_lSettings, sID+sToken, sValue);
if (sValue != "") {
if (sID == "auth_") {
sToken = llToLower(sToken);
if (llListFindList(["block","trust","owner"], [sToken]) != -1) {
list lTest = llParseString2List(sValue, [","], []);
list lOut;
integer n;
do {
if (llList2Key(lTest, n))
lOut += llList2String(lTest, n);
} while (++n < llGetListLength(lTest));
sValue = llDumpList2String(lOut, ",");
lTest = [];
lOut = [];
}
}
if (sValue != "") g_lSettings = SetSetting(g_lSettings, sID + sToken, sValue);
}
}
}
}
LoadLinksetData()
{
g_lSettings = []; // just to be sure
integer iNumTokens = llLinksetDataCountKeys();
list lKeys = llLinksetDataListKeys(0, iNumTokens);
integer i;
for (i = 0; i < llGetListLength(lKeys); i++)
{
string sToken = llList2String(lKeys,i);
string sValue = llLinksetDataRead(sToken);
if (llListFindList(g_lExceptionTokens, [SplitToken(sToken,0)]) == -1)
{
integer idx = llListFindList(g_lSettings, [sToken]);
if (idx != -1) {
g_lSettings = llListReplaceList(g_lSettings, [sValue], idx+1, idx+1);
continue;
}
idx = GroupIndex(g_lSettings, sToken);
if (idx != -1) {
g_lSettings = llListInsertList(g_lSettings, [sToken, sValue], idx);
continue;
}
g_lSettings = g_lSettings + [sToken, sValue];
}
}
lKeys = []; // force gc
}
PrintLinksetData()
{
llOwnerSay("--- dump of linksetdata ---\n");
integer iNumTokens = llLinksetDataCountKeys();
list lKeys = llLinksetDataListKeys(0, iNumTokens);
integer i;
for (i = 0; i < llGetListLength(lKeys); i++)
{
string sKey = llList2String(lKeys,i);
string sValue = llLinksetDataRead(sKey);
if (llListFindList(g_lExceptionTokens, [SplitToken(sKey,0)]) == -1)
{
if (sValue != "")
llOwnerSay(sKey+"="+sValue+"\n");
}
}
lKeys = [];
}
SendValues()
{
integer n;
@@ -269,21 +341,26 @@ SendValues()
for (n = 0; n < llGetListLength(lOut); n++)
llMessageLinked(LINK_ALL_OTHERS, LM_SETTING_RESPONSE, llList2String(lOut, n), "");
llMessageLinked(LINK_ALL_OTHERS, LM_SETTING_RESPONSE, "settings=sent", "");
lOut = [];
}
UserCommand(integer iAuth, string sStr, key kID)
{
string sStrLower = llToLower(sStr);
if (sStrLower == "print settings" || sStrLower == "debug settings") PrintSettings(kID, llGetSubString(sStrLower, 0, 4));
else if (llSubStringIndex(sStrLower,"load") == 0) {
else if (llSubStringIndex(sStrLower,"load card") == 0) {
if (iAuth == CMD_OWNER && kID != g_kTempOwner) {
if (llGetInventoryKey(g_sCard) != NULL_KEY) {
if (llGetInventoryType(g_sCard) == INVENTORY_NOTECARD) {
llMessageLinked(LINK_DIALOG, NOTIFY, "0"+ "\n\nLoading backup from "+g_sCard+" card. If you want to load settings from the web, please type: /%CHANNEL% %PREFIX% load url <url>\n\n", kID);
llLinksetDataReset();
g_lSettings = [];
g_kLineID = llGetNotecardLine(g_sCard, g_iLineNr);
} else llMessageLinked(LINK_DIALOG, NOTIFY, "0"+"No "+g_sCard+" to load found.", kID);
} else llMessageLinked(LINK_DIALOG, NOTIFY, "0"+"%NOACCESS%", kID);
} else if (llSubStringIndex(sStrLower,"save") == 0) {
if (iAuth == CMD_OWNER) SaveSettings(kID);
} else if (llSubStringIndex(sStrLower,"save card") == 0) {
if (iAuth == CMD_OWNER) SaveCard(kID);
} else if (llSubStringIndex(sStrLower,"dump lsd") == 0) { // debug
if (iAuth == CMD_OWNER) PrintLinksetData();
} else if (sStrLower == "reboot" || sStrLower == "reboot --f") {
if (g_iRebootConfirmed || sStrLower == "reboot --f") {
llMessageLinked(LINK_DIALOG, NOTIFY, "0"+"Rebooting your %DEVICETYPE% ....", kID);
@@ -294,7 +371,16 @@ UserCommand(integer iAuth, string sStr, key kID)
g_kConfirmDialogID = llGenerateKey();
llMessageLinked(LINK_DIALOG, DIALOG, (string)kID+"|\nAre you sure you want to reboot the %DEVICETYPE%?|0|Yes`No|Cancel|"+(string)iAuth, g_kConfirmDialogID);
}
} else if (sStrLower == "runaway") llSetTimerEvent(2.0);
} else if (sStrLower == "runaway") {
// We'll have to delete the card if we can't save a new one (with no owners set)
// due to no ossl permissions, otherwise old owners might still be reloaded
// from the old card!
if (llGetInventoryType(g_sCard) == INVENTORY_NOTECARD && SaveCard(g_kWearer)==FALSE) {
llGiveInventory(g_kWearer, g_sCard);
llRemoveInventory(g_sCard);
}
llSetTimerEvent(2.0);
}
}
PieSlice()
@@ -325,12 +411,9 @@ default
if (llGetInventoryType("OC_Cuffs_sync") == INVENTORY_SCRIPT) llRemoveInventory("OC_Cuffs_sync");
llSleep(0.5);
g_kWearer = llGetOwner();
g_iLineNr = 0;
if (llGetStartParameter() == 0) {
if (llGetInventoryType(g_sCard) == INVENTORY_NOTECARD) {
g_kCardID = llGetInventoryKey(g_sCard);
g_kLineID = llGetNotecardLine(g_sCard, g_iLineNr);
} else if (llGetListLength(g_lSettings) > 0) llMessageLinked(LINK_ALL_OTHERS, LM_SETTING_RESPONSE, llDumpList2String(g_lSettings, "="), "");
LoadLinksetData();
llMessageLinked(LINK_ALL_OTHERS, LM_SETTING_RESPONSE, llDumpList2String(g_lSettings, "="), "");
}
PieSlice();
}
@@ -348,11 +431,11 @@ default
{
if (kID == g_kLineID) {
if (sData != EOF) {
LoadSetting(sData, ++g_iLineNr);
ParseCardLine(sData, ++g_iLineNr);
g_kLineID = llGetNotecardLine(g_sCard, g_iLineNr);
} else {
g_iLineNr = 0;
LoadSetting(sData, g_iLineNr);
ParseCardLine(sData, g_iLineNr);
llSetTimerEvent(2.0);
}
}
@@ -408,17 +491,5 @@ default
llSetTimerEvent(0.0);
SendValues();
}
changed(integer iChange)
{
if ((iChange & CHANGED_INVENTORY) && llGetInventoryKey(g_sCard) != g_kCardID) {
// Re-read settings card if it has been changed
llSetTimerEvent(0.0);
g_iLineNr = 0;
g_kCardID = llGetInventoryKey(g_sCard);
if (g_kCardID != NULL_KEY)
g_kLineID = llGetNotecardLine(g_sCard, g_iLineNr);
}
}
}

View File

@@ -22,7 +22,7 @@
//on menu request, give dialog, with alphabetized list of submenus
//on listen, send submenu link message
string g_sCollarVersion="2023.09.06";
string g_sCollarVersion="2026.02";
key g_kWearer = NULL_KEY;
@@ -87,11 +87,6 @@ integer g_iLocked = FALSE;
integer g_bDetached = FALSE;
integer g_iHide ; // global hide
list g_lCacheAlpha; // integer link, float alpha. for preserving transparent links when unhiding the device
list g_lCacheGlows; // integer link, float glow. for restoring links with glow when unhiding the device
list g_lClosedLockElements; // integer link. links to show when device locked
list g_lOpenLockElements; // integer link. links to show when device unlocked
string g_sDefaultLockSound="sound_lock";
string g_sDefaultUnlockSound="sound_unlock";
string g_sLockSound="sound_lock";
@@ -118,7 +113,7 @@ integer g_iWaitUpdate;
integer g_iWaitRebuild;
string g_sIntegrity = "(pending...)";
string g_sHelpCard = "OsCollar Help";
string g_sHelpCard = ".help";
integer compareVersions(string v1, string v2) { //compares two symantic version strings, true if v1 >= v2
integer v1Index = llSubStringIndex(v1, ".");
@@ -156,7 +151,7 @@ string NameGroupURI(string sStr){
SettingsMenu(key kID, integer iAuth) {
string sPrompt = "\nSettings";
list lButtons = ["Print","Load","Save","Fix"];
list lButtons = ["Print","Load Card","Save Card","Dump LSD","Fix"];
lButtons += g_lResizeButtons;
if (g_iHide) lButtons += ["☐ Visible"];
else lButtons += ["☑ Visible"];
@@ -177,14 +172,17 @@ UpdateConfirmMenu() {
HelpMenu(key kID, integer iAuth) {
string sPrompt="\nVersion: "+g_sCollarVersion+"\n";
sPrompt += "\nThis %DEVICETYPE% has a "+g_sIntegrity+" core.\n";
sPrompt += "\nScript engine: "+osGetScriptEngineName();
string sVersion = osGetSimulatorVersion();
integer idx = llSubStringIndex(sVersion, " ");
integer idx2 = llSubStringIndex(llGetSubString(sVersion, idx+1, -1), " ");
sPrompt += "\nSimulator: "+llGetSubString(sVersion, 0, idx+idx2); // strip contents of bin/.version
list lUtility = [UPMENU];
list lStaticButtons=["Help","Update","Version"];
Dialog(kID, sPrompt, lStaticButtons, lUtility, 0, iAuth, "Help/About");
}
MainMenu(key kID, integer iAuth) {
string sPrompt = "\n𝐎 𝐒 𝐂 𝐨 𝐥 𝐥 𝐚 𝐫\t"+g_sCollarVersion+"\n";
string sPrompt = "\nOsCollar\t"+g_sCollarVersion+"\n";
sPrompt += "\nPrefix: %PREFIX%\nChannel: %CHANNEL%\nSafeword: "+g_sSafeWord;
list lStaticButtons = ["Apps"];
if (g_iAnimsMenu) lStaticButtons += "Animations";
@@ -240,7 +238,6 @@ UserCommand(integer iNum, string sStr, key kID, integer fromMenu) {
g_iLocked = TRUE;
llMessageLinked(LINK_SAVE, LM_SETTING_SAVE, g_sGlobalToken+"locked=1", "");
llMessageLinked(LINK_ROOT, LM_SETTING_RESPONSE, g_sGlobalToken+"locked=1", "");
llOwnerSay("@detach=n");
llMessageLinked(LINK_RLV, RLV_CMD, "detach=n", "main");
llPlaySound(g_sLockSound, 1.0);
SetLockElementAlpha();//EB
@@ -253,7 +250,6 @@ UserCommand(integer iNum, string sStr, key kID, integer fromMenu) {
g_iLocked = FALSE;
llMessageLinked(LINK_SAVE, LM_SETTING_SAVE, g_sGlobalToken+"locked=0", "");
llMessageLinked(LINK_ROOT, LM_SETTING_RESPONSE, g_sGlobalToken+"locked=0", "");
llOwnerSay("@detach=y");
llMessageLinked(LINK_RLV, RLV_CMD, "detach=y", "main");
llPlaySound(g_sUnlockSound, 1.0);
SetLockElementAlpha(); //EB
@@ -267,9 +263,13 @@ UserCommand(integer iNum, string sStr, key kID, integer fromMenu) {
llMessageLinked(LINK_DIALOG, NOTIFY, "0"+"Menus have been fixed!", kID);
//} else llMessageLinked(LINK_DIALOG,NOTIFY,"0"+"%NOACCESS%",kID);
} else if (sCmd == "stealth") Stealth(!g_iHide);
else if (sCmd == "hide") Stealth(TRUE);
else if (sCmd == "show") Stealth(FALSE);
else if (sCmd == "update") {
else if (sCmd == "hide") {
Stealth(TRUE);
if (fromMenu) SettingsMenu(kID, iNum);
} else if (sCmd == "show") {
Stealth(FALSE);
if (fromMenu) SettingsMenu(kID, iNum);
} else if (sCmd == "update") {
if (kID == g_kWearer) {
g_iWillingUpdaters = 0;
g_kCurrentUser = kID;
@@ -327,20 +327,25 @@ string GetTimestamp() {
SetLockElementAlpha() { //EB
if (g_iHide) return ; // ***** if collar is hide, don't do anything
//loop through stored links, setting alpha if element type is lock
integer n;
integer iLinkElements = llGetListLength(g_lOpenLockElements);
for (n = 0; n < iLinkElements; n++) {
llSetLinkAlpha(llList2Integer(g_lOpenLockElements,n), !g_iLocked, ALL_SIDES);
integer idx = llListFindList(g_lCacheGlows, [n]);
if (idx != -1 && (idx %2 == 0))
llSetLinkPrimitiveParamsFast(n, [PRIM_GLOW, ALL_SIDES, llList2Float(g_lCacheGlows, idx+1)]);
}
iLinkElements = llGetListLength(g_lClosedLockElements);
for (n=0; n < iLinkElements; n++) {
llSetLinkAlpha(llList2Integer(g_lClosedLockElements,n), g_iLocked, ALL_SIDES);
integer idx = llListFindList(g_lCacheGlows, [n]);
if (idx != -1 && (idx %2 == 0))
llSetLinkPrimitiveParamsFast(n, [PRIM_GLOW, ALL_SIDES, llList2Float(g_lCacheGlows, idx+1)]);
integer iLink;
for (iLink = LINK_ROOT; iLink < llGetNumberOfPrims(); iLink++) {
string sName = llGetLinkName(iLink);
if (sName=="Lock") llSetLinkAlpha(iLink, !g_iLocked, ALL_SIDES); // openlockelement
else if (sName=="ClosedLock") llSetLinkAlpha(iLink, g_iLocked, ALL_SIDES);
else jump next;
// restore glow (if any):
list lPrimParams = llGetLinkPrimitiveParams(iLink, [PRIM_TEXT, PRIM_DESC]);
list sDesc = llList2String(lPrimParams, 3);
if (llSubStringIndex(sDesc, "noglow") == -1)
{
list lText = llParseString2List(llList2String(lPrimParams, 0), ["~","="], []);
integer idx = llListFindList(lText, ["glow"]);
if (idx != -1) {
float fGlow = llList2Float(lText, idx+1);
if (fGlow > 0.0) llSetLinkPrimitiveParamsFast(iLink, [PRIM_GLOW, ALL_SIDES, fGlow]);
}
}
@next;
}
}
@@ -357,68 +362,53 @@ RebuildMenu() {
llMessageLinked(LINK_ALL_OTHERS, LINK_UPDATE,"LINK_REQUEST","");
}
RebuildCaches() {
g_lCacheAlpha = [-1000, 0.1]; // dummy pair to detect if we lost the lists due to state loss
g_lCacheGlows = [];
g_lOpenLockElements = [];
g_lClosedLockElements = [];
integer iLink;
integer idx;
for (iLink = LINK_ROOT; iLink < llGetNumberOfPrims(); iLink++) {
list lLinkParams = llGetLinkPrimitiveParams(iLink, [PRIM_DESC, PRIM_COLOR, 0, PRIM_GLOW, 0]);
// ^^ returns string desc, vector color, float alpha, float glow. note ALL_SIDES doesn't work on OS, so we use side 0.
string sDesc = llList2String(lLinkParams, 0);
list lSettings = llParseString2List(llToLower(sDesc), ["~"], []);
// is hidden? has alpha?
idx = llListFindList(lSettings, ["hidden"]);
if (idx != -1) g_lCacheAlpha += [iLink, 0.0]; // found hidden setting in prim desc, state-loss-safe.
else {
idx = llListFindList(lSettings, ["alpha"]);
if (idx != -1) g_lCacheAlpha += [iLink, llList2Float(lSettings, idx+1)]; // found desc alpha~f setting
else if (g_iHide == FALSE) {
// backup method, get alpha from prim if collar not hidden yet. NOT state-loss-safe!
float fAlpha = llList2Float(lLinkParams,2);
if (fAlpha < 1.0) g_lCacheAlpha += [iLink, fAlpha];
Stealth(integer iHide) {
if (iHide) {
integer iLink;
integer idx;
for (iLink = LINK_ROOT; iLink < llGetNumberOfPrims(); iLink++) {
list lPrimParams = llGetLinkPrimitiveParams(iLink, [PRIM_DESC, PRIM_COLOR, 0, PRIM_GLOW, 0]);
// ^^ returns [desc, color, alpha, glow]. note ALL_SIDES doesn't work on OS, so we use side 0.
string sText; // stored as key1=value1~key2=value2
string sDesc = llList2String(lPrimParams, 0);
if (llSubStringIndex(sDesc, "FloatText") != 0) { // ignore titler prim
if (llSubStringIndex(sDesc, "hidden") == -1 || llSubStringIndex(sDesc, "nohide") == -1) {
float fAlpha = llList2Float(lPrimParams,2);
if (fAlpha < 1.0) sText = "alpha="+(string)fAlpha;
}
if (llSubStringIndex(sDesc, "noglow") == -1) {
float fGlow = llList2Float(lPrimParams, 3);
if (fGlow > 0.0) sText += "~glow="+(string)fGlow;
}
llSetLinkPrimitiveParamsFast(iLink, [PRIM_TEXT, sText, <1,1,1>, 0.0]);
}
}
// has glows?
idx = llListFindList(lSettings, ["glow"]);
if (idx != -1) g_lCacheGlows += [iLink, llList2Float(lSettings, idx+1)]; // found desc glow~f setting
else if (g_iHide == FALSE) {
// backup method: get glow from prim if collar not hidden yet. NOT state-loss-safe!
float fGlow = llList2Float(lLinkParams, 3);
if (fGlow > 0) g_lCacheGlows += [iLink, fGlow];
}
// is a lock prim?
list lPrimName = llParseString2List(llGetLinkName(iLink), ["~"], []);
if (llListFindList(lPrimName, ["Lock"]) != -1 || llListFindList(lPrimName, ["ClosedLock"]) != -1)
g_lClosedLockElements += [iLink];
else if (llListFindList(lPrimName, ["OpenLock"]) != -1)
g_lOpenLockElements += [iLink];
}
}
Stealth(integer iHide) {
if (llGetListLength(g_lCacheAlpha) == 0) RebuildCaches(); // cache lost, rebuild
if (iHide) {
// Finally, hide:
llSetLinkPrimitiveParamsFast(LINK_SET, [PRIM_GLOW, ALL_SIDES, 0.0]);
llSetLinkAlpha(LINK_SET, 0.0, ALL_SIDES);
} else { // Show
integer iLink;
for (iLink = LINK_ROOT; iLink < llGetNumberOfPrims(); iLink++) {
// restore alpha's:
integer idx = llListFindList(g_lCacheAlpha, [iLink]);
if (idx != -1 && (idx % 2 == 0)) {
float fAlpha = llList2Float(g_lCacheAlpha, idx+1);
llSetLinkAlpha(iLink, fAlpha, ALL_SIDES);
} else llSetLinkAlpha(iLink, 1.0, ALL_SIDES);
// restore glows:
idx = llListFindList(g_lCacheGlows, [iLink]);
if (idx != -1 && (idx %2 == 0)) {
float fGlow = llList2Float(g_lCacheGlows, idx+1);
llSetLinkPrimitiveParamsFast(iLink, [PRIM_GLOW, ALL_SIDES, fGlow]);
list lPrimParams = llGetLinkPrimitiveParams(iLink, [PRIM_TEXT,PRIM_DESC]);
// lPrimParams returns: [hovertext, hovercolor, hoveralpha, desc]
list lText = llParseString2List(llList2String(lPrimParams, 0), ["~","="], []);
string sDesc = llList2String(lPrimParams, 3);
if (llSubStringIndex(sDesc, "FloatText") != 0) { // ignore titler prim
if (llSubStringIndex(sDesc, "hidden") == -1 || llSubStringIndex(sDesc, "nohide") == -1) {
integer idx = llListFindList(lText, ["alpha"]);
if (idx != -1) {
float fAlpha = (float)llList2String(lText, idx+1);
llSetLinkAlpha(iLink, fAlpha, ALL_SIDES); // show alpha'd
} else llSetLinkAlpha(iLink, 1.0, ALL_SIDES); // show all
}
if (llSubStringIndex(sDesc, "noglow") == -1) {
integer idx = llListFindList(lText, ["glow"]);
if (idx != -1) {
float fGlow = (float)llList2String(lText, idx+1);
llSetLinkPrimitiveParamsFast(iLink, [PRIM_GLOW, ALL_SIDES, fGlow]);
}
}
}
}
}
@@ -430,8 +420,6 @@ Stealth(integer iHide) {
init() {
g_iWaitRebuild = TRUE;
llSetTimerEvent(1.0);
if (g_iLocked) llOwnerSay("@detach=n");
SetLockElementAlpha();
}
StartUpdate() {
@@ -444,10 +432,7 @@ default {
state_entry() {
g_kWearer = llGetOwner();
if (llGetInventoryType("oc_installer_sys")==INVENTORY_SCRIPT) return;
string sObjectName = osReplaceString(llGetObjectName(), "\\d+\\.\\d+\\.?\\d+", g_sCollarVersion, -1, 0);
if (sObjectName != llGetObjectName()) llSetObjectName(sObjectName);
g_iHide = !(integer)llGetAlpha(ALL_SIDES);
if (llGetListLength(g_lCacheAlpha) == 0) RebuildCaches(); // no dummy pair, so cache lost, rebuild
init();
//Debug("Starting");
}
@@ -514,7 +499,7 @@ default {
else if (sMessage == "Help") UserCommand(iAuth, "help", kAv, TRUE);
else if (sMessage == "Update") UserCommand(iAuth, "update", kAv, TRUE);
else if (sMessage == "Version")
g_kHttpVersion = llHTTPRequest("https://raw.githubusercontent.com/lickx/oscollar-dev/stable/web/device", [], "");
g_kHttpVersion = llHTTPRequest("https://git.lotix.org/lotek/oscollar/raw/branch/master/web/device", [], "");
} else if (sMenu == "UpdateConfirmMenu"){
if (sMessage=="Yes") StartUpdate();
else {
@@ -523,17 +508,18 @@ default {
}
} else if (sMenu == "Settings") {
if (sMessage == "Print") llMessageLinked(LINK_SAVE, iAuth, "print settings", kAv);
else if (sMessage == "Load") llMessageLinked(LINK_SAVE, iAuth, sMessage, kAv);
else if (sMessage == "Save") llMessageLinked(LINK_SAVE, iAuth, sMessage, kAv);
else if (sMessage == "Load Card") llMessageLinked(LINK_SAVE, iAuth, sMessage, kAv);
else if (sMessage == "Save Card") llMessageLinked(LINK_SAVE, iAuth, sMessage, kAv);
else if (sMessage == "Dump LSD") llMessageLinked(LINK_SAVE, iAuth, sMessage, kAv);
else if (sMessage == "Fix") {
UserCommand(iAuth, sMessage, kAv, TRUE);
return;
} else if (sMessage == "☑ Visible") {
Stealth(TRUE);
llMessageLinked(LINK_ROOT, iAuth, "hide", kAv);
UserCommand(iAuth, "hide", kAv, TRUE);
return;
} else if (sMessage == "☐ Visible") {
Stealth(FALSE);
llMessageLinked(LINK_ROOT, iAuth, "show", kAv);
UserCommand(iAuth, "show", kAv, TRUE);
return;
} else if (sMessage == "Themes") {
llMessageLinked(LINK_ROOT, iAuth, "menu Themes", kAv);
return;
@@ -557,7 +543,7 @@ default {
string sValue = llList2String(lParams, 1);
if (sToken == g_sGlobalToken+"locked") {
g_iLocked = (integer)sValue;
if (g_iLocked) llOwnerSay("@detach=n");
if (g_iLocked) llMessageLinked(LINK_RLV, RLV_CMD, "detach=n", "main");
SetLockElementAlpha();
} else if (sToken == "intern_integrity") g_sIntegrity = sValue;
else if (sToken == "intern_looks") g_iLooks = (integer)sValue;
@@ -568,12 +554,16 @@ default {
if (sValue=="default") g_sUnlockSound=g_sDefaultUnlockSound;
else if ((key)sValue!=NULL_KEY || llGetInventoryType(sValue)==INVENTORY_SOUND) g_sUnlockSound=sValue;
} else if (sToken == g_sGlobalToken+"safeword") g_sSafeWord = sValue;
else if (sToken == g_sGlobalToken+"stealth") g_iHide = (integer)sValue;
} else if (iNum == DIALOG_TIMEOUT) {
integer iMenuIndex = llListFindList(g_lMenuIDs, [kID]);
g_lMenuIDs = llDeleteSubList(g_lMenuIDs, iMenuIndex-1, iMenuIndex-2 + g_iMenuStride);
} else if (iNum == RLV_REFRESH || iNum == RLV_CLEAR) {
} else if (iNum == RLV_REFRESH) {
if (g_iLocked) llMessageLinked(LINK_RLV, RLV_CMD, "detach=n", "main");
else llMessageLinked(LINK_RLV, RLV_CMD, "detach=y", "main");
SetLockElementAlpha();
} else if (iNum == RLV_CLEAR) {
if (g_iLocked) llMessageLinked(LINK_RLV, RLV_CMD, "detach=y", "main");
} else if (iNum == REBOOT && sStr == "reboot") llResetScript();
}
@@ -594,14 +584,10 @@ default {
integer iNewHide=!(integer)llGetAlpha(ALL_SIDES) ; //check alpha
if (g_iHide != iNewHide){ //check there's a difference to avoid infinite loop
g_iHide = iNewHide;
RebuildCaches();
SetLockElementAlpha(); // update hide elements
}
}
if (iChange & CHANGED_LINK) {
llMessageLinked(LINK_ALL_OTHERS,LINK_UPDATE,"LINK_REQUEST","");
RebuildCaches();
}
if (iChange & CHANGED_LINK) llMessageLinked(LINK_ALL_OTHERS,LINK_UPDATE,"LINK_REQUEST","");
if (iChange & CHANGED_REGION) llMessageLinked(LINK_ALL_OTHERS,REGION_CROSSED,"","");
if (iChange & CHANGED_TELEPORT) llMessageLinked(LINK_ALL_OTHERS,REGION_TELEPORT,"","");
}
@@ -610,7 +596,7 @@ default {
if (g_iLocked) {
if(kID == NULL_KEY) {
g_bDetached = TRUE;
llMessageLinked(LINK_DIALOG,NOTIFY_OWNERS, "%WEARERNAME% has attached me while locked at "+GetTimestamp()+"!",kID);
llMessageLinked(LINK_DIALOG,NOTIFY_OWNERS, "%WEARERNAME% has detached me while locked at "+GetTimestamp()+"!",kID);
} else {
if (g_bDetached)
llMessageLinked(LINK_DIALOG,NOTIFY_OWNERS, "%WEARERNAME% has re-attached me at "+GetTimestamp()+"!",kID);
@@ -670,7 +656,7 @@ default {
if (compareVersions(sWebVersion, g_sCollarVersion)) {
llOwnerSay("An update is available!");
// Fetch a list of distribution sites:
g_kHttpDistsites = llHTTPRequest("https://raw.githubusercontent.com/lickx/oscollar-dev/stable/web/distsites", [], "");
g_kHttpDistsites = llHTTPRequest("https://git.lotix.org/lotek/oscollar/raw/branch/master/web/distsites", [], "");
} else
llOwnerSay("You are using the most recent version");
} else if (kID == g_kHttpDistsites) {

View File

@@ -379,8 +379,8 @@ default
llMessageLinked(LINK_DIALOG, NOTIFY, "0"+"If you would like to stop the animation early, say /" + (string)g_iStopChan + g_sStopString + " to stop.", g_kPartner);
string sText = llList2String(g_lAnimSettings, (g_iCmdIndex*4) + 3);
if (sText != "" && g_iVerbose) {
sText = osReplaceString(sText, "_PARTNER_" ,g_sPartnerName, -1, 0);
sText = osReplaceString(sText, "_SELF_", "%WEARERNAME%", -1, 0);
sText = llReplaceSubString(sText, "_PARTNER_" ,g_sPartnerName, 0);
sText = llReplaceSubString(sText, "_SELF_", "%WEARERNAME%", 0);
llMessageLinked(LINK_DIALOG,SAY, "0"+sText, "");
}
if (g_fTimeOut > 0.0) {

View File

@@ -2,7 +2,7 @@ SCRIPT|oc_root
SCRIPT|oc_update
SCRIPT|oc_stealth
SCRIPT|oc_lock
ITEM|.license
ITEM|.help
ITEM|OsCollar License
ITEM|OsCollar Help
ITEM|chain
ITEM|rope

View File

@@ -12,8 +12,8 @@ SCRIPT|oc_resizer
SCRIPT|oc_rlvsuite
SCRIPT|oc_themes
SCRIPT|oc_titler
ITEM|OsCollar License
ITEM|OsCollar Help
ITEM|.license
ITEM|.help
ITEM|sound_lock
ITEM|sound_unlock
ITEM|leash_chain

View File

@@ -1,5 +0,0 @@
## The Owner HUD
###### A graphical user interface for ease of access to OsCollar scripted devices.
Formerly "OpenCollar Owner HUD", this variation is vastly slimmed down and more resource friendly. There are also a lot more buttons on the device itself. The new button textures can be found in the ./res directory of this repo; they are created by and used with permission from Wendy Starfall.

5
src/remote/README.md Normal file
View File

@@ -0,0 +1,5 @@
## The OsCollar Remote
###### A graphical user interface for ease of access to OsCollar scripted devices.

View File

@@ -18,8 +18,6 @@
// along with this script; if not, see www.gnu.org/licenses/gpl-2.0
//
// Debug(string sStr) { llOwnerSay("Debug ["+llGetScriptName()+"]: " + sStr); }
//chopped from the OpenCollar_Dialog script in slimmer shape for the Owner HUD june 2015 Otto (garvin.twine)
//an adaptation of Schmobag Hogfather's SchmoDialog script

View File

@@ -18,8 +18,6 @@
// along with this script; if not, see www.gnu.org/licenses/gpl-2.0
//
// Debug(string sStr) { llOwnerSay("Debug ["+llGetScriptName()+"]: " + sStr); }
//Adjusted to OpenCollar name convention und format standards June 2015 Otto (garvin.twine)
//Updated Romka(romka.swallowtail)
@@ -292,7 +290,7 @@ DoMenu(string sMenu)
lUtils = ["Reset", UPMENU];
}
if (sMenu == g_sHudMenu) { // Main
sPrompt = "\nCustomize your Owner HUD!";
sPrompt = "\nCustomize your Remote!";
lButtons = ["Rows: "+(string)g_iRows] ;
if (g_iRows > 1) lButtons += llList2List(["Columns >","Alternate >"], g_iColumn, g_iColumn) ;
else lButtons += [" - "] ;
@@ -340,7 +338,7 @@ StoreSettings()
// Store button order:
integer idx = llListFindList(g_lButtons, "Hudmenu");
if (idx != -1) {
string sOrder = osReplaceString(llList2CSV(g_lPrimOrder), " ", "", -1, 0);
string sOrder = llReplaceSubString(llList2CSV(g_lPrimOrder), " ", "", 0);
sOldSettings = llList2String(llGetLinkPrimitiveParams(idx, [PRIM_DESC]), 0);
if (sOldSettings != sOrder) llSetLinkPrimitiveParamsFast(idx, [PRIM_DESC, sOrder]);
}
@@ -416,7 +414,7 @@ default
string sButton = llList2String(lParams, 1);
//integer iPage = llList2Integer(lParams, 2);
if (g_sCurrentMenu == g_sHudMenu) { // -- Inside the 'Options' menu, or 'submenu'
// If we press the 'Back' and we are inside the Options menu, go back to OwnerHUD menu
// If we press the 'Back' and we are inside the Options menu, go back to Remote menu
if (sButton == UPMENU) {
llMessageLinked(LINK_SET, SUBMENU, g_sParentMenu, kID);
return;

View File

@@ -18,11 +18,9 @@
// along with this script; if not, see www.gnu.org/licenses/gpl-2.0
//
// Debug(string sStr) { llOwnerSay("Debug ["+llGetScriptName()+"]: " + sStr); }
//merged HUD-menu, HUD-leash and HUD-rezzer into here June 2015 Otto (garvin.twine)
string g_sVersion = "2023.01.19";
string g_sVersion = "2026.01";
list g_lPartners;
list g_lNewPartnerIDs;
@@ -57,7 +55,7 @@ integer ACC_CMD = 7000;
integer DIALOG = -9000;
integer DIALOG_RESPONSE = -9001;
integer DIALOG_TIMEOUT = -9002;
integer CMD_OWNER_HUD = 10000;
integer CMD_REMOTE = 10000;
integer UPDATE = 5555;
string UPMENU = "BACK";
string g_sListPartners = "List";
@@ -191,7 +189,7 @@ AddPartner(string sID)
if (llListFindList(g_lPartners, [sID]) != -1) return;
if ((key)sID != NULL_KEY) {//don't register any unrecognised
g_lPartners += [sID];//Well we got here so lets add them to the list.
llOwnerSay("\n\n"+NameURI(sID)+" has been registered.\nFor easy selection, add a photo or texture to the Owner HUD called '"+PlainName((key)sID)+"'.\n");//Tell the owner we made it.
llOwnerSay("\n\n"+NameURI(sID)+" has been registered.\nFor easy selection, add a photo or texture to the Remote called '"+PlainName((key)sID)+"'.\n");//Tell the owner we made it.
StorePartners();
}
}
@@ -217,7 +215,7 @@ Dialog(string sPrompt, list lChoices, list lUtilityButtons, integer iPage, strin
MainMenu()
{
string sPrompt = "\n𝐎 𝐒 𝐂 𝐨 𝐥 𝐥 𝐚 𝐫 Owner HUD\t"+g_sVersion;
string sPrompt = "\nOsCollar - Remote\t"+g_sVersion;
sPrompt += "\n\nSelected Partner: "+NameURI(g_sActivePartnerID);
list lButtons = g_lMainMenuButtons + g_lMenus;
Dialog(sPrompt, lButtons, [], 0, g_sMainMenu);
@@ -297,7 +295,6 @@ NextPartner(integer iDirection, integer iTouch)
integer iAt = llSubStringIndex(llKey2Name((key)g_sActivePartnerID), "@");
// Convert 'First.Last @grid:port' to 'First Last' if hypergrid name found
if (iDot > 0 && iAt > 0) sActivePartnerName = llGetSubString(sActivePartnerName, 0, iDot-1) +" "+llGetSubString(sActivePartnerName, iDot+1, iAt-2);
llOwnerSay("calling SetPicturePrim for "+sActivePartnerName);
if (g_iPicturePrim) SetPicturePrim(sActivePartnerName);
} else if (g_sActivePartnerID == g_sAllPartners)
if (g_iPicturePrim) llSetLinkPrimitiveParamsFast(g_iPicturePrim,[PRIM_TEXTURE, 1, g_sTextureALL,<1.0, 1.0, 0.0>, ZERO_VECTOR, 0.0]);
@@ -321,8 +318,6 @@ default {
state_entry() {
g_kOwner = llGetOwner();
if (llGetInventoryType("oc_installer_sys") == INVENTORY_SCRIPT) return;
string sObjectName = osReplaceString(llGetObjectName(), "\\d+\\.\\d+\\.?\\d+", g_sVersion, -1, 0);
if (sObjectName != llGetObjectName()) llSetObjectName(sObjectName);
llSleep(1.0);//giving time for others to reset before populating menu
g_iListener = llListen(PersonalChannel(g_kOwner, 0), "", "", ""); //lets listen here
g_iCmdListener = llListen(g_iChannel, "", g_kOwner, "");
@@ -330,7 +325,7 @@ default {
g_iPicturePrim = PicturePrim();
LoadPartners();
if (llGetListLength(g_lPartners) == 0) {
llOwnerSay("\n\nYou are probably wearing this Owner HUD for the first time. I'm opening the menu where you can manage your partners. Make sure that your partners are near you and click Add to register them. To open the menu again, please select the gear (⚙) icon on your HUD.\n");
llOwnerSay("\n\nYou are probably wearing this Remote for the first time. I'm opening the menu where you can manage your partners. Make sure that your partners are near you and click Add to register them. To open the menu again, please select the gear (⚙) icon on your HUD.\n");
}
NextPartner(0,0);
MainMenu();
@@ -400,7 +395,7 @@ default {
}
lParams = [];
} else if (iNum == SUBMENU && sStr == "Main") MainMenu();
else if (iNum == CMD_OWNER_HUD) SendCollarCommand(sStr);
else if (iNum == CMD_REMOTE) SendCollarCommand(sStr);
else if (iNum == UPDATE) {
if (sStr != "") g_lPartners = llCSV2List(sStr);
else llMessageLinked(iSender, UPDATE+1, llList2CSV(g_lPartners),"");

View File

@@ -614,8 +614,8 @@ SetState(integer iState) {
g_kOwnerRequestHandle = llRequestAgentData(g_kCageOwnerKey, DATA_ONLINE);
} else if (iState == iWARNING) {
if (g_iWarningTime > 1) {
string sMsg = osReplaceString(g_sWarningMessage, "@", Name(g_kWearer), -1, 0);
sMsg = osReplaceString(sMsg, "#", (string)g_iWarningTime, -1, 0);
string sMsg = llReplaceSubString(g_sWarningMessage, "@", Name(g_kWearer), 0);
sMsg = llReplaceSubString(sMsg, "#", (string)g_iWarningTime, 0);
string sObjectName = llGetObjectName();
llSetObjectName(g_sPluginTitle);
llSay(0, sMsg);

View File

@@ -245,7 +245,7 @@ default
if(k!=menuUser)
{
// calculate collar channel per victim and add a listener
channel=PersonalChannel((string)k,0);
channel=PersonalChannel((string)k,1234);
listeners+=
[
llListen(channel,"",NULL_KEY,"")

1
web/ao Normal file
View File

@@ -0,0 +1 @@
2025.12

View File

@@ -1 +1 @@
2023.09.06
2026.02

View File

@@ -1,8 +1,4 @@
Get an updater at:
ArcadiaShop
hop://hg.osgrid.org:80/ArcadiaShop/271/441/37
Kinky Hub
hop://hg.tamai.nl:80/Eternal/206/190/20
TBD

1
web/remote Normal file
View File

@@ -0,0 +1 @@
2026.01