User:Kitty Barnett/RLV

From Second Life Wiki
Revision as of 13:49, 3 April 2009 by Kitty Barnett (talk | contribs)
Jump to navigation Jump to search

Restrained Life Alternative (RLVa)

RLVa is an alternative - from scratch - implementation of the Restrained Life API, released under the GPL.

Disclaimer

All the code was written in just short of two weeks and my primary goal up until now has been to just get the entire API set implemented. While there shouldn't be anything in it that would cause harm to your account or inventory, until I've run over all the code and verified just what works and what doesn't I would stress that if you plan on compiling it that you treat it as you would anything else "alpha" so use a (disposable) alt to test it with, or log on to the beta grid instead of the main grid.

Compiling

I did run a test compile after applying the patch to the "clean" SL 1.22.11 source and while that worked for me, your mileage may vary.

I don't think I used anything particularly crazy, but I imagine some warnings/errors would come up if you try to compile it on Linux or Mac. Even a list of compiler warnings/errors is helpful if you wouldn't mind supplying it :).

Changes

Behaviour was changed where I felt it made sense, and was still within the "spirit" of the restriction. There is no attempt at making a statement and anything is open to discussion really. If I changed something it was either because I felt it would enable functionality without creating a loophole to bypass the permission.

I'll put my notes online sooner or later, but until then here's a change list (compared to RLV 1.16.1):

@detach=n

  • behaviour : child prims can issue @detach=n (unintended feature)
  • behaviour : can't open scripts inside of a locked attachment (causes less confusion)
  • behaviour : can't drag items out of a locked attachment (defeats not being able to read notecards inside of one)
  • visual cue: inventory context menus are disabled rather than hidden ("Detach from Yourself"/"Wear"/etc)
  • visual cue: locked attachment points are disabled on the Take Off > Detach > ... avie pie menu
  • visual cue: locked attachment points are disabled on the Attach > ... object/prim pie menu
  • visual cue: locked attachment points are disabled in the Edit "Attach Object" and "Detach Object" main menu
  • behaviour : allow drop of multiple selected attachments as long as none of them is a locked attachment
  • behaviour : allow use of View / Show HUD Attachments as long as no HUD attachment is locked on
  • behaviour : allow use of Advanced / Hide Selected, but it can't be used to hide locked HUD attachments

@redirchat=add

  • behaviour : acts consistent with @sendchat: if a non-emote would have been filtered by @sendchat then it is redirected; if not then it won't be redirected, but will be subject to @sendchat filtering (allows for short script triggers like "/ao off" and "/hug XX" under @redirchat)

@sendim=n

  • behaviour : sending IMs to chat conferences is allowed as long as every participant is a sendim exception

@recvim=n

  • behaviour : receiving IMs from chat conferences is allowed as long as the participant is a recvim exception

@recvchat=n

  • behaviour : your own chat isn't filtered

@sittp=n

  • behaviour : side restrictions only apply if *you* are sitting on the object, rather than if *someone* is sitting on it

