Replace the media filter with something a little different
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
153
indra/newview/llfloatermediafilter.cpp
Normal file
153
indra/newview/llfloatermediafilter.cpp
Normal 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;
|
||||
}
|
||||
55
indra/newview/llfloatermediafilter.h
Normal file
55
indra/newview/llfloatermediafilter.h
Normal 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
|
||||
491
indra/newview/llmediafilter.cpp
Normal file
491
indra/newview/llmediafilter.cpp
Normal 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;
|
||||
}
|
||||
92
indra/newview/llmediafilter.h
Normal file
92
indra/newview/llmediafilter.h
Normal 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
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 ¬ification, 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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
216
indra/newview/skins/default/xui/en-us/floater_media_lists.xml
Normal file
216
indra/newview/skins/default/xui/en-us/floater_media_lists.xml
Normal 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>
|
||||
@@ -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"
|
||||
|
||||
@@ -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"/>
|
||||
|
||||
@@ -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 ;) -->
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user