Skip to content

Instantly share code, notes, and snippets.

@masterpoppy
Last active July 19, 2017 18:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save masterpoppy/72651dc13cf632ef781e595f891d1aea to your computer and use it in GitHub Desktop.
Save masterpoppy/72651dc13cf632ef781e595f891d1aea to your computer and use it in GitHub Desktop.
[monso] Texture Changer
// ***********************************************
// [monso] Hair Script V2 CLIENT TypeA
// (with Resize)
// 2017-01-15 MasterPoppy
// ***********************************************
// ***********************************************
// BEGINNING OF USERDATA
// ***********************************************
// Product ID is used to generate listen channnel.
// Recomended to change product per product.
integer PRODUCT_ID = 7275;
// ***********************************************
// END OF USERDATA
// ***********************************************
string ResizeFactor;
list listResizeFactor = [
"XYZ+", <1.01, 1.01, 1.01>,
"XYZ++", <1.05, 1.05, 1.05>,
"XYZ+++", <1.10, 1.10, 1.10>,
"XYZ-", <0.99, 0.99, 0.99>,
"XYZ--", <0.95, 0.95, 0.95>,
"XYZ---", <0.90, 0.90, 0.90>,
"X+", <1.01, 1.00, 1.00>,
"X++", <1.05, 1.00, 1.00>,
"X+++", <1.10, 1.00, 1.00>,
"X-", <0.99, 1.00, 1.00>,
"X--", <0.95, 1.00, 1.00>,
"X---", <0.90, 1.00, 1.00>,
"Y+", <1.00, 1.01, 1.00>,
"Y++", <1.00, 1.05, 1.00>,
"Y+++", <1.00, 1.10, 1.00>,
"Y-", <1.00, 0.99, 1.00>,
"Y--", <1.00, 0.95, 1.00>,
"Y---", <1.00, 0.90, 1.00>,
"Z+", <1.00, 1.00, 1.01>,
"Z++", <1.00, 1.00, 1.05>,
"Z+++", <1.00, 1.00, 1.10>,
"Z-", <1.00, 1.00, 0.99>,
"Z--", <1.00, 1.00, 0.95>,
"Z---", <1.00, 1.00, 0.90>
];
// Encryption Key for llXorBase64
// To be the same thru HUD, DB, CLIENT
key KEY1 = "For sale:";
key KEY2 = "baby shoes, never worn.";
integer i;
integer j;
integer ch;
integer handle;
integer handle_delete;
key owner;
key http_request_id;
integer prim_num;
list link_data = [];
vector ORIGINAL_SIZE;
integer getNumberOfPrims()
{
if (llGetObjectPrimCount(llGetKey()) == 0 ) return llGetNumberOfPrims(); // attachment
return llGetObjectPrimCount(llGetKey()); // non-attachment
}
init()
{
link_data = [];
prim_num = getNumberOfPrims();
//save initial size;
ORIGINAL_SIZE = llGetScale();
for(i = 2; i <= prim_num; i++){
list get = llGetLinkPrimitiveParams(i, [ PRIM_SIZE, PRIM_POS_LOCAL ] );
vector scale = llList2Vector(get, 0);
vector pos = llList2Vector(get, 1);
link_data = (link_data=[]) + link_data + llGetLinkPrimitiveParams(i, [ PRIM_SIZE, PRIM_POS_LOCAL ] );
}
}
restore()
{
llSetLinkPrimitiveParamsFast( LINK_THIS, [ PRIM_SIZE, ORIGINAL_SIZE ] );
for(i = 2; i <= prim_num; i++){
vector scale = llList2Vector(link_data, - 4 + 2 * i);
vector pos = llList2Vector(link_data, - 3 + 2 * i);
llSetLinkPrimitiveParamsFast( i, [ PRIM_SIZE, scale, PRIM_POS_LOCAL, pos ] );
}
}
vector rescale(vector f, vector v)
{
//計算誤差回避のためVector各要素の計算をFloatで分割
float x = f.x * v.x;
float y = f.y * v.y;
float z = f.z * v.z;
return <x, y, z>;
}
open_listen()
{
ch = - PRODUCT_ID - (integer)("0x" + llGetSubString((string)owner, 0, 3));
handle = llListen(ch, "", NULL_KEY, "ping");
handle_delete = llListen(ch - 1, "", NULL_KEY, "OK");
}
default
{
state_entry()
{
owner = llGetOwner();
ResizeFactor = llList2Json(JSON_OBJECT, listResizeFactor);
listResizeFactor = [];
init();
open_listen();
}
listen(integer channel, string name, key id, string message)
{
if(message == "ping"){
if(llGetOwnerKey(id) != owner) return;
string URI = llList2String(llGetObjectDetails(id, [OBJECT_DESC]), 0);
URI = llBase64ToString(llXorBase64(URI, llStringToBase64(KEY1)));
if(llGetSubString(URI, 0, 3) == "http"){
http_request_id = llHTTPRequest(URI, [], "");
}
}
else if(message == "OK"){
llOwnerSay("Script was removed.");
llRemoveInventory(llGetScriptName());
}
}
http_response(key request_id, integer status, list metadata, string body)
{
if (request_id != http_request_id) return;
body = llBase64ToString(llXorBase64(body, llStringToBase64(KEY2)));
string type = llJsonGetValue(body, ["type"]);
string data = llJsonGetValue(body, ["data"]);
integer linknum;
string object;
string allface;
string value;
if(type == "texture"){
for(i = 1; i <= prim_num; i++){
if(i == 1){
linknum = LINK_THIS;
object = llJsonGetValue(data, ["root"]);
}
else{
linknum = i;
object = llJsonGetValue(data, [ llGetLinkName(linknum) ] );
}
if(object != JSON_INVALID){
allface = llJsonGetValue(object, [ "-1" ] );
for(j = 0; j < llGetLinkNumberOfSides(linknum); j++){
if(allface != JSON_INVALID){
value = allface;
}
else{
value = llJsonGetValue(object, [ (string)j ] );
}
if(value != JSON_INVALID){
llSetLinkPrimitiveParamsFast(linknum,
[ PRIM_TEXTURE, j, value ] + llList2List( llGetLinkPrimitiveParams( linknum, [ PRIM_TEXTURE, j ]), 1, 3)
);
}
}
}
}
return;
}
if(type == "material"){
for(i = 1; i <= prim_num; i++){
if(i == 1){
linknum = LINK_THIS;
object = llJsonGetValue(data, ["root"]);
}
else{
linknum = i;
object = llJsonGetValue(data, [ llGetLinkName(linknum) ] );
}
if(object != JSON_INVALID){
allface = llJsonGetValue(object, [ "-1" ] );
for(j = 0; j < llGetLinkNumberOfSides(linknum); j++){
if(allface != JSON_INVALID){
value = allface;
}
else{
value = llJsonGetValue(object, [ (string)j ] );
}
if(value != JSON_INVALID){
llSetLinkPrimitiveParamsFast(linknum,
[ PRIM_NORMAL, j, llJsonGetValue(value, [0]) ]
+ llList2List( llGetLinkPrimitiveParams( linknum, [ PRIM_NORMAL, j ]), 1, 3) +
[ PRIM_SPECULAR, j, llJsonGetValue(value, [1]) ]
+ llList2List( llGetLinkPrimitiveParams( linknum, [ PRIM_SPECULAR, j ]), 1, 3) +
[(vector)llJsonGetValue(value, [2]), (integer)llJsonGetValue(value, [3]), (integer)llJsonGetValue(value, [4])]
);
}
}
}
}
return;
}
if(type == "cmd"){
if(data == "-MATERIAL"){
llSetLinkPrimitiveParamsFast(
LINK_SET, [
PRIM_NORMAL, ALL_SIDES, "", <1,1,0>, <0,0,0>, 0.0,
PRIM_SPECULAR, ALL_SIDES, "", <1,1,0>, <0,0,0>, 0.0, <1,1,1>, 51, 0
]);
return;
}
else if(data == "RESTORE"){
restore();
return;
}
else if(data == "REMOVE_SCRIPT"){
llDialog(owner,"\n"+
"This oparation will delete scripts in your [monso] hair."
+"\nMake sure that you made a backup. \nReady to continue?"
,["OK","Cancel"], ch - 1 );
}
//resize & restore size
string sfactor = llJsonGetValue(ResizeFactor, [data]);
if(sfactor != JSON_INVALID){
integer total = getNumberOfPrims();
list prim_param;
list target_param;
vector factor = (vector)sfactor;
vector scale = llGetScale();
vector pos;
if(total < 2){
scale = rescale(factor, scale);
llSetScale(scale);
}
else{
scale = rescale(factor, scale);
target_param = [ scale, ZERO_VECTOR ];
for(i = 2; i <= total; i++ ){
prim_param = llGetLinkPrimitiveParams( i, [ PRIM_SIZE, PRIM_POS_LOCAL ] );
scale = llList2Vector(prim_param, 0);
pos = llList2Vector(prim_param, 1);
scale = rescale(factor, scale);
pos = rescale(factor, pos);
target_param += [ scale, pos ];
}
integer min_scale_check = TRUE;
for(i = 0; i < total; i++ ){
scale = llList2Vector(target_param, 2 * i);
if(llListStatistics(LIST_STAT_MIN, [ scale.x, scale.y, scale.z ])< 0.01){
min_scale_check = FALSE;
}
}
if(min_scale_check){
scale = llList2Vector(target_param, 0 );
llSetLinkPrimitiveParamsFast(1, [
PRIM_SIZE, scale
]);
for(i = 2; i <= total; i++ ){
scale = llList2Vector(target_param, 2 * (i - 1) );
pos = llList2Vector(target_param, 2 * (i - 1) + 1 );
llSetLinkPrimitiveParamsFast(i, [
PRIM_SIZE, scale, PRIM_POS_LOCAL, pos
]);
}
}
else{
llOwnerSay("Prim scale reached at minimum.");
}
}
target_param = [];
return;
}
}
}
changed(integer change)
{
if(change & CHANGED_OWNER){
owner = llGetOwner();
llListenRemove(handle);
llListenRemove(handle_delete);
open_listen();
}
else if(change & CHANGED_LINK){
init();
}
}
}
// ***********************************************
// [monso] Hair Script V2 CLIENT TypeB
// (No Resize)
// 2017-01-15 MasterPoppy
// ***********************************************
// ***********************************************
// BEGINNING OF USERDATA
// ***********************************************
// Product ID is used to generate listen channnel.
// Recomended to change product per product.
integer PRODUCT_ID = 7275;
// ***********************************************
// END OF USERDATA
// ***********************************************
// Encryption Key for llXorBase64
// To be the same thru HUD, DB, CLIENT
key KEY1 = "For sale:";
key KEY2 = "baby shoes, never worn.";
integer i;
integer j;
integer ch;
integer handle;
integer handle_delete;
key owner;
key http_request_id;
integer prim_num;
list link_data = [];
vector ORIGINAL_SIZE;
integer getNumberOfPrims()
{
if (llGetObjectPrimCount(llGetKey()) == 0 ) return llGetNumberOfPrims(); // attachment
return llGetObjectPrimCount(llGetKey()); // non-attachment
}
open_listen()
{
ch = - PRODUCT_ID - (integer)("0x" + llGetSubString((string)owner, 0, 3));
handle = llListen(ch, "", NULL_KEY, "ping");
handle_delete = llListen(ch - 1, "", NULL_KEY, "OK");
}
default
{
state_entry()
{
owner = llGetOwner();
prim_num = getNumberOfPrims();
open_listen();
}
listen(integer channel, string name, key id, string message)
{
if(message == "ping"){
if(llGetOwnerKey(id) != owner) return;
string URI = llList2String(llGetObjectDetails(id, [OBJECT_DESC]), 0);
URI = llBase64ToString(llXorBase64(URI, llStringToBase64(KEY1)));
if(llGetSubString(URI, 0, 3) == "http"){
http_request_id = llHTTPRequest(URI, [], "");
}
}
else if(message == "OK"){
llOwnerSay("Script was removed.");
llRemoveInventory(llGetScriptName());
}
}
http_response(key request_id, integer status, list metadata, string body)
{
if (request_id != http_request_id) return;
body = llBase64ToString(llXorBase64(body, llStringToBase64(KEY2)));
string type = llJsonGetValue(body, ["type"]);
string data = llJsonGetValue(body, ["data"]);
integer linknum;
string object;
string allface;
string value;
if(type == "texture"){
for(i = 1; i <= prim_num; i++){
if(i == 1){
linknum = LINK_THIS;
object = llJsonGetValue(data, ["root"]);
}
else{
linknum = i;
object = llJsonGetValue(data, [ llGetLinkName(linknum) ] );
}
if(object != JSON_INVALID){
allface = llJsonGetValue(object, [ "-1" ] );
for(j = 0; j < llGetLinkNumberOfSides(linknum); j++){
if(allface != JSON_INVALID){
value = allface;
}
else{
value = llJsonGetValue(object, [ (string)j ] );
}
if(value != JSON_INVALID){
llSetLinkPrimitiveParamsFast(linknum,
[ PRIM_TEXTURE, j, value ] + llList2List( llGetLinkPrimitiveParams( linknum, [ PRIM_TEXTURE, j ]), 1, 3)
);
}
}
}
}
return;
}
if(type == "material"){
for(i = 1; i <= prim_num; i++){
if(i == 1){
linknum = LINK_THIS;
object = llJsonGetValue(data, ["root"]);
}
else{
linknum = i;
object = llJsonGetValue(data, [ llGetLinkName(linknum) ] );
}
if(object != JSON_INVALID){
allface = llJsonGetValue(object, [ "-1" ] );
for(j = 0; j < llGetLinkNumberOfSides(linknum); j++){
if(allface != JSON_INVALID){
value = allface;
}
else{
value = llJsonGetValue(object, [ (string)j ] );
}
if(value != JSON_INVALID){
llSetLinkPrimitiveParamsFast(linknum,
[ PRIM_NORMAL, j, llJsonGetValue(value, [0]) ]
+ llList2List( llGetLinkPrimitiveParams( linknum, [ PRIM_NORMAL, j ]), 1, 3) +
[ PRIM_SPECULAR, j, llJsonGetValue(value, [1]) ]
+ llList2List( llGetLinkPrimitiveParams( linknum, [ PRIM_SPECULAR, j ]), 1, 3) +
[(vector)llJsonGetValue(value, [2]), (integer)llJsonGetValue(value, [3]), (integer)llJsonGetValue(value, [4])]
);
}
}
}
}
return;
}
if(type == "cmd"){
if(data == "-MATERIAL"){
llSetLinkPrimitiveParamsFast(
LINK_SET, [
PRIM_NORMAL, ALL_SIDES, "", <1,1,0>, <0,0,0>, 0.0,
PRIM_SPECULAR, ALL_SIDES, "", <1,1,0>, <0,0,0>, 0.0, <1,1,1>, 51, 0
]);
return;
}
else if(data == "REMOVE_SCRIPT"){
llDialog(owner,"\n"+
"This oparation will delete scripts in your [monso] hair."
+"\nMake sure that you made a backup. \nReady to continue?"
,["OK","Cancel"], ch - 1 );
}
}
}
changed(integer change)
{
if(change & CHANGED_OWNER){
owner = llGetOwner();
llListenRemove(handle);
llListenRemove(handle_delete);
open_listen();
}
else if(change & CHANGED_LINK){
prim_num = getNumberOfPrims();
}
}
}
// ***********************************************
// [monso] Hair Script V2 DB
// 2017-01-15 MasterPoppy
// ***********************************************
list listUUID = [
// "TextureName", "TextureUUID"
"SampleTex1", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"SampleTex2", "50330856-2510-bb1c-4ff2-838aa7d706aa",
"SampleTex3", "9bfaf28e-88e4-9d6e-98af-4f208112f61f",
"SampleTex4", "cc5ac2fc-efeb-701a-92df-15bb28792cda",
"SampleTex5", "dead6094-76a7-9fa8-1630-cbad1ace8000",
"SampleTex6", "63c205c9-1f5a-c07c-1d0d-d42d5889a3b2",
"SampleTex7", "078a7d3d-f1e8-8b67-07ec-bc32598a47db",
"SampleTex8", "3fa95aa6-c0ae-16ca-ff40-d13f378994fa",
0];
string UUID;
list listTEXTURE = [
// "ButtonName", (NumOfData)
// "PrimName", FaceNum(0-7), "TextureName",
// Note:RootPrim="root"
// Note:All Face of sides: FaceNum=-1
"A33", 3,
"hair1", 0, "SampleTex1",
"hair2", 0, "SampleTex1",
"hair3", 0, "SampleTex1",
"A34", 3,
"hair1", 0, "SampleTex2",
"hair2", 0, "SampleTex2",
"hair3", 0, "SampleTex2",
"A35", 3,
"hair1", 0, "SampleTex3",
"hair2", 0, "SampleTex3",
"hair3", 0, "SampleTex3",
"A36", 3,
"hair1", 0, "SampleTex4",
"hair2", 0, "SampleTex4",
"hair3", 0, "SampleTex4",
"A37", 3,
"hair1", 0, "SampleTex5",
"hair2", 0, "SampleTex5",
"hair3", 0, "SampleTex5",
"A38", 3,
"hair1", 0, "SampleTex6",
"hair2", 0, "SampleTex6",
"hair3", 0, "SampleTex6",
"A39", 3,
"hair1", 0, "SampleTex7",
"hair2", 0, "SampleTex7",
"hair3", 0, "SampleTex7",
"A40", 3,
"hair1", 0, "SampleTex8",
"hair2", 0, "SampleTex8",
"hair3", 0, "SampleTex8",
"A41", 3,
"hair1", 0, "SampleTex1",
"hair2", 0, "SampleTex1",
"hair3", 0, "SampleTex1",
"A42", 3,
"hair1", 0, "SampleTex2",
"hair2", 0, "SampleTex2",
"hair3", 0, "SampleTex3",
"A43", 3,
"hair1", 0, "SampleTex3",
"hair2", 0, "SampleTex3",
"hair3", 0, "SampleTex3",
"A44", 3,
"hair1", 0, "SampleTex4",
"hair2", 0, "SampleTex4",
"hair3", 0, "SampleTex4",
"A45", 3,
"hair1", 0, "SampleTex5",
"hair2", 0, "SampleTex5",
"hair3", 0, "SampleTex5",
"A46", 3,
"hair1", 0, "SampleTex6",
"hair2", 0, "SampleTex6",
"hair3", 0, "SampleTex6",
"A47", 3,
"hair1", 0, "SampleTex7",
"hair2", 0, "SampleTex7",
"hair3", 0, "SampleTex7",
"A48", 3,
"hair1", 0, "SampleTex8",
"hair2", 0, "SampleTex8",
"hair3", 0, "SampleTex8",
"A49", 3,
"hair1", 0, "SampleTex1",
"hair2", 0, "SampleTex1",
"hair3", 0, "SampleTex1",
"A50", 3,
"hair1", 0, "SampleTex2",
"hair2", 0, "SampleTex2",
"hair3", 0, "SampleTex2",
"A51", 3,
"hair1", 0, "SampleTex3",
"hair2", 0, "SampleTex3",
"hair3", 0, "SampleTex3",
"A52", 3,
"hair1", 0, "SampleTex4",
"hair2", 0, "SampleTex4",
"hair3", 0, "SampleTex4",
"A53", 3,
"hair1", 0, "SampleTex5",
"hair2", 0, "SampleTex5",
"hair3", 0, "SampleTex5",
"A54", 3,
"hair1", 0, "SampleTex6",
"hair2", 0, "SampleTex6",
"hair3", 0, "SampleTex6",
"A55", 3,
"hair1", 0, "SampleTex7",
"hair2", 0, "SampleTex7",
"hair3", 0, "SampleTex7",
"A56", 3,
"hair1", 0, "SampleTex8",
"hair2", 0, "SampleTex8",
"hair3", 0, "SampleTex8",
"A57", 3,
"hair1", 0, "SampleTex1",
"hair2", 0, "SampleTex1",
"hair3", 0, "SampleTex1",
"A58", 3,
"hair1", 0, "SampleTex2",
"hair2", 0, "SampleTex2",
"hair3", 0, "SampleTex2",
"A59", 3,
"hair1", 0, "SampleTex3",
"hair2", 0, "SampleTex3",
"hair3", 0, "SampleTex3",
"A60", 3,
"hair1", 0, "SampleTex4",
"hair2", 0, "SampleTex4",
"hair3", 0, "SampleTex4",
"A61", 3,
"hair1", 0, "SampleTex5",
"hair2", 0, "SampleTex5",
"hair3", 0, "SampleTex5",
"A62", 3,
"hair1", 0, "SampleTex6",
"hair2", 0, "SampleTex6",
"hair3", 0, "SampleTex6",
"A63", 3,
"hair1", 0, "SampleTex7",
"hair2", 0, "SampleTex7",
"hair3", 0, "SampleTex7",
"A64", 3,
"hair1", 0, "SampleTex8",
"hair2", 0, "SampleTex8",
"hair3", 0, "SampleTex8",
0];
string TEXTURE;
// Encryption Key for llXorBase64
// To be the same thru HUD, DB, CLIENT
key KEY1 = "For sale:";
key KEY2 = "baby shoes, never worn.";
integer i;
integer j;
key owner;
string calc_memory()
{
return llGetSubString((string)(0.01*(float)llRound(100*llGetFreeMemory()/1024.0)),0,-5) + " / 64 kbyte";
}
check_memory()
{
string freemem = llGetSubString((string)(0.01*(float)llRound(100*llGetFreeMemory()/1024.0)),0,-5);
llOwnerSay("[FreeMemory] " + calc_memory() + " @ `" + llGetScriptName() + "`");
}
default
{
state_entry()
{
UUID = llList2Json(JSON_OBJECT, llList2List(listUUID, 0, - 1 - llGetListLength(listUUID) % 2));
listUUID = [];
owner = llGetOwner();
string cmd;
//Make Texture JSON
integer numdata;
integer listlength = - 1 + llGetListLength(listTEXTURE);
for(i = 0; i < listlength; i++){
llSetText("Proccesing " + (string)i + "/" + (string)listlength + " - " + (string)llRound(100 * (float)i / (float)listlength) + " %\n" + calc_memory(), <1,1,1>, 1.0);
cmd = llList2String(listTEXTURE, i);
string tex_name;
string prim;
string face;
string tex_key;
numdata = llList2Integer(listTEXTURE, i + 1);
for(j = 0; j < numdata; j++){
prim = llList2String(listTEXTURE, i + 3 * j + 2);
face = llList2String(listTEXTURE, i + 3 * j + 3);
tex_name = llList2String(listTEXTURE, i + 3 * j + 4);
tex_key = llJsonGetValue(UUID, [tex_name]);
if(tex_key == JSON_INVALID) {
llOwnerSay("[ERROR] `" + cmd + "." + prim + "." + face + "." + tex_name + "` is not found in script `" + llGetScriptName() + "`.");
}
TEXTURE = llJsonSetValue(TEXTURE, [cmd, "data" , prim, face], tex_key);
}
TEXTURE = llJsonSetValue(TEXTURE, [cmd, "type"], "texture");
i += 1 + 3 * numdata;
}
listTEXTURE = [];
UUID = "";
check_memory();
llSetText("", <1,1,1>, 1.0);
//llMessageLinked(LINK_THIS, 0, llXorBase64(llStringToBase64(TEXTURE), llStringToBase64(KEY2)), (key)("a"));
}
link_message(integer sender_num, integer num, string str, key id)
{
if(id == owner){
string value = llJsonGetValue(TEXTURE, [str]);
if(value != JSON_INVALID){
value = llXorBase64(llStringToBase64(value), llStringToBase64(KEY2));
}
llMessageLinked(LINK_THIS, 0, value, (key)str);
}
}
changed(integer change)
{
if(change & CHANGED_OWNER){
owner = llGetOwner();
}
}
}
// ***********************************************
// [monso] Hair Script V2 DB
// 2017-01-15 MasterPoppy
// ***********************************************
list listUUID = [
// "TextureName", "TextureUUID"
"hair_mixed_basic8_root", "9f5f6ff2-957b-9328-fbf3-26003108c8e2",
"hair_mixed_basic8_root_alpha1", "23aa44a8-6e03-49a7-9657-711d6a59661f",
"hair_mixed_basic8_root_alpha2", "68e653d9-2695-80e3-c1d9-23fe5d3df5b4",
"SampleTex1", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"SampleTex2", "50330856-2510-bb1c-4ff2-838aa7d706aa",
"SampleTex3", "9bfaf28e-88e4-9d6e-98af-4f208112f61f",
"SampleTex4", "cc5ac2fc-efeb-701a-92df-15bb28792cda",
"SampleTex5", "dead6094-76a7-9fa8-1630-cbad1ace8000",
"SampleTex6", "63c205c9-1f5a-c07c-1d0d-d42d5889a3b2",
"SampleTex7", "078a7d3d-f1e8-8b67-07ec-bc32598a47db",
"SampleTex8", "3fa95aa6-c0ae-16ca-ff40-d13f378994fa",
//Following UUID list is dummy for free memory test
"Test01", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test02", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test03", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test04", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test05", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test06", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test07", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test08", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test09", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test10", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test11", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test12", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test13", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test14", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test15", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test16", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test17", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test18", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test19", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test20", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test21", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test22", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test23", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test24", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test25", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test26", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test27", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test28", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test29", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test30", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test31", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test32", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test33", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test34", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test35", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test36", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test37", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test38", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test39", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test40", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test41", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test42", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test43", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test44", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test45", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test46", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test47", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test48", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test49", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test50", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test51", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test52", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test53", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test54", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test55", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test56", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test57", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test58", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test59", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test60", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test61", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test62", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test63", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test64", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test65", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test66", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test67", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test68", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test69", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test70", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test71", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test72", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test73", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test74", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test75", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test76", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test77", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test78", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test79", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test80", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test81", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test82", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test83", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test84", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"Test85", "44c78d32-845c-d586-b213-530eb7f7ecd9",
0];
string UUID;
list listTEXTURE = [
// "ButtonName", (NumOfData)
// "PrimName", FaceNum(0-7), "TextureName",
// Note:RootPrim="root"
// Note:All Face of sides: FaceNum=-1
"A01", 5,
"hair1", 0, "hair_mixed_basic8_root", // Apply to single face
"hair2", -1, "hair_mixed_basic8_root_alpha1", // Apply to all face
"hair3", 0, "hair_mixed_basic8_root_alpha2", // Apply to multiple face
"hair3", 1, "hair_mixed_basic8_root_alpha2", // Apply to multiple face
"hair3", 2, "hair_mixed_basic8_root_alpha2", // Apply to multiple face
"A02", 5,
"hair1", 0, "SampleTex2", // Apply to single face
"hair2", -1, "SampleTex2", // Apply to all face
"hair3", 0, "SampleTex2", // Apply to multiple face
"hair3", 1, "SampleTex2", // Apply to multiple face
"hair3", 2, "SampleTex2", // Apply to multiple face
"A03", 3,
"hair1", 0, "SampleTex3",
"hair2", 0, "SampleTex3",
"hair3", 0, "SampleTex3",
"A04", 3,
"hair1", 0, "SampleTex4",
"hair2", 0, "SampleTex4",
"hair3", 0, "SampleTex4",
"A05", 3,
"hair1", 0, "SampleTex5",
"hair2", 0, "SampleTex5",
"hair3", 0, "SampleTex5",
"A06", 3,
"hair1", 0, "SampleTex6",
"hair2", 0, "SampleTex6",
"hair3", 0, "SampleTex6",
"A07", 3,
"hair1", 0, "SampleTex7",
"hair2", 0, "SampleTex7",
"hair3", 0, "SampleTex7",
"A08", 3,
"hair1", 0, "SampleTex8",
"hair2", 0, "SampleTex8",
"hair3", 0, "SampleTex8",
"A09", 3,
"hair1", 0, "SampleTex1",
"hair2", 0, "SampleTex1",
"hair3", 0, "SampleTex1",
"A10", 3,
"hair1", 0, "SampleTex2",
"hair2", 0, "SampleTex2",
"hair3", 0, "SampleTex3",
"A11", 3,
"hair1", 0, "SampleTex3",
"hair2", 0, "SampleTex3",
"hair3", 0, "SampleTex3",
"A12", 3,
"hair1", 0, "SampleTex4",
"hair2", 0, "SampleTex4",
"hair3", 0, "SampleTex4",
"A13", 3,
"hair1", 0, "SampleTex5",
"hair2", 0, "SampleTex5",
"hair3", 0, "SampleTex5",
"A14", 3,
"hair1", 0, "SampleTex6",
"hair2", 0, "SampleTex6",
"hair3", 0, "SampleTex6",
"A15", 3,
"hair1", 0, "SampleTex7",
"hair2", 0, "SampleTex7",
"hair3", 0, "SampleTex7",
"A16", 3,
"hair1", 0, "SampleTex8",
"hair2", 0, "SampleTex8",
"hair3", 0, "SampleTex8",
"A17", 3,
"hair1", 0, "SampleTex1",
"hair2", 0, "SampleTex1",
"hair3", 0, "SampleTex1",
"A18", 3,
"hair1", 0, "SampleTex2",
"hair2", 0, "SampleTex2",
"hair3", 0, "SampleTex2",
"A19", 3,
"hair1", 0, "SampleTex3",
"hair2", 0, "SampleTex3",
"hair3", 0, "SampleTex3",
"A20", 3,
"hair1", 0, "SampleTex4",
"hair2", 0, "SampleTex4",
"hair3", 0, "SampleTex4",
"A21", 3,
"hair1", 0, "SampleTex5",
"hair2", 0, "SampleTex5",
"hair3", 0, "SampleTex5",
"A22", 3,
"hair1", 0, "SampleTex6",
"hair2", 0, "SampleTex6",
"hair3", 0, "SampleTex6",
"A23", 3,
"hair1", 0, "SampleTex7",
"hair2", 0, "SampleTex7",
"hair3", 0, "SampleTex7",
"A24", 3,
"hair1", 0, "SampleTex8",
"hair2", 0, "SampleTex8",
"hair3", 0, "SampleTex8",
"A25", 3,
"hair1", 0, "SampleTex1",
"hair2", 0, "SampleTex1",
"hair3", 0, "SampleTex1",
"A26", 3,
"hair1", 0, "SampleTex2",
"hair2", 0, "SampleTex2",
"hair3", 0, "SampleTex2",
"A27", 3,
"hair1", 0, "SampleTex3",
"hair2", 0, "SampleTex3",
"hair3", 0, "SampleTex3",
"A28", 3,
"hair1", 0, "SampleTex4",
"hair2", 0, "SampleTex4",
"hair3", 0, "SampleTex4",
"A29", 3,
"hair1", 0, "SampleTex5",
"hair2", 0, "SampleTex5",
"hair3", 0, "SampleTex5",
"A30", 3,
"hair1", 0, "SampleTex6",
"hair2", 0, "SampleTex6",
"hair3", 0, "SampleTex6",
"A31", 3,
"hair1", 0, "SampleTex7",
"hair2", 0, "SampleTex7",
"hair3", 0, "SampleTex7",
"A32", 3,
"hair1", 0, "SampleTex8",
"hair2", 0, "SampleTex8",
"hair3", 0, "SampleTex8",
"B01", 3,
"ribbon", 0, "SampleTex1",
"ribbon", 1, "SampleTex1",
"ribbon", 2, "SampleTex1",
"B02", 3,
"ribbon", 0, "SampleTex2",
"ribbon", 1, "SampleTex2",
"ribbon", 2, "SampleTex2",
"B03", 3,
"ribbon", 0, "SampleTex3",
"ribbon", 1, "SampleTex3",
"ribbon", 2, "SampleTex3",
"B04", 3,
"ribbon", 0, "SampleTex4",
"ribbon", 1, "SampleTex4",
"ribbon", 2, "SampleTex4",
0];
string TEXTURE;
// Encryption Key for llXorBase64
// To be the same thru HUD, DB, CLIENT
key KEY1 = "For sale:";
key KEY2 = "baby shoes, never worn.";
integer i;
integer j;
key owner;
string calc_memory()
{
return llGetSubString((string)(0.01*(float)llRound(100*llGetFreeMemory()/1024.0)),0,-5) + " / 64 kbyte";
}
check_memory()
{
string freemem = llGetSubString((string)(0.01*(float)llRound(100*llGetFreeMemory()/1024.0)),0,-5);
llOwnerSay("[FreeMemory] " + calc_memory() + " @ `" + llGetScriptName() + "`");
}
default
{
state_entry()
{
UUID = llList2Json(JSON_OBJECT, llList2List(listUUID, 0, - 1 - llGetListLength(listUUID) % 2));
listUUID = [];
owner = llGetOwner();
string cmd;
//Make Texture JSON
integer numdata;
integer listlength = - 1 + llGetListLength(listTEXTURE);
for(i = 0; i < listlength; i++){
llSetText("Proccesing " + (string)i + "/" + (string)listlength + " - " + (string)llRound(100 * (float)i / (float)listlength) + " %\n" + calc_memory(), <1,1,1>, 1.0);
cmd = llList2String(listTEXTURE, i);
string tex_name;
string prim;
string face;
string tex_key;
numdata = llList2Integer(listTEXTURE, i + 1);
for(j = 0; j < numdata; j++){
prim = llList2String(listTEXTURE, i + 3 * j + 2);
face = llList2String(listTEXTURE, i + 3 * j + 3);
tex_name = llList2String(listTEXTURE, i + 3 * j + 4);
tex_key = llJsonGetValue(UUID, [tex_name]);
if(tex_key == JSON_INVALID) {
llOwnerSay("[ERROR] `" + cmd + "." + prim + "." + face + "." + tex_name + "` is not found in script `" + llGetScriptName() + "`.");
}
TEXTURE = llJsonSetValue(TEXTURE, [cmd, "data" , prim, face], tex_key);
}
TEXTURE = llJsonSetValue(TEXTURE, [cmd, "type"], "texture");
i += 1 + 3 * numdata;
}
listTEXTURE = [];
UUID = "";
check_memory();
llSetText("", <1,1,1>, 1.0);
//llMessageLinked(LINK_THIS, 0, llXorBase64(llStringToBase64(TEXTURE), llStringToBase64(KEY2)), (key)("a"));
}
link_message(integer sender_num, integer num, string str, key id)
{
if(id == owner){
string value = llJsonGetValue(TEXTURE, [str]);
if(value != JSON_INVALID){
value = llXorBase64(llStringToBase64(value), llStringToBase64(KEY2));
}
llMessageLinked(LINK_THIS, 0, value, (key)str);
}
}
changed(integer change)
{
if(change & CHANGED_OWNER){
owner = llGetOwner();
}
}
}
// ***********************************************
// [monso] Hair Script V2 HUD
// 2017-01-15 MasterPoppy
// ***********************************************
// ***********************************************
// BEGINNING OF USERDATA
// ***********************************************
// Product ID is used to generate listen channnel.
// Recomended to change product per product.
integer PRODUCT_ID = 7275;
list listUUID = [
// "TextureName", "TextureUUID"
"hair_nm", "aa9c6a4c-60de-a094-f4fd-7e1e0dd53a41",
"hair_sp", "4fcee739-b0a8-86a7-b62d-3bfb1f93642b"
];
string UUID;
list listMATERIAL = [
// (NumOfData)
// "PrimName", FaceNum(0-7), "TextureName(NomalMap)", "TextureName(SpecularMap)", <Specular_Color>, Specular_Glossiness, Specular_Environment
// Note:All Face of sides: FaceNum=-1
// Note:Buttom Name for material is reserved as "+MATERIAL" & "-MATERIAL".
5,
"hair1", 0, "hair_nm", "hair_sp", <1,1,1>, 70, 1, // Apply to single face
"hair2", -1, "hair_nm", "hair_sp", <1,1,1>, 70, 1, // Apply to all face
"hair3", 0, "hair_nm", "hair_sp", <1,1,1>, 70, 1, // Apply to multiple face
"hair3", 1, "hair_nm", "hair_sp", <1,1,1>, 70, 1,
"hair3", 2, "hair_nm", "hair_sp", <1,1,1>, 70, 1,
0];
string MATERIAL;
list listWEB = [
// "ButtonName", URL,
"[monso] WordPress", "https://mymonso.wordpress.com/",
"[monso] flickr", "https://www.flickr.com/photos/mymonso/",
"[monso] Market Place", "https://marketplace.secondlife.com/stores/105079"
];
string WEB;
list listTAB = [
// "ButtonName", HUD Z-Axis Rotation
"TAB1", 0.0, // for Main + Root Colors
"TAB2", 90.0, // for Ombre + Highlight Colors
"TAB3", 180.0, // for Resize + Material + Script Delete
"TAB4", 270.0 // TAB4 is available if needed.
];
string TAB;
// ***********************************************
// END OF USERDATA
// ***********************************************
list plane_command = [
"-MATERIAL", "RESTORE", "REMOVE_SCRIPT",
"XYZ+++", "XYZ++", "XYZ+", "XYZ---", "XYZ--", "XYZ-",
"X+++", "X++", "X+", "X---", "X--", "X-",
"Y+++", "Y++", "Y+", "Y---", "Y--", "Y-",
"Z+++", "Z++", "Z+", "Z---", "Z--", "Z-"
];
// Encryption Key for llXorBase64
// To be the same thru HUD, DB, CLIENT
key KEY1 = "For sale:";
key KEY2 = "baby shoes, never worn.";
integer i;
integer j;
key owner;
integer ch;
integer handle;
key request;
string URI;
string response;
// Resize
// 注) リサイズ用のボタンはプリム名を"RESIZE"としてください。
string resize_mode;
list ResizeMenu = ["Stretch(X)","Stretch(Y)","Stretch(Z)","Resize(XYZ)"];
list ResizeButton = ["-", "--", "---", "+", "++", "+++"];
list listResizeCommand = [
"Stretch(X)",
"X-", "X--", "X---",
"X+", "X++", "X+++",
"Stretch(Y)",
"Y-", "Y--", "Y---",
"Y+", "Y++", "Y+++",
"Stretch(Z)",
"Z-", "Z--", "Z---",
"Z+", "Z++", "Z+++",
"Resize(XYZ)",
"XYZ-", "XYZ--", "XYZ---",
"XYZ+", "XYZ++", "XYZ+++"
];
string ResizeCommand;
open_listen()
{
ch = - 1 - PRODUCT_ID - (integer)("0x" + llGetSubString((string)owner, 0, 3));
handle = llListen(ch , "", owner, "");
}
ping()
{
llRegionSayTo(owner, - PRODUCT_ID - (integer)("0x" + llGetSubString((string)owner, 0, 3)), "ping");
}
setURI()
{
llSetObjectDesc(llXorBase64(llStringToBase64(URI), llStringToBase64(KEY1)));
}
check_memory()
{
string freemem = llGetSubString((string)(0.01*(float)llRound(100*llGetFreeMemory()/1024.0)),0,-5);
llOwnerSay("[FreeMemory] " + freemem+" / 64 kbyte @ `" + llGetScriptName() + "`");
}
default
{
state_entry()
{
llSetText("", <1,1,1>, 1);
owner = llGetOwner();
UUID = llList2Json(JSON_OBJECT, llList2List(listUUID, 0, - 1 - llGetListLength(listUUID) % 2));
listUUID = [];
WEB = llList2Json(JSON_OBJECT, listWEB);
listWEB = [];
TAB = llList2Json(JSON_OBJECT, listTAB);
listTAB = [];
//Make Material JSON
string prim;
string face;
string normal;
string specular;
string tex_key;
for(j = 0; j < llList2Integer(listMATERIAL, 0); j++){
prim = llList2String(listMATERIAL, 7 * j + 1);
face = llList2String(listMATERIAL, 7 * j + 2);
normal = llList2String(listMATERIAL, 7 * j + 3);
specular = llList2String(listMATERIAL, 7 * j + 4);
tex_key = llJsonGetValue(UUID, [normal]);
if(tex_key == JSON_INVALID) {
llOwnerSay("[ERROR] `" + prim + "." + face + "." + normal + "` is not found in script `" + llGetScriptName() + "`.");
normal = TEXTURE_BLANK;
}
else{
normal = tex_key;
}
tex_key = llJsonGetValue(UUID, [specular]);
if(specular == JSON_INVALID) {
llOwnerSay("[ERROR] `" + prim + "." + face + "." + specular + "` is not found in script `" + llGetScriptName() + "`.");
specular = TEXTURE_BLANK;
}
else{
specular = tex_key;
}
MATERIAL = llJsonSetValue(MATERIAL,
["data" , prim, face],
llList2Json(JSON_ARRAY, [ normal, specular ] + llList2List(listMATERIAL, 7 * j + 5, 7 * j + 7) )
);
}
MATERIAL = llJsonSetValue(MATERIAL, ["type"], "material");
listMATERIAL = [];
UUID = "";
for(i = 0; i < llGetListLength(listResizeCommand) / 7; i++){
ResizeCommand = llJsonSetValue(ResizeCommand, [ llList2String(listResizeCommand, 7 * i) ],
llList2Json(JSON_ARRAY, llList2List(listResizeCommand, 7 * i + 1, 7 * i + 6)));
}
listResizeCommand = [];
llReleaseURL(URI);
request = llRequestURL();
open_listen();
check_memory();
}
touch_start(integer total_number)
{
integer linknum = llDetectedLinkNumber(0);
string linkname = llGetLinkName(linknum);
if(linknum == LINK_ROOT || llDetectedTouchFace(0) != 4 || !llGetAttached()) return;
string clicked = llJsonGetValue(TAB, [linkname]);
if(clicked != JSON_INVALID){
llSetRot( llEuler2Rot( DEG_TO_RAD * <0,0,(float)clicked> ) );
return;
}
clicked = llJsonGetValue(WEB, [linkname]);
if(clicked != JSON_INVALID){
llLoadURL(owner, linkname, clicked);
return;
}
if(llGetTime() < 0.8) return;
llResetTime();
setURI();
if(linkname == "+MATERIAL"){
response = MATERIAL;
ping();
return;
}
if(linkname == "RESIZE"){
llDialog(owner, "\nResize Menu (Only for Non-Rigged)\n(*Select Stretch Mode*)", ResizeMenu + [ "*Restore*", "*End*" ], ch);
return;
}
integer index = llListFindList(plane_command, [linkname]);
if(index != -1){
response = llList2Json(JSON_OBJECT, ["type", "cmd", "data", linkname]);
ping();
return;
}
llMessageLinked(LINK_THIS, 0, linkname, llDetectedKey(0));
llSetTimerEvent(0.8);
}
listen(integer channel, string name, key id, string message)
{
if(channel == ch){
integer index = llListFindList(ResizeMenu, [message]);
if(index != -1){
resize_mode = message;
llDialog(owner, "\nResize Menu (Only for Non-Rigged)\nMode [ " + resize_mode + " ]", ResizeButton + [ "*Back*" ], ch );
return;
}
if(message == "*Back*"){
llDialog(owner, "\nResize Menu (Only for Non-Rigged)\n(*Select Stretch Mode*)", ResizeMenu + [ "*Restore*", "*End*" ], ch );
return;
}
if(llGetTime() < 0.8) return;
llResetTime();
setURI();
if(message == "*Restore*"){
response = llList2Json(JSON_OBJECT, ["type", "cmd", "data", "RESTORE"]);
ping();
llDialog(owner, "\nResize Menu (Only for Non-Rigged)\n(*Select Stretch Mode*)", ResizeMenu + [ "*Restore*", "*End*" ], ch );
return;
}
index = llListFindList(ResizeButton, [message]);
if(index != -1){
string resize_msg = llJsonGetValue(ResizeCommand, [resize_mode, index]);
if(resize_msg != JSON_INVALID){
response = llList2Json(JSON_OBJECT, ["type", "cmd", "data", resize_msg]);
ping();
}
else{
llSay(DEBUG_CHANNEL, "[JSON ERROR]" + resize_mode + ", " + (string)index);
}
llDialog(owner, "\nResize Menu (Only for Non-Rigged)\nMode [ " + resize_mode + " ]", ResizeButton + [ "*Back*" ], ch );
return;
}
}
}
link_message(integer sender_num, integer num, string str, key id)
{
if(id != NULL_KEY && id != owner){
if(str != JSON_INVALID){
response = llBase64ToString(llXorBase64(str, llStringToBase64(KEY2)));
ping();
llSetTimerEvent(0);
//llLoadURL(owner, "debug", URI);
}
}
}
http_request(key id, string method, string body)
{
if(request == id){
request = "";
if (method == URL_REQUEST_GRANTED){
URI = body;
//response = MATERIAL;
//llLoadURL(owner, "debug", URI);
}
}
else{
if(method == "GET"){
llSetContentType(id, CONTENT_TYPE_JSON);
llHTTPResponse(id, 200, llXorBase64(llStringToBase64(response), llStringToBase64(KEY2)));
//llHTTPResponse(id, 200, response);
llSetObjectDesc("");
}
}
}
changed(integer change)
{
if(change & CHANGED_REGION || change & CHANGED_REGION_START){
llReleaseURL(URI);
request = llRequestURL();
}
else if(change & CHANGED_OWNER){
owner = llGetOwner();
llListenRemove(handle);
open_listen();
}
}
attach(key id)
{
if(id){
llReleaseURL(URI);
request = llRequestURL();
}
}
}

