Replace the media filter with something a little different

This commit is contained in:
Cinder
2014-07-16 21:22:12 -06:00
committed by Inusaito Sayori
parent b633c3ffea
commit 45f5eb9671
17 changed files with 1156 additions and 935 deletions

View File

@@ -232,6 +232,7 @@ set(viewer_SOURCE_FILES
llfloaterlandholdings.cpp
llfloaterlandmark.cpp
llfloatermap.cpp
llfloatermediafilter.cpp
llfloatermediasettings.cpp
llfloatermemleak.cpp
llfloatermessagelog.cpp
@@ -334,6 +335,7 @@ set(viewer_SOURCE_FILES
llmaterialmgr.cpp
llmediactrl.cpp
llmediadataclient.cpp
llmediafilter.cpp
llmediaremotectrl.cpp
llmenucommands.cpp
llmenuoptionpathfindingrebakenavmesh.cpp
@@ -594,7 +596,6 @@ set(viewer_SOURCE_FILES
sgversion.cpp
shcommandhandler.cpp
shfloatermediaticker.cpp
slfloatermediafilter.cpp
wlfPanel_AdvSettings.cpp
)
@@ -758,6 +759,7 @@ set(viewer_HEADER_FILES
llfloaterlandholdings.h
llfloaterlandmark.h
llfloatermap.h
llfloatermediafilter.h
llfloatermediasettings.h
llfloatermemleak.h
llfloatermessagelog.h
@@ -860,6 +862,7 @@ set(viewer_HEADER_FILES
llmaterialmgr.h
llmediactrl.h
llmediadataclient.h
llmediafilter.h
llmediaremotectrl.h
llmenucommands.h
llmenuoptionpathfindingrebakenavmesh.h
@@ -1130,7 +1133,6 @@ set(viewer_HEADER_FILES
sgversion.h
shcommandhandler.h
shfloatermediaticker.h
slfloatermediafilter.h
wlfPanel_AdvSettings.h
VertexCache.h
VorbisFramework.h

View File

@@ -345,17 +345,6 @@
</array>
</map>
<key>MediaEnableFilter</key>
<map>
<key>Comment</key>
<string>Enable media domain filtering</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>1</integer>
</map>
<key>MediaFilterRect</key>
<map>
<key>Comment</key>
@@ -18572,6 +18561,17 @@ This should be as low as possible, but too low may break functionality</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>MediaFilterEnable</key>
<map>
<key>Comment</key>
<string>Enable media domain filtering (0 = Off, 1 = Blacklist only, 2 = Prompt)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>2</integer>
</map>
</map>
</llsd>

View File

@@ -0,0 +1,153 @@
/*
* @file llfloatermediafilter.cpp
* @brief Stupid floater for listing junk
* @author Cinder Biscuits
*
* Permission is hereby granted, free of charge, to any person or organization
* obtaining a copy of the software and accompanying documentation covered by
* this license (the "Software") to use, reproduce, display, distribute,
* execute, and transmit the Software, and to prepare derivative works of the
* Software, and to permit third-parties to whom the Software is furnished to
* do so, all subject to the following:
*
* The copyright notices in the Software and this entire statement, including
* the above license grant, this restriction and the following disclaimer,
* must be included in all copies of the Software, in whole or in part, and
* all derivative works of the Software, unless such copies or derivative
* works are solely in the form of machine-executable object code generated by
* a source language processor.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
#include "llviewerprecompiledheaders.h"
#include "llfloatermediafilter.h"
#include "llnotificationsutil.h"
#include "llscrolllistctrl.h"
#include "llscrolllistitem.h"
#include "lltrans.h"
#include "lluictrlfactory.h"
bool handle_add_callback(const LLSD& notification, const LLSD& response);
// TODO: Maybe add removal confirmation?
//bool handle_remove_callback(const LLSD& notification, const LLSD& response);
LLFloaterMediaFilter::LLFloaterMediaFilter(const LLSD& key)
: LLFloater(key)
{
mCommitCallbackRegistrar.add("MediaFilter.CommitAction", boost::bind(&LLFloaterMediaFilter::onCommitAction, this, _2));
mMediaListConnection = LLMediaFilter::getInstance()->setMediaListUpdateCallback(boost::bind(&LLFloaterMediaFilter::updateLists, this, _1));
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_media_lists.xml", NULL, false);
}
LLFloaterMediaFilter::~LLFloaterMediaFilter()
{
if (mMediaListConnection.connected())
mMediaListConnection.disconnect();
}
BOOL LLFloaterMediaFilter::postBuild()
{
mWhitelist = getChild<LLScrollListCtrl>("whitelist");
mBlacklist = getChild<LLScrollListCtrl>("blacklist");
updateLists(LLMediaFilter::WHITELIST);
updateLists(LLMediaFilter::BLACKLIST);
return TRUE;
}
void LLFloaterMediaFilter::updateLists(LLMediaFilter::EMediaList list)
{
if (list == LLMediaFilter::WHITELIST && mWhitelist)
{
LLMediaFilter::string_list_t list = LLMediaFilter::getInstance()->getWhiteList();
mWhitelist->clearRows();
for (LLMediaFilter::string_list_t::const_iterator itr = list.begin(); itr != list.end(); ++itr)
{
LLSD element;
element["columns"][0]["column"] = "list";
element["columns"][0]["value"] = (*itr);
mWhitelist->addElement(element);
}
}
if (list == LLMediaFilter::BLACKLIST && mBlacklist)
{
LLMediaFilter::string_list_t list = LLMediaFilter::getInstance()->getBlackList();
mBlacklist->clearRows();
for (LLMediaFilter::string_list_t::const_iterator itr = list.begin(); itr != list.end(); ++itr)
{
LLSD element;
element["columns"][0]["column"] = "list";
element["columns"][0]["value"] = (*itr);
mBlacklist->addElement(element);
}
}
}
void LLFloaterMediaFilter::onCommitAction(const LLSD& userdata)
{
std::string chosen_item = userdata.asString();
if (chosen_item == "AddToWhitelist")
{
LLSD payload, args;
args["LIST"] = LLTrans::getString("MediaFilterWhitelist");
payload = true;
LLNotificationsUtil::add("AddToMediaList", args, payload, &handle_add_callback);
}
else if (chosen_item == "AddToBlacklist")
{
LLSD payload, args;
args["LIST"] = LLTrans::getString("MediaFilterBlacklist");
payload = false;
LLNotificationsUtil::add("AddToMediaList", args, payload, &handle_add_callback);
}
else if (chosen_item == "RemoveFromWhitelist")
{
std::vector<LLScrollListItem*> selected = mWhitelist->getAllSelected();
if (!selected.empty())
{
LLMediaFilter::string_vec_t domains;
for (std::vector<LLScrollListItem*>::iterator itr = selected.begin(); itr != selected.end(); ++itr)
{
domains.push_back((*itr)->getColumn(0)->getValue().asString());
}
LLMediaFilter::getInstance()->removeFromMediaList(domains, LLMediaFilter::WHITELIST);
}
}
else if (chosen_item == "RemoveFromBlacklist")
{
std::vector<LLScrollListItem*> selected = mBlacklist->getAllSelected();
if (!selected.empty())
{
LLMediaFilter::string_vec_t domains;
for (std::vector<LLScrollListItem*>::iterator itr = selected.begin(); itr != selected.end(); ++itr)
{
domains.push_back((*itr)->getColumn(0)->getValue().asString());
}
LLMediaFilter::getInstance()->removeFromMediaList(domains, LLMediaFilter::BLACKLIST);
}
}
}
bool handle_add_callback(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if (option == 0)
{
std::string url = response["url"].asString();
if (notification["payload"].asBoolean())
LLMediaFilter::getInstance()->addToMediaList(url, LLMediaFilter::WHITELIST);
else
LLMediaFilter::getInstance()->addToMediaList(url, LLMediaFilter::BLACKLIST);
}
return false;
}

View File

@@ -0,0 +1,55 @@
/*
* @file LLFloaterMediaFilter.h
* @brief Stupid floater for listing junk
* @author Cinder Biscuits
*
* Permission is hereby granted, free of charge, to any person or organization
* obtaining a copy of the software and accompanying documentation covered by
* this license (the "Software") to use, reproduce, display, distribute,
* execute, and transmit the Software, and to prepare derivative works of the
* Software, and to permit third-parties to whom the Software is furnished to
* do so, all subject to the following:
*
* The copyright notices in the Software and this entire statement, including
* the above license grant, this restriction and the following disclaimer,
* must be included in all copies of the Software, in whole or in part, and
* all derivative works of the Software, unless such copies or derivative
* works are solely in the form of machine-executable object code generated by
* a source language processor.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
#ifndef LL_FLOATERMEDIAFILTER_H
#define LL_FLOATERMEDIAFILTER_H
#include "llfloater.h"
#include "llmediafilter.h"
#include <boost/signals2.hpp>
class LLScrollListCtrl;
class LLFloaterMediaFilter : public LLFloater, public LLFloaterSingleton<LLFloaterMediaFilter>
{
friend class LLUISingleton<LLFloaterMediaFilter, VisibilityPolicy<LLFloater> >;
public:
LLFloaterMediaFilter(const LLSD& key);
BOOL postBuild();
private:
~LLFloaterMediaFilter();
void updateLists(LLMediaFilter::EMediaList list);
void onCommitAction(const LLSD& userdata);
LLScrollListCtrl* mWhitelist;
LLScrollListCtrl* mBlacklist;
boost::signals2::connection mMediaListConnection;
};
#endif // LL_FLOATERMEDIAFILTER_H

View File

@@ -0,0 +1,491 @@
/*
* @file llmediafilter.h
* @brief Hyperbalistic SLU paranoia controls
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, Sione Lomu.
* Copyright (C) 2014, Cinder Roxley.
*
* 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
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llmediafilter.h"
#include "llaudioengine.h"
#include "llchat.h"
#include "llfloaterchat.h"
#include "llnotifications.h"
#include "llnotificationsutil.h"
#include "llsdserialize.h"
#include "lltrans.h"
#include "llvieweraudio.h"
#include "llviewercontrol.h"
#include "llviewerparcelmgr.h"
#include "llviewerparcelmedia.h"
const std::string MEDIALIST_XML = "medialist.xml";
bool handle_audio_filter_callback(const LLSD& notification, const LLSD& response);
bool handle_media_filter_callback(const LLSD& notification, const LLSD& response, LLParcel* parcel);
std::string extractDomain(const std::string& in_url);
void reportToChat(const std::string& message)
{
LLChat chat;
chat.mText = message;
chat.mSourceType = CHAT_SOURCE_SYSTEM;
LLFloaterChat::addChat(chat, FALSE, FALSE);
}
void LLMediaFilter::filterMediaUrl(LLParcel* parcel)
{
if (!parcel) return;
const std::string url = parcel->getMediaURL();
if (url.empty())
{
return;
}
const std::string domain = extractDomain(url);
mCurrentParcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
U32 enabled = gSavedSettings.getU32("MediaFilterEnable");
if (enabled > 1 && (filter(domain, WHITELIST) || filter(url, WHITELIST)))
{
LL_DEBUGS("MediaFilter") << "Media filter: URL allowed by whitelist: " << url << LL_ENDL;
LLViewerParcelMedia::play(parcel);
//mAudioState = PLAY;
}
else if (enabled && (filter(domain, BLACKLIST) || filter(url, BLACKLIST)))
{
LLNotifications::instance().add("MediaBlocked", LLSD().with("DOMAIN", domain));
//mAudioState = STOP;
}
else if (enabled && isAlertActive())
{
mMediaQueue = parcel;
}
else if (enabled > 1)
{
LL_DEBUGS("MediaFilter") << "Media Filter: Unhanded by lists. Toasting: " << url << LL_ENDL;
setAlertStatus(true);
LLSD args, payload;
args["MEDIA_TYPE"] = LLTrans::getString("media");
args["URL"] = url;
args["DOMAIN"] = domain;
payload = url;
LLNotifications::instance().add("MediaAlert", args, payload,
boost::bind(&handle_media_filter_callback, _1, _2, parcel));
}
else
{
LL_DEBUGS("MediaFilter") << "Media Filter: Skipping filters and playing " << url << LL_ENDL;
LLViewerParcelMedia::play(parcel);
//mAudioState = PLAY;
}
}
void LLMediaFilter::filterAudioUrl(const std::string& url)
{
if (url.empty())
{
gAudiop->startInternetStream(url);
return;
}
if (url == mCurrentAudioURL) return;
const std::string domain = extractDomain(url);
mCurrentParcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
U32 enabled = gSavedSettings.getU32("MediaFilterEnable");
if (enabled > 1 && (filter(domain, WHITELIST) || filter(url, WHITELIST)))
{
LL_DEBUGS("MediaFilter") << "Audio filter: URL allowed by whitelist: " << url << LL_ENDL;
gAudiop->startInternetStream(url);
}
else if (enabled && (filter(domain, BLACKLIST) || filter(url, BLACKLIST)))
{
LLNotifications::instance().add("MediaBlocked", LLSD().with("DOMAIN", domain));
gAudiop->stopInternetStream();
}
else if (enabled && isAlertActive())
{
mAudioQueue = url;
}
else if (enabled > 1)
{
LL_DEBUGS("MediaFilter") << "Audio Filter: Unhanded by lists. Toasting: " << url << LL_ENDL;
setAlertStatus(true);
LLSD args, payload;
args["MEDIA_TYPE"] = LLTrans::getString("audio");
args["URL"] = url;
args["DOMAIN"] = domain;
payload = url;
LLNotifications::instance().add("MediaAlert", args, payload,
boost::bind(&handle_audio_filter_callback, _1, _2));
}
else
{
LL_DEBUGS("MediaFilter") << "Audio Filter: Skipping filters and playing: " << url << LL_ENDL;
gAudiop->startInternetStream(url);
}
}
bool LLMediaFilter::filter(const std::string& url, EMediaList list)
{
string_list_t p_list;
if (list == WHITELIST)
p_list = mWhiteList;
else
p_list = mBlackList;
string_list_t::const_iterator find_itr = std::find(p_list.begin(), p_list.end(), url);
return (find_itr != p_list.end());
}
// List bizznizz
void LLMediaFilter::addToMediaList(const std::string& in_url, EMediaList list, bool extract)
{
std::string url = extract ? extractDomain(in_url) : in_url;
if (url.empty())
{
LL_INFOS("MediaFilter") << "No url found. Can't add to list." << LL_ENDL;
return;
}
switch (list)
{
case WHITELIST:
// Check for duplicates
for (string_list_t::const_iterator itr = mWhiteList.begin(); itr != mWhiteList.end(); ++itr)
{
if (url == *itr)
{
LL_INFOS("MediaFilter") << "URL " << url << " already in list!" << LL_ENDL;
return;
}
}
mWhiteList.push_back(url);
mMediaListUpdate(WHITELIST);
break;
case BLACKLIST:
for (string_list_t::const_iterator itr = mBlackList.begin(); itr != mBlackList.end(); ++itr)
{
if (url == *itr)
{
LL_INFOS("MediaFilter") << "URL " << url << "already in list!" << LL_ENDL;
return;
}
}
mBlackList.push_back(url);
mMediaListUpdate(BLACKLIST);
break;
}
saveMediaFilterToDisk();
}
void LLMediaFilter::init()
{
loadMediaFilterFromDisk();
}
void LLMediaFilter::removeFromMediaList(string_vec_t domains, EMediaList list)
{
switch (list)
{
case WHITELIST:
for (string_vec_t::const_iterator itr = domains.begin(); itr != domains.end(); ++itr)
mWhiteList.remove(*itr);
mMediaListUpdate(WHITELIST);
break;
case BLACKLIST:
for (string_vec_t::const_iterator itr = domains.begin(); itr != domains.end(); ++itr)
mBlackList.remove(*itr);
mMediaListUpdate(BLACKLIST);
break;
}
saveMediaFilterToDisk();
}
void LLMediaFilter::loadMediaFilterFromDisk()
{
const std::string medialist_filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, MEDIALIST_XML);
mWhiteList.clear();
mBlackList.clear();
LLSD medialist;
if (LLFile::isfile(medialist_filename))
{
llifstream medialist_xml(medialist_filename);
LLSDSerialize::fromXML(medialist, medialist_xml);
medialist_xml.close();
}
else
LL_INFOS("MediaFilter") << medialist_filename << " not found." << LL_ENDL;
for (LLSD::array_const_iterator p_itr = medialist.beginArray();
p_itr != medialist.endArray();
++p_itr)
{
LLSD itr = (*p_itr);
/// I hate this string shit more than you could ever imagine,
/// but I'm retaining it for backwards and cross-compatibility. :|
if (itr["action"].asString() == "allow")
{
LL_DEBUGS("MediaFilter") << "Adding " << itr["domain"].asString() << " to whitelist." << LL_ENDL;
mWhiteList.push_back(itr["domain"].asString());
}
else if (itr["action"].asString() == "deny")
{
LL_DEBUGS("MediaFilter") << "Adding " << itr["domain"].asString() << " to blacklist." << LL_ENDL;
mBlackList.push_back(itr["domain"].asString());
}
}
}
void LLMediaFilter::saveMediaFilterToDisk()
{
const std::string medialist_filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, MEDIALIST_XML);
LLSD medialist_llsd;
for (string_list_t::const_iterator itr = mWhiteList.begin(); itr != mWhiteList.end(); ++itr)
{
LLSD item;
item["domain"] = *itr;
item["action"] = "allow"; // <- $*#@()&%@
medialist_llsd.append(item);
}
for (string_list_t::const_iterator itr = mBlackList.begin(); itr != mBlackList.end(); ++itr)
{
LLSD item;
item["domain"] = *itr;
item["action"] = "deny"; // sigh.
medialist_llsd.append(item);
}
llofstream medialist;
medialist.open(medialist_filename);
LLSDSerialize::toPrettyXML(medialist_llsd, medialist);
medialist.close();
}
bool handle_audio_filter_callback(const LLSD& notification, const LLSD& response)
{
LLMediaFilter::getInstance()->setAlertStatus(false);
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
const std::string url = notification["payload"].asString();
const std::string queue = LLMediaFilter::getInstance()->getQueuedAudio();
switch(option)
{
case 3: // Whitelist domain
LLMediaFilter::getInstance()->addToMediaList(url, LLMediaFilter::WHITELIST);
case 0: // Allow
if (gAudiop != NULL)
{
if (LLMediaFilter::getInstance()->getCurrentParcel() == LLViewerParcelMgr::getInstance()->getAgentParcel())
{
gAudiop->startInternetStream(url);
}
}
break;
case 2: // Blacklist domain
LLMediaFilter::getInstance()->addToMediaList(url, LLMediaFilter::BLACKLIST);
case 1: // Deny
if (gAudiop != NULL)
{
if (LLMediaFilter::getInstance()->getCurrentParcel() == LLViewerParcelMgr::getInstance()->getAgentParcel())
{
gAudiop->stopInternetStream();
}
}
break;
/*case 4: //Whitelist url
LLMediaFilter::getInstance()->addToMediaList(url, LLMediaFilter::WHITELIST, false);
if (gAudiop != NULL)
{
if (LLMediaFilter::getInstance()->getCurrentParcel() == LLViewerParcelMgr::getInstance()->getAgentParcel())
{
gAudiop->startInternetStream(url);
}
}
break;
case 5: //Blacklist url
LLMediaFilter::getInstance()->addToMediaList(url, LLMediaFilter::BLACKLIST, false);
if (gAudiop != NULL)
{
if (LLMediaFilter::getInstance()->getCurrentParcel() == LLViewerParcelMgr::getInstance()->getAgentParcel())
{
gAudiop->stopInternetStream();
}
}
break;*/
default:
// We should never be able to get here.
llassert(option);
break;
}
if (!queue.empty())
{
LLMediaFilter::getInstance()->clearQueuedAudio();
LLMediaFilter::getInstance()->filterAudioUrl(queue);
}
else if (LLMediaFilter::getInstance()->getQueuedMedia())
{
LLMediaFilter::getInstance()->clearQueuedMedia();
LLParcel* queued_media = LLMediaFilter::getInstance()->getQueuedMedia();
if (queued_media)
LLMediaFilter::getInstance()->filterMediaUrl(queued_media);
}
else if (LLMediaFilter::getInstance()->getQueuedMediaCommand())
{
U32 command = LLMediaFilter::getInstance()->getQueuedMediaCommand();
if (command == PARCEL_MEDIA_COMMAND_STOP)
{
LLViewerParcelMedia::stop();
}
else if (command == PARCEL_MEDIA_COMMAND_PAUSE)
{
LLViewerParcelMedia::pause();
}
else if (command == PARCEL_MEDIA_COMMAND_UNLOAD)
{
LLViewerParcelMedia::stop();
}
else if (command == PARCEL_MEDIA_COMMAND_TIME)
{
//LLViewerParcelMedia::seek(LLViewerParcelMedia::sMediaCommandTime);
}
LLMediaFilter::getInstance()->setQueuedMediaCommand(0);
}
return false;
}
bool handle_media_filter_callback(const LLSD& notification, const LLSD& response, LLParcel* parcel)
{
LLMediaFilter::getInstance()->setAlertStatus(false);
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
const std::string url = notification["payload"].asString();
LLParcel* queue = LLMediaFilter::getInstance()->getQueuedMedia();
switch(option)
{
case 2: // Whitelist domain
LLMediaFilter::getInstance()->addToMediaList(url, LLMediaFilter::WHITELIST);
case 0: // Allow
if (LLMediaFilter::getInstance()->getCurrentParcel() == LLViewerParcelMgr::getInstance()->getAgentParcel())
LLViewerParcelMedia::play(parcel);
break;
case 3: // Blacklist domain
LLMediaFilter::getInstance()->addToMediaList(url, LLMediaFilter::BLACKLIST);
case 1: // Deny
break;
case 4: //Whitelist url
LLMediaFilter::getInstance()->addToMediaList(url, LLMediaFilter::WHITELIST, false);
if (LLMediaFilter::getInstance()->getCurrentParcel() == LLViewerParcelMgr::getInstance()->getAgentParcel())
LLViewerParcelMedia::play(parcel);
break;
case 5:
LLMediaFilter::getInstance()->addToMediaList(url, LLMediaFilter::BLACKLIST, false);
break;
default:
// We should never be able to get here.
llassert(option);
break;
}
const std::string audio_queue = LLMediaFilter::getInstance()->getQueuedAudio();
if (queue)
{
LLMediaFilter::getInstance()->clearQueuedMedia();
LLMediaFilter::getInstance()->filterMediaUrl(queue);
}
else if (!audio_queue.empty())
{
LLMediaFilter::getInstance()->clearQueuedAudio();
LLMediaFilter::getInstance()->filterAudioUrl(audio_queue);
}
else if (LLMediaFilter::getInstance()->getQueuedMediaCommand())
{
U32 command = LLMediaFilter::getInstance()->getQueuedMediaCommand();
if (command == PARCEL_MEDIA_COMMAND_STOP)
{
LLViewerParcelMedia::stop();
}
else if (command == PARCEL_MEDIA_COMMAND_PAUSE)
{
LLViewerParcelMedia::pause();
}
else if (command == PARCEL_MEDIA_COMMAND_UNLOAD)
{
LLViewerParcelMedia::stop();
}
else if (command == PARCEL_MEDIA_COMMAND_TIME)
{
//LLViewerParcelMedia::seek(LLViewerParcelMedia::sMediaCommandTime);
}
LLMediaFilter::getInstance()->setQueuedMediaCommand(0);
}
return false;
}
// Local Functions
std::string extractDomain(const std::string& in_url)
{
std::string url = in_url;
// First, find and strip any protocol prefix.
size_t pos = url.find("//");
if (pos != std::string::npos)
{
S32 count = url.size()-pos+2;
url = url.substr(pos+2, count);
}
// Now, look for a / marking a local part; if there is one,
// strip it and anything after.
pos = url.find("/");
if (pos != std::string::npos)
{
url = url.substr(0, pos);
}
// If there's a user{,:password}@ part, remove it,
pos = url.find("@");
if (pos != std::string::npos)
{
S32 count = url.size()-pos+1;
url = url.substr(pos+1, count);
}
// Finally, find and strip away any port number. This has to be done
// after the previous step, or else the extra : for the password,
// if supplied, will confuse things.
pos = url.find(":");
if (pos != std::string::npos)
{
url = url.substr(0, pos);
}
// Now map the whole thing to lowercase, since domain names aren't
// case sensitive.
std::transform(url.begin(), url.end(),url.begin(), ::tolower);
return url;
}

View File

@@ -0,0 +1,92 @@
/*
* @file llmediafilter.h
* @brief Definitions for paranoia controls
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, Sione Lomu.
* Copyright (C) 2014, Cinder Roxley.
*
* 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
* $/LicenseInfo$
*/
#ifndef LL_MEDIAFILTER_H
#define LL_MEDIAFILTER_H
#include "llparcel.h"
class LLMediaFilter : public LLSingleton<LLMediaFilter>
{
friend class LLSingleton<LLMediaFilter>;
public:
typedef enum e_media_list {
WHITELIST,
BLACKLIST
} EMediaList;
typedef std::list<std::string> string_list_t;
typedef std::vector<std::string> string_vec_t;
typedef boost::signals2::signal<void(EMediaList list)> media_list_signal_t;
media_list_signal_t mMediaListUpdate;
boost::signals2::connection setMediaListUpdateCallback(const media_list_signal_t::slot_type& cb)
{
return mMediaListUpdate.connect(cb);
};
void filterMediaUrl(LLParcel* parcel);
void filterAudioUrl(const std::string& url);
//void filterSharedMediaUrl
void addToMediaList(const std::string& in_url, EMediaList list, bool extract = true);
void removeFromMediaList(string_vec_t, EMediaList list);
string_list_t getWhiteList() { return mWhiteList; };
string_list_t getBlackList() { return mBlackList; };
U32 getQueuedMediaCommand() { return mMediaCommandQueue; };
void setQueuedMediaCommand(U32 command) { mMediaCommandQueue = command; };
bool isAlertActive() { return mAlertActive; };
void setAlertStatus(bool active) { mAlertActive = active; };
LLParcel* getCurrentParcel() { return mCurrentParcel; };
LLParcel* getQueuedMedia() { return mMediaQueue; };
void clearQueuedMedia() { mMediaQueue = NULL; };
std::string getQueuedAudio() { return mAudioQueue; };
void clearQueuedAudio() { mAudioQueue.clear(); };
void setCurrentAudioURL(const std::string url ) { mCurrentAudioURL = url; };
void clearCurrentAudioURL() { mCurrentAudioURL.clear(); };
bool filter(const std::string& url, EMediaList list);
void init();
private:
void loadMediaFilterFromDisk();
void saveMediaFilterToDisk();
string_list_t mBlackList;
string_list_t mWhiteList;
U32 mMediaCommandQueue;
LLParcel* mCurrentParcel;
LLParcel* mMediaQueue;
std::string mAudioQueue;
std::string mCurrentAudioURL;
std::string mCurrentMediaURL;
bool mAlertActive;
//typedef enum e_audio_state {
// PLAY,
// STOP
//} EAudioState;
//EAudioState mAudioState;
};
#endif // LL_MEDIAFILTER_H

View File

@@ -74,6 +74,7 @@
#include "llfloaterland.h"
#include "llfloaterlandholdings.h"
#include "llfloatermap.h"
#include "llfloatermediafilter.h"
#include "llfloatermemleak.h"
#include "llfloatermessagelog.h"
#include "llfloatermute.h"
@@ -112,7 +113,6 @@
#include "rlvfloaters.h"
// [/RLVa:LF]
#include "shfloatermediaticker.h"
#include "slfloatermediafilter.h"
void handle_chat()
{
@@ -231,7 +231,7 @@ struct MenuFloaterDict : public LLSingleton<MenuFloaterDict>
registerFloater<LLFloaterInspect> ("inspect");
registerFloater<LLFloaterJoystick> ("joystick");
registerFloater<LLFloaterLagMeter> ("lag meter");
registerFloater<SLFloaterMediaFilter> ("media filter");
registerFloater<LLFloaterMediaFilter> ("media filter");
registerFloater<LLFloaterMap> ("mini map");
registerFloater<LLFloaterMove> ("movement controls");
registerFloater<LLFloaterMute> ("mute list");

View File

@@ -479,7 +479,7 @@ void LLOverlayBar::toggleMediaPlay(void*)
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
if (parcel)
{
LLViewerParcelMedia::sIsUserAction = true;
//LLViewerParcelMedia::sIsUserAction = true;
LLViewerParcelMedia::play(parcel);
}
}
@@ -505,7 +505,7 @@ void LLOverlayBar::toggleMusicPlay(void*)
// stream is stopped, it doesn't return the right thing - commenting out for now.
// if ( gAudiop->isInternetStreamPlaying() == 0 )
{
LLViewerParcelMedia::sIsUserAction = true;
//LLViewerParcelMedia::sIsUserAction = true;
LLViewerParcelMedia::playStreamingMusic(parcel);
}
}

View File

@@ -140,6 +140,7 @@
#include "llkeyboard.h"
#include "llloginhandler.h" // gLoginHandler, SLURL support
#include "llpanellogin.h"
#include "llmediafilter.h"
#include "llmutelist.h"
#include "llnotify.h"
#include "llpanelavatar.h"
@@ -1723,6 +1724,7 @@ bool idle_startup()
if (STATE_MULTIMEDIA_INIT == LLStartUp::getStartupState())
{
LLStartUp::multimediaInit();
LLMediaFilter::getInstance()->init();
LLStartUp::setStartupState( STATE_FONT_INIT );
display_startup();
return FALSE;
@@ -2633,7 +2635,6 @@ bool idle_startup()
{
set_startup_status(1.0, "", "");
display_startup();
LLViewerParcelMedia::loadDomainFilterList();
// Let the map know about the inventory.
LLFloaterWorldMap* floater_world_map = gFloaterWorldMap;

View File

@@ -49,11 +49,11 @@
#include "llviewerwindow.h"
#include "llfirstuse.h"
#include "llpluginclassmedia.h"
#include "llmediafilter.h"
#include "llnotify.h"
#include "llsdserialize.h"
#include "llaudioengine.h"
#include "lloverlaybar.h"
#include "slfloatermediafilter.h"
#include "llstreamingaudio.h"
// Static Variables
@@ -61,12 +61,7 @@
S32 LLViewerParcelMedia::sMediaParcelLocalID = 0;
LLUUID LLViewerParcelMedia::sMediaRegionID;
viewer_media_t LLViewerParcelMedia::sMediaImpl;
bool LLViewerParcelMedia::sIsUserAction = false;
bool LLViewerParcelMedia::sMediaFilterListLoaded = false;
LLSD LLViewerParcelMedia::sMediaFilterList;
std::set<std::string> LLViewerParcelMedia::sMediaQueries;
std::set<std::string> LLViewerParcelMedia::sAllowedMedia;
std::set<std::string> LLViewerParcelMedia::sDeniedMedia;
F32 LLViewerParcelMedia::sMediaCommandTime = 0;
// Local functions
bool callback_play_media(const LLSD& notification, const LLSD& response, LLParcel* parcel);
@@ -151,7 +146,15 @@ void LLViewerParcelMedia::update(LLParcel* parcel)
// Only play if the media types are the same.
if(sMediaImpl->getMimeType() == parcel->getMediaType())
{
play(parcel);
if (gSavedSettings.getU32("MediaFilterEnable"))
{
LL_DEBUGS("MediaFilter") << "Filtering media URL: " << parcel->getMediaURL() << LL_ENDL;
LLMediaFilter::getInstance()->filterMediaUrl(parcel);
}
else
{
play(parcel);
}
}
else
@@ -187,7 +190,7 @@ void LLViewerParcelMedia::update(LLParcel* parcel)
}
// static
void LLViewerParcelMedia::play(LLParcel* parcel, bool filter)
void LLViewerParcelMedia::play(LLParcel* parcel)
{
lldebugs << "LLViewerParcelMedia::play" << llendl;
@@ -197,17 +200,7 @@ void LLViewerParcelMedia::play(LLParcel* parcel, bool filter)
return;
std::string media_url = parcel->getMediaURL();
LLStringUtil::trim(media_url);
if (!media_url.empty() && gSavedSettings.getBOOL("MediaEnableFilter") && (filter || !allowedMedia(media_url)))
{
// If filtering is needed or in case media_url just changed
// to something we did not yet approve.
LLViewerParcelMediaAutoPlay::playStarted();
filterMedia(parcel, 0);
return;
}
std::string media_current_url = parcel->getMediaCurrentURL();
std::string mime_type = parcel->getMediaType();
LLUUID placeholder_texture_id = parcel->getMediaID();
U8 media_auto_scale = parcel->getMediaAutoScale();
@@ -399,13 +392,27 @@ void LLViewerParcelMedia::processParcelMediaCommandMessage( LLMessageSystem *msg
// stop
if( command == PARCEL_MEDIA_COMMAND_STOP )
{
stop();
if (!LLMediaFilter::getInstance()->isAlertActive())
{
stop();
}
else
{
LLMediaFilter::getInstance()->setQueuedMediaCommand(PARCEL_MEDIA_COMMAND_STOP);
}
}
else
// pause
if( command == PARCEL_MEDIA_COMMAND_PAUSE )
{
pause();
if (!LLMediaFilter::getInstance()->isAlertActive())
{
pause();
}
else
{
LLMediaFilter::getInstance()->setQueuedMediaCommand(PARCEL_MEDIA_COMMAND_PAUSE);
}
}
else
// play
@@ -419,14 +426,29 @@ void LLViewerParcelMedia::processParcelMediaCommandMessage( LLMessageSystem *msg
else
{
LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
play(parcel);
if (gSavedSettings.getU32("MediaFilterEnable"))
{
LL_DEBUGS("MediaFilter") << "PARCEL_MEDIA_COMMAND_PLAY: Filtering media URL: " << parcel->getMediaURL() << LL_ENDL;
LLMediaFilter::getInstance()->filterMediaUrl(parcel);
}
else
{
play(parcel);
}
}
}
else
// unload
if( command == PARCEL_MEDIA_COMMAND_UNLOAD )
{
stop();
if (!LLMediaFilter::getInstance()->isAlertActive())
{
stop();
}
else
{
LLMediaFilter::getInstance()->setQueuedMediaCommand(PARCEL_MEDIA_COMMAND_UNLOAD);
}
}
}
@@ -435,10 +457,26 @@ void LLViewerParcelMedia::processParcelMediaCommandMessage( LLMessageSystem *msg
if(sMediaImpl.isNull())
{
LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
play(parcel);
if (gSavedSettings.getU32("MediaFilterEnable"))
{
LL_DEBUGS("MediaFilter") << "PARCEL_MEDIA_COMMAND_TIME: Filtering media URL: " << parcel->getMediaURL() << LL_ENDL;
LLMediaFilter::getInstance()->filterMediaUrl(parcel);
}
else
{
play(parcel);
}
}
}
if (!LLMediaFilter::getInstance()->isAlertActive())
{
seek(time);
}
else
{
LLMediaFilter::getInstance()->setQueuedMediaCommand(PARCEL_MEDIA_COMMAND_TIME);
sMediaCommandTime = time;
}
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -492,7 +530,18 @@ void LLViewerParcelMedia::processParcelMediaUpdate( LLMessageSystem *msg, void *
parcel->setMediaAutoScale(media_auto_scale);
parcel->setMediaLoop(media_loop);
play(parcel);
if (sMediaImpl.notNull())
{
if (gSavedSettings.getU32("MediaFilterEnable"))
{
LL_DEBUGS("MediaFilter") << "Parcel media changed. Filtering media URL: " << parcel->getMediaURL() << LL_ENDL;
LLMediaFilter::getInstance()->filterMediaUrl(parcel);
}
else
{
play(parcel);
}
}
}
}
}
@@ -623,37 +672,37 @@ void LLViewerParcelMedia::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent
case MEDIA_EVENT_CLOSE_REQUEST:
{
LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLOSE_REQUEST" << LL_ENDL;
};
}
break;
case MEDIA_EVENT_PICK_FILE_REQUEST:
{
LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PICK_FILE_REQUEST" << LL_ENDL;
};
}
break;
case MEDIA_EVENT_GEOMETRY_CHANGE:
{
LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_GEOMETRY_CHANGE" << LL_ENDL;
};
LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_GEOMETRY_CHANGE, uuid is " << self->getClickUUID() << LL_ENDL;
}
break;
case MEDIA_EVENT_AUTH_REQUEST:
{
LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_AUTH_REQUEST" << LL_ENDL;
};
LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_AUTH_REQUEST, url " << self->getAuthURL() << ", realm " << self->getAuthRealm() << LL_ENDL;
}
break;
case MEDIA_EVENT_LINK_HOVERED:
{
LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_LINK_HOVERED" << LL_ENDL;
LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_LINK_HOVERED, hover text is: " << self->getHoverText() << LL_ENDL;
};
break;
default:
{
LL_WARNS("Media") << "Media event: unknown event type" << LL_ENDL;
};
}
};
}
@@ -663,7 +712,14 @@ bool callback_play_media(const LLSD& notification, const LLSD& response, LLParce
if (option == 0)
{
gSavedSettings.setBOOL("AudioStreamingMedia", TRUE);
LLViewerParcelMedia::play(parcel);
if (gSavedSettings.getU32("MediaFilterEnable"))
{
LLMediaFilter::getInstance()->filterMediaUrl(parcel);
}
else
{
LLViewerParcelMedia::play(parcel);
}
}
else
{
@@ -694,11 +750,10 @@ void LLViewerParcelMedia::playStreamingMusic(LLParcel* parcel, bool filter)
{
std::string music_url = parcel->getMusicURL();
LLStringUtil::trim(music_url);
if (!music_url.empty() && gSavedSettings.getBOOL("MediaEnableFilter") && (filter || !allowedMedia(music_url)))
if (gSavedSettings.getU32("MediaFilterEnable"))
{
// If filtering is needed or in case music_url just changed
// to something we did not yet approve.
filterMedia(parcel, 1);
LL_DEBUGS("MediaFilter") << "Filtering media URL: " << parcel->getMediaURL() << LL_ENDL;
LLMediaFilter::getInstance()->filterAudioUrl(music_url);
}
else if (gAudiop)
{
@@ -726,401 +781,3 @@ void LLViewerParcelMedia::stopStreamingMusic()
LLOverlayBar::audioFilterStop();
}
}
bool LLViewerParcelMedia::allowedMedia(std::string media_url)
{
LLStringUtil::trim(media_url);
std::string domain = extractDomain(media_url);
LLHost host;
host.setHostByName(domain);
std::string ip = host.getIPString();
if (sAllowedMedia.count(domain) || sAllowedMedia.count(ip))
{
return true;
}
std::string server;
for (S32 i = 0; i < (S32)sMediaFilterList.size(); i++)
{
server = sMediaFilterList[i]["domain"].asString();
if (server == domain || server == ip)
{
if (sMediaFilterList[i]["action"].asString() == "allow")
{
return true;
}
else
{
return false;
}
}
}
return false;
}
void LLViewerParcelMedia::filterMedia(LLParcel* parcel, U32 type)
{
std::string media_action;
std::string media_url;
std::string domain;
std::string ip;
if (parcel != LLViewerParcelMgr::getInstance()->getAgentParcel())
{
// The parcel just changed (may occur right out after a TP)
sIsUserAction = false;
return;
}
if (type == 0)
{
media_url = parcel->getMediaURL();
}
else
{
media_url = parcel->getMusicURL();
}
LLStringUtil::trim(media_url);
domain = extractDomain(media_url);
if (sMediaQueries.count(domain) > 0)
{
sIsUserAction = false;
return;
}
LLHost host;
host.setHostByName(domain);
ip = host.getIPString();
if (sIsUserAction)
{
// This was a user manual request to play this media, so give
// it another chance...
sIsUserAction = false;
bool dirty = false;
if (sDeniedMedia.count(domain))
{
sDeniedMedia.erase(domain);
dirty = true;
}
if (sDeniedMedia.count(ip))
{
sDeniedMedia.erase(ip);
dirty = true;
}
if (dirty && SLFloaterMediaFilter::findInstance())
{
SLFloaterMediaFilter::getInstance()->setDirty();
}
}
if (media_url.empty())
{
media_action = "allow";
}
else if (!sMediaFilterListLoaded || sDeniedMedia.count(domain) || sDeniedMedia.count(ip))
{
media_action = "ignore";
}
else if (sAllowedMedia.count(domain) || sAllowedMedia.count(ip))
{
media_action = "allow";
}
else
{
std::string server;
for (S32 i = 0; i < (S32)sMediaFilterList.size(); i++)
{
server = sMediaFilterList[i]["domain"].asString();
if (server == domain || server == ip)
{
media_action = sMediaFilterList[i]["action"].asString();
break;
}
}
}
if (media_action == "allow")
{
if (type == 0)
{
play(parcel, false);
}
else
{
playStreamingMusic(parcel, false);
}
return;
}
if (media_action == "ignore")
{
if (type == 1)
{
LLViewerParcelMedia::stopStreamingMusic();
}
return;
}
LLSD args;
if (ip != domain && domain.find('/') == std::string::npos)
{
args["DOMAIN"] = domain + " (" + ip + ")";
}
else
{
args["DOMAIN"] = domain;
}
if (media_action == "deny")
{
LLNotificationsUtil::add("MediaBlocked", args);
if (type == 1)
{
LLViewerParcelMedia::stopStreamingMusic();
}
// So to avoid other "blocked" messages later in the session
// for this url should it be requested again by a script.
// We don't add the IP, on purpose (want to show different
// blocks for different domains pointing to the same IP).
sDeniedMedia.insert(domain);
}
else
{
sMediaQueries.insert(domain);
args["URL"] = media_url;
if (type == 0)
{
args["TYPE"] = "media";
}
else
{
args["TYPE"] = "audio";
}
LLNotificationsUtil::add("MediaAlert", args, LLSD(), boost::bind(callback_media_alert, _1, _2, parcel, type, domain));
}
}
void callback_media_alert(const LLSD &notification, const LLSD &response, LLParcel* parcel, U32 type, std::string domain)
{
S32 option = LLNotification::getSelectedOption(notification, response);
LLHost host;
host.setHostByName(domain);
std::string ip = host.getIPString();
LLSD args;
if (ip != domain && domain.find('/') == std::string::npos)
{
args["DOMAIN"] = domain + " (" + ip + ")";
}
else
{
args["DOMAIN"] = domain;
}
if (option == 0 || option == 3) // Allow or Whitelist
{
LLViewerParcelMedia::sAllowedMedia.insert(domain);
if (option == 3) // Whitelist
{
LLSD newmedia;
newmedia["domain"] = domain;
newmedia["action"] = "allow";
LLViewerParcelMedia::sMediaFilterList.append(newmedia);
if (ip != domain && domain.find('/') == std::string::npos)
{
newmedia["domain"] = ip;
LLViewerParcelMedia::sMediaFilterList.append(newmedia);
}
LLViewerParcelMedia::saveDomainFilterList();
args["LISTED"] = "whitelisted";
LLNotificationsUtil::add("MediaListed", args);
}
if (type == 0)
{
LLViewerParcelMedia::play(parcel, false);
}
else
{
LLViewerParcelMedia::playStreamingMusic(parcel, false);
}
}
else
{
if (type == 1)
{
LLViewerParcelMedia::stopStreamingMusic();
}
else
{
LLViewerParcelMedia::stopStreamingMusic();
}
if (option == 1 || option == 2) // Deny or Blacklist
{
LLViewerParcelMedia::sDeniedMedia.insert(domain);
if (ip != domain && domain.find('/') == std::string::npos)
{
LLViewerParcelMedia::sDeniedMedia.insert(ip);
}
if (option == 1) // Deny
{
LLNotificationsUtil::add("MediaBlocked", args);
}
else // Blacklist
{
LLSD newmedia;
newmedia["domain"] = domain;
newmedia["action"] = "deny";
LLViewerParcelMedia::sMediaFilterList.append(newmedia);
if (ip != domain && domain.find('/') == std::string::npos)
{
newmedia["domain"] = ip;
LLViewerParcelMedia::sMediaFilterList.append(newmedia);
}
LLViewerParcelMedia::saveDomainFilterList();
args["LISTED"] = "blacklisted";
LLNotificationsUtil::add("MediaListed", args);
}
}
}
LLViewerParcelMedia::sMediaQueries.erase(domain);
if (SLFloaterMediaFilter::findInstance()) SLFloaterMediaFilter::getInstance()->setDirty();
}
void LLViewerParcelMedia::saveDomainFilterList()
{
std::string medialist_filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "media_filter.xml");
llofstream medialistFile(medialist_filename);
LLSDSerialize::toPrettyXML(sMediaFilterList, medialistFile);
medialistFile.close();
}
bool LLViewerParcelMedia::loadDomainFilterList()
{
sMediaFilterListLoaded = true;
std::string medialist_filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "media_filter.xml");
if (!LLFile::isfile(medialist_filename))
{
LLSD emptyllsd;
llofstream medialistFile(medialist_filename);
LLSDSerialize::toPrettyXML(emptyllsd, medialistFile);
medialistFile.close();
}
if (LLFile::isfile(medialist_filename))
{
llifstream medialistFile(medialist_filename);
LLSDSerialize::fromXML(sMediaFilterList, medialistFile);
medialistFile.close();
if (SLFloaterMediaFilter::findInstance()) SLFloaterMediaFilter::getInstance()->setDirty();
return true;
}
else
{
return false;
}
}
void LLViewerParcelMedia::clearDomainFilterList()
{
sMediaFilterList.clear();
sAllowedMedia.clear();
sDeniedMedia.clear();
saveDomainFilterList();
LLNotificationsUtil::add("MediaFiltersCleared");
if (SLFloaterMediaFilter::findInstance()) SLFloaterMediaFilter::getInstance()->setDirty();
}
std::string LLViewerParcelMedia::extractDomain(std::string url)
{
static std::string last_region = "@";
if (url.empty())
{
return url;
}
LLStringUtil::toLower(url);
size_t pos = url.find("//");
if (pos != std::string::npos)
{
size_t count = url.size() - pos + 2;
url = url.substr(pos + 2, count);
}
// Check that there is at least one slash in the URL and add a trailing
// one if not (for media/audio URLs such as http://mydomain.net)
if (url.find('/') == std::string::npos)
{
url += '/';
}
// If there's a user:password@ part, remove it
pos = url.find('@');
if (pos != std::string::npos && pos < url.find('/')) // if '@' is not before the first '/', then it's not a user:password
{
size_t count = url.size() - pos + 1;
url = url.substr(pos + 1, count);
}
//Singu note: The call to getHostName() freezes the viewer for a few seconds if the region has no reverse DNS...
// Avoid calling it three times therefore -- not to mention that if it fails, it returns an empty string which
// does NOT mean that it should match the current url as if the current url contains the current regions hostname!
std::string const hostname = gAgent.getRegion()->getHost().getHostName();
if ((!hostname.empty() && url.find(hostname) == 0) || url.find(last_region) == 0)
{
// This must be a scripted object rezzed in the region:
// extend the concept of "domain" to encompass the
// scripted object server id and avoid blocking all other
// objects at once in this region...
// Get rid of any port number
pos = url.find('/'); // We earlier made sure that there's one
url = hostname + url.substr(pos);
pos = url.find('?');
if (pos != std::string::npos)
{
// Get rid of any parameter
url = url.substr(0, pos);
}
pos = url.rfind('/');
if (pos != std::string::npos)
{
// Get rid of the filename, if any, keeping only the server + path
url = url.substr(0, pos);
}
}
else
{
pos = url.find(':');
if (pos != std::string::npos && pos < url.find('/'))
{
// Keep anything before the port number and strip the rest off
url = url.substr(0, pos);
}
else
{
pos = url.find('/'); // We earlier made sure that there's one
url = url.substr(0, pos);
}
}
// Remember this region, so to cope with requests occuring just after a
// TP out of it.
if (!hostname.empty()) // Singu note: also make sure that last_region doesn't become empty.
{
last_region = hostname;
}
return url;
}

