Discord rich presence support
parent
768cced8fb
commit
1c8be4e323
|
|
@ -237,6 +237,58 @@
|
|||
</map>
|
||||
</map>
|
||||
</map>
|
||||
<key>discord-rpc</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
<string>Copyright 2019 Discord, Inc.</string>
|
||||
<key>description</key>
|
||||
<string>C++ library to interface with Discord's API</string>
|
||||
<key>license</key>
|
||||
<string>MIT</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSES/discord-rpc.txt</string>
|
||||
<key>name</key>
|
||||
<string>discord-rpc</string>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>windows</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>b760b4f3ab7794a897cf7f464d92e587</string>
|
||||
<key>url</key>
|
||||
<uri>http://downloads.phoenixviewer.com/discord_rpc-3.4.0-windows-192510505.tar.bz2</uri>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows</string>
|
||||
</map>
|
||||
<key>linux64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>756c1dd3dddf218352b83b54db400056</string>
|
||||
<key>url</key>
|
||||
<uri>http://downloads.phoenixviewer.com/discord_rpc-3.4.0-darwin64-192522358.tar.bz2</uri>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
</map>
|
||||
<key>darwin64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>3bc297a0fa47094bb52d361f80186387</string>
|
||||
<key>url</key>
|
||||
<uri>http://downloads.phoenixviewer.com/discord_rpc-3.4.0-linux64-192531056.tar.bz2</uri>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
</map>
|
||||
</map>
|
||||
</map>
|
||||
<key>SDL</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ set(cmake_SOURCE_FILES
|
|||
Copy3rdPartyLibs.cmake
|
||||
DBusGlib.cmake
|
||||
DeploySharedLibs.cmake
|
||||
Discord.cmake # <FS:LO> Discord rich presence
|
||||
DirectX.cmake
|
||||
DragDrop.cmake
|
||||
EXPAT.cmake
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
# -*- cmake -*-
|
||||
|
||||
|
||||
|
||||
|
||||
include(Prebuilt)
|
||||
use_prebuilt_binary(discord-rpc)
|
||||
set(DISCORD_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/discord-rpc)
|
||||
if (ADDRESS_SIZE EQUAL 32 AND WINDOWS)
|
||||
set(DISCORD_LIBRARY discord-rpc)
|
||||
elseif (WINDOWS)
|
||||
set(DISCORD_LIBRARY discord-rpc_x64)
|
||||
elseif (LINUX || DARWIN)
|
||||
set(DISCORD_LIBRARY libdiscord-rpc)
|
||||
endif (ADDRESS_SIZE EQUAL 32 AND WINDOWS)
|
||||
if (DISCORD_API_KEY)
|
||||
add_definitions( -DDISCORD_API_KEY=\"${DISCORD_API_KEY}\")
|
||||
endif (DISCORD_API_KEY)
|
||||
|
|
@ -60,6 +60,7 @@ include(URIPARSER)
|
|||
include(Growl)
|
||||
include(ColladaDom)
|
||||
include(jemalloc)
|
||||
include(Discord)
|
||||
|
||||
# <FS:ND> if using ndPhysicsstub this variable will be unset, we don't need to build any stub code viewer side in that case
|
||||
if( LLPHYSICSEXTENSIONS_SRC_DIR )
|
||||
|
|
@ -1792,6 +1793,11 @@ if (WINDOWS)
|
|||
# [FS]
|
||||
)
|
||||
|
||||
#<FS:LO> Discord rich presence
|
||||
LIST(APPEND viewer_HEADER_FILES fsfloaterdiscord.h fsdiscordconnect.h)
|
||||
LIST(APPEND viewer_SOURCE_FILES fsfloaterdiscord.cpp fsdiscordconnect.cpp)
|
||||
#</FS:LO>
|
||||
|
||||
# precompiled header configuration
|
||||
# llviewerprecompiledheaders.cpp generates
|
||||
# the .pch file.
|
||||
|
|
@ -2432,6 +2438,7 @@ target_link_libraries(${VIEWER_BINARY_NAME}
|
|||
${LLPHYSICSEXTENSIONS_LIBRARIES}
|
||||
${LLAPPEARANCE_LIBRARIES}
|
||||
${GROWL_LIBRARY}
|
||||
${DISCORD_LIBRARY}
|
||||
)
|
||||
|
||||
if (BUGSPLAT_DB)
|
||||
|
|
|
|||
|
|
@ -633,4 +633,14 @@
|
|||
execute_function="Tools.StopAllAnimations"
|
||||
execute_parameters="stop"
|
||||
/>
|
||||
<command name="discord"
|
||||
available_in_toybox="true"
|
||||
icon="Command_Discord_Icon"
|
||||
label_ref="Command_Discord_Label"
|
||||
tooltip_ref="Command_Discord_Tooltip"
|
||||
execute_function="Floater.Toggle"
|
||||
execute_parameters="fs_discord"
|
||||
is_running_function="Floater.IsOpen"
|
||||
is_running_parameters="fs_discord"
|
||||
/>
|
||||
</commands>
|
||||
|
|
|
|||
|
|
@ -1224,5 +1224,38 @@
|
|||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>FSEnableDiscordIntegration</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>If enabled, well allow Firestorm to connect to discord if open and share location data with. Default (false)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>FSMaxSharedMaturity</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Max maturity rating to share with Discord</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>13</integer>
|
||||
</map>
|
||||
<key>FSBlacklistedRegionNames</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>List of region names to never share with Discord</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>LLSD</string>
|
||||
<key>Value</key>
|
||||
<array></array>
|
||||
</map>
|
||||
</map>
|
||||
</llsd>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,332 @@
|
|||
/**
|
||||
* @file fsdiscordconnect.cpp
|
||||
* @brief Connection to Discord
|
||||
* @author liny@pinkfox.xyz
|
||||
*
|
||||
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
|
||||
* Phoenix Firestorm Viewer Source Code
|
||||
* Copyright (C) 2019 Liny Odell @ Second Life
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
|
||||
* http://www.firestormviewer.org
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "fsdiscordconnect.h"
|
||||
|
||||
#include "llagent.h"
|
||||
#include "llcallingcard.h" // for LLAvatarTracker
|
||||
#include "llcommandhandler.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "lltrans.h"
|
||||
#include "llevents.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llavatarnamecache.h"
|
||||
#include "llregioninfomodel.h"
|
||||
|
||||
#include "rlvactions.h"
|
||||
#include "rlvhandler.h"
|
||||
|
||||
#include "llfloaterreg.h"
|
||||
|
||||
#include "discord-rpc\discord_rpc.h"
|
||||
|
||||
#include "boost/algorithm/string/case_conv.hpp"
|
||||
|
||||
#ifndef DISCORD_API_KEY
|
||||
#define DISCORD_API_KEY ""
|
||||
#endif
|
||||
|
||||
boost::scoped_ptr<LLEventPump> FSDiscordConnect::sStateWatcher(new LLEventStream("DiscordConnectState"));
|
||||
boost::scoped_ptr<LLEventPump> FSDiscordConnect::sInfoWatcher(new LLEventStream("DiscordConnectInfo"));
|
||||
|
||||
|
||||
// Returns false when the file exists and has not our UUID
|
||||
// Or, put simply, returns true if someone else is using it
|
||||
bool FSDiscordConnect::checkMarkerFile()
|
||||
{
|
||||
if (!LLFile::isfile(mMarkerFilename))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
LLUUID fileID;
|
||||
llifstream file(mMarkerFilename);
|
||||
file >> fileID;
|
||||
if ((fileID == gAgentID) || fileID.isNull())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void FSDiscordConnect::setMarkerFile()
|
||||
{
|
||||
//LLFile file = LLFile::fopen(mMarkerFilename, "w");
|
||||
if (!checkMarkerFile())
|
||||
{
|
||||
return; // dont over-write another instances file
|
||||
}
|
||||
llofstream file = llofstream(mMarkerFilename.c_str());
|
||||
file << gAgentID << std::endl;
|
||||
file.close();
|
||||
}
|
||||
|
||||
void FSDiscordConnect::clearMarkerFile()
|
||||
{
|
||||
if (!checkMarkerFile())
|
||||
{
|
||||
return; // dont remove another instances file
|
||||
}
|
||||
LLFile::remove(mMarkerFilename);
|
||||
}
|
||||
|
||||
void handleDiscordReady(const DiscordUser *request)
|
||||
{
|
||||
LLSD info;
|
||||
info["name"] = request->username;
|
||||
FSDiscordConnect::getInstance()->storeInfo(info);
|
||||
FSDiscordConnect::getInstance()->setConnectionState(FSDiscordConnect::DISCORD_CONNECTED);
|
||||
}
|
||||
|
||||
void handleDiscordError(int errorCode, const char* message)
|
||||
{
|
||||
LL_WARNS("DiscordConnect") << "Discord error, errorCode: \"" << errorCode << "\", message: \"" << message << "\"" << LL_ENDL;
|
||||
}
|
||||
|
||||
void handleDiscordDisconnected(int errorCode, const char* message)
|
||||
{
|
||||
LL_INFOS("DiscordConnect") << "Discord disconnected, errorCode: \"" << errorCode << "\", message: \"" << message << "\"" << LL_ENDL;
|
||||
FSDiscordConnect::getInstance()->setConnectionState(FSDiscordConnect::DISCORD_NOT_CONNECTED);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void FSDiscordConnect::discordConnectCoro()
|
||||
{
|
||||
DiscordEventHandlers handlers;
|
||||
memset(&handlers, 0, sizeof(handlers));
|
||||
handlers.ready = handleDiscordReady;
|
||||
handlers.errored = handleDiscordError;
|
||||
handlers.disconnected = handleDiscordDisconnected;
|
||||
//TODO: Get this working and sending TPs
|
||||
/*handlers.joinGame = handleDiscordJoinGame;
|
||||
handlers.spectateGame = handleDiscordSpectateGame;
|
||||
handlers.joinRequest = handleDiscordJoinRequest;*/
|
||||
|
||||
Discord_Initialize(DISCORD_API_KEY, &handlers, 1, "");
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void FSDiscordConnect::discordDisconnectCoro()
|
||||
{
|
||||
Discord_Shutdown();
|
||||
setConnectionState(FSDiscordConnect::DISCORD_NOT_CONNECTED);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void FSDiscordConnect::discordConnectedCoro(bool autoConnect)
|
||||
{
|
||||
if (autoConnect)
|
||||
{
|
||||
setConnectionState(FSDiscordConnect::DISCORD_CONNECTION_IN_PROGRESS);
|
||||
if (!checkMarkerFile())
|
||||
{
|
||||
connectToDiscord();
|
||||
}
|
||||
else
|
||||
{
|
||||
setConnectionState(FSDiscordConnect::DISCORD_CONNECTION_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool isRegionVisible(LLViewerRegion* region)
|
||||
{
|
||||
U8 rating = region->getSimAccess();
|
||||
bool visible = true;
|
||||
if (!(rating <= gSavedPerAccountSettings.getU32("FSMaxSharedMaturity")))
|
||||
{
|
||||
visible = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string name = region->getName();
|
||||
LLSD list = gSavedPerAccountSettings.getLLSD("FSBlacklistedRegionNames");
|
||||
for (LLSD::array_const_iterator iter = list.beginArray();
|
||||
iter != list.endArray();
|
||||
iter++)
|
||||
{
|
||||
if (boost::algorithm::to_lower_copy((*iter).asString()) == boost::algorithm::to_lower_copy(name))
|
||||
{
|
||||
visible = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return visible;
|
||||
}
|
||||
|
||||
void FSDiscordConnect::updateRichPresence()
|
||||
{
|
||||
LLViewerRegion * region = gAgent.getRegion();
|
||||
if (!isConnected() || !region)
|
||||
{
|
||||
return;
|
||||
}
|
||||
std::string region_name;
|
||||
if (RlvActions::canShowLocation() && isRegionVisible(region))
|
||||
{
|
||||
region_name = gAgent.getRegion()->getName();
|
||||
region_name += " ";
|
||||
LLVector3 pos = gAgent.getPositionAgent();
|
||||
|
||||
region_name += llformat("(%.0f, %.0f, %.0f)", pos.mV[0], pos.mV[1], pos.mV[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
region_name = RlvStrings::getString(RLV_STRING_HIDDEN_REGION);
|
||||
}
|
||||
|
||||
DiscordRichPresence discordPresence;
|
||||
memset(&discordPresence, 0, sizeof(discordPresence));
|
||||
discordPresence.state = region_name.c_str();
|
||||
LLAvatarName av_name;
|
||||
std::string name;
|
||||
if (RlvActions::canShowName(RlvActions::SNC_DEFAULT, gAgentID))
|
||||
{
|
||||
if (LLAvatarNameCache::get(gAgentID, &av_name))
|
||||
{
|
||||
name = av_name.getCompleteName(true, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
name = gAgentUsername;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
name = RlvStrings::getAnonym(av_name);
|
||||
}
|
||||
discordPresence.details = name.c_str();
|
||||
|
||||
discordPresence.largeImageKey = "secondlife_512";
|
||||
discordPresence.largeImageText = "Second Life";
|
||||
discordPresence.smallImageKey = "firestorm_512";
|
||||
//const char* appname = std::string("via " + APP_NAME).c_str(); // No idea why this doesnt work, but discord receives random data from somewhere in the programs address space and not the text that it should
|
||||
discordPresence.smallImageText = "via Firestorm"; // I hate to hardcode the word "Firestorm" cause of the above global, but this way works
|
||||
|
||||
discordPresence.partyId = gAgent.getRegion()->getRegionID().asString().c_str();
|
||||
discordPresence.partySize = gAgent.getRegion()->mMapAvatars.size();
|
||||
discordPresence.partyMax = LLRegionInfoModel::instance().mAgentLimit;
|
||||
Discord_UpdatePresence(&discordPresence);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
FSDiscordConnect::FSDiscordConnect()
|
||||
: mConnectionState(DISCORD_NOT_CONNECTED),
|
||||
mConnected(false),
|
||||
mInfo(),
|
||||
mRefreshInfo(false)
|
||||
{
|
||||
mMarkerFilename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "discord_in_use_marker");
|
||||
LLEventPumps::instance().obtain("mainloop").listen("FSDiscordConnect", boost::bind(&FSDiscordConnect::Tick, this, _1));
|
||||
}
|
||||
|
||||
FSDiscordConnect::~FSDiscordConnect()
|
||||
{
|
||||
disconnectFromDiscord();
|
||||
}
|
||||
|
||||
void FSDiscordConnect::connectToDiscord()
|
||||
{
|
||||
LLCoros::instance().launch("FSDiscordConnect::discordConnectCoro",
|
||||
boost::bind(&FSDiscordConnect::discordConnectCoro, this));
|
||||
}
|
||||
|
||||
void FSDiscordConnect::disconnectFromDiscord()
|
||||
{
|
||||
setConnectionState(FSDiscordConnect::DISCORD_DISCONNECTING);
|
||||
|
||||
LLCoros::instance().launch("FSDiscordConnect::discordDisconnectCoro",
|
||||
boost::bind(&FSDiscordConnect::discordDisconnectCoro, this));
|
||||
}
|
||||
|
||||
void FSDiscordConnect::checkConnectionToDiscord(bool auto_connect)
|
||||
{
|
||||
LLCoros::instance().launch("FSDiscordConnect::discordConnectedCoro",
|
||||
boost::bind(&FSDiscordConnect::discordConnectedCoro, this, auto_connect));
|
||||
}
|
||||
|
||||
bool FSDiscordConnect::Tick(const LLSD&)
|
||||
{
|
||||
Discord_RunCallbacks();
|
||||
updateRichPresence();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void FSDiscordConnect::storeInfo(const LLSD& info)
|
||||
{
|
||||
mInfo = info;
|
||||
mRefreshInfo = false;
|
||||
|
||||
sInfoWatcher->post(info);
|
||||
}
|
||||
|
||||
const LLSD& FSDiscordConnect::getInfo() const
|
||||
{
|
||||
return mInfo;
|
||||
}
|
||||
|
||||
void FSDiscordConnect::clearInfo()
|
||||
{
|
||||
mInfo = LLSD();
|
||||
}
|
||||
|
||||
void FSDiscordConnect::setConnectionState(FSDiscordConnect::EConnectionState connection_state)
|
||||
{
|
||||
if(connection_state == DISCORD_CONNECTED)
|
||||
{
|
||||
setMarkerFile();
|
||||
setConnected(true);
|
||||
}
|
||||
else if(connection_state == DISCORD_NOT_CONNECTED)
|
||||
{
|
||||
clearMarkerFile();
|
||||
setConnected(false);
|
||||
}
|
||||
|
||||
if (mConnectionState != connection_state)
|
||||
{
|
||||
// set the connection state before notifying watchers
|
||||
mConnectionState = connection_state;
|
||||
|
||||
LLSD state_info;
|
||||
state_info["enum"] = connection_state;
|
||||
sStateWatcher->post(state_info);
|
||||
}
|
||||
}
|
||||
|
||||
void FSDiscordConnect::setConnected(bool connected)
|
||||
{
|
||||
mConnected = connected;
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/**
|
||||
* @file fsdiscordconnect.h
|
||||
* @brief Connection to Discord
|
||||
* @author liny@pinkfox.xyz
|
||||
*
|
||||
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
|
||||
* Phoenix Firestorm Viewer Source Code
|
||||
* Copyright (C) 2019 Liny Odell @ Second Life
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
|
||||
* http://www.firestormviewer.org
|
||||
*/
|
||||
|
||||
#ifndef FS_FSDISCORDCONNECT_H
|
||||
#define FS_FSDISCORDCONNECT_H
|
||||
|
||||
#include "llsingleton.h"
|
||||
#include "llcoros.h"
|
||||
#include "lleventcoro.h"
|
||||
|
||||
class LLEventPump;
|
||||
|
||||
/**
|
||||
* @class LLTwitterConnect
|
||||
*
|
||||
* Manages authentication to, and interaction with, a web service allowing the
|
||||
* the viewer to post status updates and upload photos to Twitter.
|
||||
*/
|
||||
class FSDiscordConnect : public LLSingleton<FSDiscordConnect>
|
||||
{
|
||||
LLSINGLETON(FSDiscordConnect);
|
||||
LOG_CLASS(FSDiscordConnect);
|
||||
public:
|
||||
enum EConnectionState
|
||||
{
|
||||
DISCORD_NOT_CONNECTED = 0,
|
||||
DISCORD_CONNECTION_IN_PROGRESS = 1,
|
||||
DISCORD_CONNECTED = 2,
|
||||
DISCORD_CONNECTION_FAILED = 3,
|
||||
DISCORD_DISCONNECTING = 4
|
||||
};
|
||||
|
||||
~FSDiscordConnect();
|
||||
|
||||
void connectToDiscord(); // Initiate the complete Discord connection. Please use checkConnectionToDiscord() in normal use.
|
||||
void disconnectFromDiscord(); // Disconnect from the Discord service.
|
||||
void checkConnectionToDiscord(bool auto_connect = false); // Check if connected to the Discord service. If not, call connectToDiscord().
|
||||
|
||||
void storeInfo(const LLSD& info);
|
||||
const LLSD& getInfo() const;
|
||||
void clearInfo();
|
||||
|
||||
void setConnectionState(EConnectionState connection_state);
|
||||
void setConnected(bool connected);
|
||||
bool isConnected() { return mConnected; }
|
||||
EConnectionState getConnectionState() { return mConnectionState; }
|
||||
|
||||
void updateRichPresence();
|
||||
|
||||
bool Tick(const LLSD&);
|
||||
|
||||
private:
|
||||
|
||||
EConnectionState mConnectionState;
|
||||
BOOL mConnected;
|
||||
LLSD mInfo;
|
||||
bool mRefreshInfo;
|
||||
|
||||
static boost::scoped_ptr<LLEventPump> sStateWatcher;
|
||||
static boost::scoped_ptr<LLEventPump> sInfoWatcher;
|
||||
static boost::scoped_ptr<LLEventPump> sContentWatcher;
|
||||
|
||||
void discordConnectCoro();
|
||||
void discordDisconnectCoro();
|
||||
void discordConnectedCoro(bool autoConnect);
|
||||
|
||||
bool checkMarkerFile();
|
||||
void setMarkerFile();
|
||||
void clearMarkerFile();
|
||||
|
||||
std::string mMarkerFilename;
|
||||
};
|
||||
|
||||
#endif // FS_FSDISCORDCONNECT_H
|
||||
|
|
@ -0,0 +1,323 @@
|
|||
/**
|
||||
* @file fsfloaterdiscord.cpp
|
||||
* @brief Implementation of fsfloaterdiscord.cpp
|
||||
* @author liny@pinkfox.xyz
|
||||
*
|
||||
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
|
||||
* Phoenix Firestorm Viewer Source Code
|
||||
* Copyright (C) 2019 Liny Odell @ Second Life
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
|
||||
* http://www.firestormviewer.org
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "fsfloaterdiscord.h"
|
||||
|
||||
#include "llagent.h"
|
||||
#include "llagentui.h"
|
||||
#include "llcheckboxctrl.h"
|
||||
#include "llcombobox.h"
|
||||
#include "fsdiscordconnect.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "lltrans.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "lltabcontainer.h"
|
||||
|
||||
#include "boost/algorithm/string/case_conv.hpp"
|
||||
|
||||
////////////////////////
|
||||
//FSFloaterDiscord///////
|
||||
////////////////////////
|
||||
|
||||
void FSFloaterDiscord::onVisibilityChange(BOOL visible)
|
||||
{
|
||||
if(visible)
|
||||
{
|
||||
LLEventPumps::instance().obtain("DiscordConnectState").stopListening("FSDiscordAccountPanel");
|
||||
LLEventPumps::instance().obtain("DiscordConnectState").listen("FSDiscordAccountPanel", boost::bind(&FSFloaterDiscord::onDiscordConnectStateChange, this, _1));
|
||||
|
||||
LLEventPumps::instance().obtain("DiscordConnectInfo").stopListening("FSDiscordAccountPanel");
|
||||
LLEventPumps::instance().obtain("DiscordConnectInfo").listen("FSDiscordAccountPanel", boost::bind(&FSFloaterDiscord::onDiscordConnectInfoChange, this));
|
||||
|
||||
LLSD info = FSDiscordConnect::instance().getInfo();
|
||||
|
||||
if (info.has("name"))
|
||||
{
|
||||
mAccountNameLabel->setText(info["name"].asString());
|
||||
}
|
||||
|
||||
//Connected
|
||||
if(FSDiscordConnect::instance().isConnected())
|
||||
{
|
||||
showConnectedLayout();
|
||||
}
|
||||
//Check if connected (show disconnected layout in meantime)
|
||||
else
|
||||
{
|
||||
showDisconnectedLayout();
|
||||
}
|
||||
if ((FSDiscordConnect::instance().getConnectionState() == FSDiscordConnect::DISCORD_NOT_CONNECTED) ||
|
||||
(FSDiscordConnect::instance().getConnectionState() == FSDiscordConnect::DISCORD_CONNECTION_FAILED))
|
||||
{
|
||||
FSDiscordConnect::instance().checkConnectionToDiscord();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LLEventPumps::instance().obtain("DiscordConnectState").stopListening("FSDiscordAccountPanel");
|
||||
LLEventPumps::instance().obtain("DiscordConnectInfo").stopListening("FSDiscordAccountPanel");
|
||||
}
|
||||
}
|
||||
|
||||
void FSFloaterDiscord::onAllow()
|
||||
{
|
||||
gSavedPerAccountSettings.setBOOL("FSEnableDiscordIntegration", mAllowCheckbox->get());
|
||||
}
|
||||
|
||||
bool FSFloaterDiscord::onDiscordConnectStateChange(const LLSD& data)
|
||||
{
|
||||
if(FSDiscordConnect::instance().isConnected())
|
||||
{
|
||||
mAccountCaptionLabel->setText(getString("discord_connected"));
|
||||
showConnectedLayout();
|
||||
}
|
||||
else
|
||||
{
|
||||
mAccountCaptionLabel->setText(getString("discord_disconnected"));
|
||||
showDisconnectedLayout();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FSFloaterDiscord::onDiscordConnectInfoChange()
|
||||
{
|
||||
LLSD info = FSDiscordConnect::instance().getInfo();
|
||||
|
||||
if(info.has("name"))
|
||||
{
|
||||
mAccountNameLabel->setText(info["name"].asString());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void FSFloaterDiscord::showConnectButton()
|
||||
{
|
||||
if(!mConnectButton->getVisible())
|
||||
{
|
||||
mConnectButton->setVisible(TRUE);
|
||||
mDisconnectButton->setVisible(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
void FSFloaterDiscord::hideConnectButton()
|
||||
{
|
||||
if(mConnectButton->getVisible())
|
||||
{
|
||||
mConnectButton->setVisible(FALSE);
|
||||
mDisconnectButton->setVisible(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
void FSFloaterDiscord::showDisconnectedLayout()
|
||||
{
|
||||
mAccountCaptionLabel->setText(getString("discord_disconnected"));
|
||||
mAccountNameLabel->setText(std::string(""));
|
||||
showConnectButton();
|
||||
}
|
||||
|
||||
void FSFloaterDiscord::showConnectedLayout()
|
||||
{
|
||||
mAccountCaptionLabel->setText(getString("discord_connected"));
|
||||
hideConnectButton();
|
||||
}
|
||||
|
||||
void FSFloaterDiscord::onConnect()
|
||||
{
|
||||
FSDiscordConnect::instance().checkConnectionToDiscord(true);
|
||||
}
|
||||
|
||||
void FSFloaterDiscord::onDisconnect()
|
||||
{
|
||||
FSDiscordConnect::instance().disconnectFromDiscord();
|
||||
}
|
||||
|
||||
FSFloaterDiscord::FSFloaterDiscord(const LLSD& key) : LLFloater(key),
|
||||
mStatusText(NULL)
|
||||
{
|
||||
mCommitCallbackRegistrar.add("FSDiscord.Connect", boost::bind(&FSFloaterDiscord::onConnect, this));
|
||||
mCommitCallbackRegistrar.add("FSDiscord.Disconnect", boost::bind(&FSFloaterDiscord::onDisconnect, this));
|
||||
mCommitCallbackRegistrar.add("FSDiscord.Allow", boost::bind(&FSFloaterDiscord::onAllow, this));
|
||||
mCommitCallbackRegistrar.add("FSDiscord.Combo", boost::bind(&FSFloaterDiscord::onCombo, this));
|
||||
mCommitCallbackRegistrar.add("FSDiscord.Add", boost::bind(&FSFloaterDiscord::onAdd, this));
|
||||
mCommitCallbackRegistrar.add("FSDiscord.Rem", boost::bind(&FSFloaterDiscord::onRemove, this));
|
||||
|
||||
setVisibleCallback(boost::bind(&FSFloaterDiscord::onVisibilityChange, this, _2));
|
||||
}
|
||||
|
||||
void FSFloaterDiscord::onCombo()
|
||||
{
|
||||
gSavedPerAccountSettings.setU32("FSMaxSharedMaturity", mMaturityCombo->getSelectedValue().asInteger());
|
||||
}
|
||||
|
||||
void FSFloaterDiscord::onAdd()
|
||||
{
|
||||
std::string name = mBlacklistEntry->getText();
|
||||
LLStringUtil::trim(name);
|
||||
if (name == "")
|
||||
{
|
||||
return;
|
||||
}
|
||||
std::string name_lower = boost::algorithm::to_lower_copy(name);
|
||||
std::vector<LLScrollListItem*> items = mBlacklistedNames->getAllData();
|
||||
std::vector<LLScrollListItem*>::iterator itor;
|
||||
for (itor = items.begin(); itor != items.end(); ++itor)
|
||||
{
|
||||
std::string tmp = (*itor)->getValue().asString();
|
||||
boost::algorithm::to_lower(tmp);
|
||||
if (tmp == name_lower)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
mBlacklistedNames->addSimpleElement(name);
|
||||
LLSD save;
|
||||
for (itor = items.begin(); itor != items.end(); ++itor)
|
||||
{
|
||||
save.append((*itor)->getValue());
|
||||
}
|
||||
save.append(name);
|
||||
gSavedPerAccountSettings.setLLSD("FSBlacklistedRegionNames", save);
|
||||
}
|
||||
|
||||
void FSFloaterDiscord::onRemove()
|
||||
{
|
||||
std::vector<LLScrollListItem*> items = mBlacklistedNames->getAllData();
|
||||
std::vector<LLScrollListItem*>::iterator itor;
|
||||
LLSD save = LLSD::emptyArray();
|
||||
for (itor = items.begin(); itor != items.end(); ++itor)
|
||||
{
|
||||
if ((*itor)->getSelected())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
save.append((*itor)->getValue());
|
||||
}
|
||||
mBlacklistedNames->deleteAllItems();
|
||||
for (LLSD::array_const_iterator iter = save.beginArray();
|
||||
iter != save.endArray();
|
||||
iter++)
|
||||
{
|
||||
mBlacklistedNames->addSimpleElement(iter->asString());
|
||||
}
|
||||
gSavedPerAccountSettings.setLLSD("FSBlacklistedRegionNames", save);
|
||||
}
|
||||
|
||||
void FSFloaterDiscord::onClose(bool app_quitting)
|
||||
{
|
||||
if (app_quitting)
|
||||
{
|
||||
std::vector<LLScrollListItem*> items = mBlacklistedNames->getAllData();
|
||||
std::vector<LLScrollListItem*>::iterator itor;
|
||||
LLSD save = LLSD::emptyArray();
|
||||
for (itor = items.begin(); itor != items.end(); ++itor)
|
||||
{
|
||||
if ((*itor)->getSelected())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
save.append((*itor)->getValue());
|
||||
}
|
||||
gSavedPerAccountSettings.setLLSD("FSBlacklistedRegionNames", save);
|
||||
}
|
||||
LLFloater::onClose(app_quitting);
|
||||
}
|
||||
|
||||
BOOL FSFloaterDiscord::postBuild()
|
||||
{
|
||||
mAccountCaptionLabel = getChild<LLTextBox>("account_caption_label");
|
||||
mAccountNameLabel = getChild<LLTextBox>("account_name_label");
|
||||
mDisconnectButton = getChild<LLButton>("disconnect_btn");
|
||||
mConnectButton = getChild<LLButton>("connect_btn");
|
||||
mAllowCheckbox = getChild<LLCheckBoxCtrl>("startup_check");
|
||||
mMaturityCombo = getChild<LLComboBox>("maturity_desired_combobox");
|
||||
mBlacklistedNames = getChild<LLScrollListCtrl>("blacklisted_names");
|
||||
mBlacklistEntry = getChild<LLLineEditor>("blacklist_entry");
|
||||
mAddBlacklist = getChild<LLButton>("blacklist_entry_add");
|
||||
mRemBlacklist = getChild<LLButton>("blacklist_entry_rem");
|
||||
|
||||
LLSD list = gSavedPerAccountSettings.getLLSD("FSBlacklistedRegionNames");
|
||||
for (LLSD::array_const_iterator iter = list.beginArray();
|
||||
iter != list.endArray();
|
||||
iter++)
|
||||
{
|
||||
mBlacklistedNames->addSimpleElement(iter->asString());
|
||||
}
|
||||
|
||||
mMaturityCombo->selectByValue((LLSD::Integer)gSavedPerAccountSettings.getU32("FSMaxSharedMaturity"));
|
||||
|
||||
mAllowCheckbox->set(gSavedPerAccountSettings.getBOOL("FSEnableDiscordIntegration"));
|
||||
|
||||
// Connection status widgets
|
||||
mStatusText = getChild<LLTextBox>("connection_status_text");
|
||||
|
||||
return LLFloater::postBuild();
|
||||
}
|
||||
|
||||
void FSFloaterDiscord::draw()
|
||||
{
|
||||
if (mStatusText)
|
||||
{
|
||||
mStatusText->setVisible(false);
|
||||
FSDiscordConnect::EConnectionState connection_state = FSDiscordConnect::instance().getConnectionState();
|
||||
std::string status_text;
|
||||
|
||||
switch (connection_state)
|
||||
{
|
||||
case FSDiscordConnect::DISCORD_NOT_CONNECTED:
|
||||
// No status displayed when first opening the panel and no connection done
|
||||
break;
|
||||
case FSDiscordConnect::DISCORD_CONNECTION_IN_PROGRESS:
|
||||
// Connection loading indicator
|
||||
mStatusText->setVisible(true);
|
||||
status_text = LLTrans::getString("SocialDiscordConnecting");
|
||||
mStatusText->setValue(status_text);
|
||||
break;
|
||||
case FSDiscordConnect::DISCORD_CONNECTED:
|
||||
// When successfully connected, no message is displayed
|
||||
break;
|
||||
case FSDiscordConnect::DISCORD_CONNECTION_FAILED:
|
||||
// Error connecting to the service
|
||||
mStatusText->setVisible(true);
|
||||
status_text = LLTrans::getString("SocialDiscordErrorConnecting");
|
||||
mStatusText->setValue(status_text);
|
||||
break;
|
||||
case FSDiscordConnect::DISCORD_DISCONNECTING:
|
||||
// Disconnecting loading indicator
|
||||
mStatusText->setVisible(true);
|
||||
status_text = LLTrans::getString("SocialDiscordDisconnecting");
|
||||
mStatusText->setValue(status_text);
|
||||
break;
|
||||
}
|
||||
}
|
||||
LLFloater::draw();
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/**
|
||||
* @file llfloatertwitter.h
|
||||
* @brief Header file for fsfloaterdiscord
|
||||
* @author liny@pinkfox.xyz
|
||||
*
|
||||
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
|
||||
* Phoenix Firestorm Viewer Source Code
|
||||
* Copyright (C) 2019 Liny Odell @ Second Life
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
|
||||
* http://www.firestormviewer.org
|
||||
*/
|
||||
#ifndef FS_FSFLOATERDISCORD_H
|
||||
#define FS_FSFLOATERDISCORD_H
|
||||
|
||||
#include "llfloater.h"
|
||||
#include "lltextbox.h"
|
||||
|
||||
class LLCheckBoxCtrl;
|
||||
class LLComboBox;
|
||||
class LLScrollListCtrl;
|
||||
class LLLineEditor;
|
||||
|
||||
class FSFloaterDiscord : public LLFloater
|
||||
{
|
||||
public:
|
||||
FSFloaterDiscord(const LLSD& key);
|
||||
BOOL postBuild();
|
||||
void draw();
|
||||
void onClose(bool app_quitting);
|
||||
|
||||
private:
|
||||
void onVisibilityChange(BOOL visible);
|
||||
bool onDiscordConnectStateChange(const LLSD& data);
|
||||
bool onDiscordConnectInfoChange();
|
||||
void onConnect();
|
||||
void onUseAnotherAccount();
|
||||
void onDisconnect();
|
||||
void onAllow();
|
||||
void onCombo();
|
||||
void onAdd();
|
||||
void onRemove();
|
||||
|
||||
void showConnectButton();
|
||||
void hideConnectButton();
|
||||
void showDisconnectedLayout();
|
||||
void showConnectedLayout();
|
||||
|
||||
LLTextBox * mAccountCaptionLabel;
|
||||
LLTextBox * mAccountNameLabel;
|
||||
LLButton * mConnectButton;
|
||||
LLButton * mDisconnectButton;
|
||||
LLCheckBoxCtrl * mAllowCheckbox;
|
||||
LLComboBox * mMaturityCombo;
|
||||
LLScrollListCtrl * mBlacklistedNames;
|
||||
LLLineEditor * mBlacklistEntry;
|
||||
LLButton * mAddBlacklist;
|
||||
LLButton * mRemBlacklist;
|
||||
|
||||
LLTextBox* mStatusText;
|
||||
};
|
||||
|
||||
#endif // FS_FSFLOATERDISCORD_H
|
||||
|
||||
|
|
@ -180,6 +180,7 @@
|
|||
#include "fsfloateravatarrendersettings.h"
|
||||
#include "fsfloatercontacts.h"
|
||||
#include "fsfloatercontactsetconfiguration.h"
|
||||
#include "fsfloaterdiscord.h"
|
||||
#include "fsfloaterexport.h"
|
||||
#include "fsfloaterblocklist.h"
|
||||
#include "fsfloatergroup.h"
|
||||
|
|
@ -465,6 +466,7 @@ void LLViewerFloaterReg::registerFloaters()
|
|||
LLFloaterReg::add("fs_blocklist", "floater_fs_blocklist.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterBlocklist>);
|
||||
LLFloaterReg::add("fs_add_contact", "floater_fs_contact_add.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterAddToContactSet>);
|
||||
LLFloaterReg::add("fs_contact_set_config", "floater_fs_contact_set_configuration.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterContactSetConfiguration>);
|
||||
LLFloaterReg::add("fs_discord", "floater_fs_discord.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterDiscord>);
|
||||
LLFloaterReg::add("fs_group", "floater_fs_group.xml",&LLFloaterReg::build<FSFloaterGroup>);
|
||||
LLFloaterReg::add("fs_group_titles", "floater_fs_group_titles.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterGroupTitles>);
|
||||
LLFloaterReg::add("fs_export", "floater_fs_export.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterObjectExport>);
|
||||
|
|
|
|||
|
|
@ -130,6 +130,8 @@
|
|||
#include "llsidepanelappearance.h"
|
||||
#include "fsavatarrenderpersistence.h"
|
||||
|
||||
#include "fsdiscordconnect.h" // <FS:LO> tapping a place that happens on landing in world to start up discord
|
||||
|
||||
extern F32 SPEED_ADJUST_MAX;
|
||||
extern F32 SPEED_ADJUST_MAX_SEC;
|
||||
extern F32 ANIM_SPEED_MAX;
|
||||
|
|
@ -3078,6 +3080,8 @@ void LLVOAvatar::idleUpdateLoadingEffect()
|
|||
|
||||
// <FS:Zi> Animation Overrider
|
||||
AOEngine::instance().onLoginComplete();
|
||||
// <FS:LO> tapping a place that happens on landing in world to start up discord
|
||||
FSDiscordConnect::instance().checkConnectionToDiscord(gSavedPerAccountSettings.getBOOL("FSEnableDiscordIntegration"));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1031,6 +1031,8 @@ with the same filename but different name
|
|||
|
||||
<texture name="Icon_DialogStack" file_name="icons/Icon_DialogStack.png" preload="false" />
|
||||
|
||||
<texture name="Command_Discord_Icon" file_name="toolbar_icons/discord.png" preload="true" />
|
||||
|
||||
<!-- Higher Resolution 200px Loading Progress Indicator -->
|
||||
<texture name="ProgressLarge_1" file_name="icons/ProgressLarge_1.png" preload="true" />
|
||||
<texture name="ProgressLarge_2" file_name="icons/ProgressLarge_2.png" preload="true" />
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 501 B |
|
|
@ -0,0 +1,189 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<floater
|
||||
positioning="cascading"
|
||||
can_close="true"
|
||||
can_resize="false"
|
||||
help_topic="floater_discord"
|
||||
layout="topleft"
|
||||
name="floater_discord"
|
||||
save_rect="true"
|
||||
single_instance="true"
|
||||
reuse_instance="true"
|
||||
title="Discord"
|
||||
height="462"
|
||||
width="272">
|
||||
<string
|
||||
name="discord_connected"
|
||||
value="You are connected to Discord as:" />
|
||||
<string
|
||||
name="discord_disconnected"
|
||||
value="Not connected to Discord" />
|
||||
<string name="SocialDiscordConnecting">Connecting to Discord</string>
|
||||
<string name="SocialDiscordErrorConnecting">Error connecting to Discord</string>
|
||||
<string name="SocialDiscordDisconnecting">Disconnecting from Discord</string>
|
||||
<text
|
||||
layout="topleft"
|
||||
length="1"
|
||||
follows="top|left"
|
||||
font="SansSerif"
|
||||
height="16"
|
||||
left="10"
|
||||
name="account_caption_label"
|
||||
top="5"
|
||||
type="string">
|
||||
Not connected to Discord.
|
||||
</text>
|
||||
<text
|
||||
layout="topleft"
|
||||
top_pad="2"
|
||||
length="1"
|
||||
follows="top|left"
|
||||
font="SansSerif"
|
||||
height="16"
|
||||
left="10"
|
||||
name="account_name_label"
|
||||
parse_urls="true"
|
||||
type="string"/>
|
||||
<check_box
|
||||
layout="topleft"
|
||||
follows="left|top|right"
|
||||
top_pad="9"
|
||||
left="10"
|
||||
right="-10"
|
||||
visible="true"
|
||||
height="23"
|
||||
label="Automaticly connect to Discord on login?"
|
||||
name="startup_check"
|
||||
width="210">
|
||||
<commit_callback function="FSDiscord.Allow"/>
|
||||
</check_box>
|
||||
<button
|
||||
layout="topleft"
|
||||
follows="left|top|right"
|
||||
top_pad="9"
|
||||
left="10"
|
||||
right="-10"
|
||||
visible="true"
|
||||
height="23"
|
||||
label="Connect..."
|
||||
name="connect_btn"
|
||||
width="210">
|
||||
<commit_callback function="FSDiscord.Connect"/>
|
||||
</button>
|
||||
|
||||
<button
|
||||
layout="topleft"
|
||||
follows="left|top|right"
|
||||
top_delta="0"
|
||||
left="10"
|
||||
right="-10"
|
||||
height="23"
|
||||
label="Disconnect"
|
||||
name="disconnect_btn"
|
||||
width="210"
|
||||
visible="false">
|
||||
<commit_callback function="FSDiscord.Disconnect"/>
|
||||
</button>
|
||||
<text
|
||||
layout="topleft"
|
||||
length="1"
|
||||
follows="top|left"
|
||||
font="SansSerif"
|
||||
height="26"
|
||||
word_wrap="true"
|
||||
left="10"
|
||||
name="dont_show_higher_label"
|
||||
top_pad="5"
|
||||
type="string">
|
||||
Dont share region names to Discord if the maturity is higher than:
|
||||
</text>
|
||||
<combo_box
|
||||
follows="left|top"
|
||||
height="23"
|
||||
layout="topleft"
|
||||
name="maturity_desired_combobox"
|
||||
width="200">
|
||||
<combo_box.item
|
||||
label="General, Moderate, Adult"
|
||||
name="Desired_Adult"
|
||||
value="42" />
|
||||
<combo_box.item
|
||||
label="General and Moderate"
|
||||
name="Desired_Mature"
|
||||
value="21" />
|
||||
<combo_box.item
|
||||
label="General"
|
||||
name="Desired_PG"
|
||||
value="13" />
|
||||
<commit_callback function="FSDiscord.Combo"/>
|
||||
</combo_box>
|
||||
<text
|
||||
layout="topleft"
|
||||
length="1"
|
||||
follows="top|left"
|
||||
font="SansSerif"
|
||||
height="26"
|
||||
word_wrap="true"
|
||||
left="10"
|
||||
name="dont_names_label"
|
||||
top_pad="5"
|
||||
type="string">
|
||||
Dont share region names to Discord if they are listed below:
|
||||
</text>
|
||||
<scroll_list
|
||||
follows="top|left|right"
|
||||
height="215"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
multi_select="true"
|
||||
name="blacklisted_names"
|
||||
sort_column="0"
|
||||
sort_ascending="true"
|
||||
width="250" />
|
||||
<line_editor
|
||||
follows="left|top"
|
||||
bottom_delta="24"
|
||||
height="20"
|
||||
max_length_chars="256"
|
||||
name="blacklist_entry"
|
||||
width="202">
|
||||
<commit_callback function="FSDiscord.Add"/>
|
||||
</line_editor>
|
||||
<button
|
||||
follows="left|top"
|
||||
height="20"
|
||||
image_overlay="AddItem_Off"
|
||||
layout="topleft"
|
||||
left_pad="4"
|
||||
name="blacklist_entry_add"
|
||||
scale_image="true"
|
||||
width="20">
|
||||
<commit_callback function="FSDiscord.Add"/>
|
||||
</button>
|
||||
<button
|
||||
follows="left|top"
|
||||
height="20"
|
||||
image_overlay="MinusItem_Off"
|
||||
layout="topleft"
|
||||
left_pad="4"
|
||||
name="blacklist_entry_rem"
|
||||
scale_image="true"
|
||||
width="20">
|
||||
<commit_callback function="FSDiscord.Rem"/>
|
||||
</button>
|
||||
<text
|
||||
name="connection_status_text"
|
||||
type="string"
|
||||
follows="left|bottom|right"
|
||||
bottom_delta="20"
|
||||
left="-262"
|
||||
width="223"
|
||||
height="20"
|
||||
wrap="true"
|
||||
halign="left"
|
||||
valign="center"
|
||||
text_color="EmphasisColor"
|
||||
font="SansSerif">
|
||||
Loading...
|
||||
</text>
|
||||
</floater>
|
||||
|
|
@ -604,6 +604,13 @@
|
|||
<menu_item_call.on_click
|
||||
function="Floater.Toggle"
|
||||
parameter="flickr"/>
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Discord..."
|
||||
name="Discord">
|
||||
<menu_item_call.on_click
|
||||
function="Floater.Toggle"
|
||||
parameter="fs_discord"/>
|
||||
</menu_item_call>
|
||||
<menu_item_separator/>
|
||||
<menu
|
||||
|
|
|
|||
|
|
@ -234,6 +234,11 @@ Please try logging in again in a minute.</string>
|
|||
<string name="SocialTwitterErrorConnecting">Problem connecting to Twitter</string>
|
||||
<string name="SocialTwitterErrorPosting">Problem posting to Twitter</string>
|
||||
<string name="SocialTwitterErrorDisconnecting">Problem disconnecting from Twitter</string>
|
||||
|
||||
<!-- Firestorm social strings -->
|
||||
<string name="SocialDiscordConnecting">Connecting to Discord</string>
|
||||
<string name="SocialDiscordErrorConnecting">Error connecting to Discord</string>
|
||||
<string name="SocialDiscordDisconnecting">Disconnecting from Discord</string>
|
||||
|
||||
<!-- SLShare: User Friendly Filter Names Translation -->
|
||||
<string name="BlackAndWhite">Black & White</string>
|
||||
|
|
@ -2712,6 +2717,9 @@ Try enclosing path to the editor with double quotes.
|
|||
<string name="Command_Fly_Tooltip">Toggle flying mode on/off (HOME)</string>
|
||||
<string name="Command_Stop_Animations_Label">Stop Animations</string>
|
||||
<string name="Command_Stop_Animations_Tooltip">Stop Animating my Avatar</string>
|
||||
|
||||
<string name="Command_Discord_Label">Discord</string>
|
||||
<string name="Command_Discord_Tooltip">Discord</string>
|
||||
|
||||
<!-- Mesh UI terms -->
|
||||
<string name="Retain%">Retain%</string>
|
||||
|
|
|
|||
Loading…
Reference in New Issue