FIRE-1094: Script Count implementation

meow-7.2.2
Arrehn 2011-09-04 19:30:46 -04:00
parent 91de10d17d
commit ff7c7f47e5
13 changed files with 937 additions and 542 deletions

View File

@ -1,279 +1,594 @@
//http bridge draft 0.1.7
//Firestorm
//Tozh Taurog, Arrehn Oberlander
//
// global Variables
//
// Bridge platform
string bridgeURL;
string latestURL;
integer channel = 99;
integer debug = FALSE;
integer httpStatus = 200;
//key httpReqID;
integer FIRESTORM_VIEWER = 0;
integer UNKNOWN_VIEWER = 1;
integer keyViewerHandshake;
integer tryHandshakeOnce = 1;
// for teleport
integer MAX_TIME_TO_TP = 10; //should be set to 10 for normal use
vector mttVector; // target for llMoveToTarget() teleport
integer startTimer;
// for object details
vector opVector; // object position for llGetobjectDetails()
key opUUID; // key for llGetobjectDetails()
list opObjDetails; // result for llGetobjectDetails()
//
// helper functions
//
makeSane()
// try and resist "accidental" damage from other scripts
{
string myName = llGetScriptName();
integer n = llGetInventoryNumber(INVENTORY_SCRIPT);
if (n > 1)
{
llOwnerSay("WARNING: One or more scripts have been added to your Firestorm bridge! If you did not expect this message, delete your bridge now.");
llSleep(1.0);
while(n)
{
string s = llGetInventoryName(INVENTORY_SCRIPT,--n);
if (s != myName)
llSetScriptState(s,FALSE);
}
}
llParticleSystem([]);
llSetText("",ZERO_VECTOR,0.0);
llSetTexture("757c276e-6409-ad54-a862-ca89c04e4940",ALL_SIDES);
llSetTextureAnim(0,ALL_SIDES,1,1,1.0,1.0,1.0);
llAllowInventoryDrop(FALSE);
// make bridge inconspicuous
llSetScale(<0.01,0.01,0.01>);
llSetPos(<0.0,0.0,-0.15>);
llSetObjectDesc(llGetObjectName());
}
initBridge()
{
llRequestURL();
debugOutput("rezzed");
if(llGetAttached() != 0)
{
llRequestPermissions(llGetOwner(),PERMISSION_TAKE_CONTROLS);
}
//assume the worst and let the viewer convince us otherwise
keyViewerHandshake = UNKNOWN_VIEWER;
}
saveNewURL(string url)
{
latestURL = url;
}
parseCommand(key httpReqID, string msg)
{
debugOutput("Parsing original input: " + msg);
//remove the <llsd> </llsd> wrapper
integer end = llStringLength(msg) - llStringLength("</llsd>") -1;
string inner = llGetSubString(msg, 6, end - 1);
debugOutput("Parsing inner string: " + inner);
//remove the <string> </string> wrapper
end = llStringLength(inner) - llStringLength("</string>") -1;
string msgClean = llGetSubString(inner, 8, end);
debugOutput("Parsing final string: " + msgClean);
list commandList = llParseString2List(msgClean,["|"],[]);
//get command name
string cmd = llList2String(commandList,0);
debugOutput("Parsing command: " + cmd);
//Large If statement for command processing. Shame on you, LSL!
if (cmd == "URL Confirmed")
{
//we're in the right viewer, go on.
keyViewerHandshake = FIRESTORM_VIEWER;
} // URL Confirmed
else if (cmd == "llMoveToTarget")
{
// Get parameters
string params = "<" + llList2String(commandList,1) + ">";
debugOutput("Parsing params: " + params);
mttVector=(vector)params;
debugOutput("Parsing vector: " + (string)mttVector);
startTimer = llGetUnixTime();
llSetTimerEvent(0.05);
//llHTTPResponse(httpReqID, httpStatus, "<llsd><string>test response from llMoveToTarget</string></llsd>");
}// "llMoveToTarget"
else if (cmd == "llGetObjectDetails")
{
// Get parameters
opUUID = (key)llList2String(commandList, 1);
//string opV = "<" + llList2String(commandList,2) + ">";
//debugOutput("Parsing params: " + opV);
//opVector=(vector)opV;
//debugOutput("Parsing vector: " + (string)opVector);
opObjDetails = llGetObjectDetails(opUUID, ([OBJECT_POS]));
string body = "<llsd><string>" + llList2String(opObjDetails,0) + "</string></llsd>";
llHTTPResponse(httpReqID, httpStatus, body);
}// "llGetObjectDetails"
}
debugOutput(string msg)
{
if (debug)
{
llOwnerSay("BridgeDebug: " + msg);
}
}
//
// main
//
default
{
state_entry()
{
makeSane();
initBridge();
}
on_rez(integer i)
{
tryHandshakeOnce = 1;
llSetPrimitiveParams([PRIM_TEMP_ON_REZ,TRUE]);
llSetObjectDesc(llGetObjectName());
initBridge();
}
touch_start(integer total_number)
{
debugOutput("touched");
}
run_time_permissions(integer i)
{
if(i)
{
llTakeControls(1024,TRUE,TRUE);
}
}
changed(integer change)
{
if (change & CHANGED_REGION)
{
llRequestURL();
debugOutput("The region the bridge is in has changed.");
}
if (change & CHANGED_INVENTORY)
{
makeSane();
}
}
timer()
{
llSetTimerEvent(0.0);
vector loc = llGetPos(); // current position
vector targ = mttVector - loc;
//has to be less than 65m
float dist = llVecMag(targ);
debugOutput("current: " + (string)loc + " target: " + (string)targ + " tp distance: " + (string)dist);
//if we are out of time or distance - stop
if((dist < 2.0) || (llGetUnixTime() - MAX_TIME_TO_TP > startTimer) || (mttVector == loc))
{
llStopMoveToTarget();
//llHTTPResponse(httpReqID, httpStatus, "Test MoveToTarget body");
return;
}
if (dist < 65)
{
debugOutput("One jump to :" + (string)mttVector);
llMoveToTarget(mttVector, 0.05);
}
else
{
debugOutput("Multiple jump to :" + (string)(loc+llVecNorm(targ)*60));
llMoveToTarget(loc+llVecNorm(targ)*60, 0.05);
}
// try again.
llSetTimerEvent(.05);
}
http_request(key ID, string Method, string Body)
{
//httpReqID = ID;
debugOutput("Received HTTP " + Method + " message. Command body: " + Body);
if (Method == URL_REQUEST_GRANTED)
{
saveNewURL(Body);
debugOutput ("keyViewerHandshake " + (string)keyViewerHandshake + " tryHandshakeOnce " + (string)tryHandshakeOnce);
//Saying URL to owner
if (keyViewerHandshake == FIRESTORM_VIEWER || tryHandshakeOnce == 1)
{
debugOutput ("Firestorm viewer and handshake");
llOwnerSay("<bridgeURL>" + latestURL+ "</bridgeURL>");
tryHandshakeOnce = 0;
}
else
{
//we're in a wrong viewer. just sit quietly
llDetachFromAvatar();
}
}
else if (Method == URL_REQUEST_DENIED)
{
saveNewURL("");
debugOutput("No URLs free !");
//keep trying?
llRequestURL();
}
else if (Method == "GET")
{
parseCommand(ID, Body);
llHTTPResponse(ID, httpStatus, "<llsd><string> command=\"GET\" text=\"get - Hello Bridge!</string></llsd>");
}
else if (Method == "PUT")
{
llHTTPResponse(ID, httpStatus, "<llsd><string>PUT - Hello Bridge!</string></llsd>");
}
else if (Method == "POST")
{
parseCommand(ID, Body);
llHTTPResponse(ID, httpStatus, "<llsd><string>POST - Hello Bridge!</string></llsd>");
}
}
}
//http bridge script 3.0.1.22450
//Firestorm
//Tozh Taurog, Arrehn Oberlander
//
// Global Variables and CONSTANTS
//
// Shared
integer timerMask; // Every function that shares the timer needs a TIMER_ entry below.
float timerInterval; // float, seconds. Always set this when using llSetTimerEvent
float timerElapsed; // floats, seconds since last tick.
integer TIMER_TP = 1;
integer TIMER_FLIGHT = 2;
// Bridge platform
integer FIRESTORM_VIEWER = 0;
integer UNKNOWN_VIEWER = 1;
integer META_CONTROL = 1024; //control value to do nothing; for no-script sims
string bridgeURL;
string latestURL;
integer channel = 99;
integer debug = FALSE;
integer httpStatus = 200;
//key httpReqID;
integer keyViewerHandshake;
integer tryHandshakeOnce = TRUE;
key owner;
// Teleport
integer MAX_TIME_TO_TP = 10; // (seconds) should be set to 10 for normal use
float TP_TIMER_TICK = 0.05;
integer TIMER_TYPE_NONE = 0;
integer TIMER_TYPE_TP = 1;
integer TIMER_TYPE_FLIGHT = 2;
integer timerType = TIMER_TYPE_NONE;
vector mttVector; // target for llMoveToTarget() teleport
integer startTPTimer;
// Object details (improved radar)
vector opVector; // object position for llGetobjectDetails()
key opUUID; // key for llGetobjectDetails()
list opObjDetails; // result for llGetobjectDetails()
// Flight assist
float MIN_SPEED = 2.0;
float WANT_SPEED = 20.0;
float MAX_SPEED = 25.0;
float MIN_TIME = 1.0;
float DEFAULT_BOOST = 0.5;
float FAST_TICK = 0.1;
float SLOW_TICK = 1.0;
float LONG_TIME = 5.0; // reset boost if no work in a long time
float MIN_BOOST_HEIGHT = 72.0;
float MIN_BOOST_CLEARANCE = 36.0;
integer useFlightAssist = 1;
integer pendingFlightFeather = 0;
float last_alt;
float last_time;
float last_move;
float boost;
integer controls;
integer flying = -1;
integer falling = -1;
integer hovering = -1;
integer dimmed = -1;
float last_boost_height;
float average_boost;
//
// Bridge platform helper functions
//
makeSane()
// try and resist "accidental" damage from other scripts
// reset persistent prim attributes frequently set via scripts, try and stop other scripts
{
string myName = llGetScriptName();
integer n = llGetInventoryNumber(INVENTORY_SCRIPT);
if (n > 1)
{
llOwnerSay("NOTICE: One or more scripts have been added to your Firestorm bridge! If you did not expect this message, use the Firestorm 'Avatar/Avatar Health/Recreate Bridge' menu option re-create your bridge now.");
llSleep(1.0);
while(n)
{
string s = llGetInventoryName(INVENTORY_SCRIPT,--n);
if (s != myName)
llSetScriptState(s,FALSE);
}
}
llParticleSystem([]);
llSetText("",ZERO_VECTOR,0.0);
llSetTexture("757c276e-6409-ad54-a862-ca89c04e4940",ALL_SIDES);
llSetTextureAnim(0,ALL_SIDES,1,1,1.0,1.0,1.0);
llAllowInventoryDrop(FALSE);
// make bridge inconspicuous
llSetScale(<0.01,0.01,0.01>);
llSetPos(<0.0,0.0,-0.15>);
llSetObjectDesc(llGetObjectName());
}
initBridge()
{
llRequestURL();
debugOutput("rezzed");
owner = llGetOwner();
if(llGetAttached() != 0)
{
llRequestPermissions(llGetOwner(),PERMISSION_TAKE_CONTROLS);
}
//assume the worst and let the viewer convince us otherwise
keyViewerHandshake = UNKNOWN_VIEWER;
}
saveNewURL(string url)
{
latestURL = url;
}
parseCommand(key httpReqID, string msg)
{
debugOutput("Parsing original input: " + msg);
//remove the <llsd> </llsd> wrapper
integer end = llStringLength(msg) - llStringLength("</llsd>") -1;
string inner = llGetSubString(msg, 6, end - 1);
debugOutput("Parsing inner string: " + inner);
//remove the <string> </string> wrapper
end = llStringLength(inner) - llStringLength("</string>") -1;
string msgClean = llGetSubString(inner, 8, end);
debugOutput("Parsing final string: " + msgClean);
list commandList = llParseString2List(msgClean,["|"],[]);
//get command name
string cmd = llList2String(commandList,0);
debugOutput("Parsing command: " + cmd);
//Large If statement for command processing. Shame on you, LSL!
if (cmd == "URL Confirmed")
{
//we're in the right viewer, go on.
keyViewerHandshake = FIRESTORM_VIEWER;
} // URL Confirmed
if (cmd == "UseLSLFlightAssist")
{
string params = "<" + llList2String(commandList,1) + ">";
debugOutput("Parsing params: " + params);
useFlightAssist = llList2Integer(commandList,1);
if (useFlightAssist)
{
flight_init();
}
else
{
if (timerMask & TIMER_FLIGHT)
timerMask = timerMask ^ TIMER_FLIGHT; // remove flight from event counter
}
}
else if (cmd == "llMoveToTarget")
{
// Get parameters
string params = "<" + llList2String(commandList,1) + ">";
debugOutput("Parsing params: " + params);
mttVector=(vector)params;
debugOutput("Parsing vector: " + (string)mttVector);
startTPTimer = llGetUnixTime();
// tp commands immediately configure a TP timer consumer
timerMask = timerMask | TIMER_TP;
if ((timerInterval > TP_TIMER_TICK) || (timerInterval == 0))
{
timerInterval = TP_TIMER_TICK;
llSetTimerEvent(timerInterval);
}
//llHTTPResponse(httpReqID, httpStatus, "<llsd><string>test response from llMoveToTarget</string></llsd>");
}// "llMoveToTarget"
else if (cmd == "llGetObjectDetails")
{
// Get parameters
opUUID = (key)llList2String(commandList, 1);
//string opV = "<" + llList2String(commandList,2) + ">";
//debugOutput("Parsing params: " + opV);
//opVector=(vector)opV;
//debugOutput("Parsing vector: " + (string)opVector);
opObjDetails = llGetObjectDetails(opUUID, ([OBJECT_POS]));
string body = "<llsd><string>" + llList2String(opObjDetails,0) + "</string></llsd>";
llHTTPResponse(httpReqID, httpStatus, body);
}// "llGetObjectDetails"
else if ( cmd == "getScriptInfo")
{
key target = (key)llList2String(commandList, 1);
getScriptInfo(target);
}
}
debugOutput(string msg)
{
if (debug)
{
llOwnerSay("BridgeDebug: " + msg);
}
}
//
// Get Script Count
//
getScriptInfo(key target)
{
list details = llGetObjectDetails(target, ([OBJECT_NAME,
OBJECT_TOTAL_SCRIPT_COUNT, OBJECT_RUNNING_SCRIPT_COUNT, OBJECT_SCRIPT_MEMORY, OBJECT_SCRIPT_TIME]));
llOwnerSay("'"+(string)llList2String(details,0) +
"' [" + (string)llList2Integer(details,2) + "/" + (string)llList2Integer(details,1) + "] running scripts. " +
(string)(llList2Integer(details,3)/1024) + "Kb consumed for " + (string)llList2Float(details,4) + " seconds of cpu time.");
}
//
// Teleport Helper functions
//
tpMoveStep()
{
vector loc = llGetPos(); // current position
vector targ = mttVector - loc;
//has to be less than 65m
float dist = llVecMag(targ);
debugOutput("current: " + (string)loc + " target: " + (string)targ + " tp distance: " + (string)dist);
//if we are out of time or distance - stop
if((dist < 2.0) || (llGetUnixTime() - MAX_TIME_TO_TP > startTPTimer) || (mttVector == loc))
{
llStopMoveToTarget();
timerMask = timerMask ^ TIMER_TP; // remove our timer if we finish
}
if (dist < 65)
{
debugOutput("One jump to :" + (string)mttVector);
llMoveToTarget(mttVector, TP_TIMER_TICK);
}
else
{
debugOutput("Multiple jump to :" + (string)(loc+llVecNorm(targ)*60));
llMoveToTarget(loc+llVecNorm(targ)*60, TP_TIMER_TICK);
}
// if we get this far, set our the timer for the next tick
if (timerInterval > TP_TIMER_TICK)
{
timerInterval = TP_TIMER_TICK;
llSetTimerEvent(timerInterval);
}
}
//
// Flight Assist Functions
//
flight_set_hover(integer active)
{
debugOutput("Flight:set_hover " + (string)active);
if(active == hovering) return;
hovering = active;
if(hovering)
llSetForce(<0,0,9.8> * llGetMass(), FALSE);
else
llSetForce(<0,0,0>, FALSE);
}
flight_set_tick(float tick)
// positively intializes a spot for us in the eventTimer.
{
debugOutput("Flight:set_tick " + (string)tick);
timerMask = timerMask | TIMER_FLIGHT;
timerInterval = tick;
if (timerMask == TIMER_FLIGHT)
{
llSetTimerEvent(timerInterval);
}
else if ((timerInterval > tick) || (timerInterval < 0.1))
{
llSetTimerEvent(timerInterval);
}
}
flight_check_boost()
{
debugOutput("Flight:check_boost ");
// Sleep if we don't have controls
if(controls <= 0)
{
flight_set_tick(SLOW_TICK);
return;
}
flying = 1;
falling = 0;
integer info = llGetAgentInfo(owner);
// Sleep if not flying
if((info & AGENT_FLYING) == 0)
{
debugOutput("not flying");
flight_set_hover(FALSE);
falling = (info & AGENT_IN_AIR) != 0;
flying = 0;
boost = 0;
flight_set_tick(SLOW_TICK);
return;
}
// Otherwise, we may be flying = look up further details
vector pos = llGetPos();
if(pos.z < last_boost_height / 2) // trim running average of boost if big altitude drop
average_boost = average_boost * (pos.z / last_boost_height)
+ DEFAULT_BOOST * (1.0 - pos.z / last_boost_height);
// Sleep if low to the ground
if(pos.z < MIN_BOOST_HEIGHT || pos.z - llGround(<0,0,0>) < MIN_BOOST_CLEARANCE)
{
flight_set_hover(FALSE);
flight_set_tick(SLOW_TICK);
boost = 0;
return;
}
// Otherwise hover and get even more details
flight_set_hover(TRUE);
vector vel = llGetVel();
float time = llGetTime();
float speed = vel.z;
float target = WANT_SPEED;
float window = WANT_SPEED / 20;
if(speed > 0)
last_move = time;
if(time - last_time >= LONG_TIME)
boost = 0;
else
{
if(speed < target - window)
{
if(boost == 0)
boost = average_boost;
if(time - last_move > MIN_TIME) boost += 0.4;
else if(speed < target * 0.25) boost += 0.2;
else if(speed < target * 0.5 ) boost += 0.1;
else if(speed < target * 0.75) boost += 0.05;
else if(speed < target - window * 4) boost += 0.02;
else boost += 0.01;
}
else if(speed > MAX_SPEED) boost -= 0.5;
else if(speed > target + window * 4) boost -= 0.1;
else if(speed > target + window * 2) boost -= 0.03;
else if(speed > target + window) boost -= 0.01;
if(boost <= 0)
boost = 0;
if(boost > 0)
{
llApplyImpulse(<0,0,boost> * llGetMass(), FALSE);
average_boost = average_boost * 0.9 + boost * 0.1; // 10 sample running average
last_boost_height = pos.z;
}
}
// If we find we need a correction
if(boost)
{
flight_set_tick(FAST_TICK);
}
else
flight_set_tick(SLOW_TICK);
last_alt = pos.z;
last_time = time;
}
flight_take_controls()
{
llTakeControls(CONTROL_UP|CONTROL_DOWN,TRUE,TRUE);
}
flight_request_perms()
{
flight_take_controls();
}
flight_init()
{
debugOutput("Flight:init ");
// initialize flight vars
useFlightAssist = TRUE;
boost = 0;
flying = -1;
falling = -1;
hovering = -1;
if(llGetAttached())
flight_request_perms();
flight_set_tick(SLOW_TICK);
}
//
// MAIN
//
default
{
state_entry()
{
makeSane();
initBridge();
}
on_rez(integer i)
// We don't want to be rezzed without being attached. Insure we don't create litter.
{
llSetPrimitiveParams([PRIM_TEMP_ON_REZ,TRUE]);
}
attach(key k)
// Initialize bridge functionality when worn as an attachment
{
if (k != NULL_KEY)
{
tryHandshakeOnce = TRUE;
initBridge();
}
}
touch_start(integer total_number)
{
debugOutput("touched");
}
run_time_permissions(integer i)
{
if (i)
{
if(useFlightAssist)
flight_take_controls();
else
{
//take control for value that does nothing, in order to work in no-script sims
llTakeControls(META_CONTROL,TRUE,TRUE);
}
}
}
control(key id, integer level, integer edge)
{
if(llGetAgentInfo(owner) & AGENT_FLYING)
{
controls = 0;
if(level & CONTROL_UP) controls++;
if(level & CONTROL_DOWN) controls--;
if (controls > 0)
flight_check_boost();
}
}
changed(integer change)
{
if (change & CHANGED_REGION)
{
llRequestURL();
debugOutput("The region the bridge is in has changed.");
}
if (change & CHANGED_INVENTORY)
{
makeSane();
}
}
timer()
{
debugOutput("tick. mask = "+(string)timerMask);
// Multiple functions may have to share the timer
// Do not assume you know the timer interval in advance.
// Each consumer will have to check whether the interval that has passed
// since last tick is long enough to trigger functionality.
// every tick, stop ourself. Consumers are responsible for restarting the timer
// each time they get a tick, if they still need it
llSetTimerEvent(0);
timerInterval = 0;
timerElapsed = llGetAndResetTime();
// All consumers should have an entry here, and must manage their interval.
// Consumers should reset the timer only of they need it faster, otherwise
// leave it as it is. Order this list by fastest timer consumers first.
if (timerMask & TIMER_TP)
{
if (timerElapsed > TP_TIMER_TICK)
tpMoveStep();
return; // teleports shortcut other timers
}
if (timerMask & TIMER_FLIGHT)
{
flight_check_boost();
}
}
http_request(key ID, string Method, string Body)
{
//httpReqID = ID;
debugOutput("Received HTTP " + Method + " message. Command body: " + Body);
if (Method == URL_REQUEST_GRANTED)
{
saveNewURL(Body);
debugOutput ("keyViewerHandshake " + (string)keyViewerHandshake + " tryHandshakeOnce " + (string)tryHandshakeOnce);
//Saying URL to owner
if (keyViewerHandshake == FIRESTORM_VIEWER || tryHandshakeOnce == 1)
{
debugOutput ("Firestorm viewer and handshake");
llOwnerSay("<bridgeURL>" + latestURL+ "</bridgeURL>");
tryHandshakeOnce = 0;
}
else
{
//we're in a wrong viewer. just sit quietly
llDetachFromAvatar();
}
}
else if (Method == URL_REQUEST_DENIED)
{
saveNewURL("");
debugOutput("No URLs free !");
//keep trying?
llRequestURL();
}
else if (Method == "GET")
{
parseCommand(ID, Body);
llHTTPResponse(ID, httpStatus, "<llsd><string> command=\"GET\" text=\"get - Hello Bridge!</string></llsd>");
}
else if (Method == "PUT")
{
llHTTPResponse(ID, httpStatus, "<llsd><string>PUT - Hello Bridge!</string></llsd>");
}
else if (Method == "POST")
{
parseCommand(ID, Body);
llHTTPResponse(ID, httpStatus, "<llsd><string>POST - Hello Bridge!</string></llsd>");
}
}
}
//
//Flight assist code
//
//Copyright (c) 2005, Argent Stonecutter & player
//All rights reserved.
//
//Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
//
// * Redistributions in modifiable form must retain the above copyright notice, this list of conditions and the following disclaimer.
// * Redistributions in non-modifiable form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
// * Neither the name of Argent Stonecutter nor his player may be used to endorse or promote products derived from this software without specific prior written permission.
//
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// END //