Specification and Instruction for '[monso] Hair Script V2'

Date : 2017-01-15 MasterPoppy

Item List

  1. [monso] Hair Script V2 HUD sample (32 hair color) HUD assembly sample 16 hair colors and 4 accessory colors on TAB1 and TAB2 Resize and Material on TAB3 Main HUD script and one DB script is needed for 32 colors.
  2. [monso] Hair Script V2 HUD sample (64 hair color) HUD assembly sample 32 hair colors and 4 accessory colors on TAB1 and TAB2 Resize and Material on TAB3 Main HUD script and two DB scripts are needed for 64 colors.
  3. [monso] Hair Script V2 CLIENT sample (With Resize) Run function (change texture, resize, restore size, material on/off, remove script) by command from HUD.
  4. [monso] Hair Script V2 CLIENT sample (No Resize) Run function (change texture, material on/off, remove script) by command from HUD.
  5. UUID List Maker Automatic texture UUID list maker for supporting data input.
  6. Delivery Specification (this document)

Instruction for HUD assembly

Button Naming

Prim name of button is used as command to run Client script. Following names are reserved keyword, so other name to be used for texture change button. TAB1, TAB2, TAB3, TAB4, +MATERIAL, -MATERIAL, RESIZE, RESTORE, REMOVE_SCRIPT, XYZ+++, XYZ++, XYZ+, XYZ---, XYZ--, XYZ-, X+++, X++, X+, X---, X--, X-, Y+++, Y++, Y+, Y---, Y--, Y-, Z+++, Z++, Z+, Z---, Z--, Z-