@rez=n

  • visual cue: show "not allowed" cursor when attempting to rez an object
  • visual cue: disable "Create" on pie menu (sort of - see above)
  • behaviour : tentatively allowed deletion of objects not owned by the avie (unless group-owned since: deed to a group -> return -> returns to avie's own inventory == take)
  • behaviour : tentatively allowed return of objects not owned by the avie (group-owned exception applies)

@addoutfit=n

  • visual cue: dragging/dropping a wearable onto your avie will show the proper cursor (ie @addoutfit:shirt=n will show the "accepted" cursor for everything; but will show the "locked" cursor on a shirt layer wearable)

@remoutfit=n

  • visual cue: locked clothing layers are properly grayed out on the avie right-click / Take Off > / Clothes / pie menu
  • visual cue: locked clothing layers are properly grayed out on the Edit / Take Off Clothing sub menu
  • visual cue: dragging/dropping a wearable onto your avie will show the proper cursor (ie @addoutfit:shirt=n will show the "accepted" cursor for everything; but will show the "locked" cursor on a shirt layer wearable if you're currently wearing one)

@acceptpermission=n

  • behaviour : only "take control" and "attach" permissions are granted, all others require user consent (prevents grabbing permissions not part of the auto-accept set)

@denypermission=n

  • behaviour : only TAKE_CONTROLS and ATTACH permissions are auto-declined, everything else is subject to user consent

@showinv=n

  • visual cue: inventory button becomes disabled if you can't access inventory

@unsit=n

  • behaviour : side restrictions only apply if *you* are sitting on the object, rather than if *someone* is sitting on it
  • behaviour : allows going into appearance if not currently sitting

@unsit=force

  • behaviour : tentatively allow if the object that issues the command is the only one that would prevent success (precedent in @sittp and @tpto in RLV 1.16.1)

@showminimap=n

  • visual cue: Mini Map button disabled on the toolbar when restricted

@showworldmap=n

  • map button disabled on the toolbar when restricted

@fartouch=n

  • visual cue: don't show "Touch" cursor when you're out of touch range
  • behaviour : can drag-select objects (subject to the 1.5m limit)
  • behaviour : rezzing new prims is limited to within a 1.5m radius around the avie
  • behaviour : walking away from a selected prim will deselect it when distance >1.5m
  • behaviour : dragging a prim to a distance >1.5m away from the avie will result in it snapping back

@showloc=n

  • behaviour : tentatively allow viewing the world map, but hide any mention of surrounding sim names
  • behaviour : tentatively allow access to "About Land" if you have the power to return prims
  • behaviour : tentatively allow access to "Estate" if you're an estate manager

@shownames=n

  • visual cue : disable the profile button in the Build window if the name was filtered
  • consistency: don't filter the owner name if the owner is a group
  • consistency: don't filter the owner name if the selection has multiple owners
  • behaviour  : allow Inspect, but filter the owner name (see the Build floater)
  • behaviour  : allow dropping of inventory onto avies directly (accepted/declined notices are filtered anyway)

(I just put in @showloc=n and @shownames=n in today and I do know I missed some revealing that should/will be caught)

ToDo

Plenty :p.

I do want to take a break this weekend (or Saturday at least) and there's always less time to get something done during the week but my current "to do soon" list:

  • code review
  • one by one review of every command and run through the tests for every command to make sure it actually works
  • @showloc=n and @shownames=n definitely still need some work (and @fartouch=n might as well, I forgot now :()
  • resolve all "TODO" code comments
  • implement some minor things I forgot about (particles should be hidden for RLV commands, rename inventory items on wear if descendant of the shared root, ...)
  • get it ready for 1.23 in trunk (probably first on the list)

I hope to get the above done by the end of next week at which point the implementation should be stable enough for serious use :).

Extensions

The problem with adding extra commands is always that while there's little risk of conflicts in Linden written code, the handler is likely to see some changes which might conflict.

If you're adding new commands look at the RlvObserver class (and RlvGetSet which implements the get/setdebug_XXX and get/setenv_XXX pseudo-commands as an RlvObserver class) which is there to solve that exact problem :).

Download

RLVa 0.1.0b: http://kitty.catznip.com/rlva/RLVa-0.1.0b.patch

My "behaviour notes": http://kitty.catznip.com/rlva/notesBehaviour.h

[ Note that I didn't originally intend to make those public and I don't have time to "PR filter" them right now, so if I sound frustrated or silly, I apologize :o ]

RLV "proper"

Below is a list of various bugs I found in "RLV proper" while I was still tinkering with that and that I either have the code to create a path from, or am willing to create a patch for on demand. Since I have my own implementation now, and because of the official "no integrating any patch coming from other people" policy it just is not worthwhile to spend days writing and creating individual patches until I know someone is actually interested in looking at one/some in particular.

In most cases (the "RLV didn't kick in" bug being the exception) the fix is minor/trivial and doesn't in any way alter behaviour/whatever so if anyone is interested, please just give me a nudge.

@chatshout=n and @chatnormal=n limit the range of viewer replies [fixed]

Repro:

  • create/rez a prim a with a listener script on channel 500 (any positive channel will do)
  • walk >20m away from the "listener prim"
  • issue @getoutfit=500 (getoutfit is just an example) and verify that you receive notice of the response
  • now issue @chatshout=n [or @chatnormal=n]
  • issue @getoutfit=500 again

The response range will be limited to 20m (under @chatshout=n) or 10m (under @chatwhisper=n) and while scripts inside attachment are covered either way, it does impact relays.

(This also limits the "volume" on @redirchat)

"RLV didn't kick in"

The sim will not sync chat and initial "object update" messages so there is a "race condition" (for lack of a better description) between RRInterface::handleCommand() and RRInterface::garbageCollector().

handleCommand will accept commands from object/attachments that don't exist (from the viewer's point of view) but the GC will discard restrictions on attachments/objects that aren't in the (viewer's) object list.