View File

@@ -57,21 +57,13 @@ class LLViewerParcelMedia : public LLViewerMediaObserver
// called when the agent's parcel has a new URL, or the agent has
// walked on to a new parcel with media
static void play(LLParcel* parcel, bool filter = true);
static void play(LLParcel* parcel);
// user clicked play button in media transport controls
static void playStreamingMusic(LLParcel* parcel, bool filter = true);
// play the parcel music stream
static void stopStreamingMusic();
// stop the parcel music stream
static void filterMedia(LLParcel* parcel, U32 type); // type: 0 = media, 1 = streaming music
static bool allowedMedia(std::string media_url);
static bool loadDomainFilterList();
static void saveDomainFilterList();
static void clearDomainFilterList();
static std::string extractDomain(std::string url);
static void stop();
// user clicked stop button in media transport controls
@@ -102,13 +94,9 @@ class LLViewerParcelMedia : public LLViewerMediaObserver
static LLUUID sMediaRegionID;
// HACK: this will change with Media on a Prim
static viewer_media_t sMediaImpl;
static bool sIsUserAction;
static bool sMediaFilterListLoaded;
static LLSD sMediaFilterList;
static std::set<std::string> sMediaQueries;
static std::set<std::string> sAllowedMedia;
static std::set<std::string> sDeniedMedia;
// Media Filter
static F32 sMediaCommandTime;
};