Tab Function

Button named shown as following table rotates Z-Axis of HUD object in default configuration.

Button Name Factor [degree] Remarks
TAB1 0.0
TAB2 90.0
TAB3 180.0
TAB4 270.0 Not used in sample HUD

Button Prim Direction

"X-" side of prim for button to be faced forward. Other side face cannnot be handled to prevent miss oparations in other TAB page.

Button Face

PRODUCT_ID

HUD script and Client script needs PRODUCT_ID. PRODUCT_ID is used to generate listen channnel. Recomended to change product per product.

integer PRODUCT_ID = 7275;

HUD Script Data Input

HUD has two type script. Number of DB script can be one at least, or more as needed. It is recomended that free memory is 10 kbyte/script or upper. Please refer to the FreeMemory information when you save the script.

[FreeMemory] 16.42 / 64 kbyte @ `[monso] Hair Script V2 DB`
Script Name Data type Required Q'ty
[monso] Hair Script V2 HUD Material (Normal Map & Specular Map) 1
[monso] Hair Script V2 DB Texture (Diffuse Map) 1 or more as needed

Texte UUID should be defined in list listUUID on the head of each script. UUID List Maker is helpful for this data preparation.

list listUUID = [
// "TextureName", "TextureUUID"
"hair_mixed_basic8_root", "9f5f6ff2-957b-9328-fbf3-26003108c8e2",
"hair_mixed_basic8_root_alpha1", "23aa44a8-6e03-49a7-9657-711d6a59661f",
"hair_mixed_basic8_root_alpha2", "68e653d9-2695-80e3-c1d9-23fe5d3df5b4",
"SampleTex1", "44c78d32-845c-d586-b213-530eb7f7ecd9",
"SampleTex2", "50330856-2510-bb1c-4ff2-838aa7d706aa",
"SampleTex3", "9bfaf28e-88e4-9d6e-98af-4f208112f61f",
"SampleTex4", "cc5ac2fc-efeb-701a-92df-15bb28792cda",
"SampleTex5", "dead6094-76a7-9fa8-1630-cbad1ace8000",
"SampleTex6", "63c205c9-1f5a-c07c-1d0d-d42d5889a3b2",
"SampleTex7", "078a7d3d-f1e8-8b67-07ec-bc32598a47db",
"SampleTex8", "3fa95aa6-c0ae-16ca-ff40-d13f378994fa",
0];