This can occur "naturally", even if scripts delay a few seconds before issuing their restrictions. It most commonly happens on relogs - on one sim I go to it happens almost every relog -, but can happen while attaching mid-session (particularly when attaching after a tp and before most has rezzed).

Can also be used as a way to circumvent restrictions by clearing cache, setting the bandwidth slider to 50, relogging into a "busy" area and restoring bandwidth to normal after the GC removed restrictions. Higher fps increases the chance since the GC runs every 500 frames.

Trimmed debug log (extra code added to report on object creation/attaching):

2009-03-20T10:49:17Z INFO: RRInterface::handleCommand: [66e0d23e-79a4-1bd4-f9b0-7348efe1be7e]  [version]  [] [234]
2009-03-20T10:49:17Z INFO: RRInterface::answerOnChat: /234 RestrainedLife viewer v1.16.1 (SL 1.22.11)
2009-03-20T10:49:17Z INFO: RRInterface::handleCommand: [66e0d23e-79a4-1bd4-f9b0-7348efe1be7e]  [detach]  [] [n]
2009-03-20T10:49:17Z INFO: RRInterface::add: 66e0d23e-79a4-1bd4-f9b0-7348efe1be7e       detach      
2009-03-20T10:49:17Z INFO: RRInterface::isAllowed: 66e0d23e-79a4-1bd4-f9b0-7348efe1be7e      detach
2009-03-20T10:49:17Z INFO: RRInterface::isAllowed:   => allowed. 
 
2009-03-20T10:49:24Z INFO: RRInterface::garbageCollector: 66e0d23e-79a4-1bd4-f9b0-7348efe1be7e not found => cleaning... 
2009-03-20T10:49:24Z INFO: RRInterface::clear: 66e0d23e-79a4-1bd4-f9b0-7348efe1be7e   /   
2009-03-20T10:49:24Z INFO: RRInterface::clear:   checking detach
2009-03-20T10:49:24Z INFO: RRInterface::clear: detach => removed. 
 
2009-03-18T10:49:43Z INFO: LLViewerObjectList::createObject: Adding 66e0d23e-79a4-1bd4-f9b0-7348efe1be7e
2009-03-18T10:49:43Z INFO: LLVOAvatar::addChild: Lazy attach for 66e0d23e-79a4-1bd4-f9b0-7348efe1be7e
2009-03-18T10:49:43Z INFO: LLVOAvatar::attachObject: Attaching 66e0d23e-79a4-1bd4-f9b0-7348efe1be7e

(Fix retains y|n|add|rem commands until the viewer received the intial object update message)

@remoutfit:option=force allows removal of body parts (skin/shape/hair/eyes) [fixed]

@unsit=force won't always unsit [fixed]

Simplified LLAppViewer::mainLoop() flow chart:
     ...
 1 ) gViewerWindow->mWindow->gatherInput();
     ...
 2 ) idle();
       ....
 2a)   BOOL flags_changed = gAgent.controlFlagsDirty() ...
       if (flags_changed || (agent_update_time > (1.0f / (F32) AGENT_UPDATES_PER_SECOND)))
       ...
 2b)   idleNetwork();
         ...
         while (gMessageSystem->checkAllMessages(frame_count, gServicePump)) 
           ..
           process_chat_from_simulator invoked by message handler <- RLV command

Clicking the stand up button always succeeds because LLOverlayBar::onClickStandUp() gets called by the input handlers as part of (1) and the control flags update get sent back to the sim as part of (2a).

The reason why LLOverlayBar::onClickStandUp() fails as an RLV command is because it's possible for idleNetwork() to process an "AgentUpdate" message right after the flag is set which will reset the AGENT_CONTROL_STAND_UP flag since it's the the sim that's authorative for that one and the "stand up" request never gets sent.

@shownames=n hash overflow [fixed]

Hash = (ASCII value of the third letter + length of the name) mod 28