View File

@@ -0,0 +1,216 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
can_close="true"
can_drag_on_left="false"
can_minimize="true"
can_resize="true"
height="254"
name="floatermedialists"
positioning="centered"
rect_control="MediaFilterRect"
title="Media Filter"
width="460"
min_height="160"
min_width="300">
<floater.string name="EnterUrlAllow">
Enter domain or URL to always allow:
</floater.string>
<floater.string name="EnterUrlDeny">
Enter domain or URL to never allow:
</floater.string>
<layout_stack
name="lists_layout_stack"
left="10"
bottom="-254"
right="-10"
height="234"
width="440"
follows="all"
orientation="horizontal"
layout="topleft">
<layout_panel
name="whitelist_layout_panel"
width="220"
height="204"
auto_resize="true"
follows="all"
layout="topleft">
<scroll_list
left="0"
right="-1"
height="166"
follows="all"
background_visible="true"
column_padding="5"
draw_border="true"
draw_heading="true"
mouse_opaque="false"
multi_select="true"
name="whitelist">
<column label="Allowed Domains" name="list"/>
</scroll_list>
<layout_stack
name="whitelist_buttons_layout_stack"
left="0"
bottom_delta="-24"
right="-1"
height="20"
follows="left|right|bottom"
orientation="horizontal"
layout="topleft">
<layout_panel
name="whitelist_buttons_panel_add"
width="110"
height="20"
user_resize="false"
auto_resize="true"
follows="all"
layout="topleft">
<button
bottom="0"
left="0"
height="20"
right="-1"
enabled="true"
follows="all"
font="SansSerifSmall"
halign="center"
label="Add..."
mouse_opaque="false"
name="add_whitelist">
<button.commit_callback
function="MediaFilter.CommitAction"
parameter="AddToWhitelist"/>
</button>
</layout_panel>
<layout_panel
name="whitelist_buttons_panel_remove"
left="110"
width="110"
height="20"
auto_resize="true"
follows="all"
layout="topleft">
<button
bottom="0"
left="0"
height="20"
right="-1"
enabled="true"
follows="all"
font="SansSerifSmall"
halign="center"
label="Remove"
mouse_opaque="false"
name="remove_whitelist">
<button.commit_callback
function="MediaFilter.CommitAction"
parameter="RemoveFromWhitelist"/>
</button>
</layout_panel>
</layout_stack>
</layout_panel>
<layout_panel
name="blacklist_layout_panel"
width="220"
height="204"
auto_resize="true"
follows="all"
layout="topleft">
<scroll_list
left="0"
right="-1"
height="166"
follows="all"
background_visible="true"
column_padding="5"
draw_border="true"
draw_heading="true"
mouse_opaque="false"
multi_select="true"
name="blacklist">
<column label="Blocked Domains" name="list"/>
</scroll_list>
<layout_stack
name="blacklist_buttons_layout_stack"
left="0"
bottom_delta="-24"
right="-1"
height="20"
follows="left|right|bottom"
orientation="horizontal"
layout="topleft">
<layout_panel
name="blacklist_buttons_panel_add"
width="110"
height="20"
user_resize="false"
auto_resize="true"
follows="all"
layout="topleft">
<button
bottom="0"
left="0"
height="20"
right="-1"
enabled="true"
follows="all"
font="SansSerifSmall"
halign="center"
label="Add..."
mouse_opaque="false"
name="add_blacklist">
<button.commit_callback
function="MediaFilter.CommitAction"
parameter="AddToBlacklist"/>
</button>
</layout_panel>
<layout_panel
name="blacklist_buttons_panel_remove"
width="110"
left_delta="110"
height="20"
auto_resize="true"
follows="all"
layout="topleft">
<button
bottom="0"
left="0"
height="20"
right="-1"
enabled="true"
follows="all"
font="SansSerifSmall"
halign="center"
label="Remove"
mouse_opaque="false"
name="remove_blacklist">
<button.commit_callback
function="MediaFilter.CommitAction"
parameter="RemoveFromBlacklist"/>
</button>
</layout_panel>
</layout_stack>
</layout_panel>
</layout_stack>
</floater>