Button and Texture and Material is associated with list listMATERIAL (HUD script) and list listTEXTURE (DB script). Horizontal Scale, Vertical scale and Repeats per meter is loaded from the product prim and duplicated automatically, so they are not necessary to input in HUD and DB script.

HUD script Button name for material (normal & specular) change is reserved as +MATERIAL & -MATERIAL;

list listMATERIAL = [
//  (NumOfData)
//  "PrimName", FaceNum(0-7), "TextureName(NomalMap)", "TextureName(SpecularMap)", <Specular_Color>, Specular_Glossiness, Specular_Environment
//  Note:All Face of sides: FaceNum=-1
//  Note:Buttom Name for material is reserved as "+MATERIAL" & "-MATERIAL".
5,
"hair1",  0, "hair_nm", "hair_sp", <1,1,1>, 70, 1, // Apply to single face
"hair2", -1, "hair_nm", "hair_sp", <1,1,1>, 70, 1, // Apply to all face
"hair3",  0, "hair_nm", "hair_sp", <1,1,1>, 70, 1, // Apply to multiple face
"hair3",  1, "hair_nm", "hair_sp", <1,1,1>, 70, 1,
"hair3",  2, "hair_nm", "hair_sp", <1,1,1>, 70, 1,
0];

DB script Button name for texture (diffuse map) change to be inputed manually;