View File

@ -5712,6 +5712,17 @@ class LLWorldPlaceProfile : public view_listener_t
}
};
void handle_script_info()
{
LLUUID object_id;
if (LLSelectMgr::getInstance()->getSelection()->getPrimaryObject())
{
object_id = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()->mID;
llinfos << "Reporting Script Info for object: " << object_id.asString() << llendl;
FSLSLBridge::instance().viewerToLSL("getScriptInfo|" + object_id.asString());
}
}
void handle_look_at_selection(const LLSD& param)
{
const F32 PADDING_FACTOR = 1.75f;
@ -8757,6 +8768,7 @@ void initialize_menus()
view_listener_t::addMenu(new LLToolsReleaseKeys(), "Tools.ReleaseKeys");
view_listener_t::addMenu(new LLToolsEnableReleaseKeys(), "Tools.EnableReleaseKeys");
commit.add("Tools.LookAtSelection", boost::bind(&handle_look_at_selection, _2));
commit.add("Tools.ScriptInfo",boost::bind(&handle_script_info));
commit.add("Tools.BuyOrTake", boost::bind(&handle_buy_or_take));
commit.add("Tools.TakeCopy", boost::bind(&handle_take_copy));
view_listener_t::addMenu(new LLToolsSaveToInventory(), "Tools.SaveToInventory");

View File

@ -101,6 +101,7 @@ void handle_object_open();
void handle_buy();
void handle_take_copy();
void handle_look_at_selection(const LLSD& param);
void handle_script_info();
void handle_zoom_to_object(LLUUID object_id);
void handle_buy_land();

View File

@ -124,6 +124,13 @@
<menu_item_call.on_enable
function="Object.EnableInspect" />
</menu_item_call>
<menu_item_call
enabled="true"
label="Script Info"
name="ScriptInfo">
<menu_item_call.on_click
function="Tools.ScriptInfo" />
</menu_item_call>
<menu_item_call
enabled="true"
label="Derender"

View File

@ -123,6 +123,13 @@ name="Edit Outfit">
<menu_item_call.on_visible
function="IsGodCustomerService"/>
</menu_item_call>
<menu_item_call
enabled="true"
label="Script Info"
name="ScriptInfo">
<menu_item_call.on_click
function="Tools.ScriptInfo" />
</menu_item_call>
<menu_item_separator
layout="topleft" />
<menu_item_call

View File

@ -121,4 +121,11 @@
<menu_item_call.on_click
function="Object.Derender" />
</menu_item_call>
<menu_item_call
enabled="true"
label="Script Info"
name="ScriptInfo">
<menu_item_call.on_click
function="Tools.ScriptInfo" />
</menu_item_call>
</context_menu>

View File

@ -261,4 +261,11 @@
<menu_item_call.on_visible
function="IsGodCustomerService"/>
</menu_item_call>
<menu_item_call
enabled="true"
label="Script Info"
name="ScriptInfo">
<menu_item_call.on_click
function="Tools.ScriptInfo" />
</menu_item_call>
</context_menu>

View File

@ -1,257 +1,264 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<context_menu
layout="topleft"
name="Object Pie">
<menu_item_call
enabled="false"
label="Touch"
name="Object Touch">
<menu_item_call.on_click
function="Object.Touch" />
<menu_item_call.on_enable
function="Object.EnableTouch"
name="EnableTouch"
parameter="Touch" />
</menu_item_call>
<menu_item_call
label="Edit"
name="Edit...">
<menu_item_call.on_click
function="Object.Edit" />
<menu_item_call.on_enable
function="EnableEdit"/>
</menu_item_call>
<menu_item_call
label="Build"
name="Build">
<menu_item_call.on_click
function="Object.Build" />
<menu_item_call.on_enable
function="EnableEdit"/>
</menu_item_call>
<menu_item_call
enabled="false"
label="Open"
name="Open">
<menu_item_call.on_click
function="Object.Open" />
<menu_item_call.on_enable
function="Object.EnableOpen" />
</menu_item_call>
<menu_item_separator layout="topleft" />
<menu_item_call
enabled="false"
label="Sit Here"
name="Object Sit">
<menu_item_call.on_click
function="Object.SitOrStand" />
<menu_item_call.on_enable
function="Object.EnableSit" />
</menu_item_call>
<menu_item_separator layout="topleft" />
<menu_item_call
enabled="false"
label="Stand Up"
name="Object Stand Up">
<menu_item_call.on_click
function="Object.SitOrStand" />
<menu_item_call.on_enable
function="Object.EnableStandUp" />
</menu_item_call>
<menu_item_separator layout="topleft" />
<context_menu
label="Object"
name="Object Features">
<menu_item_call
label="Profile"
name="Object Inspect">
<menu_item_call.on_click
function="Object.Inspect" />
<menu_item_call.on_enable
function="Object.EnableInspect" />
</menu_item_call>
<menu_item_call
label="Inspect"
name="Object_Inspect_Floater">
<menu_item_call.on_click
function="Floater.Show"
parameter="inspect" />
</menu_item_call>
<menu_item_separator layout="topleft" />
<menu_item_call
enabled="false"
label="Link"
name="Object Link">
<menu_item_call.on_click
function="Tools.Link" />
<menu_item_call.on_enable
function="Tools.EnableLink" />
</menu_item_call>
<menu_item_call
enabled="false"
label="Unlink"
name="Object Unlink">
<menu_item_call.on_click
function="Tools.Unlink" />
<menu_item_call.on_enable
function="Tools.EnableUnlink" />
</menu_item_call>
<menu_item_check label="Edit Linked Parts" name="Object Edit Linked Parts">
<menu_item_check.on_check control="EditLinkedParts" />
<menu_item_check.on_click function="Tools.EditLinkedParts" parameter="EditLinkedParts" />
<menu_item_check.on_enable function="Tools.EnableToolNotPie" />
</menu_item_check>
<menu_item_separator layout="topleft" />
<menu_item_call
label="Reset Scripts"
name="Object Reset Scripts">
<menu_item_call.on_click
function="Tools.SelectedScriptAction"
parameter="reset" />
<menu_item_call.on_enable
function="EditableSelected" />
</menu_item_call>
<menu_item_call
label="Run Scripts"
name="Object Set Scripts to Running">
<menu_item_call.on_click
function="Tools.SelectedScriptAction"
parameter="start" />
<menu_item_call.on_enable
function="EditableSelected" />
</menu_item_call>
<menu_item_call
label="Stop Scripts"
name="Object Set Scripts to Not Running">
<menu_item_call.on_click
function="Tools.SelectedScriptAction"
parameter="stop" />
<menu_item_call.on_enable
function="EditableSelected" />
</menu_item_call>
</context_menu>
<menu_item_call
label="Zoom In"
name="Zoom In">
<menu_item_call.on_click
function="Object.ZoomIn" />
</menu_item_call>
<menu_item_separator layout="topleft" />
<context_menu
label="Put On"
name="Put On" >
<menu_item_call
enabled="false"
label="Wear"
name="Wear">
<menu_item_call.on_click
function="Object.AttachToAvatar" />
<menu_item_call.on_enable
function="Object.EnableWear" />
</menu_item_call>
<menu_item_call
enabled="false"
label="Add"
name="Add">
<menu_item_call.on_click
function="Object.AttachAddToAvatar" />
<menu_item_call.on_enable
function="Object.EnableWear" />
</menu_item_call>
<context_menu
label="Attach"
name="Object Attach" />
<context_menu
label="Attach HUD"
name="Object Attach HUD" />
</context_menu>
<context_menu
label="Annoyance"
name="Remove">
<menu_item_call
enabled="false"
label="Report Abuse"
name="Report Abuse...">
<menu_item_call.on_click
function="Object.ReportAbuse" />
<menu_item_call.on_enable
function="Object.EnableReportAbuse" />
</menu_item_call>
<menu_item_call
enabled="false"
label="Block"
name="Object Mute">
<menu_item_call.on_click
function="Object.Mute" />
<menu_item_call.on_enable
function="Object.EnableMute" />
</menu_item_call>
</context_menu>
<menu_item_separator layout="topleft" />
<!-- Derender -->
<menu_item_call
enabled="true"
label="Derender"
name="Derender">
<menu_item_call.on_click
function="Object.Derender" />
</menu_item_call>
<!-- /Derender -->
<menu_item_call
enabled="false"
label="Return"
name="Return...">
<menu_item_call.on_click
function="Object.Return" />
<menu_item_call.on_enable
function="Object.EnableReturn" />
</menu_item_call>
<menu_item_call
label="Take"
layout="topleft"
name="Pie Object Take">
<menu_item_call.on_click
function="Object.Take"/>
<menu_item_call.on_enable
function="Object.VisibleTake"/>
</menu_item_call>
<menu_item_call
enabled="false"
label="Take Copy"
name="Take Copy">
<menu_item_call.on_click
function="Tools.TakeCopy" />
<menu_item_call.on_enable
function="Tools.EnableTakeCopy" />
</menu_item_call>
<menu_item_call
enabled="false"
label="Pay"
name="Pay...">
<menu_item_call.on_click
function="PayObject" />
<menu_item_call.on_enable
function="EnablePayObject" />
</menu_item_call>
<menu_item_call
enabled="false"
label="Buy"
name="Buy...">
<menu_item_call.on_click
function="Object.Buy" />
<menu_item_call.on_enable
function="Object.EnableBuy" />
</menu_item_call>
<menu_item_separator layout="topleft" />
<menu_item_call
enabled="false"
label="Delete"
name="Delete">
<menu_item_call.on_click
function="Object.Delete" />
<menu_item_call.on_enable
function="Object.EnableDelete" />
</menu_item_call>
</context_menu>
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<context_menu
layout="topleft"
name="Object Pie">
<menu_item_call
enabled="false"
label="Touch"
name="Object Touch">
<menu_item_call.on_click
function="Object.Touch" />
<menu_item_call.on_enable
function="Object.EnableTouch"
name="EnableTouch"
parameter="Touch" />
</menu_item_call>
<menu_item_call
label="Edit"
name="Edit...">
<menu_item_call.on_click
function="Object.Edit" />
<menu_item_call.on_enable
function="EnableEdit"/>
</menu_item_call>
<menu_item_call
label="Build"
name="Build">
<menu_item_call.on_click
function="Object.Build" />
<menu_item_call.on_enable
function="EnableEdit"/>
</menu_item_call>
<menu_item_call
enabled="false"
label="Open"
name="Open">
<menu_item_call.on_click
function="Object.Open" />
<menu_item_call.on_enable
function="Object.EnableOpen" />
</menu_item_call>
<menu_item_separator layout="topleft" />
<menu_item_call
enabled="false"
label="Sit Here"
name="Object Sit">
<menu_item_call.on_click
function="Object.SitOrStand" />
<menu_item_call.on_enable
function="Object.EnableSit" />
</menu_item_call>
<menu_item_separator layout="topleft" />
<menu_item_call
enabled="false"
label="Stand Up"
name="Object Stand Up">
<menu_item_call.on_click
function="Object.SitOrStand" />
<menu_item_call.on_enable
function="Object.EnableStandUp" />
</menu_item_call>
<menu_item_separator layout="topleft" />
<context_menu
label="Object"
name="Object Features">
<menu_item_call
label="Profile"
name="Object Inspect">
<menu_item_call.on_click
function="Object.Inspect" />
<menu_item_call.on_enable
function="Object.EnableInspect" />
</menu_item_call>
<menu_item_call
label="Inspect"
name="Object_Inspect_Floater">
<menu_item_call.on_click
function="Floater.Show"
parameter="inspect" />
</menu_item_call>
<menu_item_call
enabled="true"
label="Script Info"
name="ScriptInfo">
<menu_item_call.on_click
function="Tools.ScriptInfo" />
<menu_item_separator layout="topleft" />
<menu_item_call
enabled="false"
label="Link"
name="Object Link">
<menu_item_call.on_click
function="Tools.Link" />
<menu_item_call.on_enable
function="Tools.EnableLink" />
</menu_item_call>
<menu_item_call
enabled="false"
label="Unlink"
name="Object Unlink">
<menu_item_call.on_click
function="Tools.Unlink" />
<menu_item_call.on_enable
function="Tools.EnableUnlink" />
</menu_item_call>
<menu_item_check label="Edit Linked Parts" name="Object Edit Linked Parts">
<menu_item_check.on_check control="EditLinkedParts" />
<menu_item_check.on_click function="Tools.EditLinkedParts" parameter="EditLinkedParts" />
<menu_item_check.on_enable function="Tools.EnableToolNotPie" />
</menu_item_check>
<menu_item_separator layout="topleft" />
<menu_item_call
label="Reset Scripts"
name="Object Reset Scripts">
<menu_item_call.on_click
function="Tools.SelectedScriptAction"
parameter="reset" />
<menu_item_call.on_enable
function="EditableSelected" />
</menu_item_call>
<menu_item_call
label="Run Scripts"
name="Object Set Scripts to Running">
<menu_item_call.on_click
function="Tools.SelectedScriptAction"
parameter="start" />
<menu_item_call.on_enable
function="EditableSelected" />
</menu_item_call>
<menu_item_call
label="Stop Scripts"
name="Object Set Scripts to Not Running">
<menu_item_call.on_click
function="Tools.SelectedScriptAction"
parameter="stop" />
<menu_item_call.on_enable
function="EditableSelected" />
</menu_item_call>
</context_menu>
<menu_item_call
label="Zoom In"
name="Zoom In">
<menu_item_call.on_click
function="Object.ZoomIn" />
</menu_item_call>
<menu_item_separator layout="topleft" />
<context_menu
label="Put On"
name="Put On" >
<menu_item_call
enabled="false"
label="Wear"
name="Wear">
<menu_item_call.on_click
function="Object.AttachToAvatar" />
<menu_item_call.on_enable
function="Object.EnableWear" />
</menu_item_call>
<menu_item_call
enabled="false"
label="Add"
name="Add">
<menu_item_call.on_click
function="Object.AttachAddToAvatar" />
<menu_item_call.on_enable
function="Object.EnableWear" />
</menu_item_call>
<context_menu
label="Attach"
name="Object Attach" />
<context_menu
label="Attach HUD"
name="Object Attach HUD" />
</context_menu>
<context_menu
label="Annoyance"
name="Remove">
<menu_item_call
enabled="false"
label="Report Abuse"
name="Report Abuse...">
<menu_item_call.on_click
function="Object.ReportAbuse" />
<menu_item_call.on_enable
function="Object.EnableReportAbuse" />
</menu_item_call>
<menu_item_call
enabled="false"
label="Block"
name="Object Mute">
<menu_item_call.on_click
function="Object.Mute" />
<menu_item_call.on_enable
function="Object.EnableMute" />
</menu_item_call>
</context_menu>
<menu_item_separator layout="topleft" />
<!-- Derender -->
<menu_item_call
enabled="true"
label="Derender"
name="Derender">
<menu_item_call.on_click
function="Object.Derender" />
</menu_item_call>
<!-- /Derender -->
<menu_item_call
enabled="false"
label="Return"
name="Return...">
<menu_item_call.on_click
function="Object.Return" />
<menu_item_call.on_enable
function="Object.EnableReturn" />
</menu_item_call>
<menu_item_call
label="Take"
layout="topleft"
name="Pie Object Take">
<menu_item_call.on_click
function="Object.Take"/>
<menu_item_call.on_enable
function="Object.VisibleTake"/>
</menu_item_call>
<menu_item_call
enabled="false"
label="Take Copy"
name="Take Copy">
<menu_item_call.on_click
function="Tools.TakeCopy" />
<menu_item_call.on_enable
function="Tools.EnableTakeCopy" />
</menu_item_call>
<menu_item_call
enabled="false"
label="Pay"
name="Pay...">
<menu_item_call.on_click
function="PayObject" />
<menu_item_call.on_enable
function="EnablePayObject" />
</menu_item_call>
<menu_item_call
enabled="false"
label="Buy"
name="Buy...">
<menu_item_call.on_click
function="Object.Buy" />
<menu_item_call.on_enable
function="Object.EnableBuy" />
</menu_item_call>
<menu_item_separator layout="topleft" />
<menu_item_call
enabled="false"
label="Delete"
name="Delete">
<menu_item_call.on_click
function="Object.Delete" />
<menu_item_call.on_enable
function="Object.EnableDelete" />
</menu_item_call>
</context_menu>

View File

@ -103,7 +103,13 @@
<pie_slice.on_visible
function="IsGodCustomerService"/>
</pie_slice>
<pie_separator name="script count placeholder" />
<pie_slice
enabled="true"
label="Script Info"
name="ScriptInfo">
<pie_slice.on_click
function="Tools.ScriptInfo" />
</pie_slice>
<pie_slice
label="Call"
name="Call">

View File

@ -23,7 +23,13 @@
label="More &gt;">
<pie_separator />
<pie_separator name="script_count_placeholder" />
<pie_slice
enabled="true"
label="Script Info"
name="ScriptInfo">
<pie_slice.on_click
function="Tools.ScriptInfo" />
</pie_slice>
<pie_slice
enabled="false"
label="Touch"

View File

@ -103,7 +103,13 @@
<pie_slice.on_visible
function="IsGodCustomerService"/>
</pie_slice>
<pie_separator name="script count placeholder" />
<pie_slice
enabled="true"
label="Script Info"
name="ScriptInfo">
<pie_slice.on_click
function="Tools.ScriptInfo" />
</pie_slice>
<pie_slice
label="Call"
name="Call">
@ -137,7 +143,8 @@
<pie_slice.on_click
function="Object.Derender" />
</pie_slice>
</pie_menu>
<pie_slice

View File

@ -238,7 +238,13 @@
<pie_slice.on_enable
function="Self.EnableStandUp" />
</pie_slice>
<pie_separator name="script_count_placeholder" />
<pie_slice
enabled="true"
label="Script Info"
name="ScriptInfo">
<pie_slice.on_click
function="Tools.ScriptInfo" />
</pie_slice>
<pie_slice
label="Gestures..."
name="Gestures">

View File

@ -158,7 +158,13 @@
<pie_slice.on_enable
function="Object.EnableMute" />
</pie_slice>
<pie_separator name="script_count_placeholder" />
<pie_slice
enabled="true"
label="Script Info"
name="ScriptInfo">
<pie_slice.on_click
function="Tools.ScriptInfo" />
</pie_slice>
<pie_slice
label="Inspect"
name="Object Inspect">
@ -167,6 +173,7 @@
parameter="inspect" />
</pie_slice>
</pie_menu>
<pie_slice