Combined LockMeister Handle Post and Collar

From Second Life Wiki
Revision as of 12:20, 31 January 2010 by Tianna Violet (talk | contribs) (Created page with '{{LSL Header}} == LockMeister+ Handles, Posts and Collar == === Overview === The LockMeister system protocol for cuffs, collars and leash h...')
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

LockMeister+ Handles, Posts and Collar

Overview

The LockMeister system protocol for cuffs, collars and leash handles has been around from many years and in that time a number of extensions to the protocol have been added and have been documented.

LockMeister+ is an effort to bring together those extensions and define a set of expected behaviours to allow greater interoperability and functionality between devices that use the extended protocol. The aims of LockMeister+ are:

  • To gather up the existing extensions into a new extended protocol.
  • To add functionality that can be gained from combining those extensions.
  • To define the expected behaviour for a number if classes of devices.
  • To be 100% backwards compatible with what has gone before.

The LockMeister+ Handle reference script

The LockMeister+ Handle:

  • MUST respond to basic "handle" messages with an "ok".
  • MUST implement the "here" and "gone" messages.

<lsl>/////////////////////////////////////////////////////////////////////// // // Lockmeister+ Handle Reference Script // // Tianna Violet // 20 Jan 2010 // // http://wiki.secondlife.com/wiki/LSL_Protocol/LockMeister_System // // Note that this script will only work in the ROOT PRIM ONLY as it // uses an "attach" event which aren't handled properly in child prims. /////////////////////////////////////////////////////////////////////// // The lockmeister name of the handle. string LOCKMEISTER_NAME = "handle"; /////////////////////////////////////////////////////////////////////// string gCuffMessage;

