710 lines
21 KiB
C++
710 lines
21 KiB
C++
/**
|
|
* @file kcwlinterface.cpp
|
|
* @brief Parcel Windlight Interface
|
|
*
|
|
* Copyright (C) 2010, Kadah Coba
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation;
|
|
* version 2.1 of the License only.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*
|
|
* The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
|
|
* http://www.firestormviewer.org
|
|
* $/LicenseInfo$
|
|
*/
|
|
|
|
#include "llviewerprecompiledheaders.h"
|
|
|
|
#include "kcwlinterface.h"
|
|
|
|
#include "llagent.h"
|
|
#include "llcallingcard.h" // isBuddy
|
|
#include "lldaycyclemanager.h"
|
|
#include "llparcel.h"
|
|
#include "llslurl.h"
|
|
#include "llstartup.h"
|
|
#include "llstatusbar.h"
|
|
#include "llviewercontrol.h" // gSavedSettings, gSavedPerAccountSettings
|
|
#include "llviewerparcelmgr.h"
|
|
#include "llwaterparammanager.h"
|
|
#include "llwlparammanager.h"
|
|
#include "rlvhandler.h"
|
|
|
|
#include <boost/regex.hpp>
|
|
|
|
const F32 PARCEL_WL_CHECK_TIME = 5.f;
|
|
const S32 PARCEL_WL_MIN_ALT_CHANGE = 3;
|
|
const std::string PARCEL_WL_DEFAULT = "Default";
|
|
|
|
const S32 NO_ZONES = -1; // Parcel WL is using default sky or region defaults (no height-mapped parcel WL)
|
|
const S32 NO_SETTINGS = -2; // We didn't receive any parcel WL settings yet
|
|
|
|
KCWindlightInterface::KCWindlightInterface() :
|
|
LLEventTimer(PARCEL_WL_CHECK_TIME),
|
|
mWLset(false),
|
|
mWeChangedIt(false),
|
|
mCurrentSpace(NO_SETTINGS),
|
|
mLastParcelID(-1),
|
|
mLastRegion(NULL),
|
|
mHasRegionOverride(false),
|
|
mHaveRegionSettings(false),
|
|
mDisabled(false),
|
|
mUsingParcelWLSkyDefault(false)
|
|
{
|
|
if (!gSavedSettings.getBOOL("FSWLParcelEnabled") || !gSavedSettings.getBOOL("UseEnvironmentFromRegionAlways"))
|
|
{
|
|
mEventTimer.stop();
|
|
mDisabled = true;
|
|
}
|
|
|
|
mParcelMgrConnection = gAgent.addParcelChangedCallback(boost::bind(&KCWindlightInterface::parcelChange, this));
|
|
}
|
|
|
|
KCWindlightInterface::~KCWindlightInterface()
|
|
{
|
|
if (mParcelMgrConnection.connected())
|
|
{
|
|
mParcelMgrConnection.disconnect();
|
|
}
|
|
}
|
|
|
|
void KCWindlightInterface::parcelChange()
|
|
{
|
|
if (checkSettings())
|
|
{
|
|
return;
|
|
}
|
|
|
|
mDisabled = false;
|
|
|
|
S32 this_parcel_id = 0;
|
|
std::string desc;
|
|
|
|
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
|
|
|
|
// Since we cannot depend on the order in which the EnvironmentSettings cap and parcel info
|
|
// will come in, we must check if the other has set something before this one for the current region.
|
|
if (gAgent.getRegion() != mLastRegion)
|
|
{
|
|
mHaveRegionSettings = false;
|
|
mLastRegion = gAgent.getRegion();
|
|
mCurrentSpace = NO_SETTINGS;
|
|
}
|
|
mHasRegionOverride = false;
|
|
mUsingParcelWLSkyDefault = false;
|
|
|
|
if (parcel)
|
|
{
|
|
this_parcel_id = parcel->getLocalID();
|
|
desc = parcel->getDesc();
|
|
}
|
|
|
|
if ( (this_parcel_id != mLastParcelID) || (mLastParcelDesc != desc) ) //parcel changed
|
|
{
|
|
LL_DEBUGS() << "Agent in new parcel: " << this_parcel_id << LL_ENDL;
|
|
|
|
mLastParcelID = this_parcel_id;
|
|
mLastParcelDesc = desc;
|
|
mCurrentSpace = NO_SETTINGS;
|
|
mCurrentSettings.clear();
|
|
setWL_Status(false); //clear the status bar icon
|
|
const LLVector3& agent_pos_region = gAgent.getPositionAgent();
|
|
mLastZ = lltrunc( agent_pos_region.mV[VZ] );
|
|
|
|
//clear the last notification if its still open
|
|
if (mSetWLNotification && !mSetWLNotification->isRespondedTo())
|
|
{
|
|
LLSD response = mSetWLNotification->getResponseTemplate();
|
|
response["Ignore"] = true;
|
|
mSetWLNotification->respond(response);
|
|
}
|
|
|
|
mEventTimer.reset();
|
|
mEventTimer.start();
|
|
|
|
// Apply new WL settings instantly on TP
|
|
if (mTPing)
|
|
{
|
|
mTPing = false;
|
|
tick();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
BOOL KCWindlightInterface::tick()
|
|
{
|
|
if ((LLStartUp::getStartupState() < STATE_STARTED) || checkSettings())
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
//TODO: there has to be a better way of doing this...
|
|
if (mCurrentSettings.has("sky"))
|
|
{
|
|
const LLVector3& agent_pos_region = gAgent.getPositionAgent();
|
|
S32 z = lltrunc( agent_pos_region.mV[VZ] );
|
|
if (llabs(z - mLastZ) >= PARCEL_WL_MIN_ALT_CHANGE)
|
|
{
|
|
mLastZ = z;
|
|
applySkySettings(mCurrentSettings);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
|
|
|
|
if (parcel)
|
|
{
|
|
if (!loadFromParcel(parcel) || !mCurrentSettings.has("sky"))
|
|
{
|
|
mEventTimer.stop();
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
void KCWindlightInterface::applySettings(const LLSD& settings)
|
|
{
|
|
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
|
|
if (!settings.has("local_id") || (settings["local_id"].asInteger() == parcel->getLocalID()) )
|
|
{
|
|
mCurrentSettings = settings;
|
|
|
|
mHasRegionOverride = settings.has("region_override");
|
|
|
|
bool non_region_default_applied = applySkySettings(settings);
|
|
|
|
// We can only apply a water preset if we didn't set region WL default previously
|
|
// or there will be unpredictable behavior where the region WL defaults will be
|
|
// disabled again and sky/day cycle presets will be reverted to whatever the user
|
|
// has set before.
|
|
if (non_region_default_applied)
|
|
{
|
|
if (settings.has("water") && (!mHaveRegionSettings || mHasRegionOverride))
|
|
{
|
|
LL_INFOS() << "Applying WL water set: " << settings["water"].asString() << LL_ENDL;
|
|
LLWLParamManager::getInstance()->mAnimator.stopInterpolation();
|
|
LLEnvManagerNew::instance().setUseWaterPreset(settings["water"].asString());
|
|
setWL_Status(true);
|
|
}
|
|
else
|
|
{
|
|
LL_INFOS() << "Applying region default WL water set" << LL_ENDL;
|
|
// Not nice to not interpolate, but these 2836724 methods of changing a WL
|
|
// setting will nicely screw up each other and this will most likely happen
|
|
// if calling useRegionWater() because it doesn't even interpolate at all.
|
|
LLWLParamManager::getInstance()->mAnimator.stopInterpolation();
|
|
LLEnvManagerNew::instance().useRegionWater();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LL_WARNS() << "Cannot apply Parcel WL water preset because region WL default has been set due to invalid sky preset" << LL_ENDL;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool KCWindlightInterface::applySkySettings(const LLSD& settings)
|
|
{
|
|
if (settings.has("sky"))
|
|
{
|
|
LL_DEBUGS() << "Checking if agent is in a defined zone" << LL_ENDL;
|
|
|
|
//TODO: there has to be a better way of doing this...
|
|
mEventTimer.reset();
|
|
mEventTimer.start();
|
|
|
|
const LLVector3& agent_pos_region = gAgent.getPositionAgent();
|
|
S32 z = lltrunc( agent_pos_region.mV[VZ] );
|
|
LLSD::array_const_iterator end_it = settings["sky"].endArray();
|
|
for (LLSD::array_const_iterator space_it = settings["sky"].beginArray(); space_it != end_it; ++space_it)
|
|
{
|
|
S32 lower = (*space_it)["lower"].asInteger();
|
|
S32 upper = (*space_it)["upper"].asInteger();
|
|
if ( (z >= lower) && (z <= upper) )
|
|
{
|
|
if (lower != mCurrentSpace) //workaround: only apply once
|
|
{
|
|
mCurrentSpace = lower; //use lower as an id
|
|
LL_INFOS() << "Applying WL sky set: " << (*space_it)["preset"].asString() << " (agent in zone " << lower << " to " << upper << ")" << LL_ENDL;
|
|
applyWindlightPreset((*space_it)["preset"].asString());
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
|
|
LL_DEBUGS() << "Agent is not within a defined zone. Trying default now" << LL_ENDL;
|
|
}
|
|
|
|
if (mCurrentSpace != NO_ZONES)
|
|
{
|
|
mCurrentSpace = NO_ZONES;
|
|
// set notes on KCWindlightInterface::haveParcelOverride
|
|
if (settings.has("sky_default") && (!mHaveRegionSettings || mHasRegionOverride))
|
|
{
|
|
LL_INFOS() << "Applying WL sky set: " << settings["sky_default"] << " (Parcel WL Default)" << LL_ENDL;
|
|
mUsingParcelWLSkyDefault = true;
|
|
applyWindlightPreset(settings["sky_default"].asString());
|
|
}
|
|
else //reset to default
|
|
{
|
|
mUsingParcelWLSkyDefault = false;
|
|
std::string reason;
|
|
if (!settings.has("sky_default"))
|
|
{
|
|
reason = "No zone or not in a defined zone and no default sky defined";
|
|
}
|
|
else if (mHaveRegionSettings && !mHasRegionOverride)
|
|
{
|
|
reason = "No zone defined or not in a defined zone, region has custom WL and \"RegionOverride\" parameter was not set";
|
|
}
|
|
|
|
LL_INFOS() << "Applying WL sky set \"Region Default\": " << reason << LL_ENDL;
|
|
applyWindlightPreset(PARCEL_WL_DEFAULT);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void KCWindlightInterface::applyWindlightPreset(const std::string& preset)
|
|
{
|
|
if (rlv_handler_t::isEnabled() && gRlvHandler.hasBehaviour(RLV_BHVR_SETENV))
|
|
{
|
|
return;
|
|
}
|
|
|
|
LLWLParamManager::getInstance()->mAnimator.stopInterpolation();
|
|
LLWLParamManager* wlprammgr = LLWLParamManager::getInstance();
|
|
LLWLParamKey key(preset, LLEnvKey::SCOPE_LOCAL);
|
|
if ( (preset != PARCEL_WL_DEFAULT) && (wlprammgr->hasParamSet(key)) )
|
|
{
|
|
LLEnvManagerNew::instance().setUseSkyPreset(preset);
|
|
setWL_Status(true);
|
|
mWeChangedIt = true;
|
|
}
|
|
else
|
|
{
|
|
if (!LLEnvManagerNew::instance().getUseRegionSettings())
|
|
{
|
|
LLEnvManagerNew::instance().setUseRegionSettings(true);
|
|
}
|
|
setWL_Status(false);
|
|
mWeChangedIt = false;
|
|
}
|
|
}
|
|
|
|
void KCWindlightInterface::resetToRegion(bool force)
|
|
{
|
|
if (rlv_handler_t::isEnabled() && gRlvHandler.hasBehaviour(RLV_BHVR_SETENV))
|
|
{
|
|
return;
|
|
}
|
|
|
|
//TODO: clear per parcel
|
|
if (mWeChangedIt || force) //dont reset anything if we didnt do it
|
|
{
|
|
applyWindlightPreset(PARCEL_WL_DEFAULT);
|
|
}
|
|
}
|
|
|
|
//KC: Disabling this for now
|
|
#if 0
|
|
bool KCWindlightInterface::chatCommand(std::string message, std::string from_name, LLUUID source_id, LLUUID owner_id)
|
|
{
|
|
boost::cmatch match;
|
|
const boost::regex prefix_exp("^\\)\\*\\((.*)");
|
|
if(boost::regex_match(message.c_str(), match, prefix_exp))
|
|
{
|
|
std::string data(match[1].first, match[1].second);
|
|
|
|
//TODO: expand these or good as is?
|
|
/*const boost::regex setWLpreset_exp("^setWLpreset\\|(.*)");
|
|
const boost::regex setWWpreset_exp("^setWWpreset\\|(.*)");
|
|
if(boost::regex_match(data.c_str(), match, setWLpreset_exp))
|
|
{
|
|
LL_INFOS() << "got setWLpreset : " << match[1] << LL_ENDL;
|
|
LLWLParamManager::instance()->mAnimator.mIsRunning = false;
|
|
LLWLParamManager::instance()->mAnimator.mUseLindenTime = false;
|
|
LLWLParamManager::instance()->loadPreset(match[1]);
|
|
return true;
|
|
}
|
|
else if(boost::regex_match(data.c_str(), match, setWWpreset_exp))
|
|
{
|
|
LL_INFOS() << "got setWWpreset : " << match[1] << LL_ENDL;
|
|
LLWaterParamManager::instance()->loadPreset(match[1], true);
|
|
return true;
|
|
}
|
|
else
|
|
{*/
|
|
|
|
//TODO: add save settings for reuse instead of just clearing on parcel change
|
|
//TODO: add support for region wide settings on non-mainland
|
|
//TODO: add support for targeting specfic users
|
|
//TODO: add support for custom settings via notecards or something
|
|
//TODO: improved data processing, possibly just use LLSD as input instead
|
|
|
|
boost::smatch match2;
|
|
const boost::regex Parcel_exp("^(Parcel),WLPreset=\"([^\"\\r\\n]+)\"(,WWPreset=\"([^\"\\r\\n]+)\")?$");
|
|
//([\\w]{8}-[\\w]{4}-[\\w]{4}-[\\w]{4}-[\\w]{12})
|
|
if(boost::regex_search(data, match2, Parcel_exp))
|
|
{
|
|
if (SetDialogVisible) //TODO: handle this better
|
|
return true;
|
|
|
|
if (match2[1]=="Parcel")
|
|
{
|
|
LL_INFOS() << "Got Parcel WL : " << match[2] << LL_ENDL;
|
|
|
|
LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
|
|
LLSD payload;
|
|
payload["local_id"] = parcel->getLocalID();
|
|
payload["land_owner"] = parcel->getOwnerID();
|
|
payload["wlpreset"] = std::string(match2[2].first, match2[2].second);
|
|
payload["wwpreset"] = std::string(match2[3].first, match2[3].second);
|
|
|
|
LLSD args;
|
|
args["PARCEL_NAME"] = parcel->getName();
|
|
|
|
LLNotifications::instance().add("FSWL", args, payload, boost::bind(&KCWindlightInterface::callbackParcelWL, this, _1, _2));
|
|
SetDialogVisible = true;
|
|
}
|
|
return true;
|
|
}
|
|
/*}*/
|
|
}
|
|
return false;
|
|
}
|
|
#endif
|
|
|
|
bool KCWindlightInterface::loadFromParcel(LLParcel *parcel)
|
|
{
|
|
if (!parcel)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
LLSD payload;
|
|
if (parseParcelForWLSettings(parcel->getDesc(), payload))
|
|
{
|
|
const LLUUID owner_id = getOwnerID(parcel);
|
|
//basic auth for now
|
|
if (allowedLandOwners(owner_id))
|
|
{
|
|
applySettings(payload);
|
|
}
|
|
else
|
|
{
|
|
LLSD args;
|
|
args["PARCEL_NAME"] = parcel->getName();
|
|
args["OWNER_NAME"] = getOwnerName(parcel);
|
|
payload["parcel_name"] = parcel->getName();
|
|
payload["local_id"] = parcel->getLocalID();
|
|
payload["land_owner"] = owner_id;
|
|
|
|
mSetWLNotification = LLNotifications::instance().add("FSWL", args, payload, boost::bind(&KCWindlightInterface::callbackParcelWL, this, _1, _2));
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//if nothing defined, reset to region settings
|
|
resetToRegion();
|
|
|
|
return false;
|
|
}
|
|
|
|
bool KCWindlightInterface::parseParcelForWLSettings(const std::string& desc, LLSD& settings)
|
|
{
|
|
bool found_settings = false;
|
|
try
|
|
{
|
|
boost::smatch mat_block;
|
|
//parcel desc /*[data goes here]*/
|
|
const boost::regex Parcel_exp("(?i)\\/\\*(?:Windlight)?([\\s\\S]*?)\\*\\/");
|
|
if (boost::regex_search(desc, mat_block, Parcel_exp))
|
|
{
|
|
//std::string data1(mat_block[1].first, mat_block[1].second);
|
|
//LL_INFOS() << "found parcel flags block: " << mat_block[1] << LL_ENDL;
|
|
|
|
S32 sky_index = 0;
|
|
LLWLParamManager* wlprammgr = LLWLParamManager::getInstance();
|
|
LLWaterParamManager* wwprammgr = LLWaterParamManager::getInstance();
|
|
boost::smatch match;
|
|
std::string::const_iterator start = mat_block[1].first;
|
|
std::string::const_iterator end = mat_block[1].second;
|
|
//Sky: "preset" Water: "preset"
|
|
const boost::regex key_regex("(?i)(?:(?:(Sky)(?:\\s?@\\s?([\\d]+)m?\\s?(?:to|-)\\s?([\\d]+)m?)?)|(Water))\\s?:\\s?\"([^\"\\r\\n]+)\"|(RegionOverride)");
|
|
while (boost::regex_search(start, end, match, key_regex, boost::match_default))
|
|
{
|
|
if (match[1].matched)
|
|
{
|
|
LL_DEBUGS() << "Sky Flags: type = " << match[1] << " from = " << match[2] << " to = " << match[3] << " preset = " << match[5] << LL_ENDL;
|
|
|
|
std::string preset(match[5]);
|
|
LLWLParamKey key(preset, LLEnvKey::SCOPE_LOCAL);
|
|
if (wlprammgr->hasParamSet(key))
|
|
{
|
|
if (match[2].matched && match[3].matched)
|
|
{
|
|
S32 lower = (S32)atoi(std::string(match[2]).c_str());
|
|
S32 upper = (S32)atoi(std::string(match[3]).c_str());
|
|
if ( (upper > lower) && (lower >= 0) )
|
|
{
|
|
LLSD space;
|
|
space["lower"] = lower;
|
|
space["upper"] = upper;
|
|
space["preset"] = preset;
|
|
if (!settings.has("sky"))
|
|
{
|
|
settings["sky"] = LLSD();
|
|
}
|
|
settings["sky"][sky_index++] = space;
|
|
found_settings = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LL_DEBUGS() << "Sky Default = " << preset << LL_ENDL;
|
|
settings["sky_default"] = preset;
|
|
found_settings = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LL_WARNS() << "Parcel Windlight contains unknown sky: " << preset << LL_ENDL;
|
|
}
|
|
}
|
|
else if (match[4].matched)
|
|
{
|
|
std::string preset(match[5]);
|
|
LL_DEBUGS() << "Got Water Preset: " << preset << LL_ENDL;
|
|
if(wwprammgr->hasParamSet(preset))
|
|
{
|
|
settings["water"] = preset;
|
|
found_settings = true;
|
|
}
|
|
}
|
|
else if (match[6].matched)
|
|
{
|
|
LL_DEBUGS() << "Got Region Override Flag" << LL_ENDL;
|
|
settings["region_override"] = true;
|
|
}
|
|
|
|
// update search position
|
|
start = match[0].second;
|
|
}
|
|
}
|
|
}
|
|
catch(...)
|
|
{
|
|
found_settings = false;
|
|
}
|
|
|
|
return found_settings;
|
|
}
|
|
|
|
void KCWindlightInterface::onClickWLStatusButton()
|
|
{
|
|
//clear the last notification if its still open
|
|
if (mClearWLNotification && !mClearWLNotification->isRespondedTo())
|
|
{
|
|
LLSD response = mClearWLNotification->getResponseTemplate();
|
|
response["Ignore"] = true;
|
|
mClearWLNotification->respond(response);
|
|
}
|
|
|
|
if (mWLset)
|
|
{
|
|
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
|
|
if (parcel)
|
|
{
|
|
//TODO: this could be better
|
|
LLSD payload;
|
|
payload["local_id"] = parcel->getLocalID();
|
|
payload["land_owner"] = getOwnerID(parcel);
|
|
|
|
LLSD args;
|
|
args["PARCEL_NAME"] = parcel->getName();
|
|
|
|
mClearWLNotification = LLNotifications::instance().add("FSWLClear", args, payload, boost::bind(&KCWindlightInterface::callbackParcelWLClear, this, _1, _2));
|
|
}
|
|
}
|
|
}
|
|
|
|
bool KCWindlightInterface::callbackParcelWL(const LLSD& notification, const LLSD& response)
|
|
{
|
|
S32 option = LLNotification::getSelectedOption(notification, response);
|
|
if (option == 0)
|
|
{
|
|
mAllowedLand.insert(notification["payload"]["land_owner"].asUUID());
|
|
|
|
applySettings(notification["payload"]);
|
|
}
|
|
else
|
|
{
|
|
resetToRegion();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool KCWindlightInterface::callbackParcelWLClear(const LLSD& notification, const LLSD& response)
|
|
{
|
|
S32 option = LLNotification::getSelectedOption(notification, response);
|
|
if (option == 0)
|
|
{
|
|
LLUUID owner_id = notification["payload"]["land_owner"].asUUID();
|
|
|
|
mAllowedLand.erase(owner_id);
|
|
resetToRegion();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool KCWindlightInterface::allowedLandOwners(const LLUUID& owner_id)
|
|
{
|
|
if ( gSavedSettings.getBOOL("FSWLWhitelistAll") || // auto all
|
|
(owner_id == gAgent.getID()) || // land is owned by agent
|
|
(LLAvatarTracker::instance().isBuddy(owner_id) && gSavedSettings.getBOOL("FSWLWhitelistFriends")) || // is friend's land
|
|
(gAgent.isInGroup(owner_id) && gSavedSettings.getBOOL("FSWLWhitelistGroups")) || // is member of land's group
|
|
(mAllowedLand.find(owner_id) != mAllowedLand.end()) ) // already on whitelist
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
LLUUID KCWindlightInterface::getOwnerID(LLParcel* parcel)
|
|
{
|
|
if (parcel->getIsGroupOwned())
|
|
{
|
|
return parcel->getGroupID();
|
|
}
|
|
return parcel->getOwnerID();
|
|
}
|
|
|
|
std::string KCWindlightInterface::getOwnerName(LLParcel* parcel)
|
|
{
|
|
std::string owner = "";
|
|
if (parcel->getIsGroupOwned())
|
|
{
|
|
owner = LLSLURL("group", parcel->getGroupID(), "inspect").getSLURLString();
|
|
}
|
|
else
|
|
{
|
|
owner = LLSLURL("agent", parcel->getOwnerID(), "inspect").getSLURLString();
|
|
}
|
|
return owner;
|
|
}
|
|
|
|
//KC: this is currently not used
|
|
//TODO: merge this relay code in to bridge when more final, currently only supports "Parcel,WLPreset='[preset name]'"
|
|
/*
|
|
integer PHOE_WL_CH = -1346916165;
|
|
default
|
|
{
|
|
state_entry()
|
|
{
|
|
llListen(PHOE_WL_CH, "", NULL_KEY, "");
|
|
}
|
|
listen( integer iChan, string sName, key kID, string sMsg )
|
|
{
|
|
if ( llGetOwnerKey(kID) == llGetLandOwnerAt(llGetPos()) )
|
|
{
|
|
llOwnerSay(")*(" + sMsg);
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
|
|
// Region settings are prefered for default parcel ones
|
|
// But parcel height mapped skies always override region's
|
|
// And parcels can use the "RegionOverride" in their config line
|
|
bool KCWindlightInterface::haveParcelOverride(const LLEnvironmentSettings& new_settings)
|
|
{
|
|
// Since we cannot depend on the order in which the EnvironmentSettings cap and parcel info
|
|
// will come in, we must check if the other has set something before this one for the current region.
|
|
if (gAgent.getRegion() != mLastRegion)
|
|
{
|
|
mHasRegionOverride = false;
|
|
mUsingParcelWLSkyDefault = false;
|
|
mCurrentSettings.clear();
|
|
mLastRegion = gAgent.getRegion();
|
|
mCurrentSpace = NO_SETTINGS;
|
|
}
|
|
|
|
//*ASSUMPTION: if region day cycle is empty, its set to default
|
|
mHaveRegionSettings = new_settings.getWLDayCycle().size() > 0;
|
|
|
|
// If no parcel WL default sky is defined, we are going to use region defaults
|
|
// (mCurrentSpace == NO_ZONES && mUsingParcelWLSkyDefault == false).
|
|
// In that case, we do NOT override so we update the WL with what we received
|
|
// from the region.
|
|
bool has_override = (mCurrentSpace == NO_ZONES && mUsingParcelWLSkyDefault && mHasRegionOverride) || // Using a default parcel WL sky and "RegionOverride" parameter set
|
|
(mCurrentSpace == NO_ZONES && mUsingParcelWLSkyDefault && !mHaveRegionSettings) || // Custom parcel WL default sky and region default WL (no custom region default WL!)
|
|
(mCurrentSpace != NO_SETTINGS && mCurrentSpace != NO_ZONES); // Height-mapped parcel WL (always override region WL)
|
|
|
|
LL_DEBUGS() << "mCurrentSpace == NO_ZONES && mUsingParcelWLSkyDefault && mHasRegionOverride = " << ((mCurrentSpace == NO_ZONES && mUsingParcelWLSkyDefault && mHasRegionOverride) ? "true" : "false") << " - "
|
|
<< "mCurrentSpace == NO_ZONES && mUsingParcelWLSkyDefault && !mHaveRegionSettings = " << ((mCurrentSpace == NO_ZONES && mUsingParcelWLSkyDefault && !mHaveRegionSettings) ? "true" : "false") << " - "
|
|
<< "mCurrentSpace != NO_SETTINGS && mCurrentSpace != NO_ZONES = " << ((mCurrentSpace != NO_SETTINGS && mCurrentSpace != NO_ZONES) ? "true" : "false")
|
|
<< LL_ENDL;
|
|
|
|
if (!has_override)
|
|
{
|
|
LL_INFOS() << "Region environment settings received. Parcel WL settings will be overridden." << LL_ENDL;
|
|
}
|
|
else
|
|
{
|
|
LL_INFOS() << "Parcel WL override active" << LL_ENDL;
|
|
}
|
|
|
|
return has_override;
|
|
}
|
|
|
|
void KCWindlightInterface::setWL_Status(bool pwl_status)
|
|
{
|
|
mWLset = pwl_status;
|
|
gStatusBar->updateParcelIcons();
|
|
}
|
|
|
|
bool KCWindlightInterface::checkSettings()
|
|
{
|
|
static LLCachedControl<bool> sFSWLParcelEnabled(gSavedSettings, "FSWLParcelEnabled");
|
|
static LLCachedControl<bool> sUseEnvironmentFromRegionAlways(gSavedSettings, "UseEnvironmentFromRegionAlways");
|
|
if (!sFSWLParcelEnabled || !sUseEnvironmentFromRegionAlways ||
|
|
(rlv_handler_t::isEnabled() && gRlvHandler.hasBehaviour(RLV_BHVR_SETENV)))
|
|
{
|
|
// The setting changed, clear everything
|
|
if (!mDisabled)
|
|
{
|
|
mCurrentSettings.clear();
|
|
mWeChangedIt = false;
|
|
mCurrentSpace = NO_SETTINGS;
|
|
mLastParcelID = -1;
|
|
mHasRegionOverride = false;
|
|
mHaveRegionSettings = false;
|
|
mLastRegion = NULL;
|
|
mEventTimer.stop();
|
|
setWL_Status(false);
|
|
mDisabled = true;
|
|
mUsingParcelWLSkyDefault = false;
|
|
}
|
|
return true;
|
|
}
|
|
mDisabled = false;
|
|
return false;
|
|
}
|