list listTEXTURE = [
//  "ButtonName", (NumOfData)
//  "PrimName", FaceNum(0-7), "TextureName",
//  Note:RootPrim="root"
//  Note:All Face of sides: FaceNum=-1
"A01", 5,
"hair1",  0, "hair_mixed_basic8_root",        // Apply to single face
"hair2", -1, "hair_mixed_basic8_root_alpha1", // Apply to all face
"hair3",  0, "hair_mixed_basic8_root_alpha2", // Apply to multiple face
"hair3",  1, "hair_mixed_basic8_root_alpha2", // Apply to multiple face
"hair3",  2, "hair_mixed_basic8_root_alpha2", // Apply to multiple face

"A02", 5,
"hair1",  0, "SampleTex2", // Apply to single face
"hair2", -1, "SampleTex2", // Apply to all face
"hair3",  0, "SampleTex2", // Apply to multiple face
"hair3",  1, "SampleTex2", // Apply to multiple face
"hair3",  2, "SampleTex2", // Apply to multiple face

// *SNIP*
0];

Resize Function

Resize(XYZ) and Restore can be handled on both of HUD touch and dialog. Stretch can be handled on dialog only. Button RESIZE call the following dialog.

Resize Dialog

The following mode and factors are available for resize function in default configuration. Factors are defined in Client script.