View File

@@ -179,6 +179,26 @@ You may choose to allow or deny the corresponding domain or in-world scripted ob
text="Whitelist"/>
</form>
</notification>
<notification
icon="alertmodal.tga"
name="AddToMediaList"
type="alertmodal">
Enter a domain name to be added to the [LIST]:
<tag>confirm</tag>
<form name="form">
<input name="url" type="text" default="true" />
<button
default="true"
index="0"
name="Add"
text="Add"/>
<button
index="1"
name="Cancel"
text="Cancel"/>
</form>
</notification>
<notification
icon="alert.tga"

View File

@@ -5,6 +5,11 @@
<text bottom="-295" height="12" name="audio_prefs_text">Audio Preferences:</text>
<panel border="true" bottom="-172" filename="panel_audio.xml" height="165" label="Volume" left="142" name="Volume Panel" width="260"/>
<check_box bottom="-195" control_name="MediaEnableFilter" follows="top" height="16" initial_value="true" label="Ask for permission (enables filtering)" left="142" name="media_filter_enable"/>
<radio_group bottom="-195" control_name="MediaEnableFilter" follows="top" height="16" label="Media Filtering" tab_stop="true" draw_border="false">
<radio_item enabled="true" follows="left|top" height="16" left="0" length="1" mouse_opaque="true" name="Off" label="Off" value="0" width="30" type="string" />
<radio_item enabled="true" follows="left|top" height="16" left_pad="4" length="1" mouse_opaque="true" name="Blacklist" label="Blacklist Only" value="1" width="30" type="string" />
<radio_item enabled="true" follows="left|top" height="16" left_pad="4" length="1" mouse_opaque="true" name="Prompt" label="Prompt" value="2" width="30" type="string" />
</radio_group>
<check_box bottom_delta="-20" control_name="AudioStreamingMusic" follows="top" height="16" initial_value="true" label="Play Streaming Music When Available (uses more bandwidth)" name="streaming_music"/>
<check_box bottom_delta="-20" control_name="AudioStreamingMedia" follows="top" height="16" initial_value="true" label="Play Streaming Media When Available (uses more bandwidth)" name="streaming_video"/>
<check_box bottom_delta="-20" control_name="PrimMediaAutoPlayEnable" follows="top" height="16" initial_value="true" label="Automatically play prim media" left="162" name="auto_prim_streaming_video"/>