default { state_entry() { gCuffMessage = (string) llGetOwner() + LOCKMEISTER_NAME; llListen(-8888, "", NULL_KEY, ""); }

attach(key id) { string message;

message = " gone"; if (id) { gCuffMessage = (string) llGetOwner() + LOCKMEISTER_NAME; message = " here"; } llSay(-8888, gCuffMessage + message); // send the "here" and "gone" message }

listen(integer channel, string name, key id, string message) { if (message == gCuffMessage) { llSay(-8888, gCuffMessage + " ok"); // the basic response return; } } } </lsl>

The LockMeister+ Post reference script

The LockMeister+ Post:

  • MUST send a "posk ok" message when the post is touched the key being the toucher's UUID
  • MUST respond to basic "handle" messages where the message key is its own UUID with an "ok".
  • SHOULD contain 'post' in its name and script SHOULD be in the root prim so that a post that is found through a scan of nearby objects can be confirmed as a LockMeister+ post.

<lsl>/////////////////////////////////////////////////////////////////////// // // Lockmeister+ Post Reference Script // // Tianna Violet // 21 Jan 2010 // // http://wiki.secondlife.com/wiki/LSL_Protocol/LockMeister_System /////////////////////////////////////////////////////////////////////// // The lockmeister name of the leash. string LOCKMEISTER_NAME = "handle"; ///////////////////////////////////////////////////////////////////////

default { state_entry() { llListen(-8888, "", NULL_KEY, ""); }

touch_start(integer total_number) { llSay(-8888, (string) llDetectedKey(0) + "post ok"); }

listen(integer channel, string name, key id, string message) { string postMessage;

postMessage = (string) llGetKey() + LOCKMEISTER_NAME; if (message == postMessage) { llSay(-8888, postMessage + " ok"); return; } } } </lsl>

The LockMeister+ Collar reference script

The LockMeister+ Collar:

  • MUST look for a handle using the basic LockMeister query/response.
  • MUST monitor "here" messages in order to connect to a handle should it appear.
  • MUST monitor the "gone" event to remove the leash should the handle disappear.
  • MUST send out new target requests should the current handle disappear.
  • MUST support the "post ok" message and basic query/response to the post.
  • SHOULD support basic LockMeister query/responses for the "collar" attach point.
  • SHOULD reconnect the leash when the AV logs on if the attach point is still available.
  • SHOULD support one touch transfer of the leash from the leash holder to a post.

<lsl>/////////////////////////////////////////////////////////////////////// // // Lockmeister+ Collar Reference Script // // Tianna Violet // 31 Jan 2010 // // http://wiki.secondlife.com/wiki/LSL_Protocol/LockMeister_System // // the collar reponds on channel 53 // // /53xxleash - grab the leash // /53xxunleash - unleash // /53xxleashpost - leash to a previously touch post // // xx = the initials of the wearer or * to effect all collars // // Note that this script will only work in the ROOT PRIM ONLY as it // uses an "attach" event which aren't handled properly in child prims. /////////////////////////////////////////////////////////////////////// // The lockmeister name of the collar. string LOCKMEISTER_NAME = "collar"; string gCuffMessage; key gLeashHolder; key gCurrentTarget; key gPostToucher; key gPost; key gPending; integer isLeashed; string gPrefix;


// Who has access to the collar // This is where the owner list etc is checked integer hasAccess(key id) { return TRUE; // everyone has access }

// Start or update the particle stream updateParticles() { llParticleSystem( [PSYS_PART_START_SCALE, <0.1, 0.1, 0>, PSYS_PART_END_SCALE, <1, 1, 0>, PSYS_PART_START_COLOR, <1, 1, 1>, PSYS_PART_END_COLOR, <1, 1, 1>, PSYS_PART_START_ALPHA, 1.0, PSYS_PART_END_ALPHA, 1.0, PSYS_SRC_TEXTURE, "1ffb37fa-2fc1-dbec-d8ea-0607583a03c6", PSYS_SRC_BURST_PART_COUNT, 1, PSYS_SRC_BURST_RATE, 0.0, PSYS_PART_MAX_AGE, 2, PSYS_SRC_MAX_AGE, 0.0, PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_DROP, PSYS_SRC_BURST_RADIUS, 0.5, PSYS_SRC_INNERANGLE, 0.0, PSYS_SRC_OUTERANGLE, 0.0, PSYS_SRC_OMEGA, <0, 0, 0>, PSYS_SRC_ACCEL, <0, 0, -0.7>, PSYS_SRC_BURST_SPEED_MIN, 1000.0, PSYS_SRC_BURST_SPEED_MAX, 1000.0, PSYS_SRC_TARGET_KEY, gCurrentTarget, PSYS_PART_FLAGS, PSYS_PART_FOLLOW_VELOCITY_MASK | PSYS_PART_FOLLOW_SRC_MASK | PSYS_PART_TARGET_POS_MASK]); }

setPrefix() { list l;

l = llParseString2List(llToLower(llKey2Name(llGetOwner())), [" "], []); gPrefix = llGetSubString(llList2String(l, 0), 0, 0) + llGetSubString(llList2String(l, 1), 0, 0); }

releash() { if (isLeashed) { if (gLeashHolder) { llSensor("", gLeashHolder, AGENT, 30.0, PI); } else { gPending = gCurrentTarget; llSay(-8888, ((string) gPending + "handle")); } llParticleSystem([]); isLeashed = 0; gLeashHolder = NULL_KEY; gCurrentTarget = NULL_KEY; } }

default { state_entry() { gLeashHolder = NULL_KEY; gCurrentTarget = NULL_KEY; gPostToucher = NULL_KEY; gPost = NULL_KEY; gPending = NULL_KEY; isLeashed = 0; setPrefix(); gCuffMessage = (string) llGetOwner() + LOCKMEISTER_NAME; llListen(-8888, "", NULL_KEY, ""); llListen(53, "", NULL_KEY, ""); }

listen(integer channel, string name, key id, string message) { list commands = ["leash", "unleash", "leashpost"]; list responses = ["handle ok", "handle here", "handle gone", "post ok"]; key target; integer index; integer len;

if (channel == 53 && hasAccess(id)) { message = llStringTrim(llToLower(message), STRING_TRIM); index = -1; if (llGetSubString(message, 0, 0) == "*") { index = 1; } else { len = llStringLength(gPrefix); if (llGetSubString(message, 0, len - 1) == gPrefix) { index = len; } } if (~index) { index = llListFindList(commands, [llGetSubString(message, index, -1)]); } if (~index) { gPending = NULL_KEY; if (!index) { if (gLeashHolder == NULL_KEY) { gLeashHolder = id; gCurrentTarget = id; isLeashed = 1; updateParticles(); llSay(-8888, ((string) id) + "handle"); gPending = id; } } if (gLeashHolder == NULL_KEY || gLeashHolder == id) { if (index == 1) { gLeashHolder = NULL_KEY; isLeashed = 0; llParticleSystem([]); } if (index == 2) { if (gPost != NULL_KEY && gPost != gCurrentTarget && gPostToucher == id) { llSay(-8888, ((string) gPost) + "handle"); gPending = gPost; } } } } }

if (channel == -8888) { if (message == gCuffMessage) { llSay(-8888, gCuffMessage + " ok"); // the basic response return; } target = (key) llGetSubString(message, 0, 35); if (target) { index = llListFindList(responses, [llGetSubString(message, 36, -1)]); if (~index) { if (!index && target == gPending) { gCurrentTarget = id; isLeashed = 1; if (id == target) { gLeashHolder = NULL_KEY; } gPending = NULL_KEY; updateParticles(); } if (target == gLeashHolder) { if (index == 1 && gCurrentTarget != id) { gCurrentTarget = id; isLeashed = 1; gPending = NULL_KEY; updateParticles(); } if (index == 2 && gCurrentTarget == id) { releash(); } } if (index == 3) { if (target == gLeashHolder || (gLeashHolder == NULL_KEY && hasAccess(target))) { gPostToucher = target; gPost = id; if (gLeashHolder != NULL_KEY && gPost != gCurrentTarget) { gLeashHolder = NULL_KEY; gCurrentTarget = gPost; isLeashed = 1; gPending = NULL_KEY; updateParticles(); } } } } } }

}

attach(key id) { string message;

message = " gone"; if (id) { gCuffMessage = (string) llGetOwner() + LOCKMEISTER_NAME; message = " here"; if (isLeashed) { releash(); } } llSay(-8888, gCuffMessage + message); // send the "here" and "gone" message }

sensor(integer total_number) { gLeashHolder = llDetectedKey(0); gCurrentTarget = gLeashHolder; isLeashed = 1; updateParticles(); llSay(-8888, ((string) gLeashHolder) + "handle"); gPending = gLeashHolder; }

on_rez(integer start_param) { setPrefix();

       }

} </lsl>