Mode X Y Z
XYZ+ +1% +1% +1%
XYZ++ +5% +5% +5%
XYZ+++ +10% +10% +10%
XYZ- -1% -1% -1%
XYZ-- -5% -5% -5%
XYZ--- -10% -10% -10%
X+ +1%
X++ +5%
X+++ +10%
X- -1%
X-- -5%
X--- -10%
Y+ +1%
Y++ +5%
Y+++ +10%
Y- -1%
Y-- -5%
Y--- -10%
Z+ +1%
Z++ +5%
Z+++ +10%
Z- -1%
Z-- -5%
Z--- -10%

Script Delete Function

Button REMOVE_SCRIPT call the following dialog. Clicking OK will delete Client script with message for owner.

Resize Dialog

Instruction for CLIENT script

Client Script has PRODUCT_ID that must be the same as HUD script. There is no user input except PRODUCT_ID, but should be selected in accordance with mesh type of the product. There are two types of Client script.

Type Description
TypeA With resize function, for non-rigg mesh.
TypeB Without resize function, for rigged mesh.

Communication system and security

Communication method between HUD and Client is HTTP Protcol. HTTP Protcol is faster than usual method Listen.

But HTTP requests are throttled at approximately 25 requests per 20 seconds. HUD script freezes 0.8 seconds after texture change or resize to prevent crash.