Kitty Barnett -> at(3) = 116 Kitty Barnett -> length = 13

(116 + 13) % 28 = (-127) % 28 = -15 (char is used instead of unsigned char)

End result is that almost everyone who's 3rd letter is >p will become "An unknown person" (seems to be about 25%).

@shownames=n partial circumvention [fixed]

Repro:

  • issue @shownames=n
  • open the Build floater / Edit tool (Ctrl-3)
  • click on a scripted attachment and go to the contents tab
  • right-click on any item in the prim's inventory and Properties
  • the ownername is censored, but clicking the Profile button will work => reveals their name

@showloc=n partial circumvention [fixed]

Repro:

  • issue @showloc=n
  • Advanced / View Admin Options
  • Admin / God Tools => sim name is visible, along with grid position of the sim (latter being a bit more obscure to turn it back into a sim name)

@sendchat=n circumvention [fixed]

Repro:

If you try to use a space the text gets cut off at the first word, but you can use a breaking space (ASCII 160) to bypass that.

@viewnote=n partial circumvention (by design?) [fixed]

Repro:

  • create a new notecard, open it and keep it open
  • issue @viewnote=n
  • Advanced / Debug Settings: make sure ShowNewInventory is set to FALSE (or uncheck "Automatically view after accepting")
  • drag a (full permission) notecard from inventory and drop it on the notecard that is still open
  • click the embedded notecard and it will open

@edit=n circumvention [fixed]

Repro:

  • issue @edit=n
  • right-click on terrain/land and pick "Create" (now we have the build window up)
  • click the Edit tool (pointer icon)
  • select the "Select Texture" tool
  • click on the prim you want to edit

@sendim=n partial circumvention [fixed]

Repro:

  • issue @sendim=n and have 1 exception
  • go to the calling card of the person you're allowed to @sendim (they need to be online)
  • right-click the calling card and Start conference chat -> IM tab opens with Session 1
  • drag the calling card of someone you're *not* allowed to IM (and who is online) into the conference chat
  • you can now send IMs and all the participants will see them

@edit=n "no beacons" circumvention [fixed]

Repro:

  • issue @edit=n
  • Advanced / Debug Settings / Scripttouchbeaon to TRUE (there's a different debug setting for every option)
  • Advanced / Debug Settings / RenderBeacons to TRUE
  • View / Beacons

As long as you don't touch one of the checkboxes, you'll see the beacons.

@detach=n "no script reset" circumvention [fixed]

(The second selected object needs a script in it and can't be @detach=n)

Repro:

  • rez a prim / new script / attach to wherever
  • edit the @detach=n attachment you want to reset
  • shift select the second attachment (the prim you attached in step 1 since we know it has a script in it)
  • Tools / Reset Scripts in Selection

(Also works for Set Scripts to Not Running in Selection and others)

Circumvention of "no interaction" or blindfold HUDs [fixed]

Repro:

  • use cuffs to block interaction (or wear a blindfold that comes with a HUD)
  • close SL, reopen and log on
  • at the "Loading World..." message press Ctrl-Shift-H (unchecks View / Show HUD Attachments)

Circumvention of "no interaction" or blindfold HUDs redux [fixed]

Repro:

  • use cuffs to block interaction (or wear a blindfold that comes with a HUD)
  • Advanced / Hide Selected
  • right-click on the HUD to hide it => you can see, rez (just drop from inventory with an active selection), touch objects (right-click on something in-world and "Touch", etc...

@sendchat=n doesn't allow a gesture to be picked from the gesture dropdown box [fixed]

Repro:

  • issue @sendchat=n
  • pick a gesture from the gesture list

Workaround: type the trigger in chat (since that will work, why not from the drop down?)

@sendchat=n blocks channel text from gestures [fixed]

Repro:

  • issue @sendchat=n
  • create a gesture with a step that says something on a channel (for instance: /123test)
  • click preview (or save it and type the trigger)
  • "..." will appear in main chat

As long as the chat isn't on channel 0 *and* there is no @sendchannel restriction prohibiting chat on that channel, this shouldn't fail.

@unsit=n circumvention (prim is copy and sitting avie is prim owner) [fixed]

Repro:

  • rez a prim and sit on it
  • issue @unsit=n
  • right-click the prim and "Take Copy" => stand up

@unsit=n circumvention redux (modify prim with mod rights to it) [fixed]

(Avie can be the prim owner, or an avie who they have mod rights to, or can be group deeded, or "Share with group")

Repro:

  • rez two prims and link them together
  • issue @unsit=n
  • Edit the linkset and Tools / Unlink => stand up

Minor memory leak in forceAttach [fixed]

@rez=n new prim creation circumvention [fixed]

Repro:

  • rez a prim
  • issue @rez=n
  • right-click the prim and Edit
  • Edit menu / Duplicate => rezzes a copy of the selected prim

@rez=n disables delete for text as well [fixed]

Repro:

  • issue @rez=n
  • select some text (chat bar, notecard, LSL, ...)
  • press Del key (or use Edit / Delete)

Clicking the Inventory toolbar fails to show inventory after "@showinv=y" if "@showinv=n" was received while more than one inventory floater was open [fixed]

Repro:

  • open X inventory windows (with X > 1)
  • issue @showinv=n
  • issue @showinv=y
  • it will take X clicks take open the inventory window (ie if 3 inventory windows were open at the time @showinv=n was issued it will take 3 clicks)

@sendchat=n truncates emotes by number of bytes instead of number of characters [fixed]

Unicode => UTF8 = variable amount of bytes/character

findAttachmentPointFromName can return the wrong attach point

findAttachmentPointFromName returns on the first match (match order is based on the order of the attachment points in avatar_lad.Xml), which gives some very weird behaviour.

The change makes it return the highest index after matching every attachment point name (since the RLV convention is to *append* the attachment point to the object name between parenthesis so the last apparance is most likely to be the correct one).

(Alternate patch: only match text between "(...)" - which is the convention - and significantly reduce false positives)

Examples:

  • Skull Necklace (spine) => attaches to skull (skull is matched before spine) => wrong
  • Skull Necklace (chest) => attaches to chest (chest is matched before skull) => correct
  • ETD Tessa - Chestnut Frosted (skull) => attaches to chest => wrong

"Take Off Items" remains disabled even after no @detach=n objects remain [fixed]

Repro:

  • wear a lockable item and lock it (@detach=n)
  • right-click the folder (Take Off Items disabled => correct)
  • unlock the item (*and* make sure everything else locked is unlocked as well - ie @getstatusall contains no detach)
  • right-click the *same* folder (Take Off Items still disabled => incorrect)

@version (in IM) doesn't respond and is visible to user when they're set "Busy" [fixed]

Locked attachment can be detached if the inventory context menu was open before @detach=n was issued [fixed]

Repro:

  • write a script that issues @detach=n 5 seconds after attaching
  • attach the prim (with the script in it) and then right-click in inventory
  • wait for "Object executes command: @detach=n"
  • pick "Detach from yourself" => item detaches

hasLockedHUDs() is called per frame [fixed]

This isn't really a bug, but it's still better to cache it since it's something that's called per frame.

Checks are made against the first selected object only

Illustrative repro:

  • rez 2 prims and sit on one of them
  • issue @unsit=n
  • right-click and try to delete the prim you're sitting on => fails => correct
  • now first select the prim you're sitting on and then the second prim
  • try to delete => succeeds => not supposed to

(Leads to possible circumvention in places where only LLObjectSelection::getFirst*() or LLObjectSelection::getPrimaryObject() is used to check)

@sittp=n doesn't check for child prim selection [fixed]

Illustrative repro:

  • rez 2 prims and link them together
  • sit on the child prim
  • issue @sittp=n
  • Edit Linked Parts on the prim you're sitting on
  • click New Script in the content tab (or drag/drop anything from inventory) => supposed to be restricted from doing that

(Variation of the above: when "Edit Linked Parts" is used you don't have root nodes to check against)

@acceptpermission=n [fixed]

There's a rare code branch that currently results in automatically granting debit permissions when under @acceptpermission=n.

Also (not sure if it's a bug or intended behaviour) all permissions (except debit) will be automatically granted as long as they're OR'ed with PERMISSION_TAKE_CONTROLS or PERMISSION_ATTACH (so if anyone wanted to get control of someone else's camera they just have to llRequestPermissions(key-here, PERMISSION_TAKE_CONTROLS | PERMISSION_CONTROL_CAMERA); and @acceptpermission=n will silently grant both).