Jump to content

Find and Delete Allegedly Pirated Animations


Missy Restless
 Share

You are about to reply to a thread that has been inactive for 4499 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

This script will find and delete animations that have commonly been distributed in freebie packs but whose creators maintain were not released full-perm. See http://wiki.secondlife.com/w/index.php?title=62_Animation_MLP_Set

A free boxed version of this script is available on the Second Life Marketplace.

 

// CheckCreator - check the creator name against a list of creators who have
//     stated their animations were pirated. Remove any animations by these
//     creators. This script is intended as an aid to content creators who are
//     packaging full-perm animations they have acquired for resale but who
//     wish to avoid redistribution of animations which are allegedly pirated.
//
// Written by Missy Restless (missyrestless at gmail dot com)
//
// Usage: Drop this script into the Contents of a prim containing the
//        animations you wish to distribute/resell. Close the edit window
//        and touch the prim when prompted. The script will chat the
//        names of animations it is deleting as well as the creator's
//        name then the script will delete itself from the prim.
//
// License: You are free to use, modify, copy, and redistribute this script.
//          Please return relevant/useful modifications to Missy Restless.
//
// Info:
//     http://wiki.secondlife.com/w/index.php?title=62_Animation_MLP_Set
//     http://wiki.secondlife.com/wiki/Stroker_Serpentine_Sexgen_Animation_Set
//     http://bit.ly/vlOPKp
//     http://tinyurl.com/5wk3mr2
//

integer numkeys;
integer keynum = 0;
integer numnames = 0;
integer numanims = 0;
string anim_name = "";
string creator_name = "";
string creator_key;
key name_query;
list key_name_pairs = [];
list creator_keys = ["b85e0cdf-4fb2-4383-8b0f-7ff15d01c427",
                     "16c565f2-b5a2-4791-bf8a-24e4599abc28",
                     "02409c8a-508c-4c68-8537-6c4166d2841b",
                     "1f3f9aea-15cd-4a6d-85c2-2e724c8c045c",
                     "32101244-c1f2-45a7-9a1f-96dc463068d8"];
// Uncomment this key and add it to the above list if you also
// wish to remove animations created by Stroker Serpentine
// "368f6798-4d43-4a01-91b0-f6259e279170"
 
default
{
    state_entry()
    {
        if (llGetInventoryType("CheckCreator Package Anchor") == -1) {
            numkeys = llGetListLength(creator_keys);
            // First we walk through the list of keys and get their names
            state getnames;
        }
    }
}

state getnames
{
    state_entry()
    {
        if (keynum < numkeys) {
            creator_key = llList2String(creator_keys, keynum);
            name_query = llRequestAgentData((key)creator_key, DATA_NAME);
        }
        else
            state doit;
    }

    dataserver(key queryid, string data)
    {
        if (name_query == queryid)
        {
            creator_name = data;
            key_name_pairs += [creator_key, creator_name];
            keynum++;
            if (keynum == numkeys)
                state doit;
            else
                state default;
        }
    }
}

state doit
{
    state_entry()
    {
        numanims = llGetInventoryNumber(INVENTORY_ANIMATION);
        llOwnerSay("CAUTION: Once removed the items are gone forever, they do not return to your inventory. Be careful with no copy items.\n");
        llOwnerSay("\nTouch the prim to begin checking and removing potentially pirated animations.");
    }

    touch_start(integer num_detected)
    {
        key         Creator = "";
        integer     i = 0;
        integer     j = 0;
        integer     index;
        integer     removed = 1;

        for(i=0; i<num_detected; i++) {
            if (llGetOwner() == llDetectedKey(i)) { // Only owner can do this
                llOwnerSay("\nChecking " + (string)numanims +
                           " animations in prim inventory");
                while (removed > 0) {
                  removed = 0;
                  for (j=0; j < numanims; j++) {
                    anim_name = llGetInventoryName(INVENTORY_ANIMATION, j);
                    Creator = llGetInventoryCreator(anim_name);
                    creator_name = "";
                    index = llListFindList(key_name_pairs, [(string)Creator]);
                    if (index != -1) {
                        creator_name = llList2String(key_name_pairs, index + 1);
                        llOwnerSay("Removing " + anim_name +
                                   " created by " + creator_name);
                        llRemoveInventory(anim_name);
                        removed++;
                        llSleep(0.4); // Slow down a bit to avoid errors
                    }
                  }
                  llSleep(0.4); // Allow inventory to refresh
                  numanims = llGetInventoryNumber(INVENTORY_ANIMATION);
                }
                llSleep(0.4); // Allow inventory to refresh
                numanims = llGetInventoryNumber(INVENTORY_ANIMATION);
                llOwnerSay("\nExiting. " + (string)numanims +
                           " animations left in prim inventory");
                llRemoveInventory(llGetScriptName());
                return;
            }
        }
    }
}

 

Link to comment
Share on other sites

It's one of those legally careful phrasings. The identified creators have said, I suppose, that none of their animations have been released for use in freebies, and it is a breach of their copyright. I suppose they should know.

I would, myself, be happier if there was some way of checking the claims, such as a pointer to a forum post made by the creator.

I have, in the past, experienced freebie AOs suddenly breaking as a DMCA is acted on by LL. The offending anmations were replaced with placeholder files, in case the original DMCA notice was challenged.

Link to comment
Share on other sites

I think the idea is that, since there's clearly doubt about whether Stroker was within his rights to distribute any of the animations, other than the ones he made, full perms, prudent content creators -- and particularly those who remember the Eva Capalini debacle (which I do, all too well) -- might not want to run the risk of the aggrieved animators filing DMCA take-down notices at some point in the future and LL then deleting the animations from items in customers' inventories.

ETA -- @arabellajones -- if you check the link in the wiki that appears in the script, http://wiki.secondlife.com/wiki/Stroker_Serpentine_Sexgen_Animation_Set, you'll find the views of one of the animators, Corsi Mousehold, on the subject.   Another animator affected, Craig Altman, made his objections to his animations being thus distributed very clear over at SLU.  The script also includes a link to a google spreadsheet I made that lists who made what animation:  http://tinyurl.com/5wk3mr2

Link to comment
Share on other sites

Thank you for this, however it should be noted that a fair number of content creators do in fact own or have obtained licenses for some of the animations in question, either before or after these were publicized as "pirated."  I am referring specifically to several cuddle poses by Craig Altman which were available inworld to buy full perm for content creation for some time (probably still are?), and a set of poses from Johan Durant that a handful of merchants paid good money for licensing after finding out they were not 'freebies.' 

People should be aware that if they see these animations in commercial builds, they are not, in all cases, pirated, but in many cases are properly licensed and are being used according to those licenses.

 

Link to comment
Share on other sites

To clarify a bit, the script is intended primarily as a tool for content creators who are packaging animations they have acquired and wish to remove any animations with uncertain rights of redistribution and resale. If you have animations whose licensing rights are clear then they need not be loaded into the prim used by this script.

The reason something like this script or a tedious manual process is needed is the great deal of uncertainty surrounding much of the content distributed inworld and on the marketplace. Especially freebie content. Even properly licensed content usually is not accompanied with a license so I may purchase something on the marketplace and it might be licensed for redistribution but how am I to know that. Second Life content typically has an "implicit license" derived from the content permissions - if it's full perm then you can redistribute/resell unless otherwise prohibited by the creator (e.g. use these full perm textures in your builds but do not resell them as-is). However, the proliferation of copybot pirated content with full perms undermines the "implicit licensing" model making everything suspect.

Add to this the apparent inability of some business partners to separate their IP properly when the partnership ends and you have a situation where prudent content creators and builders just want to totally avoid content with so much licensing ambiguity. This script is meant to help people filter some of this type of content out of their builds.

 

Link to comment
Share on other sites

Leaving aside the matters discussed by others, the script is simply bad and should not be in the library unless proper modifications as to its efficiency are made.

Let's consider the main loop.

           while (removed > 0) {
removed = 0;
for (j=0; j < numanims; j++) {
anim_name = llGetInventoryName(INVENTORY_ANIMATION, j);
Creator = llGetInventoryCreator(anim_name);
creator_name = "";
index = llListFindList(key_name_pairs, [(string)Creator]);
if (index != -1) {
creator_name = llList2String(key_name_pairs, index + 1);
llOwnerSay("Removing " + anim_name +
" created by " + creator_name);
llRemoveInventory(anim_name);
removed++;
llSleep(0.4); // Slow down a bit to avoid errors
}
}
llSleep(0.4); // Allow inventory to refresh
numanims = llGetInventoryNumber(INVENTORY_ANIMATION);
}

 

Suppose on the first iteration (j=0) in the for (j=0; j < numanims; j++) inner loop animation number 0 meets the criteria and therefore removed. Then former animation number 1 becomes animation number 0 and the number of animations  respectively decreases by one. However on the second iteration (j = 1) animation number 1 is examined (which is the original animation number 2) while the new animation number 0 (former number 1) is simply skipped.

Premises considered the inner loop will skip examining next animation after each removed animation. If there are 2 removable animations in a row, only one will be removed. That is not to mention that the inner loop number of iterations will exceed the number of animations in the content by the number of removed animations and therefore the inner loop may do quite a few unnecessary iterations

The scripter understood the problem and attempting to correct it introduced the while() outer loop. But this is a totally artificial construct. An efficient  correct solution would of course be:

for (j=0; j < numanims; j++) {
anim_name = llGetInventoryName(INVENTORY_ANIMATION, j);
Creator = llGetInventoryCreator(anim_name);
creator_name = "";
index = llListFindList(key_name_pairs, [(string)Creator]);
if (index != -1) {
creator_name = llList2String(key_name_pairs, index + 1);
llOwnerSay("Removing " + anim_name +
" created by " + creator_name);
llRemoveInventory(anim_name);
j--;
numanims--;
llSleep(0.4); // Slow down a bit to avoid errors
}
}

In this code I deleted the line: removed++; because the while(removed>0) outer loop is not needed at all any longer.

Sadly the scripter didn't see this rather obvious solution.

 

 

Link to comment
Share on other sites

Thanks for the improvement. I assume this code is also released under a free license and can be incorporated into future iterations of the CheckCreator script. No thanks for the condescending attitude. Perhaps you are not familiar with open source development and the spirit with which it is conducted. When optimizing anothers initial release of a project it is considered poor behavior to impune the character or ability of the creator and quality of the code. That tends to discourage contribution and collaboration.

At any rate, I will incorporate your improvements after testing.

  • Like 1
Link to comment
Share on other sites

Whadyanno, code reviews may be tough sometimes :)

If you traversed a patricia tree somewhat inefficiently I wouldn't have bothered. But we are talking about basic lists (arrays) management here. Should you implement something like this in C to manage a free memory list, it'd be leaking so bad that you'd run out of memory faster than a speeding bullet :) But even in LSL ppl use library code for all kinds of their own things so basic methods should be very tight. That's my only concern. I've nothing personal against you whatsoever. I don't even know you.

 

Link to comment
Share on other sites

Or just count backwards, that way you don't have to reset the index-pointer whenever you delete something:

 

default{	state_entry(){		integer Counter = llGetInventoryNumber(INVENTORY_ANIMATION);		list creator_keys = ["b85e0cdf-4fb2-4383-8b0f-7ff15d01c427",                     "16c565f2-b5a2-4791-bf8a-24e4599abc28",                     "02409c8a-508c-4c68-8537-6c4166d2841b",                     "1f3f9aea-15cd-4a6d-85c2-2e724c8c045c",                     "32101244-c1f2-45a7-9a1f-96dc463068d8"];		string Name;		while(Counter--){			Name = llGetInventoryName(INVENTORY_ANIMATION, Counter);			if(-1 != llListFindList(creator_keys, [llGetInventoryCreator(Name)])){				llRemoveInventory(Name);			}		}	}}

 

Whatever ... my greater concern is why a DMCA take-down can't just remove all these animations across SL - with both greater reach and greater accuracy (not removing ALL animations by the listed creators for a start).  We may never know ... :-(

Link to comment
Share on other sites

Agreed about counting backwards.   That's always far easier and more efficient when you're deleting stuff.

I think the issue with an automated takedown by LL is that -- at least going by previous attempts to do them -- there's a very serious risk of removing the animations from sexgen products people bought before Stroker distributed the animations full perms, and (at least in the case of Craig Altman's animations) from legitimate products that are nothing to do with sexgen.

Link to comment
Share on other sites

I've updated the free Marketplace boxed CheckCreator script incorporating the improved efficiency counting backwards suggestion made by PeterCanessa. This optimization avoids the possibility of traversing the inventory multiple times and produces the same results. Good suggestion. Here's the current version.

// CheckCreator - check the creator name against a list of creators who have//     stated their animations were pirated. Remove any animations by these//     creators. This script is intended as an aid to content creators who are//     packaging full-perm animations they have acquired for resale but who//     wish to avoid redistribution of animations which are allegedly pirated.//// Written by Missy Restless (missyrestless at gmail dot com)// Modified 26-Dec-2011 - incorporate suggestion from PeterCanessa Oh to count//     backwards in while loop to improve efficiency//// Usage: Drop this script into the Contents of a prim containing the//        animations you wish to distribute/resell. Close the edit window//        and touch the prim when prompted. The script will chat the//        names of animations it is deleting as well as the creator's//        name then the script will delete itself from the prim.//// License: You are free to use, modify, copy, and redistribute this script.//          Please return relevant/useful modifications to Missy Restless.//// Info://     http://wiki.secondlife.com/w/index.php?title=62_Animation_MLP_Set//     http://wiki.secondlife.com/wiki/Stroker_Serpentine_Sexgen_Animation_Set//     http://bit.ly/vlOPKp//     http://tinyurl.com/5wk3mr2//integer numkeys;integer keynum = 0;string creator_name = "";string creator_key;key name_query;list key_name_pairs = [];list creator_keys = ["b85e0cdf-4fb2-4383-8b0f-7ff15d01c427",                     "16c565f2-b5a2-4791-bf8a-24e4599abc28",                     "02409c8a-508c-4c68-8537-6c4166d2841b",                     "1f3f9aea-15cd-4a6d-85c2-2e724c8c045c",                     "32101244-c1f2-45a7-9a1f-96dc463068d8"];// Uncomment this key and add it to the above list if you also// wish to remove animations created by Stroker Serpentine// "368f6798-4d43-4a01-91b0-f6259e279170" default{    state_entry()    {        if (llGetInventoryType("CheckCreator Package Anchor") == -1) {            numkeys = llGetListLength(creator_keys);            // First we walk through the list of keys and get their names            state getnames;        }    }}state getnames{    state_entry()    {        if (keynum < numkeys) {            creator_key = llList2String(creator_keys, keynum);            name_query = llRequestAgentData((key)creator_key, DATA_NAME);        }        else            state doit;    }    dataserver(key queryid, string data)    {        if (name_query == queryid)        {            creator_name = data;            key_name_pairs += [creator_key, creator_name];            keynum++;            if (keynum == numkeys)                state doit;            else                state default;        }    }}state doit{    state_entry()    {        llOwnerSay("CAUTION: Once removed the items are gone forever, they do not return to your inventory. Be careful with no copy items.\n");        llOwnerSay("\nTouch the prim to begin checking and removing potentially pirated animations.");    }    touch_start(integer num_detected)    {        key         Creator = "";        integer     i = 0;        integer     j = 0;        integer     index;        string      name = "";        integer numanims = llGetInventoryNumber(INVENTORY_ANIMATION);        for(i=0; i<num_detected; i++) {            if (llGetOwner() == llDetectedKey(i)) { // Only owner can do this                i = num_detected; // Ignore multiple touches                llOwnerSay("\nChecking " + (string)numanims +                           " animations in prim inventory");                while (numanims--) {                    name = llGetInventoryName(INVENTORY_ANIMATION, numanims);                    Creator = llGetInventoryCreator(name);                    creator_name = "";                    index = llListFindList(key_name_pairs, [(string)Creator]);                    if (index != -1) {                        creator_name = llList2String(key_name_pairs, index + 1);                        llOwnerSay("Removing " + name +                                   " created by " + creator_name);                        llRemoveInventory(name);                        llSleep(0.2); // Slow down a bit to avoid errors                    }                }            }            llSleep(0.4); // Allow inventory to refresh            numanims = llGetInventoryNumber(INVENTORY_ANIMATION);            llOwnerSay("\nExiting. " + (string)numanims +                       " animations left in prim inventory");            llRemoveInventory(llGetScriptName());            return;        }    }}

 

Link to comment
Share on other sites

I remember when I first started, animations  and many many things were being distributed freely to other residents.  You never heard the words about DMCAs or copyright back then.  It is only through lots of debaucles that many learned hard lessons and LL got on the ball to protect creator rights at all. Even some of the LL supported building classes gave away animations in their AO classes that were not Linden created.  I think I still have some of them boxed up somewhere. LL made no mention back then nor educated new users about such things.  It is no wonder we have had so many issues in SL.  I know I was pretty ignorant back then!

When the Capalini instance occured...I can't remember his name...had a lists of OLD full perms animations and it was posted. I found a paper copy the other day but can't find the site again.  It would be nice if there was a repository that would maintain this information for those new to building.  This site that was complied he had gotten in touch with some of the creators who DID give permission for others to use their animations while others did not. 

I think some of the educational places needs to teach about creator rights and the law in regards to SL. It's hard enough to make it as a new person let along get caught up in all the DMCA stuff unwittingly.

Link to comment
Share on other sites

Does this delete them even if I bought them from the original creators?

I've always bought my dance animations direct from Henmations and Sinewave, and 3 other brand shops I can't recall right now. And my AOs come direct from Random Kitten, Kami Hitoe, and one other Japanese maker (this is why at least two of my friend can spot me even on a new alt I've yet to introduce... I'm too predictable...).

- I know for certain that Henmations and Sinewave have been ripped in the past. I recall the big controvery a year or so ago when a few hundred dances from them and some others went up on Marketplace from a thief... I have no idea if any of the ones I bought from their stores were in those packs...

But I know my copies are legit.

 

Link to comment
Share on other sites

Yeah, it will remove anything made by the specified animators, no matter how acquired.  

I think the script is really for people who want to drop it into the full perms SexGen kit Stroker made available when he quit SL and thus remove all animations that weren't made by him.   Then they know they can safely use anything that's left.

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 4499 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...