Transmitting and receiving data (including texture UUIDs) between scripts is secured by encrypted with llXorBase64. It is difficult for cryptanalysis without leakage of encryption keys defined in each script.

About Payment

The charge is L$10,000.


monso hair HUD request

We want to make 5 main color packs and 1 selected color pack.

one main color pack includes

  • 8 main + 8 root colors in first tab
  • 8 ombre ぼかし染め + 8 highlight colors in second tab
  • one hair color needs 3 textures
  • one tab could be added for hair acc (hairband, ribbon.. )
  • resize and material on/off in third tab
  • 3 link buttons on side (for market or blog link)

Selected color pack includes

  • 12 main + 12 root colors in first tab
  • 12 ombre ぼかし染め + 12 highlight colors in second tab
  • one hair color needs 3 textures
  • one tab could be added for hair acc (hairband, ribbon.. )
  • resize and material on/off in third tab
  • 3 link buttons on side (for market or blog link)
  • wondering one hud can includes 16 + 16 colors in one tab ( if possible )

We hope hud contains script and texture information instead of in head we did before.

  • maybe it is impossible to take all colors in one demo hud then, demo user have to wear every hairs then they try other colors.
  • so we will make 6 demo huds and 1 demo hair.

if you want ask anything plz im morphine or sora anytime. i'll check e-mail. thank you always <33