View File

@@ -4425,6 +4425,11 @@ Try enclosing path to the editor with double quotes.
<!-- teleport_strings.xml's strings we need -->
<string name="completed_from">Teleport completed from</string>
<string name="audio">audio</string>
<string name="media">media</string>
<string name="MediaFilterBlacklist">blacklist</string>
<string name="MediaFilterWhitelist">whitelist</string>
<!-- AIAlert messages -->
<!-- These two do not need translation ;) -->

View File

@@ -1,398 +0,0 @@
/**
* @file slfloatermediafilter.cpp
* @brief The SLFloaterMediaFilter class definitions
*
* $LicenseInfo:firstyear=2011&license=viewergpl$
*
* Copyright (c) 2011, Sione Lomu
* with debugging and improvements by Henri Beauchamp
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "slfloatermediafilter.h"
#include "llscrolllistctrl.h"
#include "lluictrlfactory.h"
#include "llviewerparcelmedia.h"
SLFloaterMediaFilter::SLFloaterMediaFilter(const LLSD& key) : LLFloater(std::string("media filter")), mIsDirty(false)
{
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_media_filter.xml");
}
SLFloaterMediaFilter::~SLFloaterMediaFilter()
{
}
BOOL SLFloaterMediaFilter::postBuild()
{
mWhitelistSLC = getChild<LLScrollListCtrl>("whitelist_list");
mBlacklistSLC = getChild<LLScrollListCtrl>("blacklist_list");
if (mWhitelistSLC && mBlacklistSLC)
{
getChild<LLUICtrl>("clear_lists")->setCommitCallback(boost::bind(LLViewerParcelMedia::clearDomainFilterList));
getChild<LLUICtrl>("show_ips")->setCommitCallback(boost::bind(&SLFloaterMediaFilter::onShowIPs, this));
getChild<LLUICtrl>("add_whitelist")->setCommitCallback(boost::bind(&SLFloaterMediaFilter::onWhitelistAdd, this));
getChild<LLUICtrl>("remove_whitelist")->setCommitCallback(boost::bind(&SLFloaterMediaFilter::onWhitelistRemove, this));
getChild<LLUICtrl>("add_blacklist")->setCommitCallback(boost::bind(&SLFloaterMediaFilter::onBlacklistAdd, this));
getChild<LLUICtrl>("remove_blacklist")->setCommitCallback(boost::bind(&SLFloaterMediaFilter::onBlacklistRemove, this));
getChild<LLUICtrl>("commit_domain")->setCommitCallback(boost::bind(&SLFloaterMediaFilter::onCommitDomain, this));
mIsDirty = true;
}
return TRUE;
}
void SLFloaterMediaFilter::draw()
{
if (mIsDirty && mWhitelistSLC && mBlacklistSLC)
{
S32 whitescrollpos = mWhitelistSLC->getScrollPos();
S32 blackscrollpos = mBlacklistSLC->getScrollPos();
mWhitelistSLC->deleteAllItems();
mBlacklistSLC->deleteAllItems();
std::set<std::string> listed;
LLHost host;
std::string ip;
std::string domain;
std::string action;
LLSD element;
element["columns"][0]["font"] = "SANSSERIF";
element["columns"][0]["font-style"] = "BOLD";
for (S32 i = 0; i < (S32)LLViewerParcelMedia::sMediaFilterList.size(); i++)
{
domain = LLViewerParcelMedia::sMediaFilterList[i]["domain"].asString();
if (mShowIPs)
{
host.setHostByName(domain);
ip = host.getIPString();
if (ip != domain && domain.find('/') == std::string::npos)
{
domain += " (" + ip + ")";
}
}
action = LLViewerParcelMedia::sMediaFilterList[i]["action"].asString();
if (!domain.empty() && action == "allow")
{
element["columns"][0]["column"] = "whitelist_col";
element["columns"][0]["value"] = domain;
//element["columns"][0]["color"] = LLColor4::green3.getValue();
mWhitelistSLC->addElement(element, ADD_BOTTOM);
listed.insert(domain);
}
else if (!domain.empty() && action == "deny")
{
element["columns"][0]["column"] = "blacklist_col";
element["columns"][0]["value"] = domain;
//element["columns"][0]["color"] = LLColor4::red2.getValue();
mBlacklistSLC->addElement(element, ADD_BOTTOM);
listed.insert(domain);
}
else
{
LL_WARNS("MediaFilter") << "Bad media filter list: removing corrupted entry for \"" << domain << "\"" << LL_ENDL;
LLViewerParcelMedia::sMediaFilterList.erase(i--);
}
}
std::set<std::string>::iterator it;
element["columns"][0]["font"] = "SANSSERIF";
element["columns"][0]["font-style"] = "ITALIC";
//element["columns"][0]["color"] = LLColor4::green3.getValue();
element["columns"][0]["column"] = "whitelist_col";
for (it = LLViewerParcelMedia::sAllowedMedia.begin(); it != LLViewerParcelMedia::sAllowedMedia.end(); it++)
{
domain = *it;
if (mShowIPs)
{
host.setHostByName(domain);
ip = host.getIPString();
if (ip != domain && domain.find('/') == std::string::npos)
{
domain += " (" + ip + ")";
}
}
if (listed.count(domain) == 0)
{
element["columns"][0]["value"] = domain;
mWhitelistSLC->addElement(element, ADD_BOTTOM);
}
}
element["columns"][0]["column"] = "blacklist_col";
for (it = LLViewerParcelMedia::sDeniedMedia.begin(); it != LLViewerParcelMedia::sDeniedMedia.end(); it++)
{
domain = *it;
if (mShowIPs)
{
host.setHostByName(domain);
ip = host.getIPString();
if (ip != domain && domain.find('/') == std::string::npos)
{
domain += " (" + ip + ")";
}
}
if (listed.count(domain) == 0)
{
element["columns"][0]["value"] = domain;
mBlacklistSLC->addElement(element, ADD_BOTTOM);
}
}
mWhitelistSLC->setScrollPos(whitescrollpos);
mBlacklistSLC->setScrollPos(blackscrollpos);
if (!gSavedSettings.getBOOL("MediaEnableFilter"))
{
childDisable("clear_lists");
childDisable("show_ips");
childDisable("blacklist_list");
childDisable("whitelist_list");
childDisable("remove_whitelist");
childDisable("add_whitelist");
childDisable("remove_blacklist");
childDisable("add_blacklist");
childDisable("match_ip");
childDisable("input_domain");
childDisable("commit_domain");
childSetText("add_text", std::string("****** WARNING: media filtering is currently DISABLED ******"));
}
mIsDirty = false;
mShowIPs = false;
}
LLFloater::draw();
}
void SLFloaterMediaFilter::setDirty()
{
mIsDirty = true;
}
void SLFloaterMediaFilter::onShowIPs()
{
mShowIPs = true;
mIsDirty = true;
}
void SLFloaterMediaFilter::onWhitelistAdd()
{
childDisable("clear_lists");
childDisable("show_ips");
childDisable("blacklist_list");
childDisable("whitelist_list");
childDisable("remove_whitelist");
childDisable("add_whitelist");
childDisable("remove_blacklist");
childDisable("add_blacklist");
childEnable("input_domain");
childEnable("commit_domain");
childSetText("add_text", std::string("Enter the domain/url to add to the white list:"));
mIsWhitelist = true;
}
void SLFloaterMediaFilter::onWhitelistRemove()
{
LLScrollListItem* selected = mWhitelistSLC->getFirstSelected();
if (selected)
{
std::string domain = mWhitelistSLC->getSelectedItemLabel();
size_t pos = domain.find(' ');
if (pos != std::string::npos)
{
domain = domain.substr(0, pos);
}
LLViewerParcelMedia::sAllowedMedia.erase(domain);
for (S32 i = 0; i < (S32)LLViewerParcelMedia::sMediaFilterList.size(); i++)
{
if (LLViewerParcelMedia::sMediaFilterList[i]["domain"].asString() == domain)
{
LLViewerParcelMedia::sMediaFilterList.erase(i);
break;
}
}
if (childGetValue("match_ip") && domain.find('/') == std::string::npos)
{
LLHost host;
host.setHostByName(domain);
std::string ip = host.getIPString();
if (ip != domain)
{
LLViewerParcelMedia::sAllowedMedia.erase(ip);
for (S32 i = 0; i < (S32)LLViewerParcelMedia::sMediaFilterList.size(); i++)
{
if (LLViewerParcelMedia::sMediaFilterList[i]["domain"].asString() == ip)
{
LLViewerParcelMedia::sMediaFilterList.erase(i);
break;
}
}
}
}
LLViewerParcelMedia::saveDomainFilterList();
setDirty();
}
}
void SLFloaterMediaFilter::onBlacklistAdd()
{
childDisable("clear_lists");
childDisable("show_ips");
childDisable("blacklist_list");
childDisable("whitelist_list");
childDisable("remove_whitelist");
childDisable("add_whitelist");
childDisable("remove_blacklist");
childDisable("add_blacklist");
childEnable("input_domain");
childEnable("commit_domain");
childSetText("add_text", std::string("Enter the domain/url to add to the black list:"));
mIsWhitelist = false;
}
void SLFloaterMediaFilter::onBlacklistRemove()
{
LLScrollListItem* selected = mBlacklistSLC->getFirstSelected();
if (selected)
{
std::string domain = mBlacklistSLC->getSelectedItemLabel();
size_t pos = domain.find(' ');
if (pos != std::string::npos)
{
domain = domain.substr(0, pos);
}
LLViewerParcelMedia::sDeniedMedia.erase(domain);
for (S32 i = 0; i < (S32)LLViewerParcelMedia::sMediaFilterList.size(); i++)
{
if (LLViewerParcelMedia::sMediaFilterList[i]["domain"].asString() == domain)
{
LLViewerParcelMedia::sMediaFilterList.erase(i);
break;
}
}
if (childGetValue("match_ip") && domain.find('/') == std::string::npos)
{
LLHost host;
host.setHostByName(domain);
std::string ip = host.getIPString();
if (ip != domain)
{
LLViewerParcelMedia::sDeniedMedia.erase(ip);
for (S32 i = 0; i < (S32)LLViewerParcelMedia::sMediaFilterList.size(); i++)
{
if (LLViewerParcelMedia::sMediaFilterList[i]["domain"].asString() == ip)
{
LLViewerParcelMedia::sMediaFilterList.erase(i);
break;
}
}
}
}
LLViewerParcelMedia::saveDomainFilterList();
setDirty();
}
}
void SLFloaterMediaFilter::onCommitDomain()
{
std::string domain = childGetText("input_domain");
domain = LLViewerParcelMedia::extractDomain(domain);
LLHost host;
host.setHostByName(domain);
std::string ip = host.getIPString();
bool match_ip = (childGetValue("match_ip") && ip != domain && domain.find('/') == std::string::npos);
if (!domain.empty())
{
LLViewerParcelMedia::sDeniedMedia.erase(domain);
LLViewerParcelMedia::sAllowedMedia.erase(domain);
for (S32 i = 0; i < (S32)LLViewerParcelMedia::sMediaFilterList.size(); i++)
{
if (LLViewerParcelMedia::sMediaFilterList[i]["domain"].asString() == domain)
{
LLViewerParcelMedia::sMediaFilterList.erase(i);
}
}
if (match_ip)
{
LLViewerParcelMedia::sDeniedMedia.erase(ip);
LLViewerParcelMedia::sAllowedMedia.erase(ip);
for (S32 i = 0; i < (S32)LLViewerParcelMedia::sMediaFilterList.size(); i++)
{
if (LLViewerParcelMedia::sMediaFilterList[i]["domain"].asString() == ip)
{
LLViewerParcelMedia::sMediaFilterList.erase(i);
}
}
}
LLSD newmedia;
newmedia["domain"] = domain;
if (mIsWhitelist)
{
newmedia["action"] = "allow";
}
else
{
newmedia["action"] = "deny";
}
LLViewerParcelMedia::sMediaFilterList.append(newmedia);
if (match_ip)
{
newmedia["domain"] = ip;
LLViewerParcelMedia::sMediaFilterList.append(newmedia);
}
LLViewerParcelMedia::saveDomainFilterList();
}
childEnable("clear_lists");
childEnable("show_ips");
childEnable("blacklist_list");
childEnable("whitelist_list");
childEnable("remove_whitelist");
childEnable("add_whitelist");
childEnable("remove_blacklist");
childEnable("add_blacklist");
childDisable("input_domain");
childDisable("commit_domain");
childSetText("add_text", std::string("New domain:"));
childSetText("input_domain", std::string(""));
setDirty();
}

View File

@@ -1,66 +0,0 @@
/**
* @file slfloatermediafilter.h
* @brief The SLFloaterMediaFilter class declaration
*
* $LicenseInfo:firstyear=2011&license=viewergpl$
*
* Copyright (c) 2011, Sione Lomu
* with debugging and improvements by Henri Beauchamp
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_SLFLOATERMEDIAFILTER_H
#define LL_SLFLOATERMEDIAFILTER_H
#include "llfloater.h"
class LLScrollListCtrl;
class SLFloaterMediaFilter : public LLFloater, public LLFloaterSingleton<SLFloaterMediaFilter>
{
friend class LLUISingleton<SLFloaterMediaFilter, VisibilityPolicy<LLFloater> >;
public:
SLFloaterMediaFilter(const LLSD& key = LLSD());
BOOL postBuild();
virtual void draw();
virtual ~SLFloaterMediaFilter();
void setDirty();
void onShowIPs();
void onWhitelistAdd();
void onWhitelistRemove();
void onBlacklistAdd();
void onBlacklistRemove();
void onCommitDomain();
private:
bool mIsWhitelist;
bool mShowIPs;
LLScrollListCtrl* mWhitelistSLC;
LLScrollListCtrl* mBlacklistSLC;
bool mIsDirty;
};
#endif