key request;
string URI;
string name;
string str;
title()
{
llSetText("*UUID List Maker*\nDrop textures and Touch.", <1,1,1>, 1.0);
}
default
{
state_entry()
{
title();
}
touch_start(integer index)
{
if(llDetectedKey(0) == llGetOwner()){
integer i;
integer count = llGetInventoryNumber(INVENTORY_TEXTURE);
str = "// \"TextureName\", \"TextureUUID\"\n";
for(i = 0; i < count; i++){
name = llGetInventoryName(INVENTORY_TEXTURE, i);
str += "\"" + name + "\", \"" + (string)llGetInventoryKey(name) + "\",\n";
llSetText("Proccesing " + (string)i + "/" + (string)count + " " + name, <1,1,1>, 1.0);
}
}
llReleaseURL(URI);
request = llRequestURL();
title();
}
http_request(key id, string method, string body)
{
if(request == id){
request = "";
if (method == URL_REQUEST_GRANTED){
URI = body;
llLoadURL(llGetOwner(), "Copy the content to `listUUID` in DB Script.", URI);
}
}
else{
if(method == "GET"){
llSetContentType(id, CONTENT_TYPE_TEXT);
llHTTPResponse(id, 200, "list listUUID = [\n" + str + "0];");
//llHTTPResponse(id, 200, response);
llSetObjectDesc("");
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment