merged with upstream/master

This commit is contained in:
csoler 2016-06-16 20:19:03 -04:00
commit dbd78d2401
77 changed files with 2311 additions and 1333 deletions

View File

@ -2,6 +2,22 @@ RetroShare
============================== ==============================
RetroShare is a decentralized, private and secure commmunication and sharing platform. RetroShare provides filesharing, chat, messages, forums and channels. RetroShare is a decentralized, private and secure commmunication and sharing platform. RetroShare provides filesharing, chat, messages, forums and channels.
Build Status
------------
| Platform | Build Status |
| :------------- | :------------- |
| GNU/Linux, MacOS, (via travis-ci) | [![Build Status](https://travis-ci.org/RetroShare/RetroShare.svg?branch=master)](https://travis-ci.org/RetroShare/RetroShare) |
| Windows, `MSys2` (via appveyor) | [![Build status](https://ci.appveyor.com/api/projects/status/axkopdqj9fc48kwe?svg=true)](https://ci.appveyor.com/project/PhenomRetroShare/retroshare) |
Compilation on Windows
----------------------------
Follow this file : [WindowsMSys2_InstallGuide.txt](https://github.com/RetroShare/RetroShare/blob/master/WindowsMSys2_InstallGuide.txt)
Compilation on MacOSX
----------------------------
Follow this file : [MacOS_X_InstallGuide.txt](https://github.com/RetroShare/RetroShare/blob/master/MacOS_X_InstallGuide.txt)
Compilation on Linux Compilation on Linux
---------------------------- ----------------------------

210
appveyor.yml Normal file
View File

@ -0,0 +1,210 @@
# Notes:
# - Minimal appveyor.yml file is an empty file. All sections are optional.
# - Indent each level of configuration with 2 spaces. Do not use tabs!
# - All section names are case-sensitive.
# - Section names should be unique on each level.
# from example:
# https://github.com/Phonations/Joker/blob/master/appveyor.yml
# https://github.com/unicorn-engine/autobuild/blob/master/.appveyor.yml
#---------------------------------#
# general configuration #
#---------------------------------#
# version format
version: RetroShare 6.0.{build}-{branch}
# you can use {branch} name in version format too
# version: 1.0.{build}-{branch}
# branches to build
branches:
# whitelist
#only:
# - master
# blacklist
except:
- /^skipthisbranch$/
# Do not build on tags (GitHub only)
skip_tags: true
# Skipping commits with particular message or from user
skip_commits:
message: /Created.*\.(png|jpg|jpeg|bmp|gif)/ # Regex for matching commit message
#author: Anonymous # Commit author's username, name, email or regexp maching one of these.
#---------------------------------#
# environment configuration #
#---------------------------------#
# Operating system (build VM template)
#os: Windows Server 2012
# scripts that are called at very beginning, before repo cloning
init:
- git config --global core.autocrlf input
#To get RDP while compiling
- ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
on_finish:
#To get RDP running after compiling
#- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
# clone directory
clone_folder: c:\projects\RetroShare
# fetch repository as zip archive
#shallow_clone: true # default is "false"
# set clone depth
clone_depth: 1 # clone entire repository history if not defined
environment:
global:
#Qt: https://www.appveyor.com/docs/installed-software#qt
QTDIR: C:\Qt\5.4\mingw491_32
MSYS2_ARCH: i686
TARGET: i686_32-pc-msys
# build cache to preserve files/folders between builds
cache:
- c:\projects\libs
# - packages -> **\packages.config # preserve "packages" directory in the root of build folder but will reset it if packages.config is modified
# - projectA\libs
# - node_modules # local npm modules
# - %APPDATA%\npm-cache # npm cache
# scripts that run after cloning repository
#install:
# # by default, all script lines are interpreted as batch
# - echo This is batch
# # to run script as a PowerShell command prepend it with ps:
# - ps: Write-Host 'This is PowerShell'
# # batch commands start from cmd:
# - cmd: echo This is batch again
# - cmd: set MY_VAR=12345
install:
# Configuring MSys2
- set PATH=C:\msys64\usr\bin;%PATH%
- set PATH=C:\msys64\mingw32\bin;%PATH%
# Configuring Qt
- set PATH=%QTDIR%\bin;C:\Qt\Tools\mingw491_32\bin;%PATH%
# Install all default programms
#- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -Sy base-devel git mercurial cvs wget p7zip gcc perl ruby python2" #Already installed
- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -Sy openssl-devel"
# Install toolchain
#- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-toolchain mingw-w64-x86_64-toolchain" #Already installed
# Install other binutils
- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-miniupnpc mingw-w64-x86_64-miniupnpc"
- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-sqlite3 mingw-w64-x86_64-sqlite3"
- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-speex mingw-w64-x86_64-speex"
- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-opencv mingw-w64-x86_64-opencv"
- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-ffmpeg mingw-w64-x86_64-ffmpeg"
- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-libmicrohttpd mingw-w64-x86_64-libmicrohttpd"
- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-libxslt mingw-w64-x86_64-libxslt"
# Hack for new MSys2
- copy C:\msys64\mingw32\i686-w64-mingw32\bin\ar.exe C:\msys64\mingw32\bin\i686-w64-mingw32-ar.exe
- copy C:\msys64\mingw32\i686-w64-mingw32\bin\ranlib.exe C:\msys64\mingw32\bin\i686-w64-mingw32-ranlib.exe
- copy C:\msys64\mingw32\bin\windres.exe C:\msys64\mingw32\bin\i686-w64-mingw32-windres.exe
- copy C:\msys64\mingw64\x86_64-w64-mingw32\bin\ar.exe C:\msys64\mingw64\bin\x86_64-w64-mingw32-ar.exe
- copy C:\msys64\mingw64\x86_64-w64-mingw32\bin\ranlib.exe C:\msys64\mingw64\bin\x86_64-w64-mingw32-ranlib.exe
- copy C:\msys64\mingw64\bin\windres.exe C:\msys64\mingw64\bin\x86_64-w64-mingw32-windres.exe
# Build missing Libs
- C:\msys64\mingw32_shell.bat -lc "cd /c/projects/RetroShare/msys2_build_libs/ && make"
# Clone RetroShare
#- git clone -q --branch={branch} https://github.com/RetroShare/RetroShare.git C:\projects\RetroShare
#---------------------------------#
# build configuration #
#---------------------------------#
# build platform, i.e. x86, x64, Any CPU. This setting is optional.
platform: x86
# to add several platforms to build matrix:
#platform:
# - x86
# - Any CPU
# build Configuration, i.e. Debug, Release, etc.
configuration: Release
# to add several configurations to build matrix:
#configuration:
# - Debug
# - Release
# scripts to run before build
before_build:
# scripts to run *after* solution is built and *before* automatic packaging occurs (web apps, NuGet packages, Azure Cloud Services)
before_package:
# scripts to run after build
after_build:
# to run your custom scripts instead of automatic MSBuild
build_script:
- cd C:\projects\RetroShare
- qmake
- make
# to disable automatic builds
#build: off
#---------------------------------#
# artifacts configuration #
#---------------------------------#
#artifacts:
#
# # pushing a single file
# - path: test.zip
#
# # pushing a single file with environment variable in path and "Deployment name" specified
# - path: MyProject\bin\$(configuration)
# name: myapp
#
# # pushing entire folder as a zip archive
# - path: logs
#---------------------------------#
# deployment configuration #
#---------------------------------#
#No deployment under unknown computer!!!
#---------------------------------#
# global handlers #
#---------------------------------#
# on successful build
#on_success:
# - do something
# on build failure
#on_failure:
# - do something
# after build failure or success
#on_finish:
# - do something
#---------------------------------#
# notifications #
#---------------------------------#
notifications:
# Email
- provider: Email
to:
- retrosharephenom@gmail.com
subject: 'Build {{status}}' # optional
message: "{{message}}, {{commitId}}, ..." # optional
on_build_status_changed: true

View File

@ -7,8 +7,8 @@ Group: Productivity/Networking/Other
URL: http://retroshare.sourceforge.net/ URL: http://retroshare.sourceforge.net/
Source0: %{name}-%{version}.tar.gz Source0: %{name}-%{version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
Requires: qt-x11 Requires: qt5-qtbase-gui qt5-qtmultimedia qt5-qtx11extras qt5-qtbase
BuildRequires: gcc-c++ qt-devel desktop-file-utils libgnome-keyring-devel glib2-devel libssh-devel protobuf-devel libcurl-devel libxml2-devel libxslt-devel openssl-devel libXScrnSaver-devel libupnp-devel bzip2-devel libmicrohttpd-devel BuildRequires: gcc-c++ desktop-file-utils libgnome-keyring-devel glib2-devel libssh-devel protobuf-devel libcurl-devel libxml2-devel libxslt-devel openssl-devel libXScrnSaver-devel libupnp-devel bzip2-devel libmicrohttpd-devel qt5-qtx11extras-devel qt5-qttools-devel qt5-qtmultimedia-devel qt5-qttools-static
# This is because of sqlcipher: # This is because of sqlcipher:
BuildRequires: tcl BuildRequires: tcl
@ -56,7 +56,7 @@ cd lib/sqlcipher
make make
cd - cd -
cd src cd src
qmake-qt4 "CONFIG-=debug" "CONFIG+=release" PREFIX=%{_prefix} LIB_DIR=%{_libdir} RetroShare.pro qmake-qt5 "CONFIG-=debug" "CONFIG+=release" PREFIX=%{_prefix} LIB_DIR=%{_libdir} RetroShare.pro
make make
cd - cd -

View File

@ -888,7 +888,12 @@ void ChatHandler::handleClearLobby(Request &req, Response &resp)
{ {
ChatLobbyId id = 0; ChatLobbyId id = 0;
req.mStream << makeKeyValueReference("id", id); req.mStream << makeKeyValueReference("id", id);
notifyChatCleared(ChatId(id)); if (id !=0) {
notifyChatCleared(ChatId(id));
} else {
//Is BroadCast
notifyChatCleared(ChatId("B"));
}
resp.setOk(); resp.setOk();
} }

View File

@ -211,6 +211,26 @@ function lobby(lobbyid){
} }
) )
] ]
} else {
if (lobdt.subscribed != undefined
&& lobdt.subscribed
&& lobdt.is_broadcast
) {
//set participants
particips = [
m("div.btn", {
style: {
"text-align":"center"
},
onclick: function (){
rs.request("chat/clear_lobby",{
lobbyid,
});
m.route("/chat?lobby=" + lobbyid);
}
},"clear"),
]
}
} }
return [ return [
intro, intro,

View File

@ -1163,8 +1163,10 @@ bool RsGenExchange::subscribeToGroup(uint32_t& token, const RsGxsGroupId& grpId,
if(mNetService != NULL) if(mNetService != NULL)
mNetService->subscribeStatusChanged(grpId,subscribe) ; mNetService->subscribeStatusChanged(grpId,subscribe) ;
#ifdef GEN_EXCH_DEBUG
else else
std::cerr << "(EE) No mNetService in RsGenExchange for service 0x" << std::hex << mServType << std::dec << std::endl; std::cerr << "(EE) No mNetService in RsGenExchange for service 0x" << std::hex << mServType << std::dec << std::endl;
#endif
return true; return true;
} }

View File

@ -208,6 +208,7 @@
#include "retroshare/rsgxsflags.h" #include "retroshare/rsgxsflags.h"
#include "retroshare/rsgxscircles.h" #include "retroshare/rsgxscircles.h"
#include "pgp/pgpauxutils.h" #include "pgp/pgpauxutils.h"
#include "util/rsdir.h"
#include "util/rsmemory.h" #include "util/rsmemory.h"
#include "util/stacktrace.h" #include "util/stacktrace.h"
@ -604,6 +605,21 @@ public:
std::vector<T*>::clear() ; std::vector<T*>::clear() ;
} }
}; };
RsGxsGroupId RsGxsNetService::hashGrpId(const RsGxsGroupId& gid,const RsPeerId& pid)
{
static const uint32_t SIZE = RsGxsGroupId::SIZE_IN_BYTES + RsPeerId::SIZE_IN_BYTES ;
unsigned char tmpmem[SIZE];
uint32_t offset = 0 ;
pid.serialise(tmpmem,SIZE,offset) ;
gid.serialise(tmpmem,SIZE,offset) ;
assert(RsGxsGroupId::SIZE_IN_BYTES <= Sha1CheckSum::SIZE_IN_BYTES) ;
return RsGxsGroupId( RsDirUtil::sha1sum(tmpmem,SIZE).toByteArray() );
}
void RsGxsNetService::syncWithPeers() void RsGxsNetService::syncWithPeers()
{ {
#ifdef NXS_NET_DEBUG_0 #ifdef NXS_NET_DEBUG_0
@ -742,43 +758,24 @@ void RsGxsNetService::syncWithPeers()
RsNxsSyncMsgReqItem* msg = new RsNxsSyncMsgReqItem(mServType); RsNxsSyncMsgReqItem* msg = new RsNxsSyncMsgReqItem(mServType);
msg->clear(); msg->clear();
msg->PeerId(peerId); msg->PeerId(peerId);
msg->grpId = grpId;
msg->updateTS = updateTS; msg->updateTS = updateTS;
if(encrypt_to_this_circle_id.isNull()) if(encrypt_to_this_circle_id.isNull())
{ msg->grpId = grpId;
#ifdef NXS_NET_DEBUG_7
GXSNETDEBUG_PG(*sit,grpId) << " Service " << std::hex << ((mServiceInfo.mServiceType >> 8)& 0xffff) << std::dec << " sending message TS of peer id: " << *sit << " ts=" << nice_time_stamp(time(NULL),updateTS) << " (secs ago) for group " << grpId << " to himself - in clear " << std::endl;
#endif
sendItem(msg);
}
else else
{ {
msg->grpId = hashGrpId(grpId,mNetMgr->getOwnId()) ;
msg->flag |= RsNxsSyncMsgReqItem::FLAG_USE_HASHED_GROUP_ID ;
}
#ifdef NXS_NET_DEBUG_7 #ifdef NXS_NET_DEBUG_7
GXSNETDEBUG_PG(*sit,grpId) << " Service " << std::hex << ((mServiceInfo.mServiceType >> 8)& 0xffff) << std::dec << " sending message TS of peer id: " << *sit << " ts=" << nice_time_stamp(time(NULL),updateTS) << " (secs ago) for group " << grpId << " to himself - encrypted for circle " << encrypt_to_this_circle_id << std::endl; GXSNETDEBUG_PG(*sit,grpId) << " Service " << std::hex << ((mServiceInfo.mServiceType >> 8)& 0xffff) << std::dec << " sending message TS of peer id: " << *sit << " ts=" << nice_time_stamp(time(NULL),updateTS) << " (secs ago) for group " << grpId << " to himself - in clear " << std::endl;
#endif #endif
RsNxsItem *encrypted_item = NULL ; sendItem(msg);
uint32_t status ;
if(encryptSingleNxsItem(msg, encrypt_to_this_circle_id, grpId, encrypted_item, status))
sendItem(encrypted_item) ;
else
std::cerr << "(WW) could not encrypt for circle ID " << encrypt_to_this_circle_id << ". Not yet in cache?" << std::endl;
delete msg ;
}
#ifdef NXS_NET_DEBUG_5 #ifdef NXS_NET_DEBUG_5
GXSNETDEBUG_PG(*sit,grpId) << "Service "<< std::hex << ((mServiceInfo.mServiceType >> 8)& 0xffff) << std::dec << " sending global message TS of peer id: " << *sit << " ts=" << nice_time_stamp(time(NULL),updateTS) << " (secs ago) for group " << grpId << " to himself" << std::endl; GXSNETDEBUG_PG(*sit,grpId) << "Service "<< std::hex << ((mServiceInfo.mServiceType >> 8)& 0xffff) << std::dec << " sending global message TS of peer id: " << *sit << " ts=" << nice_time_stamp(time(NULL),updateTS) << " (secs ago) for group " << grpId << " to himself" << std::endl;
#endif #endif
//}
//else
//{
// delete msg ;
//#ifdef NXS_NET_DEBUG_0
// GXSNETDEBUG_PG(*sit,grpId) << " cancel RsNxsSyncMsg req (last local update TS for group+peer) for grpId=" << grpId << " to peer " << *sit << ": not enough bandwidth." << std::endl;
//#endif
//}
} }
} }
@ -3686,7 +3683,9 @@ bool RsGxsNetService::encryptSingleNxsItem(RsNxsItem *item, const RsGxsCircleId&
if(recipients.empty()) if(recipients.empty())
{ {
std::cerr << " (EE) No recipients found for circle " << destination_circle << ". Circle not in cache, or empty circle?" << std::endl; #ifdef NXS_NET_DEBUG_7
GXSNETDEBUG_P_(item->PeerId()) << " (EE) No recipients found for circle " << destination_circle << ". Circle not in cache, or empty circle?" << std::endl;
#endif
return false ; return false ;
} }
@ -4342,28 +4341,53 @@ bool RsGxsNetService::checkCanRecvMsgFromPeer(const RsPeerId& sslId, const RsGxs
return true; return true;
} }
bool RsGxsNetService::locked_CanReceiveUpdate(const RsNxsSyncMsgReqItem *item) bool RsGxsNetService::locked_CanReceiveUpdate(RsNxsSyncMsgReqItem *item,bool& grp_is_known)
{ {
// Do we have new updates for this peer? // Do we have new updates for this peer?
// Here we compare times in the same clock: the friend's clock, so it should be fine. // Here we compare times in the same clock: the friend's clock, so it should be fine.
ServerMsgMap::const_iterator cit = mServerMsgUpdateMap.find(item->grpId); grp_is_known = false ;
if(item->flag & RsNxsSyncMsgReqItem::FLAG_USE_HASHED_GROUP_ID)
{
// Item contains the hashed group ID in order to protect is from friends who don't know it. So we de-hash it using bruteforce over known group IDs for this peer.
// We could save the de-hash result. But the cost is quite light, since the number of encrypted groups per service is usually low.
for(ServerMsgMap::const_iterator it(mServerMsgUpdateMap.begin());it!=mServerMsgUpdateMap.end();++it)
if(item->grpId == hashGrpId(it->first,item->PeerId()))
{
item->grpId = it->first ;
item->flag &= ~RsNxsSyncMsgReqItem::FLAG_USE_HASHED_GROUP_ID;
#ifdef NXS_NET_DEBUG_0
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << "(II) de-hashed group ID " << it->first << " from hash " << item->grpId << " and peer id " << item->PeerId() << std::endl;
#endif
grp_is_known = true ;
return item->updateTS < it->second->msgUpdateTS ;
}
return false ;
}
ServerMsgMap::const_iterator cit = mServerMsgUpdateMap.find(item->grpId);
if(cit != mServerMsgUpdateMap.end()) if(cit != mServerMsgUpdateMap.end())
{ {
const RsGxsServerMsgUpdateItem *msui = cit->second; const RsGxsServerMsgUpdateItem *msui = cit->second;
#ifdef NXS_NET_DEBUG_0 #ifdef NXS_NET_DEBUG_0
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " local time stamp: " << std::dec<< time(NULL) - msui->msgUpdateTS << " secs ago. Update sent: " << (item->updateTS < msui->msgUpdateTS) << std::endl; GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " local time stamp: " << std::dec<< time(NULL) - msui->msgUpdateTS << " secs ago. Update sent: " << (item->updateTS < msui->msgUpdateTS) << std::endl;
#endif #endif
return item->updateTS < msui->msgUpdateTS ; grp_is_known = true ;
return item->updateTS < msui->msgUpdateTS ;
} }
#ifdef NXS_NET_DEBUG_0 #ifdef NXS_NET_DEBUG_0
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " no local time stamp for this grp. "<< std::endl; GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " no local time stamp for this grp. "<< std::endl;
#endif #endif
return false; return false;
} }
void RsGxsNetService::handleRecvSyncMessage(RsNxsSyncMsgReqItem *item,bool item_was_encrypted) void RsGxsNetService::handleRecvSyncMessage(RsNxsSyncMsgReqItem *item,bool item_was_encrypted)
{ {
if (!item) if (!item)
@ -4372,19 +4396,28 @@ void RsGxsNetService::handleRecvSyncMessage(RsNxsSyncMsgReqItem *item,bool item_
RS_STACK_MUTEX(mNxsMutex) ; RS_STACK_MUTEX(mNxsMutex) ;
const RsPeerId& peer = item->PeerId(); const RsPeerId& peer = item->PeerId();
bool grp_is_known = false;
bool was_circle_protected = item_was_encrypted || bool(item->flag & RsNxsSyncMsgReqItem::FLAG_USE_HASHED_GROUP_ID);
bool peer_can_receive_update = locked_CanReceiveUpdate(item, grp_is_known);
if(item_was_encrypted)
std::cerr << "(WW) got an encrypted msg sync req. from " << item->PeerId() << ". This will not send messages updates for group " << item->grpId << std::endl;
// Insert the PeerId in suppliers list for this grpId // Insert the PeerId in suppliers list for this grpId
#ifdef NXS_NET_DEBUG_6 #ifdef NXS_NET_DEBUG_6
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << "RsGxsNetService::handleRecvSyncMessage(): Inserting PeerId " << item->PeerId() << " in suppliers list for group " << item->grpId << std::endl; GXSNETDEBUG_PG(item->PeerId(),item->grpId) << "RsGxsNetService::handleRecvSyncMessage(): Inserting PeerId " << item->PeerId() << " in suppliers list for group " << item->grpId << std::endl;
#endif #endif
RsGroupNetworkStatsRecord& rec(mGroupNetworkStats[item->grpId]) ; // this creates it if needed
rec.suppliers.insert(peer) ;
#ifdef NXS_NET_DEBUG_0 #ifdef NXS_NET_DEBUG_0
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << "handleRecvSyncMsg(): Received last update TS of group " << item->grpId << ", for peer " << peer << ", TS = " << time(NULL) - item->updateTS << " secs ago." ; GXSNETDEBUG_PG(item->PeerId(),item->grpId) << "handleRecvSyncMsg(): Received last update TS of group " << item->grpId << ", for peer " << peer << ", TS = " << time(NULL) - item->updateTS << " secs ago." ;
#endif #endif
if(!locked_CanReceiveUpdate(item)) if(grp_is_known)
{
RsGroupNetworkStatsRecord& rec(mGroupNetworkStats[item->grpId]) ; // this creates it if needed. When the grp is unknown (and hashed) this will would create a unused entry
rec.suppliers.insert(peer) ;
}
if(!peer_can_receive_update)
{ {
#ifdef NXS_NET_DEBUG_0 #ifdef NXS_NET_DEBUG_0
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " no update will be sent." << std::endl; GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " no update will be sent." << std::endl;
@ -4413,10 +4446,10 @@ void RsGxsNetService::handleRecvSyncMessage(RsNxsSyncMsgReqItem *item,bool item_
return ; return ;
} }
if( (grpMeta->mCircleType == GXS_CIRCLE_TYPE_EXTERNAL) != item_was_encrypted ) if( (grpMeta->mCircleType == GXS_CIRCLE_TYPE_EXTERNAL) != was_circle_protected )
{ {
std::cerr << "(EE) received a sync Msg request for group " << item->grpId << " from peer " << item->PeerId() ; std::cerr << "(EE) received a sync Msg request for group " << item->grpId << " from peer " << item->PeerId() ;
if(!item_was_encrypted) if(!was_circle_protected)
std::cerr << ". The group is tied to an external circle (ID=" << grpMeta->mCircleId << ") but the request wasn't encrypted." << std::endl; std::cerr << ". The group is tied to an external circle (ID=" << grpMeta->mCircleId << ") but the request wasn't encrypted." << std::endl;
else else
std::cerr << ". The group is not tied to an external circle (ID=" << grpMeta->mCircleId << ") but the request was encrypted." << std::endl; std::cerr << ". The group is not tied to an external circle (ID=" << grpMeta->mCircleId << ") but the request was encrypted." << std::endl;

View File

@ -384,7 +384,9 @@ private:
#endif #endif
bool locked_CanReceiveUpdate(const RsNxsSyncGrpReqItem *item); bool locked_CanReceiveUpdate(const RsNxsSyncGrpReqItem *item);
bool locked_CanReceiveUpdate(const RsNxsSyncMsgReqItem* item); bool locked_CanReceiveUpdate(RsNxsSyncMsgReqItem *item, bool &grp_is_known);
static RsGxsGroupId hashGrpId(const RsGxsGroupId& gid,const RsPeerId& pid) ;
private: private:

View File

@ -110,10 +110,6 @@ peerConnectState::peerConnectState()
inConnAttempt(0), inConnAttempt(0),
wasDeniedConnection(false), deniedTS(false), deniedInConnAttempt(false) wasDeniedConnection(false), deniedTS(false), deniedInConnAttempt(false)
{ {
//sockaddr_clear(&currentlocaladdr);
//sockaddr_clear(&currentserveraddr);
return;
} }
std::string textPeerConnectState(peerConnectState &state) std::string textPeerConnectState(peerConnectState &state)

View File

@ -129,7 +129,6 @@ class peerConnectState
time_t deniedTS; time_t deniedTS;
bool deniedInConnAttempt; /* is below valid */ bool deniedInConnAttempt; /* is below valid */
peerConnectAddress deniedConnectionAttempt; peerConnectAddress deniedConnectionAttempt;
}; };
class p3tunnel; class p3tunnel;
@ -312,7 +311,7 @@ bool addAddressIfUnique(std::list<peerConnectAddress> &addrList, peerConnectAdd
private: private:
// These should have there own Mutex Protection, // These should have their own Mutex Protection,
//p3tunnel *mP3tunnel; //p3tunnel *mP3tunnel;
DNSResolver *mDNSResolver ; DNSResolver *mDNSResolver ;

View File

@ -2009,6 +2009,10 @@ bool p3PeerMgrIMPL::saveList(bool &cleanup, std::list<RsItem *>& saveData)
#endif #endif
} }
RsPeerBandwidthLimitsItem *pblitem = new RsPeerBandwidthLimitsItem ;
pblitem->peers = mPeerBandwidthLimits ;
saveData.push_back(pblitem) ;
RsPeerServicePermissionItem *sitem = new RsPeerServicePermissionItem ; RsPeerServicePermissionItem *sitem = new RsPeerServicePermissionItem ;
for(std::map<RsPgpId,ServicePermissionFlags>::const_iterator it(mFriendsPermissionFlags.begin());it!=mFriendsPermissionFlags.end();++it) for(std::map<RsPgpId,ServicePermissionFlags>::const_iterator it(mFriendsPermissionFlags.begin());it!=mFriendsPermissionFlags.end();++it)
@ -2072,6 +2076,61 @@ bool p3PeerMgrIMPL::saveList(bool &cleanup, std::list<RsItem *>& saveData)
return true; return true;
} }
bool p3PeerMgrIMPL::getMaxRates(const RsPeerId& pid,uint32_t& maxUp,uint32_t& maxDn)
{
RsPgpId pgp_id ;
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
std::map<RsPeerId, peerState>::const_iterator it = mFriendList.find(pid) ;
if(it == mFriendList.end())
return false ;
pgp_id = it->second.gpg_id ;
}
return getMaxRates(pgp_id,maxUp,maxDn) ;
}
bool p3PeerMgrIMPL::getMaxRates(const RsPgpId& pid,uint32_t& maxUp,uint32_t& maxDn)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
std::map<RsPgpId,PeerBandwidthLimits>::const_iterator it2 = mPeerBandwidthLimits.find(pid) ;
if(it2 != mPeerBandwidthLimits.end())
{
maxUp = it2->second.max_up_rate_kbs ;
maxDn = it2->second.max_dl_rate_kbs ;
return true ;
}
else
{
maxUp = 0;
maxDn = 0;
return false ;
}
}
bool p3PeerMgrIMPL::setMaxRates(const RsPgpId& pid,uint32_t maxUp,uint32_t maxDn)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
PeerBandwidthLimits& p(mPeerBandwidthLimits[pid]) ;
if(maxUp == p.max_up_rate_kbs && maxDn == p.max_dl_rate_kbs)
return true ;
std::cerr << "Updating max rates for peer " << pid << " to " << maxUp << " kB/s (up), " << maxDn << " kB/s (dn)" << std::endl;
p.max_up_rate_kbs = maxUp ;
p.max_dl_rate_kbs = maxDn ;
IndicateConfigChanged();
return true ;
}
void p3PeerMgrIMPL::saveDone() void p3PeerMgrIMPL::saveDone()
{ {
/* clean up the save List */ /* clean up the save List */
@ -2090,276 +2149,288 @@ void p3PeerMgrIMPL::saveDone()
bool p3PeerMgrIMPL::loadList(std::list<RsItem *>& load) bool p3PeerMgrIMPL::loadList(std::list<RsItem *>& load)
{ {
// DEFAULTS. // DEFAULTS.
bool useExtAddrFinder = true; bool useExtAddrFinder = true;
std::string proxyIpAddressTor = kConfigDefaultProxyServerIpAddr; std::string proxyIpAddressTor = kConfigDefaultProxyServerIpAddr;
uint16_t proxyPortTor = kConfigDefaultProxyServerPortTor; uint16_t proxyPortTor = kConfigDefaultProxyServerPortTor;
std::string proxyIpAddressI2P = kConfigDefaultProxyServerIpAddr; std::string proxyIpAddressI2P = kConfigDefaultProxyServerIpAddr;
uint16_t proxyPortI2P = kConfigDefaultProxyServerPortI2P; uint16_t proxyPortI2P = kConfigDefaultProxyServerPortI2P;
if (load.empty()) { if (load.empty()) {
std::cerr << "p3PeerMgrIMPL::loadList() list is empty, it may be a configuration problem." << std::endl; std::cerr << "p3PeerMgrIMPL::loadList() list is empty, it may be a configuration problem." << std::endl;
return false; return false;
} }
#ifdef PEER_DEBUG #ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::loadList() Item Count: " << load.size() << std::endl; std::cerr << "p3PeerMgrIMPL::loadList() Item Count: " << load.size() << std::endl;
#endif #endif
RsPeerId ownId = getOwnId(); RsPeerId ownId = getOwnId();
/* load the list of peers */ /* load the list of peers */
std::list<RsItem *>::iterator it; std::list<RsItem *>::iterator it;
for(it = load.begin(); it != load.end(); ++it) for(it = load.begin(); it != load.end(); ++it)
{ {
RsPeerNetItem *pitem = dynamic_cast<RsPeerNetItem *>(*it); RsPeerNetItem *pitem = dynamic_cast<RsPeerNetItem *>(*it);
if (pitem) if (pitem)
{ {
RsPeerId peer_id = pitem->peerId ; RsPeerId peer_id = pitem->peerId ;
RsPgpId peer_pgp_id = pitem->pgpId ; RsPgpId peer_pgp_id = pitem->pgpId ;
if (peer_id == ownId) if (peer_id == ownId)
{ {
#ifdef PEER_DEBUG #ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::loadList() Own Config Item:" << std::endl; std::cerr << "p3PeerMgrIMPL::loadList() Own Config Item:" << std::endl;
pitem->print(std::cerr, 10); pitem->print(std::cerr, 10);
std::cerr << std::endl; std::cerr << std::endl;
#endif #endif
/* add ownConfig */ /* add ownConfig */
setOwnNetworkMode(pitem->netMode); setOwnNetworkMode(pitem->netMode);
setOwnVisState(pitem->vs_disc, pitem->vs_dht); setOwnVisState(pitem->vs_disc, pitem->vs_dht);
mOwnState.gpg_id = AuthGPG::getAuthGPG()->getGPGOwnId(); mOwnState.gpg_id = AuthGPG::getAuthGPG()->getGPGOwnId();
mOwnState.location = AuthSSL::getAuthSSL()->getOwnLocation(); mOwnState.location = AuthSSL::getAuthSSL()->getOwnLocation();
} }
else else
{ {
#ifdef PEER_DEBUG #ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::loadList() Peer Config Item:" << std::endl; std::cerr << "p3PeerMgrIMPL::loadList() Peer Config Item:" << std::endl;
pitem->print(std::cerr, 10); pitem->print(std::cerr, 10);
std::cerr << std::endl; std::cerr << std::endl;
#endif #endif
/* ************* */ /* ************* */
// permission flags is used as a mask for the existing perms, so we set it to 0xffff // permission flags is used as a mask for the existing perms, so we set it to 0xffff
addFriend(peer_id, peer_pgp_id, pitem->netMode, pitem->vs_disc, pitem->vs_dht, pitem->lastContact, RS_NODE_PERM_ALL); addFriend(peer_id, peer_pgp_id, pitem->netMode, pitem->vs_disc, pitem->vs_dht, pitem->lastContact, RS_NODE_PERM_ALL);
setLocation(pitem->peerId, pitem->location); setLocation(pitem->peerId, pitem->location);
} }
if (pitem->netMode == RS_NET_MODE_HIDDEN) if (pitem->netMode == RS_NET_MODE_HIDDEN)
{ {
/* set only the hidden stuff & localAddress */ /* set only the hidden stuff & localAddress */
setLocalAddress(peer_id, pitem->localAddrV4.addr); setLocalAddress(peer_id, pitem->localAddrV4.addr);
setHiddenDomainPort(peer_id, pitem->domain_addr, pitem->domain_port); setHiddenDomainPort(peer_id, pitem->domain_addr, pitem->domain_port);
} }
else else
{ {
setLocalAddress(peer_id, pitem->localAddrV4.addr); setLocalAddress(peer_id, pitem->localAddrV4.addr);
setExtAddress(peer_id, pitem->extAddrV4.addr); setExtAddress(peer_id, pitem->extAddrV4.addr);
setDynDNS (peer_id, pitem->dyndns); setDynDNS (peer_id, pitem->dyndns);
/* convert addresses */ /* convert addresses */
pqiIpAddrSet addrs; pqiIpAddrSet addrs;
addrs.mLocal.extractFromTlv(pitem->localAddrList); addrs.mLocal.extractFromTlv(pitem->localAddrList);
addrs.mExt.extractFromTlv(pitem->extAddrList); addrs.mExt.extractFromTlv(pitem->extAddrList);
updateAddressList(peer_id, addrs); updateAddressList(peer_id, addrs);
} }
delete(*it); delete(*it);
continue; continue;
} }
RsConfigKeyValueSet *vitem = dynamic_cast<RsConfigKeyValueSet *>(*it) ; RsConfigKeyValueSet *vitem = dynamic_cast<RsConfigKeyValueSet *>(*it) ;
if (vitem) if (vitem)
{ {
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
#ifdef PEER_DEBUG #ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::loadList() General Variable Config Item:" << std::endl; std::cerr << "p3PeerMgrIMPL::loadList() General Variable Config Item:" << std::endl;
vitem->print(std::cerr, 10); vitem->print(std::cerr, 10);
std::cerr << std::endl; std::cerr << std::endl;
#endif #endif
std::list<RsTlvKeyValue>::iterator kit; std::list<RsTlvKeyValue>::iterator kit;
for(kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); ++kit) for(kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); ++kit)
{ {
if (kit->key == kConfigKeyExtIpFinder) if (kit->key == kConfigKeyExtIpFinder)
{ {
useExtAddrFinder = (kit->value == "TRUE"); useExtAddrFinder = (kit->value == "TRUE");
#ifdef PEER_DEBUG #ifdef PEER_DEBUG
std::cerr << "setting use_extr_addr_finder to " << useExtAddrFinder << std::endl ; std::cerr << "setting use_extr_addr_finder to " << useExtAddrFinder << std::endl ;
#endif #endif
} }
// Tor // Tor
else if (kit->key == kConfigKeyProxyServerIpAddrTor) else if (kit->key == kConfigKeyProxyServerIpAddrTor)
{ {
proxyIpAddressTor = kit->value; proxyIpAddressTor = kit->value;
#ifdef PEER_DEBUG #ifdef PEER_DEBUG
std::cerr << "Loaded proxyIpAddress for Tor: " << proxyIpAddressTor; std::cerr << "Loaded proxyIpAddress for Tor: " << proxyIpAddressTor;
std::cerr << std::endl ; std::cerr << std::endl ;
#endif #endif
} }
else if (kit->key == kConfigKeyProxyServerPortTor) else if (kit->key == kConfigKeyProxyServerPortTor)
{ {
proxyPortTor = atoi(kit->value.c_str()); proxyPortTor = atoi(kit->value.c_str());
#ifdef PEER_DEBUG #ifdef PEER_DEBUG
std::cerr << "Loaded proxyPort for Tor: " << proxyPortTor; std::cerr << "Loaded proxyPort for Tor: " << proxyPortTor;
std::cerr << std::endl ; std::cerr << std::endl ;
#endif #endif
} }
// I2p // I2p
else if (kit->key == kConfigKeyProxyServerIpAddrI2P) else if (kit->key == kConfigKeyProxyServerIpAddrI2P)
{ {
proxyIpAddressI2P = kit->value; proxyIpAddressI2P = kit->value;
#ifdef PEER_DEBUG #ifdef PEER_DEBUG
std::cerr << "Loaded proxyIpAddress for I2P: " << proxyIpAddressI2P; std::cerr << "Loaded proxyIpAddress for I2P: " << proxyIpAddressI2P;
std::cerr << std::endl ; std::cerr << std::endl ;
#endif #endif
} }
else if (kit->key == kConfigKeyProxyServerPortI2P) else if (kit->key == kConfigKeyProxyServerPortI2P)
{ {
proxyPortI2P = atoi(kit->value.c_str()); proxyPortI2P = atoi(kit->value.c_str());
#ifdef PEER_DEBUG #ifdef PEER_DEBUG
std::cerr << "Loaded proxyPort for I2P: " << proxyPortI2P; std::cerr << "Loaded proxyPort for I2P: " << proxyPortI2P;
std::cerr << std::endl ; std::cerr << std::endl ;
#endif #endif
} }
} }
delete(*it); delete(*it);
continue; continue;
} }
RsPeerGroupItem *gitem = dynamic_cast<RsPeerGroupItem *>(*it) ; RsPeerGroupItem *gitem = dynamic_cast<RsPeerGroupItem *>(*it) ;
if (gitem) if (gitem)
{ {
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
#ifdef PEER_DEBUG #ifdef PEER_DEBUG
std::cerr << "p3PeerMgrIMPL::loadList() Peer group item:" << std::endl; std::cerr << "p3PeerMgrIMPL::loadList() Peer group item:" << std::endl;
gitem->print(std::cerr, 10); gitem->print(std::cerr, 10);
std::cerr << std::endl; std::cerr << std::endl;
#endif #endif
groupList.push_back(gitem); // don't delete groupList.push_back(gitem); // don't delete
if ((gitem->flag & RS_GROUP_FLAG_STANDARD) == 0) { if ((gitem->flag & RS_GROUP_FLAG_STANDARD) == 0) {
/* calculate group id */ /* calculate group id */
uint32_t groupId = atoi(gitem->id.c_str()); uint32_t groupId = atoi(gitem->id.c_str());
if (groupId > lastGroupId) { if (groupId > lastGroupId) {
lastGroupId = groupId; lastGroupId = groupId;
} }
} }
continue; continue;
} }
RsPeerServicePermissionItem *sitem = dynamic_cast<RsPeerServicePermissionItem*>(*it) ;
if(sitem) RsPeerBandwidthLimitsItem *pblitem = dynamic_cast<RsPeerBandwidthLimitsItem*>(*it) ;
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ if(pblitem)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
#ifdef PEER_DEBUG #ifdef PEER_DEBUG
std::cerr << "Loaded service permission item: " << std::endl; std::cerr << "Loaded service permission item: " << std::endl;
#endif #endif
mPeerBandwidthLimits = pblitem->peers ;
}
RsPeerServicePermissionItem *sitem = dynamic_cast<RsPeerServicePermissionItem*>(*it) ;
if(sitem)
{
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
for(uint32_t i=0;i<sitem->pgp_ids.size();++i)
if(AuthGPG::getAuthGPG()->isGPGAccepted(sitem->pgp_ids[i]) || sitem->pgp_ids[i] == AuthGPG::getAuthGPG()->getGPGOwnId())
{
mFriendsPermissionFlags[sitem->pgp_ids[i]] = sitem->service_flags[i] ;
#ifdef PEER_DEBUG #ifdef PEER_DEBUG
std::cerr << " " << sitem->pgp_ids[i] << " - " << sitem->service_flags[i] << std::endl; std::cerr << "Loaded service permission item: " << std::endl;
#endif #endif
}
for(uint32_t i=0;i<sitem->pgp_ids.size();++i)
if(AuthGPG::getAuthGPG()->isGPGAccepted(sitem->pgp_ids[i]) || sitem->pgp_ids[i] == AuthGPG::getAuthGPG()->getGPGOwnId())
{
mFriendsPermissionFlags[sitem->pgp_ids[i]] = sitem->service_flags[i] ;
#ifdef PEER_DEBUG #ifdef PEER_DEBUG
else std::cerr << " " << sitem->pgp_ids[i] << " - " << sitem->service_flags[i] << std::endl;
std::cerr << " " << sitem->pgp_ids[i] << " - Not a friend!" << std::endl;
#endif #endif
} }
#ifdef PEER_DEBUG
else
std::cerr << " " << sitem->pgp_ids[i] << " - Not a friend!" << std::endl;
#endif
}
delete (*it); delete (*it);
} }
{ {
/* set missing groupIds */ /* set missing groupIds */
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/ RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
/* Standard groups */ /* Standard groups */
const int standardGroupCount = 5; const int standardGroupCount = 5;
const char *standardGroup[standardGroupCount] = { RS_GROUP_ID_FRIENDS, RS_GROUP_ID_FAMILY, RS_GROUP_ID_COWORKERS, RS_GROUP_ID_OTHERS, RS_GROUP_ID_FAVORITES }; const char *standardGroup[standardGroupCount] = { RS_GROUP_ID_FRIENDS, RS_GROUP_ID_FAMILY, RS_GROUP_ID_COWORKERS, RS_GROUP_ID_OTHERS, RS_GROUP_ID_FAVORITES };
bool foundStandardGroup[standardGroupCount] = { false, false, false, false, false }; bool foundStandardGroup[standardGroupCount] = { false, false, false, false, false };
std::list<RsPeerGroupItem *>::iterator groupIt; std::list<RsPeerGroupItem *>::iterator groupIt;
for (groupIt = groupList.begin(); groupIt != groupList.end(); ++groupIt) { for (groupIt = groupList.begin(); groupIt != groupList.end(); ++groupIt) {
if ((*groupIt)->flag & RS_GROUP_FLAG_STANDARD) { if ((*groupIt)->flag & RS_GROUP_FLAG_STANDARD) {
int i; int i;
for (i = 0; i < standardGroupCount; ++i) { for (i = 0; i < standardGroupCount; ++i) {
if ((*groupIt)->id == standardGroup[i]) { if ((*groupIt)->id == standardGroup[i]) {
foundStandardGroup[i] = true; foundStandardGroup[i] = true;
break; break;
} }
} }
if (i >= standardGroupCount) { if (i >= standardGroupCount) {
/* No more a standard group, remove the flag standard */ /* No more a standard group, remove the flag standard */
(*groupIt)->flag &= ~RS_GROUP_FLAG_STANDARD; (*groupIt)->flag &= ~RS_GROUP_FLAG_STANDARD;
} }
} else { } else {
uint32_t groupId = atoi((*groupIt)->id.c_str()); uint32_t groupId = atoi((*groupIt)->id.c_str());
if (groupId == 0) { if (groupId == 0) {
rs_sprintf((*groupIt)->id, "%lu", lastGroupId++); rs_sprintf((*groupIt)->id, "%lu", lastGroupId++);
} }
} }
} }
/* Initialize standard groups */ /* Initialize standard groups */
for (int i = 0; i < standardGroupCount; ++i) { for (int i = 0; i < standardGroupCount; ++i) {
if (foundStandardGroup[i] == false) { if (foundStandardGroup[i] == false) {
RsPeerGroupItem *gitem = new RsPeerGroupItem; RsPeerGroupItem *gitem = new RsPeerGroupItem;
gitem->id = standardGroup[i]; gitem->id = standardGroup[i];
gitem->name = standardGroup[i]; gitem->name = standardGroup[i];
gitem->flag |= RS_GROUP_FLAG_STANDARD; gitem->flag |= RS_GROUP_FLAG_STANDARD;
groupList.push_back(gitem); groupList.push_back(gitem);
} }
} }
} }
// If we are hidden - don't want ExtAddrFinder - ever! // If we are hidden - don't want ExtAddrFinder - ever!
if (isHidden()) if (isHidden())
{ {
useExtAddrFinder = false; useExtAddrFinder = false;
} }
mNetMgr->setIPServersEnabled(useExtAddrFinder); mNetMgr->setIPServersEnabled(useExtAddrFinder);
// Configure Proxy Server. // Configure Proxy Server.
struct sockaddr_storage proxy_addr; struct sockaddr_storage proxy_addr;
// Tor // Tor
sockaddr_storage_clear(proxy_addr); sockaddr_storage_clear(proxy_addr);
sockaddr_storage_ipv4_aton(proxy_addr, proxyIpAddressTor.c_str()); sockaddr_storage_ipv4_aton(proxy_addr, proxyIpAddressTor.c_str());
sockaddr_storage_ipv4_setport(proxy_addr, proxyPortTor); sockaddr_storage_ipv4_setport(proxy_addr, proxyPortTor);
if (sockaddr_storage_isValidNet(proxy_addr)) if (sockaddr_storage_isValidNet(proxy_addr))
{ {
setProxyServerAddress(RS_HIDDEN_TYPE_TOR, proxy_addr); setProxyServerAddress(RS_HIDDEN_TYPE_TOR, proxy_addr);
} }
// I2P // I2P
sockaddr_storage_clear(proxy_addr); sockaddr_storage_clear(proxy_addr);
sockaddr_storage_ipv4_aton(proxy_addr, proxyIpAddressI2P.c_str()); sockaddr_storage_ipv4_aton(proxy_addr, proxyIpAddressI2P.c_str());
sockaddr_storage_ipv4_setport(proxy_addr, proxyPortI2P); sockaddr_storage_ipv4_setport(proxy_addr, proxyPortI2P);
if (sockaddr_storage_isValidNet(proxy_addr)) if (sockaddr_storage_isValidNet(proxy_addr))
{ {
setProxyServerAddress(RS_HIDDEN_TYPE_I2P, proxy_addr); setProxyServerAddress(RS_HIDDEN_TYPE_I2P, proxy_addr);
} }
load.clear() ; load.clear() ;
return true; return true;
} }

View File

@ -102,6 +102,8 @@ class peerState
std::string location; std::string location;
std::string name; std::string name;
uint32_t maxUpRate ;
uint32_t maxDnRate ;
}; };
class RsPeerGroupItem; class RsPeerGroupItem;
@ -207,6 +209,9 @@ virtual uint32_t getHiddenType(const RsPeerId &ssl_id) = 0;
virtual int getFriendCount(bool ssl, bool online) = 0; virtual int getFriendCount(bool ssl, bool online) = 0;
virtual bool setMaxRates(const RsPgpId& pid,uint32_t maxUp,uint32_t maxDn)=0;
virtual bool getMaxRates(const RsPgpId& pid,uint32_t& maxUp,uint32_t& maxDn)=0;
virtual bool getMaxRates(const RsPeerId& pid,uint32_t& maxUp,uint32_t& maxDn)=0;
/************* DEPRECIATED FUNCTIONS (TO REMOVE) ********/ /************* DEPRECIATED FUNCTIONS (TO REMOVE) ********/
@ -321,6 +326,9 @@ virtual int getFriendCount(bool ssl, bool online);
// Single Use Function... shouldn't be here. used by p3serverconfig.cc // Single Use Function... shouldn't be here. used by p3serverconfig.cc
virtual bool haveOnceConnected(); virtual bool haveOnceConnected();
virtual bool setMaxRates(const RsPgpId& pid,uint32_t maxUp,uint32_t maxDn);
virtual bool getMaxRates(const RsPgpId& pid,uint32_t& maxUp,uint32_t& maxDn);
virtual bool getMaxRates(const RsPeerId& pid,uint32_t& maxUp,uint32_t& maxDn);
/************************************************************************************************/ /************************************************************************************************/
/* Extra IMPL Functions (used by p3LinkMgr, p3NetMgr + Setup) */ /* Extra IMPL Functions (used by p3LinkMgr, p3NetMgr + Setup) */
@ -392,6 +400,7 @@ private:
std::list<RsItem *> saveCleanupList; /* TEMPORARY LIST WHEN SAVING */ std::list<RsItem *> saveCleanupList; /* TEMPORARY LIST WHEN SAVING */
std::map<RsPgpId, ServicePermissionFlags> mFriendsPermissionFlags ; // permission flags for each gpg key std::map<RsPgpId, ServicePermissionFlags> mFriendsPermissionFlags ; // permission flags for each gpg key
std::map<RsPgpId, PeerBandwidthLimits> mPeerBandwidthLimits ; // bandwidth limits for each gpg key
struct sockaddr_storage mProxyServerAddressTor; struct sockaddr_storage mProxyServerAddressTor;
struct sockaddr_storage mProxyServerAddressI2P; struct sockaddr_storage mProxyServerAddressI2P;

View File

@ -80,103 +80,103 @@ class RateInterface
public: public:
RateInterface() RateInterface()
:bw_in(0), bw_out(0), bwMax_in(0), bwMax_out(0), :bw_in(0), bw_out(0), bwMax_in(0), bwMax_out(0),
bwCapEnabled(false), bwCap_in(0), bwCap_out(0) { return; } bwCapEnabled(false), bwCap_in(0), bwCap_out(0) { return; }
virtual ~RateInterface() { return; } virtual ~RateInterface() { return; }
virtual void getRates(RsBwRates &rates) virtual void getRates(RsBwRates &rates)
{
rates.mRateIn = bw_in;
rates.mRateOut = bw_out;
rates.mMaxRateIn = bwMax_in;
rates.mMaxRateOut = bwMax_out;
return;
}
virtual int gatherStatistics(std::list<RSTrafficClue>& /* outqueue_lst */,std::list<RSTrafficClue>& /* inqueue_lst */) { return 0;}
virtual int getQueueSize(bool /* in */) { return 0;}
virtual float getRate(bool in)
{ {
if (in) rates.mRateIn = bw_in;
return bw_in; rates.mRateOut = bw_out;
return bw_out; rates.mMaxRateIn = bwMax_in;
rates.mMaxRateOut = bwMax_out;
return;
} }
virtual float getMaxRate(bool in) virtual int gatherStatistics(std::list<RSTrafficClue>& /* outqueue_lst */,std::list<RSTrafficClue>& /* inqueue_lst */) { return 0;}
virtual int getQueueSize(bool /* in */) { return 0;}
virtual float getRate(bool in)
{ {
if (in) if (in)
return bwMax_in; return bw_in;
return bwMax_out; return bw_out;
} }
virtual void setMaxRate(bool in, float val) virtual float getMaxRate(bool in)
{ {
if (in) if (in)
return bwMax_in;
return bwMax_out;
}
virtual void setMaxRate(bool in, float val)
{ {
bwMax_in = val; if (in)
if (bwCapEnabled)
{ {
if (bwMax_in > bwCap_in) bwMax_in = val;
if (bwCapEnabled)
{ {
bwMax_in = bwCap_in; if (bwMax_in > bwCap_in)
{
bwMax_in = bwCap_in;
}
} }
} }
} else
else
{
bwMax_out = val;
if (bwCapEnabled)
{ {
if (bwMax_out > bwCap_out) bwMax_out = val;
if (bwCapEnabled)
{ {
bwMax_out = bwCap_out; if (bwMax_out > bwCap_out)
{
bwMax_out = bwCap_out;
}
} }
} }
}
return; return;
} }
virtual void setRateCap(float val_in, float val_out) virtual void setRateCap(float val_in, float val_out)
{
if ((val_in == 0) && (val_out == 0))
{ {
if ((val_in == 0) && (val_out == 0))
{
#ifdef DEBUG_RATECAP #ifdef DEBUG_RATECAP
std::cerr << "RateInterface::setRateCap() Now disabled" << std::endl; std::cerr << "RateInterface::setRateCap() Now disabled" << std::endl;
#endif #endif
bwCapEnabled = false; bwCapEnabled = false;
} }
else else
{ {
#ifdef DEBUG_RATECAP #ifdef DEBUG_RATECAP
std::cerr << "RateInterface::setRateCap() Enabled "; std::cerr << "RateInterface::setRateCap() Enabled ";
std::cerr << "in: " << bwCap_in << " out: " << bwCap_out << std::endl; std::cerr << "in: " << bwCap_in << " out: " << bwCap_out << std::endl;
#endif #endif
bwCapEnabled = true; bwCapEnabled = true;
bwCap_in = val_in; bwCap_in = val_in;
bwCap_out = val_out; bwCap_out = val_out;
}
return;
} }
return;
}
protected: protected:
void setRate(bool in, float val) virtual void setRate(bool in, float val)
{ {
if (in) if (in)
bw_in = val; bw_in = val;
else else
bw_out = val; bw_out = val;
return; return;
} }
private: private:
float bw_in, bw_out, bwMax_in, bwMax_out; float bw_in, bw_out, bwMax_in, bwMax_out;
bool bwCapEnabled; bool bwCapEnabled;
float bwCap_in, bwCap_out; float bwCap_in, bwCap_out;
}; };

View File

@ -27,6 +27,7 @@
#include "util/rsdebug.h" #include "util/rsdebug.h"
#include "util/rsstring.h" #include "util/rsstring.h"
#include "retroshare/rspeers.h"
#include <stdlib.h> #include <stdlib.h>
#include <time.h> #include <time.h>
@ -69,18 +70,19 @@ static const float PQI_HANDLER_NB_PRIORITY_RATIO = 2 ;
pqihandler::pqihandler() : coreMtx("pqihandler") pqihandler::pqihandler() : coreMtx("pqihandler")
{ {
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/ RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
// setup minimal total+individual rates. // setup minimal total+individual rates.
rateIndiv_out = 0.01; rateIndiv_out = 0.01;
rateIndiv_in = 0.01; rateIndiv_in = 0.01;
rateMax_out = 0.01; rateMax_out = 0.01;
rateMax_in = 0.01; rateMax_in = 0.01;
rateTotal_in = 0.0 ; rateTotal_in = 0.0 ;
rateTotal_out = 0.0 ; rateTotal_out = 0.0 ;
last_m = time(NULL) ; last_m = time(NULL) ;
nb_ticks = 0 ; nb_ticks = 0 ;
ticks_per_sec = 5 ; // initial guess mLastRateCapUpdate = 0 ;
ticks_per_sec = 5 ; // initial guess
return; return;
} }
@ -113,27 +115,27 @@ int pqihandler::tick()
moreToTick = 1; moreToTick = 1;
} }
#endif #endif
} }
// static time_t last_print_time = 0 ; time_t now = time(NULL) ;
// time_t now = time(NULL) ;
// if(now > last_print_time + 3) if(now > mLastRateCapUpdate + 5)
// { {
// std::map<uint16_t,uint32_t> per_service_count ; // every 5 secs, update the max rates for all modules
// std::vector<uint32_t> per_priority_count ;
// RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
// ExtractOutQueueStatistics(per_service_count,per_priority_count) ; for(std::map<RsPeerId, SearchModule *>::iterator it = mods.begin(); it != mods.end(); ++it)
// {
// std::cerr << "PQIHandler outqueues: " << std::endl; // This is rather inelegant, but pqihandler has searchModules that are dynamically allocated, so the max rates
// // need to be updated from inside.
// for(std::map<uint16_t,uint32_t>::const_iterator it=per_service_count.begin();it!=per_service_count.end();++it) uint32_t maxUp,maxDn ;
// std::cerr << " " << std::hex << it->first << std::dec << " " << it->second << std::endl; rsPeers->getPeerMaximumRates(it->first,maxUp,maxDn);
//
// for(int i=0;i<per_priority_count.size();++i) it->second->pqi->setRateCap(maxDn,maxUp);// mind the order! Dn first, than Up.
// std::cerr << " " << i << " : " << per_priority_count[i] << std::endl; }
//
// last_print_time = now ; mLastRateCapUpdate = now ;
// } }
UpdateRates(); UpdateRates();
return moreToTick; return moreToTick;
@ -277,144 +279,6 @@ int pqihandler::SendRsRawItem(RsRawItem *ns)
return queueOutRsItem(ns) ; return queueOutRsItem(ns) ;
} }
#ifdef TO_BE_REMOVED
// inputs. This is a very basic
// system that is completely biased and slow...
// someone please fix.
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
// THIS CODE SHOULD BE ABLE TO BE REMOVED!
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
int pqihandler::locked_GetItems()
{
std::map<RsPeerId, SearchModule *>::iterator it;
RsItem *item;
int count = 0;
// loop through modules....
for(it = mods.begin(); it != mods.end(); ++it)
{
SearchModule *mod = (it -> second);
// check security... is output allowed.
if(0 < secpolicy_check((it -> second) -> sp,
0, PQI_INCOMING)) // PQI_ITEM_TYPE_ITEM, PQI_INCOMING))
{
// if yes... attempt to read.
while((item = (mod -> pqi) -> GetItem()) != NULL)
{
static int ntimes =0 ;
// if(++ntimes < 20)
{
std::cerr << "pqihandler::locked_GetItems() pqi->GetItem()";
std::cerr << " should never happen anymore!";
std::cerr << std::endl;
}
#ifdef RSITEM_DEBUG
std::string out;
rs_sprintf(out, "pqihandler::GetItems() Incoming Item from: %p\n", mod -> pqi);
item -> print_string(out);
pqioutput(PQL_DEBUG_BASIC,
pqihandlerzone, out);
#endif
if (item->PeerId() != (mod->pqi)->PeerId())
{
/* ERROR */
pqioutput(PQL_ALERT,
pqihandlerzone, "ERROR PeerIds dont match!");
item->PeerId(mod->pqi->PeerId());
}
locked_SortnStoreItem(item);
count++;
}
}
else
{
// not allowed to recieve from here....
while((item = (mod -> pqi) -> GetItem()) != NULL)
{
std::string out;
rs_sprintf(out, "pqihandler::GetItems() Incoming Item from: %p\n", mod -> pqi);
item -> print_string(out);
out += "\nItem Not Allowed (Sec Pol). deleting!";
pqioutput(PQL_DEBUG_BASIC,
pqihandlerzone, out);
delete item;
}
}
}
return count;
}
void pqihandler::locked_SortnStoreItem(RsItem *item)
{
/* get class type / subtype out of the item */
uint8_t vers = item -> PacketVersion();
/* whole Version reserved for SERVICES/CACHES */
if (vers == RS_PKT_VERSION_SERVICE)
{
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
"SortnStore -> Service");
in_service.push_back(item);
item = NULL;
return;
}
std::cerr << "pqihandler::locked_SortnStoreItem() : unhandled item! Will be deleted. This is certainly a bug." << std::endl;
if (vers != RS_PKT_VERSION1)
{
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, "SortnStore -> Invalid VERSION! Deleting!");
delete item;
item = NULL;
return;
}
if (item)
{
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, "SortnStore -> Deleting Unsorted Item");
delete item;
}
return;
}
RsRawItem *pqihandler::GetRsRawItem()
{
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
if (in_service.size() != 0)
{
RsRawItem *fi = dynamic_cast<RsRawItem *>(in_service.front());
if (!fi) { delete in_service.front(); }
in_service.pop_front();
return fi;
}
return NULL;
}
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
// ABOVE CODE SHOULD BE ABLE TO BE REMOVED!
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
#endif
static const float MIN_RATE = 0.01; // 10 B/s
int pqihandler::ExtractTrafficInfo(std::list<RSTrafficClue>& out_lst,std::list<RSTrafficClue>& in_lst) int pqihandler::ExtractTrafficInfo(std::list<RSTrafficClue>& out_lst,std::list<RSTrafficClue>& in_lst)
{ {
in_lst.clear() ; in_lst.clear() ;
@ -640,6 +504,7 @@ int pqihandler::UpdateRates()
for(it = mods.begin(); it != mods.end(); ++it) for(it = mods.begin(); it != mods.end(); ++it)
{ {
SearchModule *mod = (it -> second); SearchModule *mod = (it -> second);
mod -> pqi -> setMaxRate(true, in_max_bw); mod -> pqi -> setMaxRate(true, in_max_bw);
mod -> pqi -> setMaxRate(false, out_max_bw); mod -> pqi -> setMaxRate(false, out_max_bw);
} }
@ -649,18 +514,10 @@ int pqihandler::UpdateRates()
for(it = mods.begin(); it != mods.end(); ++it) for(it = mods.begin(); it != mods.end(); ++it)
{ {
SearchModule *mod = (it -> second); SearchModule *mod = (it -> second);
if (mod -> pqi -> getMaxRate(false) < max_out_effective) { if (mod -> pqi -> getMaxRate(false) < max_out_effective) mod -> pqi -> setMaxRate(false, max_out_effective);
mod -> pqi -> setMaxRate(false, max_out_effective); if (mod -> pqi -> getMaxRate(false) > avail_out) mod -> pqi -> setMaxRate(false, avail_out);
} if (mod -> pqi -> getMaxRate(true) < max_in_effective) mod -> pqi -> setMaxRate(true, max_in_effective);
if (mod -> pqi -> getMaxRate(false) > avail_out) { if (mod -> pqi -> getMaxRate(true) > avail_in) mod -> pqi -> setMaxRate(true, avail_in);
mod -> pqi -> setMaxRate(false, avail_out);
}
if (mod -> pqi -> getMaxRate(true) < max_in_effective) {
mod -> pqi -> setMaxRate(true, max_in_effective);
}
if (mod -> pqi -> getMaxRate(true) > avail_in) {
mod -> pqi -> setMaxRate(true, avail_in);
}
} }
return 1; return 1;

View File

@ -39,8 +39,10 @@
class SearchModule class SearchModule
{ {
public: public:
RsPeerId peerid; SearchModule() : pqi(NULL) {}
PQInterface *pqi;
RsPeerId peerid ;
PQInterface *pqi;
}; };
// Presents a P3 Face to the world! // Presents a P3 Face to the world!
@ -71,14 +73,18 @@ class pqihandler: public P3Interface, public pqiPublisher
#endif #endif
// rate control. // rate control.
//void setMaxRate(const RsPeerId& pid,bool in, uint32_t val_kBs);
void setMaxRate(bool in, float val); void setMaxRate(bool in, float val);
float getMaxRate(bool in); float getMaxRate(bool in);
void setMaxRates(const RsPeerId& pid,bool in,float val) ;
float getMaxRates(const RsPeerId& pid,bool in) ;
void getCurrentRates(float &in, float &out); void getCurrentRates(float &in, float &out);
// TESTING INTERFACE. // TESTING INTERFACE.
int ExtractRates(std::map<RsPeerId, RsBwRates> &ratemap, RsBwRates &totals); int ExtractRates(std::map<RsPeerId, RsBwRates> &ratemap, RsBwRates &totals);
int ExtractTrafficInfo(std::list<RSTrafficClue> &out_lst, std::list<RSTrafficClue> &in_lst); int ExtractTrafficInfo(std::list<RSTrafficClue> &out_lst, std::list<RSTrafficClue> &in_lst);
protected: protected:
/* check to be overloaded by those that can /* check to be overloaded by those that can
@ -115,6 +121,7 @@ protected:
uint32_t nb_ticks ; uint32_t nb_ticks ;
time_t last_m ; time_t last_m ;
time_t mLastRateCapUpdate ;
float ticks_per_sec ; float ticks_per_sec ;
}; };

View File

@ -374,11 +374,15 @@ int pqissllistenbase::acceptconnection()
#endif #endif
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/ /********************************** WINDOWS/UNIX SPECIFIC PART ******************/
std::cerr << "(II) Checking incoming connection address: " << sockaddr_storage_iptostring(remote_addr) ;
if(rsBanList != NULL && !rsBanList->isAddressAccepted(remote_addr, RSBANLIST_CHECKING_FLAGS_BLACKLIST)) if(rsBanList != NULL && !rsBanList->isAddressAccepted(remote_addr, RSBANLIST_CHECKING_FLAGS_BLACKLIST))
{ {
std::cerr << "(II) pqissllistenner::acceptConnection(): early denying connection attempt from blacklisted IP " << sockaddr_storage_iptostring(remote_addr) << std::endl; std::cerr << " => early rejected at this point, because of blacklist." << std::endl;
return false ; return false ;
} }
else
std::cerr << " => Accepted (i.e. whitelisted, or not blacklisted)." << std::endl;
{ {
std::string out; std::string out;
out += "Accepted Connection from "; out += "Accepted Connection from ";

View File

@ -616,6 +616,9 @@ bool pqissludp::moretoread(uint32_t usec)
return 0; return 0;
} }
if(SSL_pending(ssl_connection) > 0)
return 1 ;
/* otherwise - not error - strange! */ /* otherwise - not error - strange! */
rslog(RSL_DEBUG_BASIC, pqissludpzone, rslog(RSL_DEBUG_BASIC, pqissludpzone,
"pqissludp::moretoread() No Data + No Error (really nothing)"); "pqissludp::moretoread() No Data + No Error (really nothing)");

View File

@ -406,7 +406,11 @@ bool pqiSSLstore::encryptedSendItems(const std::list<RsItem*>& rsItemList)
if(rsSerialiser->serialise(*it, &data[offset],&sizeItem)) if(rsSerialiser->serialise(*it, &data[offset],&sizeItem))
offset += sizeItem; offset += sizeItem;
else else
std::cerr << "(EE) pqiSSLstore::encryptedSendItems(): One item did not serialize. The item is probably unknown from the serializer. Dropping the item. " << std::endl; {
std::cerr << "(EE) pqiSSLstore::encryptedSendItems(): One item did not serialize. The item is probably unknown from the serializer. Dropping the item. " << std::endl;
std::cerr << "Item content: " << std::endl;
(*it)->print(std::cerr) ;
}
if (!(bio_flags & BIN_FLAGS_NO_DELETE)) if (!(bio_flags & BIN_FLAGS_NO_DELETE))
delete *it; delete *it;

View File

@ -77,7 +77,14 @@ pqistreamer::pqistreamer(RsSerialiser *rss, const RsPeerId& id, BinInterface *bi
mCurrRead(0), mCurrSent(0), mCurrRead(0), mCurrSent(0),
mAvgReadCount(0), mAvgSentCount(0) mAvgReadCount(0), mAvgSentCount(0)
{ {
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
// 100 B/s (minimal)
setMaxRate(true, 0.1);
setMaxRate(false, 0.1);
setRate(true, 0); // needs to be off-mutex
setRate(false, 0);
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
mAcceptsPacketSlicing = false ; // by default. Will be turned into true when everyone's ready. mAcceptsPacketSlicing = false ; // by default. Will be turned into true when everyone's ready.
mLastSentPacketSlicingProbe = 0 ; mLastSentPacketSlicingProbe = 0 ;
@ -86,28 +93,22 @@ pqistreamer::pqistreamer(RsSerialiser *rss, const RsPeerId& id, BinInterface *bi
mIncomingSize = 0 ; mIncomingSize = 0 ;
mStatisticsTimeStamp = 0 ; mStatisticsTimeStamp = 0 ;
/* allocated once */ /* allocated once */
mPkt_rpend_size = 0; mPkt_rpend_size = 0;
mPkt_rpending = 0; mPkt_rpending = 0;
mReading_state = reading_state_initial ; mReading_state = reading_state_initial ;
// 100 B/s (minimal) pqioutput(PQL_DEBUG_ALL, pqistreamerzone, "pqistreamer::pqistreamer() Initialisation!");
setMaxRate(true, 0.1);
setMaxRate(false, 0.1);
setRate(true, 0);
setRate(false, 0);
pqioutput(PQL_DEBUG_ALL, pqistreamerzone, "pqistreamer::pqistreamer() Initialisation!"); if (!bio_in)
{
pqioutput(PQL_ALERT, pqistreamerzone, "pqistreamer::pqistreamer() NULL bio, FATAL ERROR!");
exit(1);
}
if (!bio_in) mFailed_read_attempts = 0; // reset failed read, as no packet is still read.
{
pqioutput(PQL_ALERT, pqistreamerzone, "pqistreamer::pqistreamer() NULL bio, FATAL ERROR!");
exit(1);
}
mFailed_read_attempts = 0; // reset failed read, as no packet is still read. return;
return;
} }
pqistreamer::~pqistreamer() pqistreamer::~pqistreamer()
@ -195,18 +196,39 @@ RsItem *pqistreamer::GetItem()
return osr; return osr;
} }
float pqistreamer::getRate(bool b)
{
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
return RateInterface::getRate(b) ;
}
void pqistreamer::setMaxRate(bool b,float f)
{
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
RateInterface::setMaxRate(b,f) ;
}
void pqistreamer::setRate(bool b,float f)
{
RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
RateInterface::setRate(b,f) ;
}
void pqistreamer::updateRates() void pqistreamer::updateRates()
{ {
// now update rates both ways. // now update rates both ways.
time_t t = time(NULL); // get current timestep. time_t t = time(NULL); // get current timestep.
int64_t diff ;
if (t > mAvgLastUpdate + PQISTREAM_AVG_PERIOD)
{ {
int64_t diff = int64_t(t) - int64_t(mAvgLastUpdate) ; RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
float avgReadpSec = getRate(true ) * PQISTREAM_AVG_FRAC + (1.0 - PQISTREAM_AVG_FRAC) * mAvgReadCount/(1000.0 * float(diff)); diff = int64_t(t) - int64_t(mAvgLastUpdate) ;
float avgSentpSec = getRate(false) * PQISTREAM_AVG_FRAC + (1.0 - PQISTREAM_AVG_FRAC) * mAvgSentCount/(1000.0 * float(diff)); }
if (diff > PQISTREAM_AVG_PERIOD)
{
float avgReadpSec = getRate(true ) * PQISTREAM_AVG_FRAC + (1.0 - PQISTREAM_AVG_FRAC) * mAvgReadCount/(1024.0 * float(diff));
float avgSentpSec = getRate(false) * PQISTREAM_AVG_FRAC + (1.0 - PQISTREAM_AVG_FRAC) * mAvgSentCount/(1024.0 * float(diff));
#ifdef DEBUG_PQISTREAMER #ifdef DEBUG_PQISTREAMER
std::cerr << "Peer " << PeerId() << ": Current speed estimates: " << avgReadpSec << " / " << avgSentpSec << std::endl; std::cerr << "Peer " << PeerId() << ": Current speed estimates: " << avgReadpSec << " / " << avgSentpSec << std::endl;
@ -226,9 +248,12 @@ void pqistreamer::updateRates()
setRate(false, 0); setRate(false, 0);
} }
mAvgLastUpdate = t; {
mAvgReadCount = 0; RsStackMutex stack(mStreamerMtx); /**** LOCKED MUTEX ****/
mAvgSentCount = 0; mAvgLastUpdate = t;
mAvgReadCount = 0;
mAvgSentCount = 0;
}
} }
} }

View File

@ -67,6 +67,12 @@ class pqistreamer: public PQInterface
virtual void getRates(RsBwRates &rates); virtual void getRates(RsBwRates &rates);
virtual int getQueueSize(bool in); // extracting data. virtual int getQueueSize(bool in); // extracting data.
virtual int gatherStatistics(std::list<RSTrafficClue>& outqueue_stats,std::list<RSTrafficClue>& inqueue_stats); // extracting data. virtual int gatherStatistics(std::list<RSTrafficClue>& outqueue_stats,std::list<RSTrafficClue>& inqueue_stats); // extracting data.
// mutex protected versions of RateInterface calls.
virtual void setRate(bool b,float f) ;
virtual void setMaxRate(bool b,float f) ;
virtual float getRate(bool b) ;
protected: protected:
int tick_bio(); int tick_bio();
@ -148,8 +154,8 @@ class pqistreamer: public PQInterface
time_t mCurrSentTS; time_t mCurrSentTS;
time_t mAvgLastUpdate; // TS from which these are measured. time_t mAvgLastUpdate; // TS from which these are measured.
float mAvgReadCount; uint32_t mAvgReadCount;
float mAvgSentCount; uint32_t mAvgSentCount;
time_t mLastIncomingTs; time_t mLastIncomingTs;

View File

@ -293,8 +293,8 @@ public:
/* Data Rate Control - to be moved here */ /* Data Rate Control - to be moved here */
virtual int SetMaxDataRates( int downKb, int upKb ) = 0; virtual int SetMaxDataRates( int downKb, int upKb ) = 0;
virtual int GetMaxDataRates( int &inKb, int &outKb ) = 0; virtual int GetMaxDataRates( int &inKb, int &outKb ) = 0;
virtual int GetCurrentDataRates( float &inKb, float &outKb ) = 0;
virtual int GetCurrentDataRates( float &inKb, float &outKb ) = 0;
}; };
#endif #endif

View File

@ -61,7 +61,7 @@ template<int n> class t_RsFlags32
#define FLAGS_TAG_TRANSFER_REQS 0x4228af #define FLAGS_TAG_TRANSFER_REQS 0x4228af
#define FLAGS_TAG_FILE_STORAGE 0x184738 #define FLAGS_TAG_FILE_STORAGE 0x184738
#define FLAGS_TAG_FILE_SEARCH 0xf29ba5 #define FLAGS_TAG_FILE_SEARCH 0xf29ba5
#define FLAGS_TAG_SERVICE_PERM 0x380912 #define FLAGS_TAG_SERVICE_PERM 0x380912
#define FLAGS_TAG_SERVICE_CHAT 0x839042 #define FLAGS_TAG_SERVICE_CHAT 0x839042

View File

@ -112,6 +112,7 @@ class RsGxsCircleDetails
std::string mCircleName; std::string mCircleName;
uint32_t mCircleType; uint32_t mCircleType;
RsGxsCircleId mRestrictedCircleId;
bool mAmIAllowed ; // true when one of load GXS ids belong to the circle allowed list (admin list & subscribed list). bool mAmIAllowed ; // true when one of load GXS ids belong to the circle allowed list (admin list & subscribed list).
@ -123,32 +124,29 @@ class RsGxsCircleDetails
class RsGxsCircles: public RsGxsIfaceHelper class RsGxsCircles: public RsGxsIfaceHelper
{ {
public: public:
RsGxsCircles(RsGxsIface *gxs)
:RsGxsIfaceHelper(gxs) { return; }
virtual ~RsGxsCircles() { return; }
RsGxsCircles(RsGxsIface *gxs) :RsGxsIfaceHelper(gxs) { return; }
virtual ~RsGxsCircles() { return; }
/* External Interface (Cached stuff) */ /* External Interface (Cached stuff) */
virtual bool getCircleDetails(const RsGxsCircleId &id, RsGxsCircleDetails &details) = 0; virtual bool getCircleDetails(const RsGxsCircleId &id, RsGxsCircleDetails &details) = 0;
virtual bool getCircleExternalIdList(std::list<RsGxsCircleId> &circleIds) = 0; virtual bool getCircleExternalIdList(std::list<RsGxsCircleId> &circleIds) = 0;
virtual bool getCirclePersonalIdList(std::list<RsGxsCircleId> &circleIds) = 0; virtual bool getCirclePersonalIdList(std::list<RsGxsCircleId> &circleIds) = 0;
/* membership management for external circles */ /* membership management for external circles */
virtual bool requestCircleMembership(const RsGxsId& own_gxsid,const RsGxsCircleId& circle_id)=0 ; virtual bool requestCircleMembership(const RsGxsId& own_gxsid,const RsGxsCircleId& circle_id)=0 ;
virtual bool cancelCircleMembership(const RsGxsId& own_gxsid,const RsGxsCircleId& circle_id)=0 ; virtual bool cancelCircleMembership(const RsGxsId& own_gxsid,const RsGxsCircleId& circle_id)=0 ;
/* standard load */ /* standard load */
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsCircleGroup> &groups) = 0; virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsCircleGroup> &groups) = 0;
/* make new group */ /* make new group */
virtual void createGroup(uint32_t& token, RsGxsCircleGroup &group) = 0; virtual void createGroup(uint32_t& token, RsGxsCircleGroup &group) = 0;
/* update an existing group */
virtual void updateGroup(uint32_t &token, RsGxsCircleGroup &group) = 0;
/* update an existing group */
virtual void updateGroup(uint32_t &token, RsGxsCircleGroup &group) = 0;
}; };

View File

@ -428,6 +428,10 @@ public:
virtual ServicePermissionFlags servicePermissionFlags(const RsPgpId& gpg_id) = 0; virtual ServicePermissionFlags servicePermissionFlags(const RsPgpId& gpg_id) = 0;
virtual ServicePermissionFlags servicePermissionFlags(const RsPeerId& ssl_id) = 0; virtual ServicePermissionFlags servicePermissionFlags(const RsPeerId& ssl_id) = 0;
virtual void setServicePermissionFlags(const RsPgpId& gpg_id,const ServicePermissionFlags& flags) = 0; virtual void setServicePermissionFlags(const RsPgpId& gpg_id,const ServicePermissionFlags& flags) = 0;
virtual bool setPeerMaximumRates(const RsPgpId& pid,uint32_t maxUploadRate,uint32_t maxDownloadRate) =0;
virtual bool getPeerMaximumRates(const RsPeerId& pid,uint32_t& maxUploadRate,uint32_t& maxDownloadRate) =0;
virtual bool getPeerMaximumRates(const RsPgpId& pid,uint32_t& maxUploadRate,uint32_t& maxDownloadRate) =0;
}; };
#endif #endif

View File

@ -118,6 +118,15 @@ class Condition
std::string name; std::string name;
}; };
class PeerBandwidthLimits
{
public:
PeerBandwidthLimits() : max_up_rate_kbs(0), max_dl_rate_kbs(0) {}
uint32_t max_up_rate_kbs ;
uint32_t max_dl_rate_kbs ;
};
//class SearchRequest // unused stuff. //class SearchRequest // unused stuff.
//{ //{
// public: // public:

View File

@ -35,6 +35,14 @@
#include <sqlcipher/sqlite3.h> #include <sqlcipher/sqlite3.h>
#endif #endif
#ifndef RS_ENABLE_ZCNATASSIST
#ifdef RS_USE_LIBUPNP
#include "upnp/upnpconfig.h"
#else
#include "miniupnpc/miniupnpc.h"
#endif // RS_USE_LIBUPNP
#endif // RS_ENABLE_ZCNATASSIST
std::string RsServer::getSQLCipherVersion() std::string RsServer::getSQLCipherVersion()
{ {
sqlite3* mDb; sqlite3* mDb;
@ -84,5 +92,12 @@ void RsServer::getLibraries(std::list<RsLibraryInfo> &libraries)
#ifndef NO_SQLCIPHER #ifndef NO_SQLCIPHER
libraries.push_back(RsLibraryInfo("SQLCipher", getSQLCipherVersion())); libraries.push_back(RsLibraryInfo("SQLCipher", getSQLCipherVersion()));
#endif #endif
#ifndef RS_ENABLE_ZCNATASSIST
#ifdef RS_USE_LIBUPNP
libraries.push_back(RsLibraryInfo("UPnP (libupnp)", UPNP_VERSION_STRING));
#else
libraries.push_back(RsLibraryInfo("UPnP (MiniUPnP)", MINIUPNPC_VERSION));
#endif // RS_USE_LIBUPNP
#endif // RS_ENABLE_ZCNATASSIST
libraries.push_back(RsLibraryInfo("Zlib", ZLIB_VERSION)); libraries.push_back(RsLibraryInfo("Zlib", ZLIB_VERSION));
} }

View File

@ -241,6 +241,20 @@ bool p3Peers::isFriend(const RsPeerId &ssl_id)
return mPeerMgr->isFriend(ssl_id); return mPeerMgr->isFriend(ssl_id);
} }
bool p3Peers::getPeerMaximumRates(const RsPeerId& pid,uint32_t& maxUploadRate,uint32_t& maxDownloadRate)
{
return mPeerMgr->getMaxRates(pid,maxUploadRate,maxDownloadRate) ;
}
bool p3Peers::getPeerMaximumRates(const RsPgpId& pid,uint32_t& maxUploadRate,uint32_t& maxDownloadRate)
{
return mPeerMgr->getMaxRates(pid,maxUploadRate,maxDownloadRate) ;
}
bool p3Peers::setPeerMaximumRates(const RsPgpId& pid,uint32_t maxUploadRate,uint32_t maxDownloadRate)
{
return mPeerMgr->setMaxRates(pid,maxUploadRate,maxDownloadRate) ;
}
bool p3Peers::haveSecretKey(const RsPgpId& id) bool p3Peers::haveSecretKey(const RsPgpId& id)
{ {
return AuthGPG::getAuthGPG()->haveSecretKey(id); return AuthGPG::getAuthGPG()->haveSecretKey(id);
@ -298,15 +312,15 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d)
d.hiddenType = ps.hiddenType; d.hiddenType = ps.hiddenType;
if(sockaddr_storage_isnull(ps.localaddr)) // that happens if the address is not initialised. if(sockaddr_storage_isnull(ps.localaddr)) // that happens if the address is not initialised.
{ {
d.localAddr = "INVALID_IP"; d.localAddr = "INVALID_IP";
d.localPort = 0 ; d.localPort = 0 ;
} }
else else
{ {
d.localAddr = sockaddr_storage_iptostring(ps.localaddr); d.localAddr = sockaddr_storage_iptostring(ps.localaddr);
d.localPort = sockaddr_storage_port(ps.localaddr); d.localPort = sockaddr_storage_port(ps.localaddr);
} }
d.extAddr = "hidden"; d.extAddr = "hidden";
d.extPort = 0; d.extPort = 0;
d.dyndns = ""; d.dyndns = "";
@ -344,7 +358,7 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d)
std::list<pqiIpAddress>::iterator it; std::list<pqiIpAddress>::iterator it;
for(it = ps.ipAddrs.mLocal.mAddrs.begin(); for(it = ps.ipAddrs.mLocal.mAddrs.begin();
it != ps.ipAddrs.mLocal.mAddrs.end(); ++it) it != ps.ipAddrs.mLocal.mAddrs.end(); ++it)
{ {
std::string toto; std::string toto;
toto += "L:"; toto += "L:";
@ -352,8 +366,7 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d)
rs_sprintf_append(toto, " %ld sec", time(NULL) - it->mSeenTime); rs_sprintf_append(toto, " %ld sec", time(NULL) - it->mSeenTime);
d.ipAddressList.push_back(toto); d.ipAddressList.push_back(toto);
} }
for(it = ps.ipAddrs.mExt.mAddrs.begin(); for(it = ps.ipAddrs.mExt.mAddrs.begin(); it != ps.ipAddrs.mExt.mAddrs.end(); ++it)
it != ps.ipAddrs.mExt.mAddrs.end(); ++it)
{ {
std::string toto; std::string toto;
toto += "E:"; toto += "E:";
@ -366,29 +379,28 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d)
switch(ps.netMode & RS_NET_MODE_ACTUAL) switch(ps.netMode & RS_NET_MODE_ACTUAL)
{ {
case RS_NET_MODE_EXT: case RS_NET_MODE_EXT:
d.netMode = RS_NETMODE_EXT; d.netMode = RS_NETMODE_EXT;
break; break;
case RS_NET_MODE_UPNP: case RS_NET_MODE_UPNP:
d.netMode = RS_NETMODE_UPNP; d.netMode = RS_NETMODE_UPNP;
break; break;
case RS_NET_MODE_UDP: case RS_NET_MODE_UDP:
d.netMode = RS_NETMODE_UDP; d.netMode = RS_NETMODE_UDP;
break; break;
case RS_NET_MODE_HIDDEN: case RS_NET_MODE_HIDDEN:
d.netMode = RS_NETMODE_HIDDEN; d.netMode = RS_NETMODE_HIDDEN;
break; break;
case RS_NET_MODE_UNREACHABLE: case RS_NET_MODE_UNREACHABLE:
case RS_NET_MODE_UNKNOWN: case RS_NET_MODE_UNKNOWN:
default: default:
d.netMode = RS_NETMODE_UNREACHABLE; d.netMode = RS_NETMODE_UNREACHABLE;
break; break;
} }
d.vs_disc = ps.vs_disc; d.vs_disc = ps.vs_disc;
d.vs_dht = ps.vs_dht; d.vs_dht = ps.vs_dht;
/* Translate */ /* Translate */
peerConnectState pcs; peerConnectState pcs;
if (!mLinkMgr->getFriendNetStatus(id, pcs)) if (!mLinkMgr->getFriendNetStatus(id, pcs))
@ -414,14 +426,10 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d)
} }
d.state = 0; d.state = 0;
if (pcs.state & RS_PEER_S_FRIEND) if (pcs.state & RS_PEER_S_FRIEND) d.state |= RS_PEER_STATE_FRIEND;
d.state |= RS_PEER_STATE_FRIEND; if (pcs.state & RS_PEER_S_ONLINE) d.state |= RS_PEER_STATE_ONLINE;
if (pcs.state & RS_PEER_S_ONLINE) if (pcs.state & RS_PEER_S_CONNECTED) d.state |= RS_PEER_STATE_CONNECTED;
d.state |= RS_PEER_STATE_ONLINE; if (pcs.state & RS_PEER_S_UNREACHABLE) d.state |= RS_PEER_STATE_UNREACHABLE;
if (pcs.state & RS_PEER_S_CONNECTED)
d.state |= RS_PEER_STATE_CONNECTED;
if (pcs.state & RS_PEER_S_UNREACHABLE)
d.state |= RS_PEER_STATE_UNREACHABLE;
d.actAsServer = pcs.actAsServer; d.actAsServer = pcs.actAsServer;
@ -433,7 +441,6 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d)
d.connectState = RS_PEER_CONNECTSTATE_OFFLINE; d.connectState = RS_PEER_CONNECTSTATE_OFFLINE;
d.connectStateString.clear(); d.connectStateString.clear();
if (pcs.inConnAttempt) if (pcs.inConnAttempt)
{ {
if (pcs.currentConnAddrAttempt.type & RS_NET_CONN_TCP_ALL) { if (pcs.currentConnAddrAttempt.type & RS_NET_CONN_TCP_ALL) {
@ -445,7 +452,7 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d)
} }
} }
else if (pcs.state & RS_PEER_S_CONNECTED) else if (pcs.state & RS_PEER_S_CONNECTED)
{ {
/* peer is connected - determine how and set proper connectState */ /* peer is connected - determine how and set proper connectState */
if(mPeerMgr->isHidden()) if(mPeerMgr->isHidden())
{ {
@ -519,7 +526,7 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d)
d.connectState = RS_PEER_CONNECTSTATE_CONNECTED_UNKNOWN; d.connectState = RS_PEER_CONNECTSTATE_CONNECTED_UNKNOWN;
} }
} }
} }
d.wasDeniedConnection = pcs.wasDeniedConnection; d.wasDeniedConnection = pcs.wasDeniedConnection;
d.deniedTS = pcs.deniedTS; d.deniedTS = pcs.deniedTS;

View File

@ -139,6 +139,9 @@ public:
virtual ServicePermissionFlags servicePermissionFlags(const RsPeerId & ssl_id); virtual ServicePermissionFlags servicePermissionFlags(const RsPeerId & ssl_id);
virtual void setServicePermissionFlags(const RsPgpId& gpg_id,const ServicePermissionFlags& flags); virtual void setServicePermissionFlags(const RsPgpId& gpg_id,const ServicePermissionFlags& flags);
virtual bool setPeerMaximumRates(const RsPgpId& pid,uint32_t maxUploadRate,uint32_t maxDownloadRate);
virtual bool getPeerMaximumRates(const RsPgpId& pid,uint32_t& maxUploadRate,uint32_t& maxDownloadRate);
virtual bool getPeerMaximumRates(const RsPeerId& pid,uint32_t& maxUploadRate,uint32_t& maxDownloadRate);
private: private:
p3LinkMgr *mLinkMgr; p3LinkMgr *mLinkMgr;

View File

@ -503,7 +503,6 @@ bool p3ServerConfig::switchToOperatingMode(uint32_t opMode)
return true; return true;
} }
/* handle data rates. /* handle data rates.
* Mutex must be handled at the lower levels: TODO */ * Mutex must be handled at the lower levels: TODO */

View File

@ -684,6 +684,7 @@ uint32_t RsPeerConfigSerialiser::size(RsItem *i)
RsPeerNetItem *pni; RsPeerNetItem *pni;
RsPeerGroupItem *pgi; RsPeerGroupItem *pgi;
RsPeerServicePermissionItem *pri; RsPeerServicePermissionItem *pri;
RsPeerBandwidthLimitsItem *pblitem;
if (NULL != (pni = dynamic_cast<RsPeerNetItem *>(i))) if (NULL != (pni = dynamic_cast<RsPeerNetItem *>(i)))
{ {
@ -701,6 +702,10 @@ uint32_t RsPeerConfigSerialiser::size(RsItem *i)
{ {
return sizePermissions(pri); return sizePermissions(pri);
} }
else if (NULL != (pblitem = dynamic_cast<RsPeerBandwidthLimitsItem *>(i)))
{
return sizePeerBandwidthLimits(pblitem);
}
return 0; return 0;
} }
@ -712,6 +717,7 @@ bool RsPeerConfigSerialiser::serialise(RsItem *i, void *data, uint32_t *pktsi
RsPeerStunItem *psi; RsPeerStunItem *psi;
RsPeerGroupItem *pgi; RsPeerGroupItem *pgi;
RsPeerServicePermissionItem *pri; RsPeerServicePermissionItem *pri;
RsPeerBandwidthLimitsItem *pblitem;
if (NULL != (pni = dynamic_cast<RsPeerNetItem *>(i))) if (NULL != (pni = dynamic_cast<RsPeerNetItem *>(i)))
{ {
@ -729,6 +735,10 @@ bool RsPeerConfigSerialiser::serialise(RsItem *i, void *data, uint32_t *pktsi
{ {
return serialisePermissions(pri, data, pktsize); return serialisePermissions(pri, data, pktsize);
} }
else if (NULL != (pblitem = dynamic_cast<RsPeerBandwidthLimitsItem *>(i)))
{
return serialisePeerBandwidthLimits(pblitem, data, pktsize);
}
return false; return false;
} }
@ -758,6 +768,8 @@ RsItem *RsPeerConfigSerialiser::deserialise(void *data, uint32_t *pktsize)
return deserialiseGroup(data, pktsize); return deserialiseGroup(data, pktsize);
case RS_PKT_SUBTYPE_PEER_PERMISSIONS: case RS_PKT_SUBTYPE_PEER_PERMISSIONS:
return deserialisePermissions(data, pktsize); return deserialisePermissions(data, pktsize);
case RS_PKT_SUBTYPE_PEER_BANDLIMITS:
return deserialisePeerBandwidthLimits(data, pktsize);
default: default:
return NULL; return NULL;
} }
@ -880,7 +892,6 @@ uint32_t RsPeerConfigSerialiser::sizeNet(RsPeerNetItem *i)
s += 2; /* domain_port */ s += 2; /* domain_port */
return s; return s;
} }
bool RsPeerConfigSerialiser::serialiseNet(RsPeerNetItem *item, void *data, uint32_t *size) bool RsPeerConfigSerialiser::serialiseNet(RsPeerNetItem *item, void *data, uint32_t *size)
@ -1028,6 +1039,160 @@ RsPeerNetItem *RsPeerConfigSerialiser::deserialiseNet(void *data, uint32_t *size
return item; return item;
} }
/****************************************************************************/
uint32_t RsPeerConfigSerialiser::sizePeerBandwidthLimits(RsPeerBandwidthLimitsItem *i)
{
uint32_t s = 8; /* header */
s += 4; // number of elements
s += i->peers.size() * (4 + 4 + RsPgpId::SIZE_IN_BYTES) ;
return s;
}
bool RsPeerConfigSerialiser::serialisePeerBandwidthLimits(RsPeerBandwidthLimitsItem *item, void *data, uint32_t *size)
{
uint32_t tlvsize = RsPeerConfigSerialiser::sizePeerBandwidthLimits(item);
uint32_t offset = 0;
#ifdef RSSERIAL_DEBUG
std::cerr << "RsPeerConfigSerialiser::serialiseNet() tlvsize: " << tlvsize << std::endl;
#endif
if(*size < tlvsize)
{
#ifdef RSSERIAL_ERROR_DEBUG
std::cerr << "RsPeerConfigSerialiser::serialiseNet() ERROR not enough space" << std::endl;
#endif
return false; /* not enough space */
}
*size = tlvsize;
bool ok = true;
// serialise header
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
#ifdef RSSERIAL_DEBUG
std::cerr << "RsPeerConfigSerialiser::serialiseNet() Header: " << ok << std::endl;
std::cerr << "RsPeerConfigSerialiser::serialiseNet() Header test: " << tlvsize << std::endl;
#endif
/* skip the header */
offset += 8;
ok &= setRawUInt32(data, tlvsize, &offset, item->peers.size()); /* Mandatory */
for(std::map<RsPgpId,PeerBandwidthLimits>::const_iterator it(item->peers.begin());it!=item->peers.end();++it)
{
ok &= it->first.serialise(data,tlvsize,offset);
ok &= setRawUInt32(data, tlvsize, &offset, it->second.max_up_rate_kbs); /* Mandatory */
ok &= setRawUInt32(data, tlvsize, &offset, it->second.max_dl_rate_kbs); /* Mandatory */
}
if(offset != tlvsize)
{
#ifdef RSSERIAL_ERROR_DEBUG
std::cerr << "RsPeerConfigSerialiser::serialiseNet() Size Error! " << std::endl;
#endif
ok = false;
}
return ok;
}
RsPeerBandwidthLimitsItem *RsPeerConfigSerialiser::deserialisePeerBandwidthLimits(void *data, uint32_t *size)
{
/* get the type and size */
uint32_t rstype = getRsItemId(data);
uint32_t rssize = getRsItemSize(data);
uint32_t offset = 0;
#ifdef RSSERIAL_DEBUG
std::cerr << "RsPeerConfigSerialiser::deserialiseNet() rssize: " << rssize << std::endl;
#endif
if ((RS_PKT_VERSION1 != getRsItemVersion(rstype)) ||
(RS_PKT_CLASS_CONFIG != getRsItemClass(rstype)) ||
(RS_PKT_TYPE_PEER_CONFIG != getRsItemType(rstype)) ||
(RS_PKT_SUBTYPE_PEER_BANDLIMITS != getRsItemSubType(rstype)))
{
#ifdef RSSERIAL_ERROR_DEBUG
std::cerr << "RsPeerConfigSerialiser::deserialiseNet() ERROR Type" << std::endl;
#endif
return NULL; /* wrong type */
}
if (*size < rssize) /* check size */
{
#ifdef RSSERIAL_ERROR_DEBUG
std::cerr << "RsPeerConfigSerialiser::deserialiseNet() ERROR not enough data" << std::endl;
#endif
return NULL; /* not enough data */
}
/* set the packet length */
*size = rssize;
bool ok = true;
RsPeerBandwidthLimitsItem *item = new RsPeerBandwidthLimitsItem();
/* skip the header */
offset += 8;
/* get mandatory parts first */
uint32_t n ;
ok &= getRawUInt32(data, rssize, &offset, &n) ;
for(uint32_t i=0;i<n;++i)
{
RsPgpId pgpid ;
ok &= pgpid.deserialise(data,rssize,offset) ;
PeerBandwidthLimits p ;
ok &= getRawUInt32(data, rssize, &offset, &(p.max_up_rate_kbs)); /* Mandatory */
ok &= getRawUInt32(data, rssize, &offset, &(p.max_dl_rate_kbs)); /* Mandatory */
item->peers[pgpid] = p ;
}
if (offset != rssize)
{
#ifdef RSSERIAL_ERROR_DEBUG
std::cerr << "RsPeerConfigSerialiser::deserialiseNet() ERROR size mismatch" << std::endl;
#endif
/* error */
delete item;
return NULL;
}
return item;
}
std::ostream &RsPeerBandwidthLimitsItem::print(std::ostream &out, uint16_t indent)
{
printRsItemBase(out, "RsPeerBandwidthLimitsItem", indent);
uint16_t int_Indent = indent + 2;
for(std::map<RsPgpId,PeerBandwidthLimits>::const_iterator it(peers.begin());it!=peers.end();++it)
{
printIndent(out, int_Indent);
out << it->first << " : " << it->second.max_up_rate_kbs << " (up) " << it->second.max_dl_rate_kbs << " (dn)" << std::endl;
}
printRsItemEnd(out, "RsPeerStunItem", indent);
return out;
}
/****************************************************************************/ /****************************************************************************/
RsPeerStunItem::~RsPeerStunItem() RsPeerStunItem::~RsPeerStunItem()

View File

@ -54,6 +54,7 @@ const uint8_t RS_PKT_SUBTYPE_PEER_STUN = 0x02;
const uint8_t RS_PKT_SUBTYPE_PEER_NET = 0x03; const uint8_t RS_PKT_SUBTYPE_PEER_NET = 0x03;
const uint8_t RS_PKT_SUBTYPE_PEER_GROUP = 0x04; const uint8_t RS_PKT_SUBTYPE_PEER_GROUP = 0x04;
const uint8_t RS_PKT_SUBTYPE_PEER_PERMISSIONS = 0x05; const uint8_t RS_PKT_SUBTYPE_PEER_PERMISSIONS = 0x05;
const uint8_t RS_PKT_SUBTYPE_PEER_BANDLIMITS = 0x06;
/* FILE CONFIG SUBTYPES */ /* FILE CONFIG SUBTYPES */
const uint8_t RS_PKT_SUBTYPE_FILE_TRANSFER = 0x01; const uint8_t RS_PKT_SUBTYPE_FILE_TRANSFER = 0x01;
@ -61,6 +62,8 @@ const uint8_t RS_PKT_SUBTYPE_FILE_ITEM = 0x02;
/**************************************************************************/ /**************************************************************************/
// We should make these items use a clean serialise code, and all derive from the same item type.
class RsPeerNetItem: public RsItem class RsPeerNetItem: public RsItem
{ {
public: public:
@ -97,6 +100,7 @@ std::ostream &print(std::ostream &out, uint16_t indent = 0);
uint16_t domain_port; uint16_t domain_port;
}; };
// This item should be merged with the next item, but that is not backward compatible.
class RsPeerServicePermissionItem : public RsItem class RsPeerServicePermissionItem : public RsItem
{ {
public: public:
@ -114,7 +118,21 @@ class RsPeerServicePermissionItem : public RsItem
std::vector<RsPgpId> pgp_ids ; std::vector<RsPgpId> pgp_ids ;
std::vector<ServicePermissionFlags> service_flags ; std::vector<ServicePermissionFlags> service_flags ;
}; };
class RsPeerBandwidthLimitsItem : public RsItem
{
public:
RsPeerBandwidthLimitsItem() : RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_CONFIG, RS_PKT_TYPE_PEER_CONFIG, RS_PKT_SUBTYPE_PEER_BANDLIMITS) {}
virtual ~RsPeerBandwidthLimitsItem() {}
virtual void clear()
{
peers.clear() ;
}
std::ostream &print(std::ostream &out, uint16_t indent = 0);
/* Mandatory */
std::map<RsPgpId,PeerBandwidthLimits> peers ;
};
class RsPeerGroupItem : public RsItem class RsPeerGroupItem : public RsItem
{ {
@ -183,6 +201,10 @@ virtual uint32_t sizeGroup(RsPeerGroupItem *);
virtual bool serialiseGroup (RsPeerGroupItem *item, void *data, uint32_t *size); virtual bool serialiseGroup (RsPeerGroupItem *item, void *data, uint32_t *size);
virtual RsPeerGroupItem * deserialiseGroup(void *data, uint32_t *size); virtual RsPeerGroupItem * deserialiseGroup(void *data, uint32_t *size);
virtual uint32_t sizePeerBandwidthLimits(RsPeerBandwidthLimitsItem *);
virtual bool serialisePeerBandwidthLimits (RsPeerBandwidthLimitsItem *item, void *data, uint32_t *size);
virtual RsPeerBandwidthLimitsItem *deserialisePeerBandwidthLimits(void *data, uint32_t *size);
virtual uint32_t sizePermissions(RsPeerServicePermissionItem *); virtual uint32_t sizePermissions(RsPeerServicePermissionItem *);
virtual bool serialisePermissions (RsPeerServicePermissionItem *item, void *data, uint32_t *size); virtual bool serialisePermissions (RsPeerServicePermissionItem *item, void *data, uint32_t *size);
virtual RsPeerServicePermissionItem * deserialisePermissions(void *data, uint32_t *size); virtual RsPeerServicePermissionItem * deserialisePermissions(void *data, uint32_t *size);

View File

@ -13,8 +13,10 @@ const uint8_t RsNxsSyncGrpItem::FLAG_RESPONSE = 0x002;
const uint8_t RsNxsSyncMsgItem::FLAG_REQUEST = 0x001; const uint8_t RsNxsSyncMsgItem::FLAG_REQUEST = 0x001;
const uint8_t RsNxsSyncMsgItem::FLAG_RESPONSE = 0x002; const uint8_t RsNxsSyncMsgItem::FLAG_RESPONSE = 0x002;
const uint8_t RsNxsSyncGrpItem::FLAG_USE_SYNC_HASH = 0x001; const uint8_t RsNxsSyncGrpItem::FLAG_USE_SYNC_HASH = 0x0001;
const uint8_t RsNxsSyncMsgItem::FLAG_USE_SYNC_HASH = 0x001; const uint8_t RsNxsSyncMsgItem::FLAG_USE_SYNC_HASH = 0x0001;
const uint8_t RsNxsSyncMsgReqItem::FLAG_USE_HASHED_GROUP_ID = 0x02;
/** transaction state **/ /** transaction state **/
const uint16_t RsNxsTransacItem::FLAG_BEGIN_P1 = 0x0001; const uint16_t RsNxsTransacItem::FLAG_BEGIN_P1 = 0x0001;

View File

@ -351,12 +351,12 @@ public:
#ifdef UNUSED_CODE #ifdef UNUSED_CODE
static const uint8_t FLAG_USE_SYNC_HASH; static const uint8_t FLAG_USE_SYNC_HASH;
#endif #endif
static const uint8_t FLAG_USE_HASHED_GROUP_ID;
RsNxsSyncMsgReqItem(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_SYNC_MSG_REQ_ITEM) { clear(); return; } RsNxsSyncMsgReqItem(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_SYNC_MSG_REQ_ITEM) { clear(); return; }
virtual bool serialise(void *data,uint32_t& size) const; virtual bool serialise(void *data,uint32_t& size) const;
virtual uint32_t serial_size() const; virtual uint32_t serial_size() const;
virtual void clear(); virtual void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent); virtual std::ostream &print(std::ostream &out, uint16_t indent);

View File

@ -283,6 +283,7 @@ bool p3GxsCircles:: getCircleDetails(const RsGxsCircleId &id, RsGxsCircleDetails
details.mCircleName = data.mCircleName; details.mCircleName = data.mCircleName;
details.mCircleType = data.mCircleType; details.mCircleType = data.mCircleType;
details.mRestrictedCircleId = data.mRestrictedCircleId;
details.mAllowedNodes = data.mAllowedNodes; details.mAllowedNodes = data.mAllowedNodes;
details.mSubscriptionFlags.clear(); details.mSubscriptionFlags.clear();
@ -588,6 +589,7 @@ bool RsGxsCircleCache::loadBaseCircle(const RsGxsCircleGroup &circle)
mOriginator = circle.mMeta.mOriginator ; mOriginator = circle.mMeta.mOriginator ;
mAllowedNodes = circle.mLocalFriends ; mAllowedNodes = circle.mLocalFriends ;
mRestrictedCircleId = circle.mMeta.mCircleId ;
mMembershipStatus.clear() ; mMembershipStatus.clear() ;

View File

@ -152,6 +152,7 @@ class RsGxsCircleCache
uint32_t mCircleType; uint32_t mCircleType;
bool mIsExternal; bool mIsExternal;
RsGxsCircleId mRestrictedCircleId ; // circle ID that circle is restricted to.
uint32_t mGroupStatus; uint32_t mGroupStatus;
uint32_t mGroupSubscribeFlags; uint32_t mGroupSubscribeFlags;

View File

@ -58,9 +58,14 @@
#define GXSID_MAX_CACHE_SIZE 5000 #define GXSID_MAX_CACHE_SIZE 5000
static const uint32_t MAX_KEEP_UNUSED_KEYS = 30*86400 ; // remove unused keys after 30 days // unused keys are deleted according to some heuristic that should favor known keys, signed keys etc.
static const uint32_t MAX_KEEP_BANNED_KEYS = 30*86400 ; // remove banned keys after 5 days
static const uint32_t MAX_DELAY_BEFORE_CLEANING = 601 ; // clean old keys every 10 mins static const time_t MAX_KEEP_KEYS_BANNED = 2 * 86400 ; // get rid of banned ids after 2 days. That gives a chance to un-ban someone before he gets kicked out
static const time_t MAX_KEEP_KEYS_DEFAULT = 5 * 86400 ; // default for unsigned identities: 5 days
static const time_t MAX_KEEP_KEYS_SIGNED = 8 * 86400 ; // signed identities by unknown key
static const time_t MAX_KEEP_KEYS_SIGNED_KNOWN = 30 * 86400 ; // signed identities by known node keys
static const uint32_t MAX_DELAY_BEFORE_CLEANING= 1800 ; // clean old keys every 30 mins
RsIdentity *rsIdentity = NULL; RsIdentity *rsIdentity = NULL;
@ -153,7 +158,7 @@ p3IdService::p3IdService(RsGeneralDataService *gds, RsNetworkExchangeService *ne
{ {
mBgSchedule_Mode = 0; mBgSchedule_Mode = 0;
mBgSchedule_Active = false; mBgSchedule_Active = false;
mLastKeyCleaningTime = 0 ; mLastKeyCleaningTime = time(NULL) - int(MAX_DELAY_BEFORE_CLEANING * 0.9) ;
mLastConfigUpdate = 0 ; mLastConfigUpdate = 0 ;
mOwnIdsLoaded = false ; mOwnIdsLoaded = false ;
@ -262,11 +267,16 @@ time_t p3IdService::locked_getLastUsageTS(const RsGxsId& gxs_id)
} }
void p3IdService::timeStampKey(const RsGxsId& gxs_id) void p3IdService::timeStampKey(const RsGxsId& gxs_id)
{ {
RS_STACK_MUTEX(mIdMtx) ; if(rsReputations->isIdentityBanned(gxs_id))
{
std::cerr << "(II) p3IdService:timeStampKey(): refusing to time stamp key " << gxs_id << " because it is banned." << std::endl;
return;
}
RS_STACK_MUTEX(mIdMtx) ;
mKeysTS[gxs_id] = time(NULL) ; mKeysTS[gxs_id] = time(NULL) ;
slowIndicateConfigChanged() ; slowIndicateConfigChanged() ;
} }
bool p3IdService::loadList(std::list<RsItem*>& items) bool p3IdService::loadList(std::list<RsItem*>& items)
@ -306,49 +316,114 @@ bool p3IdService::saveList(bool& cleanup,std::list<RsItem*>& items)
items.push_back(item) ; items.push_back(item) ;
return true ; return true ;
} }
class IdCacheEntryCleaner
{
public:
IdCacheEntryCleaner(const std::map<RsGxsId,time_t>& last_usage_TSs) : mLastUsageTS(last_usage_TSs) {}
bool processEntry(RsGxsIdCache& entry)
{
time_t now = time(NULL);
const RsGxsId& gxs_id = entry.details.mId ;
bool is_id_banned = rsReputations->isIdentityBanned(gxs_id) ;
bool is_own_id = (bool)(entry.details.mFlags & RS_IDENTITY_FLAGS_IS_OWN_ID) ;
bool is_known_id = (bool)(entry.details.mFlags & RS_IDENTITY_FLAGS_PGP_KNOWN) ;
bool is_signed_id = (bool)(entry.details.mFlags & RS_IDENTITY_FLAGS_PGP_LINKED) ;
bool is_a_contact = (bool)(entry.details.mFlags & RS_IDENTITY_FLAGS_IS_A_CONTACT) ;
std::cerr << "Identity: " << gxs_id << ": banned: " << is_id_banned << ", own: " << is_own_id << ", contact: " << is_a_contact << ", signed: " << is_signed_id << ", known: " << is_known_id;
if(is_own_id || is_a_contact)
{
std::cerr << " => kept" << std::endl;
return true ;
}
std::map<RsGxsId,time_t>::const_iterator it = mLastUsageTS.find(gxs_id) ;
if(it == mLastUsageTS.end())
{
std::cerr << "No Ts for this ID" << std::endl;
return true ;
}
time_t last_usage_ts = it->second;
time_t max_keep_time ;
if(is_id_banned)
max_keep_time = MAX_KEEP_KEYS_BANNED ;
else if(is_known_id)
max_keep_time = MAX_KEEP_KEYS_SIGNED_KNOWN ;
else if(is_signed_id)
max_keep_time = MAX_KEEP_KEYS_SIGNED ;
else
max_keep_time = MAX_KEEP_KEYS_DEFAULT ;
std::cerr << ". Max keep = " << max_keep_time/86400 << " days. Unused for " << (now - last_usage_ts + 86399)/86400 << " days " ;
if(now > last_usage_ts + max_keep_time)
{
std::cerr << " => delete " << std::endl;
ids_to_delete.push_back(gxs_id) ;
}
else
std::cerr << " => keep " << std::endl;
return true;
}
std::list<RsGxsId> ids_to_delete ;
const std::map<RsGxsId,time_t>& mLastUsageTS;
};
void p3IdService::cleanUnusedKeys() void p3IdService::cleanUnusedKeys()
{ {
std::list<RsGxsId> ids_to_delete ; std::list<RsGxsId> ids_to_delete ;
// we need to stash all ids to delete into an off-mutex structure since deleteIdentity() will trigger the lock std::cerr << "Cleaning unused keys:" << std::endl;
{
RS_STACK_MUTEX(mIdMtx) ;
if(!mOwnIdsLoaded) // we need to stash all ids to delete into an off-mutex structure since deleteIdentity() will trigger the lock
{ {
std::cerr << "(EE) Own ids not loaded. Cannot clean unused keys." << std::endl; RS_STACK_MUTEX(mIdMtx) ;
return ;
}
// grab at most 10 identities to delete. No need to send too many requests to the token queue at once. if(!mOwnIdsLoaded)
time_t now = time(NULL) ; {
int n=0 ; std::cerr << "(EE) Own ids not loaded. Cannot clean unused keys." << std::endl;
return ;
}
for(std::map<RsGxsId,time_t>::iterator it(mKeysTS.begin());it!=mKeysTS.end() && n < 10;++it) // grab at most 10 identities to delete. No need to send too many requests to the token queue at once.
{
if(it->second + MAX_KEEP_UNUSED_KEYS < now && std::find(mOwnIds.begin(),mOwnIds.end(),it->first) == mOwnIds.end())
ids_to_delete.push_back(it->first),++n ;
else if(it->second + MAX_KEEP_BANNED_KEYS < now && rsReputations->isIdentityBanned(it->first))
ids_to_delete.push_back(it->first),++n ;
}
}
for(std::list<RsGxsId>::const_iterator it(ids_to_delete.begin());it!=ids_to_delete.end();++it) time_t now = time(NULL) ;
{ int n=0 ;
std::cerr << "Deleting identity " << *it << " which is too old." << std::endl; IdCacheEntryCleaner idcec(mKeysTS) ;
uint32_t token ;
RsGxsIdGroup group;
group.mMeta.mGroupId=RsGxsGroupId(*it);
rsIdentity->deleteIdentity(token, group);
{ mKeyCache.applyToAllCachedEntries(idcec,&IdCacheEntryCleaner::processEntry);
RS_STACK_MUTEX(mIdMtx) ;
std::map<RsGxsId,time_t>::iterator tmp = mKeysTS.find(*it) ;
if(mKeysTS.end() != tmp) ids_to_delete = idcec.ids_to_delete ;
mKeysTS.erase(tmp) ; }
} std::cerr << "Collected " << ids_to_delete.size() << " keys to delete among " << mKeyCache.size() << std::endl;
}
for(std::list<RsGxsId>::const_iterator it(ids_to_delete.begin());it!=ids_to_delete.end();++it)
{
std::cerr << "Deleting identity " << *it << " which is too old." << std::endl;
uint32_t token ;
RsGxsIdGroup group;
group.mMeta.mGroupId=RsGxsGroupId(*it);
rsIdentity->deleteIdentity(token, group);
{
RS_STACK_MUTEX(mIdMtx) ;
std::map<RsGxsId,time_t>::iterator tmp = mKeysTS.find(*it) ;
if(mKeysTS.end() != tmp)
mKeysTS.erase(tmp) ;
// mPublicKeyCache.erase(*it) ; no need to do it now. It's done in p3IdService::deleteGroup()
}
}
} }
void p3IdService::service_tick() void p3IdService::service_tick()
@ -454,9 +529,6 @@ bool p3IdService:: getIdDetails(const RsGxsId &id, RsIdentityDetails &details)
details = data.details; details = data.details;
details.mLastUsageTS = locked_getLastUsageTS(id) ; details.mLastUsageTS = locked_getLastUsageTS(id) ;
if(mContacts.find(id) != mContacts.end())
details.mFlags |= RS_IDENTITY_FLAGS_IS_A_CONTACT ;
// one utf8 symbol can be at most 4 bytes long - would be better to measure real unicode length !!! // one utf8 symbol can be at most 4 bytes long - would be better to measure real unicode length !!!
if(details.mNickname.length() > RSID_MAXIMUM_NICKNAME_SIZE*4) if(details.mNickname.length() > RSID_MAXIMUM_NICKNAME_SIZE*4)
details.mNickname = "[too long a name]" ; details.mNickname = "[too long a name]" ;
@ -1914,6 +1986,9 @@ bool p3IdService::cache_store(const RsGxsIdGroupItem *item)
// Create Cache Data. // Create Cache Data.
RsGxsIdCache keycache(item, pubkey, fullkey,tagList); RsGxsIdCache keycache(item, pubkey, fullkey,tagList);
if(mContacts.find(id) != mContacts.end())
keycache.details.mFlags |= RS_IDENTITY_FLAGS_IS_A_CONTACT;
mKeyCache.store(id, keycache); mKeyCache.store(id, keycache);
mKeyCache.resize(); mKeyCache.resize();

View File

@ -381,14 +381,14 @@ bool upnphandler::start_upnp()
if (!SetRedirectAndTest(&(config -> urls), &(config->data), if (!SetRedirectAndTest(&(config -> urls), &(config->data),
in_addr, in_port1, eport1, eprot1, in_addr, in_port1, eport1, eprot1,
NULL /*leaseDuration*/, NULL /*description*/, NULL /*leaseDuration*/, "RetroShare_TCP" /*description*/,
0)) 0))
{ {
upnpState = RS_UPNP_S_TCP_FAILED; upnpState = RS_UPNP_S_TCP_FAILED;
} }
else if (!SetRedirectAndTest(&(config -> urls), &(config->data), else if (!SetRedirectAndTest(&(config -> urls), &(config->data),
in_addr, in_port2, eport2, eprot2, in_addr, in_port2, eport2, eprot2,
NULL /*leaseDuration*/, NULL /*description*/, NULL /*leaseDuration*/, "RetroShare_UDP" /*description*/,
0)) 0))
{ {
upnpState = RS_UPNP_S_UDP_FAILED; upnpState = RS_UPNP_S_UDP_FAILED;

View File

@ -298,7 +298,7 @@ int SetRedirectAndTest(struct UPNPUrls * urls,
// const char * remoteHost, // const char * remoteHost,
// const char * leaseDuration); // const char * leaseDuration);
r = UPNP_AddPortMapping(urls->controlURL, servicetype, r = UPNP_AddPortMapping(urls->controlURL, servicetype,
eport, iport, iaddr, NULL, proto, NULL, NULL); eport, iport, iaddr, description, proto, NULL, NULL);
#else #else
#if MINIUPNPC_API_VERSION >= -3 //1.0 2009/04/17 #if MINIUPNPC_API_VERSION >= -3 //1.0 2009/04/17
/* $Id: upnpcommands.h,v 1.18 2010/06/09 10:59:09 nanard Exp $ */ /* $Id: upnpcommands.h,v 1.18 2010/06/09 10:59:09 nanard Exp $ */
@ -311,7 +311,7 @@ int SetRedirectAndTest(struct UPNPUrls * urls,
// const char * proto, // const char * proto,
// const char * remoteHost); // const char * remoteHost);
r = UPNP_AddPortMapping(urls->controlURL, servicetype, r = UPNP_AddPortMapping(urls->controlURL, servicetype,
eport, iport, iaddr, NULL, proto, NULL); eport, iport, iaddr, description, proto, NULL);
#else #else
#if MINIUPNPC_API_VERSION >= -7//Before 1.0 #if MINIUPNPC_API_VERSION >= -7//Before 1.0
/* $Id: upnpcommands.h,v 1.14 2008/09/25 18:02:50 nanard Exp $ */ /* $Id: upnpcommands.h,v 1.14 2008/09/25 18:02:50 nanard Exp $ */
@ -323,7 +323,7 @@ int SetRedirectAndTest(struct UPNPUrls * urls,
// const char * desc, // const char * desc,
// const char * proto); // const char * proto);
r = UPNP_AddPortMapping(urls->controlURL, servicetype, r = UPNP_AddPortMapping(urls->controlURL, servicetype,
eport, iport, iaddr, NULL, proto); eport, iport, iaddr, description, proto);
#else #else
#error MINIUPNPC_API_VERSION is not defined. You may define one follow miniupnpc library version #error MINIUPNPC_API_VERSION is not defined. You may define one follow miniupnpc library version
#endif//>=-7 #endif//>=-7

View File

@ -73,6 +73,7 @@ public:
template<class ClientClass> bool applyToAllCachedEntries(ClientClass& c,bool (ClientClass::*method)(Value&)); template<class ClientClass> bool applyToAllCachedEntries(ClientClass& c,bool (ClientClass::*method)(Value&));
uint32_t size() const { return mDataMap.size() ; }
private: private:
bool update_lrumap(const Key &key, time_t old_ts, time_t new_ts); bool update_lrumap(const Key &key, time_t old_ts, time_t new_ts);

View File

@ -279,11 +279,22 @@ void *SmallObject::operator new(size_t size)
#endif #endif
RsStackMutex m(_mtx) ; RsStackMutex m(_mtx) ;
void *p = _allocator.allocate(size) ;
// This should normally not happen. But that prevents a crash when quitting, since we cannot prevent the constructor
// of an object to call operator new(), nor to handle the case where it returns NULL.
// The memory will therefore not be deleted if that happens. We thus print a warning.
if(_allocator._active)
return _allocator.allocate(size) ;
else
{
std::cerr << "(EE) allocating " << size << " bytes of memory that cannot be deleted. This is a bug, except if it happens when closing Retroshare" << std::endl;
return malloc(size) ;
}
#ifdef DEBUG_MEMORY #ifdef DEBUG_MEMORY
std::cerr << "new RsItem: " << p << ", size=" << size << std::endl; std::cerr << "new RsItem: " << p << ", size=" << size << std::endl;
#endif #endif
return p ;
} }
void SmallObject::operator delete(void *p,size_t size) void SmallObject::operator delete(void *p,size_t size)

View File

@ -3,6 +3,12 @@
#don't exit even if a command fails #don't exit even if a command fails
set +e set +e
SCRIPT_PATH=$(dirname "`readlink -f "${0}"`")
OLDLANG=${LANG}
export LANG=C
if ( git log -n 1 &> /dev/null); then if ( git log -n 1 &> /dev/null); then
#retrieve git information #retrieve git information
version="$(git log --pretty=format:"%H" | head -1 | cut -c1-8)" version="$(git log --pretty=format:"%H" | head -1 | cut -c1-8)"
@ -22,7 +28,9 @@ fi
if [[ ${version} != '' ]]; then if [[ ${version} != '' ]]; then
echo "Writing version to retroshare/rsversion.h : ${version}" echo "Writing version to retroshare/rsversion.h : ${version}"
sed -e "s%RS_REVISION_NUMBER.*%RS_REVISION_NUMBER 0x${version}%" retroshare/rsversion.in >retroshare/rsversion.h sed -e "s%RS_REVISION_NUMBER.*%RS_REVISION_NUMBER 0x${version}%" ${SCRIPT_PATH}/retroshare/rsversion.in >${SCRIPT_PATH}/retroshare/rsversion.h
fi fi
export LANG=${OLDLANG}
echo "script version_detail.sh finished normally" echo "script version_detail.sh finished normally"
exit 0 exit 0

View File

@ -1,41 +1,28 @@
TCL_VERSION=8.6.2 SQLCIPHER_VERSION=3.3.1
SQLCIPHER_VERSION=2.2.1 MSYS2AUTOMAKE=/c/msys64/usr/share/automake-1.15
all: dirs sqlcipher copylibs BLD=../build-libs
DLD=../downloads
all: dirs sqlcipher
dirs: dirs:
mkdir -p libs/include mkdir -p ../../libs/include
mkdir -p libs/lib mkdir -p ../../libs/lib
mkdir -p libs/bin mkdir -p ../../libs/bin
mkdir -p $(DLD)
mkdir -p $(BLD)
tcl$(TCL_VERSION)-src.tar.gz: sqlcipher: | ../../libs/lib/libsqlcipher.a
curl.exe -L http://prdownloads.sourceforge.net/tcl/tcl$(TCL_VERSION)-src.tar.gz -o tcl$(TCL_VERSION)-src.tar.gz
sqlcipher-$(SQLCIPHER_VERSION).tar.gz: $(DLD)/sqlcipher-$(SQLCIPHER_VERSION).tar.gz:
curl.exe -L -k https://github.com/sqlcipher/sqlcipher/archive/v$(SQLCIPHER_VERSION).tar.gz -o sqlcipher-$(SQLCIPHER_VERSION).tar.gz curl.exe -L -k https://github.com/sqlcipher/sqlcipher/archive/v$(SQLCIPHER_VERSION).tar.gz -o $(DLD)/sqlcipher-$(SQLCIPHER_VERSION).tar.gz
sqlcipher: tcl$(TCL_VERSION)-src.tar.gz sqlcipher-$(SQLCIPHER_VERSION).tar.gz
# tcl
tar xvf tcl$(TCL_VERSION)-src.tar.gz
mkdir -p tcl$(TCL_VERSION)/build
cd tcl$(TCL_VERSION)/build && ../win/configure
cd tcl$(TCL_VERSION)/build && make
#sqlcipher
tar xvf sqlcipher-$(SQLCIPHER_VERSION).tar.gz
cd sqlcipher-$(SQLCIPHER_VERSION) && ln -s ../tcl$(TCL_VERSION)/build/tclsh86.exe tclsh
mkdir -p tcl$(TCL_VERSION)/lib
ln -s `pwd`/tcl$(TCL_VERSION)/library `pwd`/tcl$(TCL_VERSION)/lib/tcl8.6
cd sqlcipher-$(SQLCIPHER_VERSION) && PATH=$$PATH:`pwd`/../tcl$(TCL_VERSION)/build && LIBS="-L`pwd`/../libs/lib -lgdi32 $$LIBS" && export LIBS && ./configure --disable-shared --enable-static --enable-tempstore=yes CFLAGS="-DSQLITE_HAS_CODEC -I`pwd`/../libs/include -I`pwd`/../tcl$(TCL_VERSION)/generic" LDFLAGS="-L`pwd`/../libs/lib -lcrypto -lgdi32" --with-tcl="`pwd`/../tcl$(TCL_VERSION)/build" && make install prefix="`pwd`/install"
cp -r sqlcipher-$(SQLCIPHER_VERSION)/install/include/* libs/include/
cp sqlcipher-$(SQLCIPHER_VERSION)/install/lib/libsqlcipher.a libs/lib/
cp sqlcipher-$(SQLCIPHER_VERSION)/install/bin/sqlcipher.exe libs/bin/
rm -r -f sqlcipher-$(SQLCIPHER_VERSION)
rm -r -f tcl$(TCL_VERSION)
touch sqlcipher
copylibs:
read -p "Do you want to copy libs to retroshare? (yes|no)" answer; \
if [ "$$answer" = "yes" ] ; then \
cp -r libs ../../ ; \
fi
../../libs/lib/libsqlcipher.a: $(DLD)/sqlcipher-$(SQLCIPHER_VERSION).tar.gz
tar xvf $(DLD)/sqlcipher-$(SQLCIPHER_VERSION).tar.gz -C $(BLD)
cp $(MSYS2AUTOMAKE)/config.guess $(BLD)/sqlcipher-$(SQLCIPHER_VERSION)/config.guess
cp $(MSYS2AUTOMAKE)/config.sub $(BLD)/sqlcipher-$(SQLCIPHER_VERSION)/config.sub
cd $(BLD)/sqlcipher-$(SQLCIPHER_VERSION) && LIBS="-L`pwd`/../../libs/lib -lgdi32 $$LIBS" && export LIBS && ./configure --disable-shared --enable-static --enable-tempstore=yes CFLAGS="-DSQLITE_HAS_CODEC -I`pwd`/../../libs/include" LDFLAGS="-L`pwd`/../../libs/lib -lcrypto -lgdi32" && make install prefix="`pwd`/install"
cp -r $(BLD)/sqlcipher-$(SQLCIPHER_VERSION)/install/include/* ../../libs/include/
cp $(BLD)/sqlcipher-$(SQLCIPHER_VERSION)/install/lib/libsqlcipher.a ../../libs/lib/
cp $(BLD)/sqlcipher-$(SQLCIPHER_VERSION)/install/bin/sqlcipher.exe ../../libs/bin/

View File

@ -72,7 +72,7 @@ ChatLobbyWidget::ChatLobbyWidget(QWidget *parent, Qt::WindowFlags flags)
QObject::connect( ui.filterLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(filterItems(QString))); QObject::connect( ui.filterLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(filterItems(QString)));
QObject::connect( ui.filterLineEdit, SIGNAL(filterChanged(int)), this, SLOT(filterColumnChanged(int))); QObject::connect( ui.filterLineEdit, SIGNAL(filterChanged(int)), this, SLOT(filterColumnChanged(int)));
QObject::connect( ui.createlobbytoolButton, SIGNAL(clicked()), this, SLOT(createChatLobby())); QObject::connect( ui.createLobbyToolButton, SIGNAL(clicked()), this, SLOT(createChatLobby()));
compareRole = new RSTreeWidgetItemCompareRole; compareRole = new RSTreeWidgetItemCompareRole;
compareRole->setRole(COLUMN_NAME, ROLE_SORT); compareRole->setRole(COLUMN_NAME, ROLE_SORT);

View File

@ -10,8 +10,17 @@
<height>517</height> <height>517</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_5"> <layout class="QVBoxLayout">
<property name="margin"> <property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
@ -28,8 +37,17 @@
<property name="frameShadow"> <property name="frameShadow">
<enum>QFrame::Sunken</enum> <enum>QFrame::Sunken</enum>
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="titleBarFrameLayout">
<property name="margin"> <property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number> <number>2</number>
</property> </property>
<item> <item>
@ -53,7 +71,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<spacer> <spacer name="titleBarVSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
@ -91,7 +109,7 @@
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<widget class="QWidget" name="layoutWidget"> <widget class="QWidget" name="layoutWidget">
<layout class="QVBoxLayout" name="verticalLayout_3"> <layout class="QVBoxLayout" name="lobbyTreeVLayout">
<item> <item>
<widget class="QFrame" name="toolBarFrame"> <widget class="QFrame" name="toolBarFrame">
<property name="styleSheet"> <property name="styleSheet">
@ -103,7 +121,7 @@
<property name="frameShadow"> <property name="frameShadow">
<enum>QFrame::Raised</enum> <enum>QFrame::Raised</enum>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="toolBarFrameGLayout">
<property name="leftMargin"> <property name="leftMargin">
<number>2</number> <number>2</number>
</property> </property>
@ -130,7 +148,7 @@
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="0" column="1">
<widget class="QToolButton" name="createlobbytoolButton"> <widget class="QToolButton" name="createLobbyToolButton">
<property name="toolTip"> <property name="toolTip">
<string>Create chat lobby</string> <string>Create chat lobby</string>
</property> </property>
@ -183,8 +201,17 @@
<number>0</number> <number>0</number>
</property> </property>
<widget class="QWidget" name="_lobby_blank_page"> <widget class="QWidget" name="_lobby_blank_page">
<layout class="QGridLayout" name="gridLayout_4"> <layout class="QGridLayout" name="_lobby_blank_pageGLayout">
<property name="margin"> <property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<property name="spacing"> <property name="spacing">
@ -195,13 +222,13 @@
<property name="title"> <property name="title">
<string>Selected lobby info</string> <string>Selected lobby info</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_4"> <layout class="QVBoxLayout" name="lobbyinfo_groupBoxVLayout">
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_2"> <layout class="QHBoxLayout" name="lobbyInfoHLayout">
<item> <item>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="lobbyInfoNameVLayout">
<item> <item>
<widget class="QLabel" name="label"> <widget class="QLabel" name="lobbyname_label">
<property name="font"> <property name="font">
<font> <font>
<weight>75</weight> <weight>75</weight>
@ -214,7 +241,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QLabel" name="label_2"> <widget class="QLabel" name="lobbyid_label">
<property name="font"> <property name="font">
<font> <font>
<weight>75</weight> <weight>75</weight>
@ -227,7 +254,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QLabel" name="label_3"> <widget class="QLabel" name="lobbytopic_label">
<property name="font"> <property name="font">
<font> <font>
<weight>75</weight> <weight>75</weight>
@ -240,7 +267,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QLabel" name="label_4"> <widget class="QLabel" name="lobbytype_label">
<property name="font"> <property name="font">
<font> <font>
<weight>75</weight> <weight>75</weight>
@ -253,7 +280,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QLabel" name="label_6"> <widget class="QLabel" name="lobbysec_label">
<property name="font"> <property name="font">
<font> <font>
<weight>75</weight> <weight>75</weight>
@ -266,7 +293,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QLabel" name="label_5"> <widget class="QLabel" name="lobbypeers_label">
<property name="font"> <property name="font">
<font> <font>
<weight>75</weight> <weight>75</weight>
@ -281,7 +308,7 @@
</layout> </layout>
</item> </item>
<item> <item>
<layout class="QVBoxLayout" name="verticalLayout_2"> <layout class="QVBoxLayout" name="lobbyInfoValueVLayout">
<item> <item>
<widget class="QLabel" name="lobbyname_lineEdit"> <widget class="QLabel" name="lobbyname_lineEdit">
<property name="sizePolicy"> <property name="sizePolicy">
@ -372,7 +399,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<spacer name="verticalSpacer"> <spacer name="lobbyInfoVSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>

View File

@ -138,6 +138,7 @@ void CreateCircleDialog::editExistingId(const RsGxsGroupId &circleId, const bool
else else
{ {
ui.circleAdminLabel->setVisible(false) ; ui.circleAdminLabel->setVisible(false) ;
ui.circleAdminLabel->hide();
ui.idChooser->setVisible(true) ; ui.idChooser->setVisible(true) ;
} }
@ -297,6 +298,8 @@ void CreateCircleDialog::addMember(const QString& keyId, const QString& idtype,
//member->setIcon(RSCIRCLEID_COL_NICKNAME, pixmap); //member->setIcon(RSCIRCLEID_COL_NICKNAME, pixmap);
tree->addTopLevelItem(member); tree->addTopLevelItem(member);
ui.members_groupBox->setTitle( tr("Invited Members") + " (" + QString::number(ui.treeWidget_membership->topLevelItemCount()) + ")" );
} }
/** Maybe we can use RsGxsCircleGroup instead of RsGxsCircleDetails ??? (TODO)**/ /** Maybe we can use RsGxsCircleGroup instead of RsGxsCircleDetails ??? (TODO)**/
@ -634,6 +637,7 @@ void CreateCircleDialog::updateCircleGUI()
//ui.idChooser->setIdConstraintSet(ids) ; //ui.idChooser->setIdConstraintSet(ids) ;
ui.idChooser->setFlags(IDCHOOSER_NO_CREATE) ; ui.idChooser->setFlags(IDCHOOSER_NO_CREATE) ;
ui.circleAdminLabel->setVisible(false) ; ui.circleAdminLabel->setVisible(false) ;
ui.circleAdminLabel->hide();
} }
} }

View File

@ -6,7 +6,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>924</width> <width>951</width>
<height>578</height> <height>578</height>
</rect> </rect>
</property> </property>
@ -51,7 +51,7 @@
<item row="1" column="0"> <item row="1" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2"> <layout class="QHBoxLayout" name="horizontalLayout_2">
<item> <item>
<widget class="QGroupBox" name="groupBox_2"> <widget class="QGroupBox" name="members_groupBox">
<property name="title"> <property name="title">
<string>Invited Members</string> <string>Invited Members</string>
</property> </property>
@ -61,6 +61,9 @@
<property name="contextMenuPolicy"> <property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum> <enum>Qt::CustomContextMenu</enum>
</property> </property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Members of this list will be automatically proposed to join the circle (by accepting membership). They will&lt;/p&gt;&lt;p&gt;not receive data that is restricted to this circle until they do so.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="sortingEnabled"> <property name="sortingEnabled">
<bool>true</bool> <bool>true</bool>
</property> </property>
@ -143,6 +146,31 @@
<string>Known People</string> <string>Known People</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="RSTreeWidget" name="treeWidget_IdList">
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<column>
<property name="text">
<string>Nickname</string>
</property>
</column>
<column>
<property name="text">
<string>ID</string>
</property>
</column>
<column>
<property name="text">
<string>Type</string>
</property>
</column>
</widget>
</item>
<item> <item>
<widget class="QFrame" name="frame_PgpTypes"> <widget class="QFrame" name="frame_PgpTypes">
<property name="frameShape"> <property name="frameShape">
@ -205,31 +233,6 @@
</item> </item>
</layout> </layout>
</item> </item>
<item>
<widget class="RSTreeWidget" name="treeWidget_IdList">
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<column>
<property name="text">
<string>Nickname</string>
</property>
</column>
<column>
<property name="text">
<string>ID</string>
</property>
</column>
<column>
<property name="text">
<string>Type</string>
</property>
</column>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>
@ -258,13 +261,23 @@
<bold>true</bold> <bold>true</bold>
</font> </font>
</property> </property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="text"> <property name="text">
<string>Name</string> <string>Name:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="1" colspan="3"> <item row="0" column="1" colspan="3">
<widget class="QLineEdit" name="circleName"/> <widget class="QLineEdit" name="circleName">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The circle name, contact author and invted member list will be visible to all invited members. If the circle is not private, it will also be visible to neighbor nodes of the nodes who host the invited members.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item> </item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="QLabel" name="idChooserLabel"> <widget class="QLabel" name="idChooserLabel">
@ -275,7 +288,7 @@
</font> </font>
</property> </property>
<property name="text"> <property name="text">
<string>Creator:</string> <string>Contact author:</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -288,7 +301,7 @@
</sizepolicy> </sizepolicy>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The creator of a circle does not need to be known. It is however useful for public circles so that people know to whom to send a request for membership.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The creator of a circle ia purely optional. It is however useful for public circles so that people know with whom to discuss membership aspects.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -324,7 +337,10 @@
</font> </font>
</property> </property>
<property name="text"> <property name="text">
<string>Distribution</string> <string>Distribution:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property> </property>
</widget> </widget>
</item> </item>
@ -362,10 +378,10 @@
<item row="0" column="1"> <item row="0" column="1">
<widget class="QRadioButton" name="radioButton_Self"> <widget class="QRadioButton" name="radioButton_Self">
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Self-restricted circles (the very existance of the circle, and its actual content) are only visible to the members of these circles. In practice the circle uses itself to limit its own distribution. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Private (a.k.a. self-restricted) circles are only visible to the invited members of these circles. In practice the circle uses its own list of invited members to limit its own distribution. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>Self-Restricted</string> <string>Private</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -375,7 +391,7 @@
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Circles can be restricted to the members of another circle. Only the members of that second circle will be allowed to see the new circle and its content (list of members, etc).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Circles can be restricted to the members of another circle. Only the members of that second circle will be allowed to see the new circle and its content (list of members, etc).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="text"> <property name="text">
<string>Restricted to:</string> <string>Only visible to members of:</string>
</property> </property>
</widget> </widget>
</item> </item>

View File

@ -71,8 +71,9 @@
#define RED_BACKGROUND 3 #define RED_BACKGROUND 3
#define GRAY_BACKGROUND 4 #define GRAY_BACKGROUND 4
#define CIRCLESDIALOG_GROUPMETA 1 #define CIRCLESDIALOG_GROUPMETA 1
#define CIRCLESDIALOG_GROUPDATA 2 #define CIRCLESDIALOG_GROUPDATA 2
#define CIRCLESDIALOG_GROUPUPDATE 3
/**************************************************************** /****************************************************************
*/ */
@ -98,6 +99,9 @@
#define IMAGE_CREATE ":/icons/circle_new_128.png" #define IMAGE_CREATE ":/icons/circle_new_128.png"
#define IMAGE_INVITED ":/icons/bullet_yellow_128.png" #define IMAGE_INVITED ":/icons/bullet_yellow_128.png"
#define IMAGE_MEMBER ":/icons/bullet_green_128.png" #define IMAGE_MEMBER ":/icons/bullet_green_128.png"
#define IMAGE_UNKNOWN ":/icons/bullet_grey_128.png"
#define IMAGE_ADMIN ":/icons/bullet_blue_128.png"
#define IMAGE_INFO ":/images/info16.png"
// comment this out in order to remove the sorting of circles into "belong to" and "other visible circles" // comment this out in order to remove the sorting of circles into "belong to" and "other visible circles"
#define CIRCLE_MEMBERSHIP_CATEGORIES 1 #define CIRCLE_MEMBERSHIP_CATEGORIES 1
@ -238,6 +242,7 @@ IdDialog::IdDialog(QWidget *parent) :
/* Set initial section sizes */ /* Set initial section sizes */
QHeaderView * circlesheader = ui->treeWidget_membership->header () ; QHeaderView * circlesheader = ui->treeWidget_membership->header () ;
circlesheader->resizeSection (CIRCLEGROUP_CIRCLE_COL_GROUPNAME, QFontMetricsF(ui->idTreeWidget->font()).width("Circle name")*1.5) ; circlesheader->resizeSection (CIRCLEGROUP_CIRCLE_COL_GROUPNAME, QFontMetricsF(ui->idTreeWidget->font()).width("Circle name")*1.5) ;
ui->treeWidget_membership->setColumnWidth(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, 270);
ui->filterLineEdit->addFilter(QIcon(), tr("ID"), RSID_COL_KEYID, tr("Search ID")); ui->filterLineEdit->addFilter(QIcon(), tr("ID"), RSID_COL_KEYID, tr("Search ID"));
@ -341,6 +346,8 @@ void IdDialog::requestCircleGroupMeta()
mCircleQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, CIRCLESDIALOG_GROUPMETA); mCircleQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, CIRCLESDIALOG_GROUPMETA);
} }
// should update this code to be called and modify the tree widget accordingly
#ifdef SUSPENDED
void IdDialog::requestCircleGroupData(const RsGxsCircleId& circle_id) void IdDialog::requestCircleGroupData(const RsGxsCircleId& circle_id)
{ {
mStateHelper->setLoading(CIRCLESDIALOG_GROUPDATA, true); mStateHelper->setLoading(CIRCLESDIALOG_GROUPDATA, true);
@ -355,12 +362,13 @@ void IdDialog::requestCircleGroupData(const RsGxsCircleId& circle_id)
RsTokReqOptions opts; RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
std::list<RsGxsGroupId> grps ; std::list<RsGxsGroupId> grps ;
grps.push_back(RsGxsGroupId(circle_id)); grps.push_back(RsGxsGroupId(circle_id));
uint32_t token; uint32_t token;
mCircleQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grps, CIRCLESDIALOG_GROUPDATA); mCircleQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grps, CIRCLESDIALOG_GROUPDATA);
} }
#endif
void IdDialog::loadCircleGroupMeta(const uint32_t &token) void IdDialog::loadCircleGroupMeta(const uint32_t &token)
{ {
@ -393,7 +401,7 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token)
if(!mExternalOtherCircleItem) if(!mExternalOtherCircleItem)
{ {
mExternalOtherCircleItem = new QTreeWidgetItem(); mExternalOtherCircleItem = new QTreeWidgetItem();
mExternalOtherCircleItem->setText(0, tr("Other visible external circles")); mExternalOtherCircleItem->setText(0, tr("Other circles"));
ui->treeWidget_membership->addTopLevelItem(mExternalOtherCircleItem); ui->treeWidget_membership->addTopLevelItem(mExternalOtherCircleItem);
} }
@ -401,7 +409,7 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token)
if(!mExternalBelongingCircleItem ) if(!mExternalBelongingCircleItem )
{ {
mExternalBelongingCircleItem = new QTreeWidgetItem(); mExternalBelongingCircleItem = new QTreeWidgetItem();
mExternalBelongingCircleItem->setText(0, tr("External circles my identities belong to")); mExternalBelongingCircleItem->setText(0, tr("Circles I belong to"));
ui->treeWidget_membership->addTopLevelItem(mExternalBelongingCircleItem); ui->treeWidget_membership->addTopLevelItem(mExternalBelongingCircleItem);
} }
#endif #endif
@ -429,13 +437,13 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token)
// find already existing items for this circle // find already existing items for this circle
// implement the search manually, because there's no find based on user role. // implement the search manually, because there's no find based on user role.
//QList<QTreeWidgetItem*> clist = ui->treeWidget_membership->findItems( QString::fromStdString(vit->mGroupId.toStdString()), Qt::MatchExactly|Qt::MatchRecursive, CIRCLEGROUP_CIRCLE_COL_GROUPID); //QList<QTreeWidgetItem*> clist = ui->treeWidget_membership->findItems( QString::fromStdString(vit->mGroupId.toStdString()), Qt::MatchExactly|Qt::MatchRecursive, CIRCLEGROUP_CIRCLE_COL_GROUPID);
QList<QTreeWidgetItem*> clist ; QList<QTreeWidgetItem*> clist ;
QString test_str = QString::fromStdString(vit->mGroupId.toStdString()) ; QString test_str = QString::fromStdString(vit->mGroupId.toStdString()) ;
for(QTreeWidgetItemIterator itt(ui->treeWidget_membership);*itt;++itt) for(QTreeWidgetItemIterator itt(ui->treeWidget_membership);*itt;++itt)
if( (*itt)->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString() == test_str) if( (*itt)->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString() == test_str)
clist.push_back(*itt) ; clist.push_back(*itt) ;
if(!clist.empty()) if(!clist.empty())
{ {
@ -499,7 +507,7 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token)
mExternalOtherCircleItem->addChild(item); mExternalOtherCircleItem->addChild(item);
} }
#else #else
ui->treeWidget_membership->addTopLevelItem(item) ; ui->treeWidget_membership->addTopLevelItem(item) ;
#endif #endif
} }
else if(item->text(CIRCLEGROUP_CIRCLE_COL_GROUPNAME) != QString::fromUtf8(vit->mGroupName.c_str())) else if(item->text(CIRCLEGROUP_CIRCLE_COL_GROUPNAME) != QString::fromUtf8(vit->mGroupName.c_str()))
@ -516,7 +524,16 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token)
QString tooltip ; QString tooltip ;
tooltip += tr("Circle ID: ")+QString::fromStdString(vit->mGroupId.toStdString()) ; tooltip += tr("Circle ID: ")+QString::fromStdString(vit->mGroupId.toStdString()) ;
tooltip += "\n"+tr("Role: "); tooltip += "\n"+tr("Visibility: ");
if(details.mRestrictedCircleId == details.mCircleId)
tooltip += tr("Private (only visible to invited members)") ;
else if(!details.mRestrictedCircleId.isNull())
tooltip += tr("Only visible to full members of circle ")+QString::fromStdString(details.mRestrictedCircleId.toStdString()) ;
else
tooltip += tr("Public") ;
tooltip += "\n"+tr("Your role: ");
if(am_I_admin) if(am_I_admin)
tooltip += tr("Administrator (Can edit invite list, and request membership).") ; tooltip += tr("Administrator (Can edit invite list, and request membership).") ;
@ -529,10 +546,10 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token)
else else
tooltip += tr("unsubscribed (Only receive invite list).") ; tooltip += tr("unsubscribed (Only receive invite list).") ;
tooltip += "\n"+tr("Permissions: ") ; tooltip += "\n"+tr("Your status: ") ;
if(am_I_in_circle) if(am_I_in_circle)
tooltip += tr("Full member (have access to data limited to this circle)") ; tooltip += tr("Full member (you have access to data limited to this circle)") ;
else else
tooltip += tr("Not a member (do not have access to data limited to this circle)") ; tooltip += tr("Not a member (do not have access to data limited to this circle)") ;
@ -553,20 +570,20 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token)
// - own GXS id is is admin and subscribed // - own GXS id is is admin and subscribed
// - own GXS id is is subscribed // - own GXS id is is subscribed
bool am_I_invited = false ; bool am_I_invited = false ;
bool am_I_pending = false ; bool am_I_pending = false ;
#ifdef ID_DEBUG #ifdef ID_DEBUG
std::cerr << " updating status of all identities for this circle:" << std::endl; std::cerr << " updating status of all identities for this circle:" << std::endl;
#endif #endif
// remove any identity that has an item, but no subscription flag entry // remove any identity that has an item, but no subscription flag entry
std::vector<QTreeWidgetItem*> to_delete ; std::vector<QTreeWidgetItem*> to_delete ;
for(int k=0;k<item->childCount();++k) for(uint32_t k=0;k<item->childCount();++k)
if(details.mSubscriptionFlags.find(RsGxsId(item->child(k)->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString().toStdString())) == details.mSubscriptionFlags.end()) if(details.mSubscriptionFlags.find(RsGxsId(item->child(k)->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString().toStdString())) == details.mSubscriptionFlags.end())
to_delete.push_back(item->child(k)); to_delete.push_back(item->child(k));
for(uint32_t k=0;k<to_delete.size();++k) for(uint32_t k=0;k<to_delete.size();++k)
delete to_delete[k] ; delete to_delete[k] ;
for(std::map<RsGxsId,uint32_t>::const_iterator it(details.mSubscriptionFlags.begin());it!=details.mSubscriptionFlags.end();++it) for(std::map<RsGxsId,uint32_t>::const_iterator it(details.mSubscriptionFlags.begin());it!=details.mSubscriptionFlags.end();++it)
{ {
@ -580,35 +597,35 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token)
#ifdef ID_DEBUG #ifdef ID_DEBUG
std::cerr << "invited: " << invited << ", subscription: " << subscrb ; std::cerr << "invited: " << invited << ", subscription: " << subscrb ;
#endif #endif
QTreeWidgetItem *subitem = NULL ; QTreeWidgetItem *subitem = NULL ;
// see if the item already exists // see if the item already exists
for(uint32_t k=0;k<item->childCount();++k) for(uint32_t k=0;k<item->childCount();++k)
if(item->child(k)->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString().toStdString() == it->first.toStdString()) if(item->child(k)->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString().toStdString() == it->first.toStdString())
{ {
subitem = item->child(k); subitem = item->child(k);
#ifdef ID_DEBUG #ifdef ID_DEBUG
std::cerr << " found existing sub item." << std::endl; std::cerr << " found existing sub item." << std::endl;
#endif #endif
break ; break ;
} }
if(!(invited || subscrb)) if(!(invited || subscrb))
{ {
if(subitem != NULL) if(subitem != NULL)
delete subitem ; delete subitem ;
#ifdef ID_DEBUG #ifdef ID_DEBUG
std::cerr << ". not relevant. Skipping." << std::endl; std::cerr << ". not relevant. Skipping." << std::endl;
#endif #endif
continue ; continue ;
} }
// remove item if flags are not ok. // remove item if flags are not ok.
if(subitem && subitem->data(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS, Qt::UserRole).toUInt() != it->second) if(subitem && subitem->data(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS, Qt::UserRole).toUInt() != it->second)
{ {
delete subitem ; delete subitem ;
subitem = NULL ; subitem = NULL ;
} }
if(!subitem) if(!subitem)
{ {
@ -625,14 +642,14 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token)
if(idd.mAvatar.mSize == 0 || !pixmap.loadFromData(idd.mAvatar.mData, idd.mAvatar.mSize, "PNG")) if(idd.mAvatar.mSize == 0 || !pixmap.loadFromData(idd.mAvatar.mData, idd.mAvatar.mSize, "PNG"))
pixmap = QPixmap::fromImage(GxsIdDetails::makeDefaultIcon(it->first)) ; pixmap = QPixmap::fromImage(GxsIdDetails::makeDefaultIcon(it->first)) ;
if(has_id) if(has_id)
subitem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, QString::fromUtf8(idd.mNickname.c_str())) ; subitem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, QString::fromUtf8(idd.mNickname.c_str())) ;
else else
subitem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, tr("Unknown ID :")+QString::fromStdString(it->first.toStdString())) ; subitem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, tr("Unknown ID :")+QString::fromStdString(it->first.toStdString())) ;
QString tooltip ; QString tooltip ;
tooltip += tr("Identity ID: ")+QString::fromStdString(it->first.toStdString()) ; tooltip += tr("Identity ID: ")+QString::fromStdString(it->first.toStdString()) ;
tooltip += "\n"+tr("Status: ") ; tooltip += "\n"+tr("Status: ") ;
if(invited) if(invited)
if(subscrb) if(subscrb)
tooltip += tr("Full member") ; tooltip += tr("Full member") ;
@ -655,23 +672,23 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token)
} }
if(invited && !subscrb) if(invited && !subscrb)
{ {
subitem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPID, tr("Invited")) ; subitem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPID, tr("Invited")) ;
if(is_own_id) if(is_own_id)
am_I_invited = true ; am_I_invited = true ;
} }
if(!invited && subscrb) if(!invited && subscrb)
{ {
subitem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPID, tr("Subscription pending")) ; subitem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPID, tr("Subscription pending")) ;
if(is_own_id) if(is_own_id)
am_I_pending = true ; am_I_pending = true ;
} }
if(invited && subscrb) if(invited && subscrb)
subitem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPID, tr("Member")) ; subitem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPID, tr("Member")) ;
if (is_own_id) if (is_own_id)
{ {
QFont font = subitem->font(CIRCLEGROUP_CIRCLE_COL_GROUPNAME) ; QFont font = subitem->font(CIRCLEGROUP_CIRCLE_COL_GROUPNAME) ;
font.setBold(true) ; font.setBold(true) ;
@ -681,12 +698,14 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token)
} }
} }
if(am_I_in_circle) if(am_I_in_circle)
item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,QIcon(IMAGE_MEMBER)) ; item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,QIcon(IMAGE_MEMBER)) ;
else if(am_I_invited || am_I_pending) else if(am_I_admin)
item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,QIcon(IMAGE_INVITED)) ; item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,QIcon(IMAGE_ADMIN)) ;
else else if(am_I_invited || am_I_pending)
item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,QIcon()) ; item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,QIcon(IMAGE_INVITED)) ;
else
item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,QIcon(IMAGE_UNKNOWN)) ;
} }
} }
@ -748,6 +767,58 @@ void IdDialog::loadCircleGroupData(const uint32_t& token)
mStateHelper->setLoading(CIRCLESDIALOG_GROUPDATA, false); mStateHelper->setLoading(CIRCLESDIALOG_GROUPDATA, false);
} }
void IdDialog::updateCircleGroup(const uint32_t& token)
{
#ifdef ID_DEBUG
std::cerr << "Loading circle info" << std::endl;
#endif
std::vector<RsGxsCircleGroup> circle_grp_v ;
rsGxsCircles->getGroupData(token, circle_grp_v);
if (circle_grp_v.empty())
{
std::cerr << "(EE) unexpected empty result from getGroupData. Cannot process circle now!" << std::endl;
return ;
}
if (circle_grp_v.size() != 1)
{
std::cerr << "(EE) very weird result from getGroupData. Should get exactly one circle" << std::endl;
return ;
}
RsGxsCircleGroup cg = circle_grp_v.front();
/* now mark all the members */
std::set<RsGxsId> members = cg.mInvitedMembers;
std::map<uint32_t,CircleUpdateOrder>::iterator it = mCircleUpdates.find(token) ;
if(it == mCircleUpdates.end())
{
std::cerr << "(EE) Cannot find token " << token << " to perform group update!" << std::endl;
return ;
}
if(it->second.action == CircleUpdateOrder::GRANT_MEMBERSHIP)
cg.mInvitedMembers.insert(it->second.gxs_id) ;
else if(it->second.action == CircleUpdateOrder::REVOKE_MEMBERSHIP)
cg.mInvitedMembers.erase(it->second.gxs_id) ;
else
{
std::cerr << "(EE) unrecognised membership action to perform: " << it->second.action << "!" << std::endl;
return ;
}
uint32_t token2 ;
rsGxsCircles->updateGroup(token2,cg) ;
mCircleUpdates.erase(it) ;
requestCircleGroupMeta();
}
bool IdDialog::getItemCircleId(QTreeWidgetItem *item,RsGxsCircleId& id) bool IdDialog::getItemCircleId(QTreeWidgetItem *item,RsGxsCircleId& id)
{ {
#ifdef CIRCLE_MEMBERSHIP_CATEGORIES #ifdef CIRCLE_MEMBERSHIP_CATEGORIES
@ -791,6 +862,58 @@ void IdDialog::showEditExistingCircle()
requestCircleGroupMeta(); // update GUI requestCircleGroupMeta(); // update GUI
} }
void IdDialog::grantCircleMembership()
{
RsGxsCircleId circle_id ;
if(!getItemCircleId(ui->treeWidget_membership->currentItem(),circle_id))
return;
RsGxsId gxs_id_to_revoke(qobject_cast<QAction*>(sender())->data().toString().toStdString());
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
std::list<RsGxsGroupId> grps ;
grps.push_back(RsGxsGroupId(circle_id));
uint32_t token;
mCircleQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grps, CIRCLESDIALOG_GROUPUPDATE);
CircleUpdateOrder c ;
c.token = token ;
c.gxs_id = gxs_id_to_revoke ;
c.action = CircleUpdateOrder::GRANT_MEMBERSHIP ;
mCircleUpdates[token] = c ;
}
void IdDialog::revokeCircleMembership()
{
RsGxsCircleId circle_id ;
if(!getItemCircleId(ui->treeWidget_membership->currentItem(),circle_id))
return;
RsGxsId gxs_id_to_revoke(qobject_cast<QAction*>(sender())->data().toString().toStdString());
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
std::list<RsGxsGroupId> grps ;
grps.push_back(RsGxsGroupId(circle_id));
uint32_t token;
mCircleQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, grps, CIRCLESDIALOG_GROUPUPDATE);
CircleUpdateOrder c ;
c.token = token ;
c.gxs_id = gxs_id_to_revoke ;
c.action = CircleUpdateOrder::REVOKE_MEMBERSHIP ;
mCircleUpdates[token] = c ;
}
void IdDialog::acceptCircleSubscription() void IdDialog::acceptCircleSubscription()
{ {
RsGxsCircleId circle_id ; RsGxsCircleId circle_id ;
@ -828,6 +951,7 @@ void IdDialog::CircleListCustomPopupMenu( QPoint )
RsGxsId current_gxs_id ; RsGxsId current_gxs_id ;
RsGxsId item_id(item->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString().toStdString()); RsGxsId item_id(item->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString().toStdString());
bool is_circle ; bool is_circle ;
bool am_I_circle_admin = false ;
if(item_id == RsGxsId(circle_id)) // is it a circle? if(item_id == RsGxsId(circle_id)) // is it a circle?
{ {
@ -838,11 +962,14 @@ void IdDialog::CircleListCustomPopupMenu( QPoint )
{ {
#endif #endif
if(group_flags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) if(group_flags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN)
{
contextMnu.addAction(QIcon(IMAGE_EDIT), tr("Edit Circle"), this, SLOT(showEditExistingCircle())); contextMnu.addAction(QIcon(IMAGE_EDIT), tr("Edit Circle"), this, SLOT(showEditExistingCircle()));
am_I_circle_admin = true ;
}
else else
contextMnu.addAction(QIcon(IMAGE_EDIT), tr("See details"), this, SLOT(showEditExistingCircle())); contextMnu.addAction(QIcon(IMAGE_INFO), tr("See details"), this, SLOT(showEditExistingCircle()));
#ifdef CIRCLE_MEMBERSHIP_CATEGORIES #ifdef CIRCLE_MEMBERSHIP_CATEGORIES
} }
#endif #endif
std::cerr << " Item is a circle item. Adding Edit/Details menu entry." << std::endl; std::cerr << " Item is a circle item. Adding Edit/Details menu entry." << std::endl;
@ -850,10 +977,16 @@ void IdDialog::CircleListCustomPopupMenu( QPoint )
contextMnu.addSeparator() ; contextMnu.addSeparator() ;
} }
else if(rsIdentity->isOwnId(item_id)) // is it one of our GXS ids? else
{ {
current_gxs_id = RsGxsId(item_id); current_gxs_id = RsGxsId(item_id);
is_circle =false ; is_circle =false ;
if(item->parent() != NULL)
{
uint32_t group_flags = item->parent()->data(CIRCLEGROUP_CIRCLE_COL_GROUPFLAGS, Qt::UserRole).toUInt();
am_I_circle_admin = bool(group_flags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN) ;
}
std::cerr << " Item is a GxsId item. Requesting flags/group id from parent: " << circle_id << std::endl; std::cerr << " Item is a GxsId item. Requesting flags/group id from parent: " << circle_id << std::endl;
} }
@ -872,7 +1005,7 @@ void IdDialog::CircleListCustomPopupMenu( QPoint )
static const int CANCEL = 3 ; // Admin list: no Subscription request: yes static const int CANCEL = 3 ; // Admin list: no Subscription request: yes
const QString menu_titles[4] = { tr("Request subscription"), tr("Accept circle invitation"), tr("Quit this circle"),tr("Cancel subscribe request")} ; const QString menu_titles[4] = { tr("Request subscription"), tr("Accept circle invitation"), tr("Quit this circle"),tr("Cancel subscribe request")} ;
const QString image_names[4] = { ":/images/edit_16.png",":/images/edit_16.png",":/images/edit_16.png",":/images/edit_16.png" } ; const QString image_names[4] = { ":/images/edit_add24.png",":/images/accepted16.png",":/images/door_in.png",":/images/cancel.png" } ;
std::vector< std::vector<RsGxsId> > ids(4) ; std::vector< std::vector<RsGxsId> > ids(4) ;
@ -911,7 +1044,7 @@ void IdDialog::CircleListCustomPopupMenu( QPoint )
RsIdentityDetails det ; RsIdentityDetails det ;
QString id_name ; QString id_name ;
if(rsIdentity->getIdDetails(ids[i][0],det)) if(rsIdentity->getIdDetails(ids[i][0],det))
id_name = tr("for identity ")+QString::fromUtf8(det.mNickname.c_str()) + "(ID=" + QString::fromStdString(ids[i][0].toStdString()) + ")" ; id_name = tr("for identity ")+QString::fromUtf8(det.mNickname.c_str()) + " (ID=" + QString::fromStdString(ids[i][0].toStdString()) + ")" ;
else else
id_name = tr("for identity ")+QString::fromStdString(ids[i][0].toStdString()) ; id_name = tr("for identity ")+QString::fromStdString(ids[i][0].toStdString()) ;
@ -939,7 +1072,7 @@ void IdDialog::CircleListCustomPopupMenu( QPoint )
RsIdentityDetails det ; RsIdentityDetails det ;
QString id_name ; QString id_name ;
if(rsIdentity->getIdDetails(ids[i][j],det)) if(rsIdentity->getIdDetails(ids[i][j],det))
id_name = tr("for identity ")+QString::fromUtf8(det.mNickname.c_str()) + "(ID=" + QString::fromStdString(ids[i][j].toStdString()) + ")" ; id_name = tr("for identity ")+QString::fromUtf8(det.mNickname.c_str()) + " (ID=" + QString::fromStdString(ids[i][j].toStdString()) + ")" ;
else else
id_name = tr("for identity ")+QString::fromStdString(ids[i][j].toStdString()) ; id_name = tr("for identity ")+QString::fromStdString(ids[i][j].toStdString()) ;
@ -958,6 +1091,32 @@ void IdDialog::CircleListCustomPopupMenu( QPoint )
} }
} }
if(!is_circle && am_I_circle_admin) // I am circle admin. I can therefore revoke/accept membership
{
std::map<RsGxsId,uint32_t>::const_iterator it = details.mSubscriptionFlags.find(current_gxs_id) ;
if(!current_gxs_id.isNull() && it != details.mSubscriptionFlags.end())
{
contextMnu.addSeparator() ;
if(it->second & GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST)
{
QAction *action = new QAction(tr("Revoke this member"),this) ;
action->setData(QString::fromStdString(current_gxs_id.toStdString()));
QObject::connect(action,SIGNAL(triggered()), this, SLOT(revokeCircleMembership()));
contextMnu.addAction(action) ;
}
else
{
QAction *action = new QAction(tr("Grant membership"),this) ;
action->setData(QString::fromStdString(current_gxs_id.toStdString()));
QObject::connect(action,SIGNAL(triggered()), this, SLOT(grantCircleMembership()));
contextMnu.addAction(action) ;
}
}
}
contextMnu.exec(QCursor::pos()); contextMnu.exec(QCursor::pos());
} }
@ -1796,6 +1955,10 @@ void IdDialog::loadRequest(const TokenQueue * queue, const TokenRequest &req)
loadCircleGroupData(req.mToken); loadCircleGroupData(req.mToken);
break; break;
case CIRCLESDIALOG_GROUPUPDATE:
updateCircleGroup(req.mToken);
break;
default: default:
std::cerr << "CirclesDialog::loadRequest() ERROR: INVALID TYPE"; std::cerr << "CirclesDialog::loadRequest() ERROR: INVALID TYPE";
std::cerr << std::endl; std::cerr << std::endl;
@ -1914,13 +2077,13 @@ void IdDialog::IdListCustomPopupMenu( QPoint )
contextMnu.addSeparator(); contextMnu.addSeparator();
if(n_positive_reputations == 0) // only unban when all items are banned if(n_positive_reputations == 0) // only unban when all items are banned
contextMnu.addAction(QIcon(), tr("Set positive opinion"), this, SLOT(positivePerson())); contextMnu.addAction(QIcon(":/images/vote_up.png"), tr("Set positive opinion"), this, SLOT(positivePerson()));
if(n_neutral_reputations == 0) // only unban when all items are banned if(n_neutral_reputations == 0) // only unban when all items are banned
contextMnu.addAction(QIcon(), tr("Set neutral opinion"), this, SLOT(neutralPerson())); contextMnu.addAction(QIcon(":/images/vote_neutral.png"), tr("Set neutral opinion"), this, SLOT(neutralPerson()));
if(n_negative_reputations == 0) if(n_negative_reputations == 0)
contextMnu.addAction(QIcon(":/images/denied16.png"), tr("Set negative opinion"), this, SLOT(negativePerson())); contextMnu.addAction(QIcon(":/images/vote_down.png"), tr("Set negative opinion"), this, SLOT(negativePerson()));
} }
if(one_item_owned_by_you && n_selected_items==1) if(one_item_owned_by_you && n_selected_items==1)

View File

@ -39,6 +39,15 @@ class IdDialog;
class UIStateHelper; class UIStateHelper;
class QTreeWidgetItem; class QTreeWidgetItem;
struct CircleUpdateOrder
{
enum { UNKNOWN_ACTION=0x00, GRANT_MEMBERSHIP=0x01, REVOKE_MEMBERSHIP=0x02 };
uint32_t token ;
RsGxsId gxs_id ;
uint32_t action ;
};
class IdDialog : public RsGxsUpdateBroadcastPage, public TokenResponse class IdDialog : public RsGxsUpdateBroadcastPage, public TokenResponse
{ {
Q_OBJECT Q_OBJECT
@ -56,20 +65,23 @@ public:
protected: protected:
virtual void updateDisplay(bool complete); virtual void updateDisplay(bool complete);
void loadCircleGroupMeta(const uint32_t &token); void loadCircleGroupMeta(const uint32_t &token);
void loadCircleGroupData(const uint32_t &token); void loadCircleGroupData(const uint32_t &token);
void updateCircleGroup(const uint32_t& token);
void requestCircleGroupMeta(); void requestCircleGroupMeta();
void requestCircleGroupData(const RsGxsCircleId& circle_id); //void requestCircleGroupData(const RsGxsCircleId& circle_id);
bool getItemCircleId(QTreeWidgetItem *item,RsGxsCircleId& id) ; bool getItemCircleId(QTreeWidgetItem *item,RsGxsCircleId& id) ;
private slots: private slots:
void createExternalCircle(); void createExternalCircle();
void showEditExistingCircle(); void showEditExistingCircle();
void updateCirclesDisplay(); void updateCirclesDisplay();
void acceptCircleSubscription() ; void acceptCircleSubscription() ;
void cancelCircleSubscription() ; void cancelCircleSubscription() ;
void grantCircleMembership() ;
void revokeCircleMembership() ;
void filterComboBoxChanged(); void filterComboBoxChanged();
void filterChanged(const QString &text); void filterChanged(const QString &text);
@ -94,7 +106,7 @@ private slots:
#endif #endif
void addtoContacts(); void addtoContacts();
void removefromContacts(); void removefromContacts();
void negativePerson(); void negativePerson();
void positivePerson(); void positivePerson();
@ -132,7 +144,9 @@ private:
QTreeWidgetItem *ownItem; QTreeWidgetItem *ownItem;
QTreeWidgetItem *mExternalBelongingCircleItem; QTreeWidgetItem *mExternalBelongingCircleItem;
QTreeWidgetItem *mExternalOtherCircleItem; QTreeWidgetItem *mExternalOtherCircleItem;
RsGxsUpdateBroadcastBase *mCirclesBroadcastBase ; RsGxsUpdateBroadcastBase *mCirclesBroadcastBase ;
std::map<uint32_t, CircleUpdateOrder> mCircleUpdates ;
RsGxsGroupId mId; RsGxsGroupId mId;

View File

@ -123,14 +123,14 @@ ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::Wi
{ {
QIcon icon ; QIcon icon ;
icon.addPixmap(QPixmap(":/images/edit_add24.png")) ; icon.addPixmap(QPixmap(":/images/user/add_user24.png")) ;
inviteFriendsButton->setIcon(icon) ; inviteFriendsButton->setIcon(icon) ;
inviteFriendsButton->setIconSize(QSize(2*S,2*S)) ; inviteFriendsButton->setIconSize(QSize(2*S,2*S)) ;
} }
connect(inviteFriendsButton, SIGNAL(clicked()), this , SLOT(inviteFriends())); connect(inviteFriendsButton, SIGNAL(clicked()), this , SLOT(inviteFriends()));
getChatWidget()->addChatBarWidget(inviteFriendsButton) ; getChatWidget()->addTitleBarWidget(inviteFriendsButton) ;
RsGxsId current_id; RsGxsId current_id;
rsMsgs->getIdentityForChatLobby(lobbyId, current_id); rsMsgs->getIdentityForChatLobby(lobbyId, current_id);
@ -159,7 +159,7 @@ ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::Wi
QIcon icon ; QIcon icon ;
icon.addPixmap(QPixmap(":/images/door_in.png")) ; icon.addPixmap(QPixmap(":/images/door_in.png")) ;
unsubscribeButton->setIcon(icon) ; unsubscribeButton->setIcon(icon) ;
unsubscribeButton->setIconSize(QSize(1.5*S,1.5*S)) ; unsubscribeButton->setIconSize(QSize(2*S,2*S)) ;
} }
/* Initialize splitter */ /* Initialize splitter */
@ -168,7 +168,7 @@ ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::Wi
connect(unsubscribeButton, SIGNAL(clicked()), this , SLOT(leaveLobby())); connect(unsubscribeButton, SIGNAL(clicked()), this , SLOT(leaveLobby()));
getChatWidget()->addChatBarWidget(unsubscribeButton) ; getChatWidget()->addTitleBarWidget(unsubscribeButton) ;
} }
void ChatLobbyDialog::leaveLobby() void ChatLobbyDialog::leaveLobby()

View File

@ -13,7 +13,7 @@
<property name="windowTitle"> <property name="windowTitle">
<string notr="true">MainWindow</string> <string notr="true">MainWindow</string>
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="ChatLobbyDialogHLayout">
<property name="margin"> <property name="margin">
<number>0</number> <number>0</number>
</property> </property>
@ -52,7 +52,7 @@
<height>0</height> <height>0</height>
</size> </size>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_2"> <layout class="QVBoxLayout" name="participantsFrameVLayout">
<property name="leftMargin"> <property name="leftMargin">
<number>0</number> <number>0</number>
</property> </property>

View File

@ -121,6 +121,7 @@ ChatWidget::ChatWidget(QWidget *parent) :
ui->actionSearchWithoutLimit->setText(tr("Don't stop to color after")+" "+QString::number(uiMaxSearchLimitColor)+" "+tr("items found (need more CPU)")); ui->actionSearchWithoutLimit->setText(tr("Don't stop to color after")+" "+QString::number(uiMaxSearchLimitColor)+" "+tr("items found (need more CPU)"));
ui->markButton->setVisible(false);
ui->leSearch->setVisible(false); ui->leSearch->setVisible(false);
ui->searchBefore->setVisible(false); ui->searchBefore->setVisible(false);
ui->searchBefore->setToolTip(tr("<b>Find Previous </b><br/><i>Ctrl+Shift+G</i>")); ui->searchBefore->setToolTip(tr("<b>Find Previous </b><br/><i>Ctrl+Shift+G</i>"));
@ -183,6 +184,8 @@ ChatWidget::ChatWidget(QWidget *parent) :
menu->addAction(ui->actionChooseFont); menu->addAction(ui->actionChooseFont);
menu->addAction(ui->actionChooseColor); menu->addAction(ui->actionChooseColor);
menu->addAction(ui->actionResetFont); menu->addAction(ui->actionResetFont);
menu->addAction(ui->actionNoEmbed);
menu->addAction(ui->actionSendAsPlainText);
ui->fontButton->setMenu(menu); ui->fontButton->setMenu(menu);
menu = new QMenu(); menu = new QMenu();
@ -191,6 +194,7 @@ ChatWidget::ChatWidget(QWidget *parent) :
menu->addAction(ui->actionSaveChatHistory); menu->addAction(ui->actionSaveChatHistory);
menu->addAction(ui->actionMessageHistory); menu->addAction(ui->actionMessageHistory);
ui->pushtoolsButton->setMenu(menu); ui->pushtoolsButton->setMenu(menu);
ui->actionSendAsPlainText->setChecked(Settings->getChatSendAsPlainTextByDef());
ui->textBrowser->installEventFilter(this); ui->textBrowser->installEventFilter(this);
ui->textBrowser->viewport()->installEventFilter(this); ui->textBrowser->viewport()->installEventFilter(this);
@ -899,7 +903,8 @@ void ChatWidget::addChatMsg(bool incoming, const QString &name, const RsGxsId gx
// embed smileys ? // embed smileys ?
if (Settings->valueFromGroup(QString("Chat"), QString::fromUtf8("Emoteicons_PrivatChat"), true).toBool()) { if (Settings->valueFromGroup(QString("Chat"), QString::fromUtf8("Emoteicons_PrivatChat"), true).toBool()) {
formatTextFlag |= RSHTML_FORMATTEXT_EMBED_SMILEYS; if (!message.contains("NoEmbed=\"true\""))
formatTextFlag |= RSHTML_FORMATTEXT_EMBED_SMILEYS;
} }
// Always fix colors // Always fix colors
@ -1134,7 +1139,12 @@ void ChatWidget::sendChat()
} }
QString text; QString text;
RsHtml::optimizeHtml(chatWidget, text); if (ui->actionSendAsPlainText->isChecked()){
text = chatWidget->toPlainText();
text.replace(QChar(-4),"");//Char used when image on text.
} else {
RsHtml::optimizeHtml(chatWidget, text, (ui->actionNoEmbed->isChecked() ? RSHTML_FORMATTEXT_NO_EMBED : 0));
}
std::string msg = text.toUtf8().constData(); std::string msg = text.toUtf8().constData();
if (msg.empty()) { if (msg.empty()) {
@ -1188,7 +1198,7 @@ void ChatWidget::on_searchButton_clicked(bool bValue)
qtcCurrent=QTextCursor(qtdDocument); qtcCurrent=QTextCursor(qtdDocument);
} }
ui->leSearch->setVisible(bValue); ui->leSearch->setVisible(bValue);
ui->markButton->setVisible(bValue);
} }
void ChatWidget::on_searchBefore_clicked() void ChatWidget::on_searchBefore_clicked()
{ {

View File

@ -1034,6 +1034,36 @@ border-image: url(:/images/closepressed.png)
<string>Save image</string> <string>Save image</string>
</property> </property>
</action> </action>
<action name="actionSendAsPlainText">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/SimpleText.png</normaloff>:/images/SimpleText.png</iconset>
</property>
<property name="text">
<string>Send as PlainText</string>
</property>
<property name="toolTip">
<string>Send as plain text without font.</string>
</property>
</action>
<action name="actionNoEmbed">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/SmileyText.png</normaloff>:/images/SmileyText.png</iconset>
</property>
<property name="text">
<string>Don't replace tag with Emote Icon.</string>
</property>
<property name="toolTip">
<string>Don't replace tag with Emote Icon.</string>
</property>
</action>
</widget> </widget>
<customwidgets> <customwidgets>
<customwidget> <customwidget>

View File

@ -103,9 +103,6 @@ ConfCertDialog::ConfCertDialog(const RsPeerId& id, const RsPgpId &pgp_id, QWidge
connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(close())); connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(close()));
connect(ui._shouldAddSignatures_CB, SIGNAL(toggled(bool)), this, SLOT(loadInvitePage())); connect(ui._shouldAddSignatures_CB, SIGNAL(toggled(bool)), this, SLOT(loadInvitePage()));
//connect(ui.denyFriendButton, SIGNAL(clicked()), this, SLOT(denyFriend()));
//connect(ui._shouldAddSignatures_CB_2, SIGNAL(toggled(bool)), this, SLOT(loadInvitePage()));
ui.avatar->setFrameType(AvatarWidget::NORMAL_FRAME); ui.avatar->setFrameType(AvatarWidget::NORMAL_FRAME);
MainWindow *w = MainWindow::getInstance(); MainWindow *w = MainWindow::getInstance();
@ -116,32 +113,16 @@ ConfCertDialog::ConfCertDialog(const RsPeerId& id, const RsPgpId &pgp_id, QWidge
ConfCertDialog::~ConfCertDialog() ConfCertDialog::~ConfCertDialog()
{ {
// if(peerId.isNull()) QMap<RsPeerId, ConfCertDialog*>::iterator it = instances_ssl.find(peerId);
{ if (it != instances_ssl.end())
QMap<RsPeerId, ConfCertDialog*>::iterator it = instances_ssl.find(peerId); instances_ssl.erase(it);
if (it != instances_ssl.end())
instances_ssl.erase(it); QMap<RsPgpId, ConfCertDialog*>::iterator it2 = instances_pgp.find(pgpId);
} if (it2 != instances_pgp.end())
// else instances_pgp.erase(it2);
{
QMap<RsPgpId, ConfCertDialog*>::iterator it = instances_pgp.find(pgpId);
if (it != instances_pgp.end())
instances_pgp.erase(it);
}
} }
void ConfCertDialog::setServiceFlags()
{
ServicePermissionFlags flags(0) ;
if( ui._direct_transfer_CB->isChecked()) flags = flags | RS_NODE_PERM_DIRECT_DL ;
if( ui._allow_push_CB->isChecked()) flags = flags | RS_NODE_PERM_ALLOW_PUSH ;
if( ui._require_WL_CB->isChecked()) flags = flags | RS_NODE_PERM_REQUIRE_WL ;
rsPeers->setServicePermissionFlags(pgpId,flags) ;
}
void ConfCertDialog::loadAll() void ConfCertDialog::loadAll()
{ {
for(QMap<RsPeerId, ConfCertDialog*>::iterator it = instances_ssl.begin(); it != instances_ssl.end(); ++it) it.value()->load(); for(QMap<RsPeerId, ConfCertDialog*>::iterator it = instances_ssl.begin(); it != instances_ssl.end(); ++it) it.value()->load();
@ -161,10 +142,6 @@ void ConfCertDialog::load()
return; return;
} }
ui._direct_transfer_CB->setChecked( detail.service_perm_flags & RS_NODE_PERM_DIRECT_DL ) ;
ui._allow_push_CB->setChecked( detail.service_perm_flags & RS_NODE_PERM_ALLOW_PUSH) ;
ui._require_WL_CB->setChecked( detail.service_perm_flags & RS_NODE_PERM_REQUIRE_WL) ;
//ui.pgpfingerprint->setText(QString::fromUtf8(detail.name.c_str())); //ui.pgpfingerprint->setText(QString::fromUtf8(detail.name.c_str()));
ui.peerid->setText(QString::fromStdString(detail.id.toStdString())); ui.peerid->setText(QString::fromStdString(detail.id.toStdString()));
@ -349,55 +326,53 @@ void ConfCertDialog::applyDialog()
RsPeerDetails detail; RsPeerDetails detail;
if (!rsPeers->getPeerDetails(peerId, detail)) if (!rsPeers->getPeerDetails(peerId, detail))
{ {
if (!rsPeers->getGPGDetails(pgpId, detail)) { if (!rsPeers->getGPGDetails(pgpId, detail)) {
QMessageBox::information(this, QMessageBox::information(this,
tr("RetroShare"), tr("RetroShare"),
tr("Error : cannot get peer details.")); tr("Error : cannot get peer details."));
close(); close();
return; return;
} }
} }
if(!detail.isHiddenNode) if(!detail.isHiddenNode)
{ {
/* check if the data is the same */ /* check if the data is the same */
bool localChanged = false; bool localChanged = false;
bool extChanged = false; bool extChanged = false;
bool dnsChanged = false; bool dnsChanged = false;
/* set local address */ /* set local address */
if ((detail.localAddr != ui.localAddress->text().toStdString()) || (detail.localPort != ui.localPort -> value())) if ((detail.localAddr != ui.localAddress->text().toStdString()) || (detail.localPort != ui.localPort -> value()))
localChanged = true; localChanged = true;
if ((detail.extAddr != ui.extAddress->text().toStdString()) || (detail.extPort != ui.extPort -> value())) if ((detail.extAddr != ui.extAddress->text().toStdString()) || (detail.extPort != ui.extPort -> value()))
extChanged = true; extChanged = true;
if ((detail.dyndns != ui.dynDNS->text().toStdString())) if ((detail.dyndns != ui.dynDNS->text().toStdString()))
dnsChanged = true; dnsChanged = true;
/* now we can action the changes */ /* now we can action the changes */
if (localChanged) if (localChanged)
rsPeers->setLocalAddress(peerId, ui.localAddress->text().toStdString(), ui.localPort->value()); rsPeers->setLocalAddress(peerId, ui.localAddress->text().toStdString(), ui.localPort->value());
if (extChanged) if (extChanged)
rsPeers->setExtAddress(peerId,ui.extAddress->text().toStdString(), ui.extPort->value()); rsPeers->setExtAddress(peerId,ui.extAddress->text().toStdString(), ui.extPort->value());
if (dnsChanged) if (dnsChanged)
rsPeers->setDynDNS(peerId, ui.dynDNS->text().toStdString()); rsPeers->setDynDNS(peerId, ui.dynDNS->text().toStdString());
if(localChanged || extChanged || dnsChanged) if(localChanged || extChanged || dnsChanged)
emit configChanged(); emit configChanged();
} }
else else
{ {
if((detail.hiddenNodeAddress != ui.localAddress->text().toStdString()) || (detail.hiddenNodePort != ui.localPort->value())) if((detail.hiddenNodeAddress != ui.localAddress->text().toStdString()) || (detail.hiddenNodePort != ui.localPort->value()))
{ {
rsPeers->setHiddenNode(peerId,ui.localAddress->text().toStdString(), ui.localPort->value()); rsPeers->setHiddenNode(peerId,ui.localAddress->text().toStdString(), ui.localPort->value());
emit configChanged(); emit configChanged();
} }
} }
setServiceFlags() ;
loadAll(); loadAll();
close(); close();

View File

@ -76,11 +76,7 @@ private:
private slots: private slots:
void applyDialog(); void applyDialog();
//void makeFriend();
//void denyFriend();
//void signGPGKey();
void loadInvitePage(); void loadInvitePage();
void setServiceFlags();
void showHelpDialog(); void showHelpDialog();
/** Called when a child window requests the given help <b>topic</b>. */ /** Called when a child window requests the given help <b>topic</b>. */

View File

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>678</width> <width>742</width>
<height>727</height> <height>915</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -35,6 +35,7 @@
<property name="frameShadow"> <property name="frameShadow">
<enum>QFrame::Plain</enum> <enum>QFrame::Plain</enum>
</property> </property>
<zorder>stabWidget</zorder>
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="1" column="0">
@ -60,7 +61,7 @@
<item row="0" column="0"> <item row="0" column="0">
<widget class="QTabWidget" name="stabWidget"> <widget class="QTabWidget" name="stabWidget">
<property name="currentIndex"> <property name="currentIndex">
<number>0</number> <number>1</number>
</property> </property>
<widget class="QWidget" name="tab"> <widget class="QWidget" name="tab">
<attribute name="icon"> <attribute name="icon">
@ -407,6 +408,13 @@
<string>Retroshare Certificate</string> <string>Retroshare Certificate</string>
</attribute> </attribute>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Use this certificate to make friends:</string>
</property>
</widget>
</item>
<item> <item>
<widget class="QTextEdit" name="userCertificateText"/> <widget class="QTextEdit" name="userCertificateText"/>
</item> </item>
@ -436,60 +444,6 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="tab_4">
<attribute name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/admin-16.png</normaloff>:/images/admin-16.png</iconset>
</attribute>
<attribute name="title">
<string>Options</string>
</attribute>
<layout class="QGridLayout" name="gridLayout">
<item row="3" column="0" colspan="2">
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>196</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0" colspan="2">
<widget class="QCheckBox" name="_direct_transfer_CB">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;Retroshare periodically checks your friend lists for browsable files matching your transfers, to establish a direct transfer. In this case, your friend knows you're downloading the file.&lt;/p&gt;&lt;p align=&quot;justify&quot;&gt;To prevent this behavior for this friend only, uncheck this box. You can still perform a direct transfer if you explicitly ask for it, by e.g. downloading from your friend's file list. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Use as direct source, when available</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="_allow_push_CB">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This option allows you to automatically download a file that is recommended in an message coming from this node. This can be used for instance to send files between your own nodes.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Auto-download recommended files from this node</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="_require_WL_CB">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Peers that have this option cannot connect if their connection address is not in the whitelist. This protects you from traffic forwarding attacks. When used, rejected peers will be reported by &amp;quot;security feed items&amp;quot; in the News Feed section. From there, you can whitelist/blacklist their IP.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Require white list clearance</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget> </widget>
</item> </item>
</layout> </layout>

View File

@ -145,44 +145,23 @@ void PGPKeyDialog::load()
ui.make_friend_button->setToolTip("") ; ui.make_friend_button->setToolTip("") ;
} }
//ui._direct_transfer_CB->setChecked( detail.service_perm_flags & RS_NODE_PERM_DIRECT_DL ) ;
//ui._allow_push_CB->setChecked( detail.service_perm_flags & RS_NODE_PERM_ALLOW_PUSH) ;
ui.name->setText(QString::fromUtf8(detail.name.c_str())); ui.name->setText(QString::fromUtf8(detail.name.c_str()));
//ui.peerid->setText(QString::fromStdString(detail.id.toStdString()));
//RetroShareLink link;
//link.createPerson(detail.gpg_id);
//ui.rsid->setText(QString::fromStdString(detail.gpg_id.toStdString())) ;
ui.pgpfingerprint->setText(misc::fingerPrintStyleSplit(QString::fromStdString(detail.fpr.toStdString()))); ui.pgpfingerprint->setText(misc::fingerPrintStyleSplit(QString::fromStdString(detail.fpr.toStdString())));
//ui.rsid->setToolTip(link.title());
//ui.avatar->setId(pgpId.toStdString(), true);
// ui.rsid->show();
// ui.peerid->hide();
// ui.label_id->hide();
// ui.label_rsid->show();
ui.pgpfingerprint->show(); ui.pgpfingerprint->show();
ui.pgpfingerprint_label->show(); ui.pgpfingerprint_label->show();
// ui.loc->hide(); ui._direct_transfer_CB->setChecked( detail.service_perm_flags & RS_NODE_PERM_DIRECT_DL ) ;
// ui.label_loc->hide(); ui._allow_push_CB->setChecked( detail.service_perm_flags & RS_NODE_PERM_ALLOW_PUSH) ;
// ui.statusline->hide(); ui._require_WL_CB->setChecked( detail.service_perm_flags & RS_NODE_PERM_REQUIRE_WL) ;
// ui.label_status->hide();
// ui.lastcontact->hide();
// ui.label_last_contact->hide();
// ui.version->hide();
// ui.label_version->hide();
// ui.groupBox_4->hide();
// ui.crypto_info->hide();
// ui.crypto_label->hide();
// ui.groupBox->hide(); uint32_t max_upload_speed = 0 ;
// ui.tabWidget->hide(); uint32_t max_download_speed = 0 ;
rsPeers->getPeerMaximumRates(pgpId,max_upload_speed,max_download_speed);
ui.maxUploadSpeed_SB->setValue(max_upload_speed) ;
ui.maxDownloadSpeed_SB->setValue(max_download_speed) ;
if (detail.gpg_id == rsPeers->getGPGOwnId()) if (detail.gpg_id == rsPeers->getGPGOwnId())
{ {
@ -323,7 +302,6 @@ void PGPKeyDialog::loadKeyPage()
ui.userCertificateText_2->setToolTip(helptext) ; ui.userCertificateText_2->setToolTip(helptext) ;
} }
void PGPKeyDialog::applyDialog() void PGPKeyDialog::applyDialog()
{ {
std::cerr << "PGPKeyDialog::applyDialog() called" << std::endl ; std::cerr << "PGPKeyDialog::applyDialog() called" << std::endl ;
@ -343,6 +321,19 @@ void PGPKeyDialog::applyDialog()
if(ui.trustlevel_CB->currentIndex() != (int)detail.trustLvl) if(ui.trustlevel_CB->currentIndex() != (int)detail.trustLvl)
rsPeers->trustGPGCertificate(pgpId, ui.trustlevel_CB->currentIndex()); rsPeers->trustGPGCertificate(pgpId, ui.trustlevel_CB->currentIndex());
uint32_t max_upload_speed = ui.maxUploadSpeed_SB->value() ;
uint32_t max_download_speed = ui.maxDownloadSpeed_SB->value();
rsPeers->setPeerMaximumRates(pgpId,max_upload_speed,max_download_speed);
ServicePermissionFlags flags(0) ;
if( ui._direct_transfer_CB->isChecked()) flags = flags | RS_NODE_PERM_DIRECT_DL ;
if( ui._allow_push_CB->isChecked()) flags = flags | RS_NODE_PERM_ALLOW_PUSH ;
if( ui._require_WL_CB->isChecked()) flags = flags | RS_NODE_PERM_REQUIRE_WL ;
rsPeers->setServicePermissionFlags(pgpId,flags) ;
//setServiceFlags() ; //setServiceFlags() ;
loadAll(); loadAll();

View File

@ -27,7 +27,7 @@
<item> <item>
<widget class="QTabWidget" name="stabWidget"> <widget class="QTabWidget" name="stabWidget">
<property name="currentIndex"> <property name="currentIndex">
<number>1</number> <number>0</number>
</property> </property>
<widget class="QWidget" name="tab"> <widget class="QWidget" name="tab">
<attribute name="title"> <attribute name="title">
@ -175,7 +175,16 @@
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="friendAndSignLayout"> <layout class="QHBoxLayout" name="friendAndSignLayout">
<property name="margin"> <property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number> <number>6</number>
</property> </property>
<item> <item>
@ -295,6 +304,16 @@ p, li { white-space: pre-wrap; }
<string>ASCII format</string> <string>ASCII format</string>
</attribute> </attribute>
<layout class="QVBoxLayout" name="verticalLayout_3"> <layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Below is the node's PGP key. It identifies the node and all its locations. A &quot;Retroshare certificate&quot; that you can exchange in order to make friends, is in the the &quot;details&quot; of each separate location.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item> <item>
<widget class="QTextEdit" name="userCertificateText_2"> <widget class="QTextEdit" name="userCertificateText_2">
<property name="sizePolicy"> <property name="sizePolicy">
@ -321,6 +340,115 @@ p, li { white-space: pre-wrap; }
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>Options</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>These options apply to all locations of the same node:</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="_direct_transfer_CB">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;Retroshare periodically checks your friend lists for browsable files matching your transfers, to establish a direct transfer. In this case, your friend knows you're downloading the file.&lt;/p&gt;&lt;p align=&quot;justify&quot;&gt;To prevent this behavior for this friend only, uncheck this box. You can still perform a direct transfer if you explicitly ask for it, by e.g. downloading from your friend's file list. This setting is applied to all locations of the same node.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Use as direct source, when available</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="_allow_push_CB">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This option allows you to automatically download a file that is recommended in an message coming from this node. This can be used for instance to send files between your own nodes. Applied to all locations of the same node.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Auto-download recommended files from this node</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="_require_WL_CB">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Peers that have this option cannot connect if their connection address is not in the whitelist. This protects you from traffic forwarding attacks. When used, rejected peers will be reported by &amp;quot;security feed items&amp;quot; in the News Feed section. From there, you can whitelist/blacklist their IP. Applies to all locations of the same node.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Require white list clearance</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Max upload speed (0=unlimited)</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Max download speed (0=unlimited)</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QSpinBox" name="maxUploadSpeed_SB">
<property name="suffix">
<string> kB/s</string>
</property>
<property name="maximum">
<number>10000</number>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="maxDownloadSpeed_SB">
<property name="suffix">
<string> kB/s</string>
</property>
<property name="maximum">
<number>10000</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>274</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget> </widget>
</item> </item>
<item> <item>
@ -334,6 +462,9 @@ p, li { white-space: pre-wrap; }
</widget> </widget>
</item> </item>
</layout> </layout>
<zorder>stabWidget</zorder>
<zorder>headerFrame</zorder>
<zorder>buttonBox</zorder>
</widget> </widget>
<customwidgets> <customwidgets>
<customwidget> <customwidget>

View File

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>928</width> <width>828</width>
<height>769</height> <height>612</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -208,222 +208,6 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="4" column="0">
<widget class="QGroupBox" name="publishGroupBox">
<property name="title">
<string>Publish Signatures</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>4</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>4</number>
</property>
<item>
<widget class="QRadioButton" name="publish_open">
<property name="text">
<string>Open</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="publish_threads">
<property name="text">
<string>New Thread</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="publish_required">
<property name="text">
<string>Required</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="publish_encrypt">
<property name="text">
<string>Encrypted Msgs</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_7">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="5" column="0">
<widget class="QGroupBox" name="personalGroupBox">
<property name="title">
<string>Personal Signatures</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_9">
<item>
<widget class="QRadioButton" name="personal_pgp">
<property name="text">
<string>PGP Required</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="personal_required">
<property name="text">
<string>Signature Required</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="personal_ifnopub">
<property name="text">
<string>If No Publish Signature</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="6" column="0">
<widget class="QGroupBox" name="commentGroupBox">
<property name="title">
<string>Comments</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>4</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>4</number>
</property>
<item>
<widget class="QRadioButton" name="comments_allowed">
<property name="text">
<string>Allow Comments</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="comments_no">
<property name="text">
<string>No Comments</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="7" column="0">
<widget class="QGroupBox" name="spamProtection_GB">
<property name="title">
<string>Spam-protection</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>4</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>4</number>
</property>
<item>
<widget class="QCheckBox" name="antiSpam_signedIds">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This makes the media increase the reputation threshold to 0.4 for anonymous ids, while keeping it to 0.0 for PGP-linked ids. Therefore, anonymous ids can still post, if their local reputation score is above that threshold.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Favor PGP-signed ids</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="antiSpam_trackMessages">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;This feature allows Retroshare to locally keep a record of who forwarded each message to you, for the last 10 days. Although useless if alone (and already available whatsoever) this information can be used by a group of collaborative friends to easily locate the source of spams. To be used with care, since it significantly decreases the anonymity of message posts.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Keep track of posts</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_8">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="8" column="0" colspan="2"> <item row="8" column="0" colspan="2">
<widget class="QFrame" name="extraFrame"> <widget class="QFrame" name="extraFrame">
<property name="frameShape"> <property name="frameShape">
@ -631,6 +415,222 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="3" column="0">
<widget class="QGroupBox" name="publishGroupBox">
<property name="title">
<string>Publish Signatures</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>4</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>4</number>
</property>
<item>
<widget class="QRadioButton" name="publish_open">
<property name="text">
<string>Open</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="publish_threads">
<property name="text">
<string>New Thread</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="publish_required">
<property name="text">
<string>Required</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="publish_encrypt">
<property name="text">
<string>Encrypted Msgs</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_7">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="4" column="0">
<widget class="QGroupBox" name="personalGroupBox">
<property name="title">
<string>Personal Signatures</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_9">
<item>
<widget class="QRadioButton" name="personal_pgp">
<property name="text">
<string>PGP Required</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="personal_required">
<property name="text">
<string>Signature Required</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="personal_ifnopub">
<property name="text">
<string>If No Publish Signature</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="5" column="0">
<widget class="QGroupBox" name="commentGroupBox">
<property name="title">
<string>Comments</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>4</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>4</number>
</property>
<item>
<widget class="QRadioButton" name="comments_allowed">
<property name="text">
<string>Allow Comments</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="comments_no">
<property name="text">
<string>No Comments</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="6" column="0">
<widget class="QGroupBox" name="spamProtection_GB">
<property name="title">
<string>Spam-protection</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>4</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>4</number>
</property>
<item>
<widget class="QCheckBox" name="antiSpam_signedIds">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This makes the media increase the reputation threshold to 0.4 for anonymous ids, while keeping it to 0.0 for PGP-linked ids. Therefore, anonymous ids can still post, if their local reputation score is above that threshold.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Favor PGP-signed ids</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="antiSpam_trackMessages">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;This feature allows Retroshare to locally keep a record of who forwarded each message to you, for the last 10 days. Although useless if alone (and already available whatsoever) this information can be used by a group of collaborative friends to easily locate the source of spams. To be used with care, since it significantly decreases the anonymity of message posts.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Keep track of posts</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_8">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="showmode"> <widget class="QWidget" name="showmode">

View File

@ -14,6 +14,18 @@
<string>Form</string> <string>Form</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_3"> <layout class="QVBoxLayout" name="verticalLayout_3">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item> <item>
<widget class="QSplitter" name="threadSplitter"> <widget class="QSplitter" name="threadSplitter">
<property name="orientation"> <property name="orientation">
@ -36,7 +48,16 @@
<enum>QFrame::Sunken</enum> <enum>QFrame::Sunken</enum>
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout_3"> <layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="margin"> <property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number> <number>2</number>
</property> </property>
<item> <item>
@ -449,7 +470,7 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name=""> <widget class="QWidget" name="layoutWidget">
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item> <item>
<widget class="RSImageBlockWidget" name="imageBlockWidget" native="true"> <widget class="RSImageBlockWidget" name="imageBlockWidget" native="true">

View File

@ -554,6 +554,7 @@
<file>images/view_split_top_bottom.png</file> <file>images/view_split_top_bottom.png</file>
<file>images/vote_up.png</file> <file>images/vote_up.png</file>
<file>images/vote_down.png</file> <file>images/vote_down.png</file>
<file>images/vote_neutral.png</file>
<file>images/window_fullscreen.png</file> <file>images/window_fullscreen.png</file>
<file>images/window_nofullscreen.png</file> <file>images/window_nofullscreen.png</file>
<file>images/identity/identities_32.png</file> <file>images/identity/identities_32.png</file>
@ -657,5 +658,8 @@
<file>images/rsmessenger16.png</file> <file>images/rsmessenger16.png</file>
<file>images/rsmessenger32.png</file> <file>images/rsmessenger32.png</file>
<file>images/rsmessenger48.png</file> <file>images/rsmessenger48.png</file>
<file>images/SmileyText.png</file>
<file>images/SimpleText.png</file>
<file>images/ColoredText.png</file>
</qresource> </qresource>
</RCC> </RCC>

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -521,6 +521,7 @@ SubFileItem QProgressBar#progressBar::chunk {
border-top-left-radius: 7px; border-top-left-radius: 7px;
border-bottom-left-radius: 7px; border-bottom-left-radius: 7px;
border: 1px solid black; border: 1px solid black;
width: 15px;
} }
PluginItem QLabel#infoLabel { PluginItem QLabel#infoLabel {

View File

@ -100,7 +100,7 @@ ChatPage::ChatPage(QWidget * parent, Qt::WindowFlags flags)
/* Invoke the Qt Designer generated object setup routine */ /* Invoke the Qt Designer generated object setup routine */
ui.setupUi(this); ui.setupUi(this);
connect(ui.distantChatcomboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(distantChatComboBoxChanged(int))); connect(ui.distantChatComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(distantChatComboBoxChanged(int)));
#if QT_VERSION < 0x040600 #if QT_VERSION < 0x040600
ui.minimumContrastLabel->hide(); ui.minimumContrastLabel->hide();
@ -123,12 +123,13 @@ ChatPage::save(QString &/*errmsg*/)
Settings->setValue("MinimumContrast", ui.minimumContrast->value()); Settings->setValue("MinimumContrast", ui.minimumContrast->value());
Settings->endGroup(); Settings->endGroup();
// state of distant Chat combobox // state of distant Chat combobox
Settings->setValue("DistantChat", ui.distantChatcomboBox->currentIndex()); Settings->setValue("DistantChat", ui.distantChatComboBox->currentIndex());
Settings->setChatScreenFont(fontTempChat.toString()); Settings->setChatScreenFont(fontTempChat.toString());
NotifyQt::getInstance()->notifyChatFontChanged(); NotifyQt::getInstance()->notifyChatFontChanged();
Settings->setChatSendMessageWithCtrlReturn(ui.sendMessageWithCtrlReturn->isChecked()); Settings->setChatSendMessageWithCtrlReturn(ui.sendMessageWithCtrlReturn->isChecked());
Settings->setChatSendAsPlainTextByDef(ui.sendAsPlainTextByDef->isChecked());
Settings->setChatSearchCharToStartSearch(ui.sbSearch_CharToStart->value()); Settings->setChatSearchCharToStartSearch(ui.sbSearch_CharToStart->value());
Settings->setChatSearchCaseSensitively(ui.cbSearch_CaseSensitively->isChecked()); Settings->setChatSearchCaseSensitively(ui.cbSearch_CaseSensitively->isChecked());
@ -231,11 +232,12 @@ ChatPage::load()
// state of distant Chat combobox // state of distant Chat combobox
int index = Settings->value("DistantChat", 0).toInt(); int index = Settings->value("DistantChat", 0).toInt();
ui.distantChatcomboBox->setCurrentIndex(index); ui.distantChatComboBox->setCurrentIndex(index);
fontTempChat.fromString(Settings->getChatScreenFont()); fontTempChat.fromString(Settings->getChatScreenFont());
ui.sendMessageWithCtrlReturn->setChecked(Settings->getChatSendMessageWithCtrlReturn()); ui.sendMessageWithCtrlReturn->setChecked(Settings->getChatSendMessageWithCtrlReturn());
ui.sendAsPlainTextByDef->setChecked(Settings->getChatSendAsPlainTextByDef());
ui.sbSearch_CharToStart->setValue(Settings->getChatSearchCharToStartSearch()); ui.sbSearch_CharToStart->setValue(Settings->getChatSearchCharToStartSearch());
ui.cbSearch_CaseSensitively->setChecked(Settings->getChatSearchCaseSensitively()); ui.cbSearch_CaseSensitively->setChecked(Settings->getChatSearchCaseSensitively());

View File

@ -6,11 +6,11 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>705</width> <width>635</width>
<height>517</height> <height>600</height>
</rect> </rect>
</property> </property>
<layout class="QGridLayout" name="gridLayout_2"> <layout class="QGridLayout">
<item row="3" column="0"> <item row="3" column="0">
<widget class="QTabWidget" name="tabWidget"> <widget class="QTabWidget" name="tabWidget">
<property name="currentIndex"> <property name="currentIndex">
@ -20,15 +20,15 @@
<attribute name="title"> <attribute name="title">
<string>General</string> <string>General</string>
</attribute> </attribute>
<layout class="QGridLayout" name="gridLayout_5"> <layout class="QGridLayout" name="generalGLayout">
<item row="0" column="0" colspan="2"> <item row="0" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox_3"> <widget class="QGroupBox" name="distantGBox">
<property name="title"> <property name="title">
<string>Distant Chat</string> <string>Distant Chat</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout_4"> <layout class="QGridLayout" name="distantGBoxGLayout">
<item row="0" column="2"> <item row="0" column="2">
<widget class="QComboBox" name="distantChatcomboBox"> <widget class="QComboBox" name="distantChatComboBox">
<item> <item>
<property name="text"> <property name="text">
<string>Everyone</string> <string>Everyone</string>
@ -47,7 +47,7 @@
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="0" column="1">
<widget class="QLabel" name="distantchatlabel"> <widget class="QLabel" name="distantChatLabel">
<property name="text"> <property name="text">
<string>Accept encrypted distant chat from</string> <string>Accept encrypted distant chat from</string>
</property> </property>
@ -57,9 +57,9 @@
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="1" column="0">
<layout class="QVBoxLayout" name="verticalLayout_5"> <layout class="QVBoxLayout" name="leftVLayout">
<item> <item>
<widget class="QGroupBox" name="groupBox"> <widget class="QGroupBox" name="chatSettingsGBox">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -69,7 +69,7 @@
<property name="title"> <property name="title">
<string>Chat Settings</string> <string>Chat Settings</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_3"> <layout class="QVBoxLayout" name="chatSettingsGBoxVLayout">
<item> <item>
<widget class="QCheckBox" name="checkBox_emoteprivchat"> <widget class="QCheckBox" name="checkBox_emoteprivchat">
<property name="text"> <property name="text">
@ -111,7 +111,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="hl_minimumFontSize"> <layout class="QHBoxLayout" name="minimumFontSizeHLayout">
<property name="topMargin"> <property name="topMargin">
<number>0</number> <number>0</number>
</property> </property>
@ -123,7 +123,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<spacer name="hs_minimumFontSize"> <spacer name="minimumFontSizeHSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
@ -168,7 +168,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_40"> <layout class="QHBoxLayout" name="minimumContrastHLayout">
<item> <item>
<widget class="QLabel" name="minimumContrastLabel"> <widget class="QLabel" name="minimumContrastLabel">
<property name="text"> <property name="text">
@ -177,7 +177,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<spacer name="horizontalSpacer_2"> <spacer name="minimumContrastHSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
@ -211,15 +211,22 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QCheckBox" name="sendAsPlainTextByDef">
<property name="text">
<string>Send as plain text by default</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QGroupBox" name="chatLobbyGroupBox"> <widget class="QGroupBox" name="chatLobbyGBox">
<property name="title"> <property name="title">
<string>Chat Lobby</string> <string>Chat Lobby</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_6"> <layout class="QVBoxLayout" name="chatLobbyGBoxVLayout">
<item> <item>
<widget class="QCheckBox" name="chatLobby_Blink"> <widget class="QCheckBox" name="chatLobby_Blink">
<property name="text"> <property name="text">
@ -228,7 +235,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QLabel" name="label"> <widget class="QLabel" name="defIDLabel">
<property name="text"> <property name="text">
<string>Default identity for chat lobbies:</string> <string>Default identity for chat lobbies:</string>
</property> </property>
@ -237,7 +244,7 @@
<item> <item>
<layout class="QHBoxLayout" name="nickNameLayout"> <layout class="QHBoxLayout" name="nickNameLayout">
<item> <item>
<spacer name="horizontalSpacer"> <spacer name="chatLobbyIdentity_HSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
@ -261,7 +268,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<spacer name="verticalSpacer_2"> <spacer name="leftVSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
@ -276,13 +283,13 @@
</layout> </layout>
</item> </item>
<item row="1" column="1"> <item row="1" column="1">
<layout class="QVBoxLayout" name="verticalLayout_2"> <layout class="QVBoxLayout" name="rightVLayout">
<item> <item>
<widget class="QGroupBox" name="groupBox_2"> <widget class="QGroupBox" name="privateChatGBox">
<property name="title"> <property name="title">
<string>Private Chat</string> <string>Private Chat</string>
</property> </property>
<layout class="QVBoxLayout" name="_2"> <layout class="QVBoxLayout" name="privateChatGBoxVLayout">
<item> <item>
<widget class="QCheckBox" name="chat_NewWindow"> <widget class="QCheckBox" name="chat_NewWindow">
<property name="text"> <property name="text">
@ -315,11 +322,11 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QGroupBox" name="groupBoxIRCColors"> <widget class="QGroupBox" name="chatFontGBox">
<property name="title"> <property name="title">
<string>Chat Font</string> <string>Chat Font</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_4"> <layout class="QVBoxLayout" name="chatFontGBoxVLayout">
<property name="spacing"> <property name="spacing">
<number>2</number> <number>2</number>
</property> </property>
@ -366,7 +373,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QGroupBox" name="groupBoxSearch"> <widget class="QGroupBox" name="searchGBox">
<property name="title"> <property name="title">
<string>Search by default</string> <string>Search by default</string>
</property> </property>
@ -530,7 +537,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<spacer name="verticalSpacer"> <spacer name="rightVSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
@ -550,9 +557,9 @@
<attribute name="title"> <attribute name="title">
<string>History</string> <string>History</string>
</attribute> </attribute>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="historyVLayout">
<item> <item>
<widget class="QLabel" name="label_8"> <widget class="QLabel" name="histHeaderLabel">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum"> <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -574,11 +581,11 @@
</widget> </widget>
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_6"> <layout class="QHBoxLayout" name="histSetupVLayout">
<item> <item>
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="histSetupGLayout">
<item row="0" column="1"> <item row="0" column="1">
<widget class="QLabel" name="label_4"> <widget class="QLabel" name="publicHeaderLabel">
<property name="font"> <property name="font">
<font> <font>
<weight>75</weight> <weight>75</weight>
@ -591,7 +598,7 @@
</widget> </widget>
</item> </item>
<item row="0" column="2"> <item row="0" column="2">
<widget class="QLabel" name="label_5"> <widget class="QLabel" name="privateHeaderLabel">
<property name="font"> <property name="font">
<font> <font>
<weight>75</weight> <weight>75</weight>
@ -604,7 +611,7 @@
</widget> </widget>
</item> </item>
<item row="0" column="3"> <item row="0" column="3">
<widget class="QLabel" name="label_6"> <widget class="QLabel" name="lobbyHeaderLabel">
<property name="font"> <property name="font">
<font> <font>
<weight>75</weight> <weight>75</weight>
@ -617,7 +624,7 @@
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="QLabel" name="label_7"> <widget class="QLabel" name="labelChatEnable">
<property name="layoutDirection"> <property name="layoutDirection">
<enum>Qt::LeftToRight</enum> <enum>Qt::LeftToRight</enum>
</property> </property>
@ -651,7 +658,7 @@
</widget> </widget>
</item> </item>
<item row="2" column="0"> <item row="2" column="0">
<widget class="QLabel" name="label1"> <widget class="QLabel" name="labelChatSaveCount">
<property name="text"> <property name="text">
<string>Saved messages (0 = unlimited):</string> <string>Saved messages (0 = unlimited):</string>
</property> </property>
@ -718,7 +725,7 @@
</widget> </widget>
</item> </item>
<item row="3" column="0"> <item row="3" column="0">
<widget class="QLabel" name="label2"> <widget class="QLabel" name="labelChatLoadCount">
<property name="text"> <property name="text">
<string>Number of messages restored (0 = off):</string> <string>Number of messages restored (0 = off):</string>
</property> </property>
@ -769,7 +776,7 @@
</layout> </layout>
</item> </item>
<item> <item>
<spacer name="horizontalSpacer_4"> <spacer name="histSetupHSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
@ -784,15 +791,15 @@
</layout> </layout>
</item> </item>
<item> <item>
<widget class="QGroupBox" name="groupBox_5"> <widget class="QGroupBox" name="histGenGBox">
<property name="title"> <property name="title">
<string>General</string> <string>General</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_8"> <layout class="QVBoxLayout" name="histGenGBoxVLayout">
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_5"> <layout class="QHBoxLayout" name="max_storage_period_HLayout">
<item> <item>
<widget class="QLabel" name="label_3"> <widget class="QLabel" name="max_storage_period_Label">
<property name="text"> <property name="text">
<string>Maximum storage period, in days (0=keep all):</string> <string>Maximum storage period, in days (0=keep all):</string>
</property> </property>
@ -802,7 +809,7 @@
<widget class="QSpinBox" name="max_storage_period"/> <widget class="QSpinBox" name="max_storage_period"/>
</item> </item>
<item> <item>
<spacer name="horizontalSpacer_3"> <spacer name="max_storage_period_HSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
@ -820,7 +827,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<spacer name="verticalSpacer_4"> <spacer name="histVSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
@ -838,7 +845,7 @@
<attribute name="title"> <attribute name="title">
<string>Style</string> <string>Style</string>
</attribute> </attribute>
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="styleHLayout">
<item> <item>
<widget class="QTabWidget" name="styleTabWidget"> <widget class="QTabWidget" name="styleTabWidget">
<property name="tabPosition"> <property name="tabPosition">
@ -851,11 +858,11 @@
<attribute name="title"> <attribute name="title">
<string>Group chat</string> <string>Group chat</string>
</attribute> </attribute>
<layout class="QVBoxLayout" name="publicLayout_1"> <layout class="QVBoxLayout" name="publicTabVLayout">
<item> <item>
<layout class="QHBoxLayout" name="publiclLayout_2"> <layout class="QHBoxLayout" name="publicStyleHLayout">
<item> <item>
<layout class="QVBoxLayout" name="publicLayout_3"> <layout class="QVBoxLayout" name="publicStyleListVLayout">
<item> <item>
<widget class="QListWidget" name="publicList"> <widget class="QListWidget" name="publicList">
<property name="sizePolicy"> <property name="sizePolicy">
@ -873,7 +880,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="publicLayout_4"> <layout class="QHBoxLayout" name="publicStyleVarHLayout">
<item> <item>
<widget class="QLabel" name="publicLabelVariant"> <widget class="QLabel" name="publicLabelVariant">
<property name="sizePolicy"> <property name="sizePolicy">
@ -921,7 +928,7 @@
<enum>QLayout::SetFixedSize</enum> <enum>QLayout::SetFixedSize</enum>
</property> </property>
<item> <item>
<widget class="QLabel" name="labelPublicAuthor"> <widget class="QLabel" name="publicLabelAuthor">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -934,7 +941,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QLabel" name="labelPublicDescription"> <widget class="QLabel" name="publicLabelDescription">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -986,11 +993,11 @@
<attribute name="title"> <attribute name="title">
<string>Private chat</string> <string>Private chat</string>
</attribute> </attribute>
<layout class="QVBoxLayout" name="privateLayout_1"> <layout class="QVBoxLayout" name="privateTabVLayout">
<item> <item>
<layout class="QHBoxLayout" name="privatelLayout_2"> <layout class="QHBoxLayout" name="privateStyleHLayout">
<item> <item>
<layout class="QVBoxLayout" name="privateLayout_3"> <layout class="QVBoxLayout" name="privateStyleListVLayout">
<item> <item>
<widget class="QListWidget" name="privateList"> <widget class="QListWidget" name="privateList">
<property name="sizePolicy"> <property name="sizePolicy">
@ -1008,7 +1015,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="privateLayout_4"> <layout class="QHBoxLayout" name="privateStyleVarHLayout">
<item> <item>
<widget class="QLabel" name="privateLabelVariant"> <widget class="QLabel" name="privateLabelVariant">
<property name="sizePolicy"> <property name="sizePolicy">
@ -1056,7 +1063,7 @@
<enum>QLayout::SetFixedSize</enum> <enum>QLayout::SetFixedSize</enum>
</property> </property>
<item> <item>
<widget class="QLabel" name="labelPrivateAuthor"> <widget class="QLabel" name="privateLabelAuthor">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -1069,7 +1076,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QLabel" name="labelPrivateDescription"> <widget class="QLabel" name="privateLabelDescription">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -1121,11 +1128,11 @@
<attribute name="title"> <attribute name="title">
<string>History</string> <string>History</string>
</attribute> </attribute>
<layout class="QVBoxLayout" name="historyLayout_1"> <layout class="QVBoxLayout" name="historyTabVLayout">
<item> <item>
<layout class="QHBoxLayout" name="historylLayout_2"> <layout class="QHBoxLayout" name="historyStyleHLayout">
<item> <item>
<layout class="QVBoxLayout" name="historyLayout_3"> <layout class="QVBoxLayout" name="historyStyleListVLayout">
<item> <item>
<widget class="QListWidget" name="historyList"> <widget class="QListWidget" name="historyList">
<property name="sizePolicy"> <property name="sizePolicy">
@ -1143,7 +1150,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="historyLayout_4"> <layout class="QHBoxLayout" name="historyStyleVarHLayout">
<item> <item>
<widget class="QLabel" name="historyLabelVariant"> <widget class="QLabel" name="historyLabelVariant">
<property name="sizePolicy"> <property name="sizePolicy">
@ -1191,7 +1198,7 @@
<enum>QLayout::SetFixedSize</enum> <enum>QLayout::SetFixedSize</enum>
</property> </property>
<item> <item>
<widget class="QLabel" name="labelHistoryAuthor"> <widget class="QLabel" name="historyLabelAuthor">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -1204,7 +1211,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QLabel" name="labelHistoryDescription"> <widget class="QLabel" name="historyLabelDescription">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch> <horstretch>0</horstretch>

View File

@ -48,6 +48,7 @@ GeneralPage::GeneralPage(QWidget * parent, Qt::WindowFlags flags)
ui.chkRunRetroshareAtSystemStartup->setEnabled(false); ui.chkRunRetroshareAtSystemStartup->setEnabled(false);
ui.chkRunRetroshareAtSystemStartupMinimized->setEnabled(false); ui.chkRunRetroshareAtSystemStartupMinimized->setEnabled(false);
#endif #endif
ui.desktopFileMissingLabel->setVisible(false);
#else #else
ui.chkRunRetroshareAtSystemStartup->setVisible(false); ui.chkRunRetroshareAtSystemStartup->setVisible(false);

View File

@ -512,6 +512,26 @@ void RshareSettings::setChatSendMessageWithCtrlReturn(bool bValue)
setValueToGroup("Chat", "SendMessageWithCtrlReturn", bValue); setValueToGroup("Chat", "SendMessageWithCtrlReturn", bValue);
} }
bool RshareSettings::getChatSendAsPlainTextByDef()
{
return valueFromGroup("Chat", "SendAsPlainTextByDef", false).toBool();
}
void RshareSettings::setChatSendAsPlainTextByDef(bool bValue)
{
setValueToGroup("Chat", "SendAsPlainTextByDef", bValue);
}
bool RshareSettings::getChatSearchShowBarByDefault()
{
return valueFromGroup("Chat", "SearchShowBarByDefault", false).toBool();
}
void RshareSettings::setChatSearchShowBarByDefault(bool bValue)
{
setValueToGroup("Chat", "SearchShowBarByDefault", bValue);
}
void RshareSettings::setChatSearchCharToStartSearch(int iValue) void RshareSettings::setChatSearchCharToStartSearch(int iValue)
{ {
setValueToGroup("Chat", "SearchCharToStartSearch", iValue); setValueToGroup("Chat", "SearchCharToStartSearch", iValue);

View File

@ -209,6 +209,12 @@ public:
bool getChatSendMessageWithCtrlReturn(); bool getChatSendMessageWithCtrlReturn();
void setChatSendMessageWithCtrlReturn(bool bValue); void setChatSendMessageWithCtrlReturn(bool bValue);
bool getChatSendAsPlainTextByDef();
void setChatSendAsPlainTextByDef(bool bValue);
bool getChatSearchShowBarByDefault();
void setChatSearchShowBarByDefault(bool bValue);
void setChatSearchCharToStartSearch(int iValue); void setChatSearchCharToStartSearch(int iValue);
int getChatSearchCharToStartSearch(); int getChatSearchCharToStartSearch();

View File

@ -46,6 +46,10 @@
#include "util/RsGxsUpdateBroadcast.h" #include "util/RsGxsUpdateBroadcast.h"
#include "gui/settings/WebuiPage.h" #include "gui/settings/WebuiPage.h"
#ifdef SIGFPE_DEBUG
#include <fenv.h>
#endif
#if QT_VERSION >= QT_VERSION_CHECK (5, 0, 0) #if QT_VERSION >= QT_VERSION_CHECK (5, 0, 0)
#ifdef WINDOWS_SYS #ifdef WINDOWS_SYS
#include <QFileDialog> #include <QFileDialog>
@ -155,6 +159,9 @@ int main(int argc, char *argv[])
QApplication app(argc, argv); QApplication app(argc, argv);
QDir::setCurrent(QCoreApplication::applicationDirPath()); QDir::setCurrent(QCoreApplication::applicationDirPath());
} }
#endif
#ifdef SIGFPE_DEBUG
feenableexcept(FE_INVALID | FE_DIVBYZERO);
#endif #endif
QStringList args = char_array_to_stringlist(argv+1, argc-1); QStringList args = char_array_to_stringlist(argv+1, argc-1);

View File

@ -27,9 +27,11 @@ QProgressBar:horizontal {
text-align: center; text-align: center;
padding: 1px; padding: 1px;
background: #201F1F; background: #201F1F;
width: 15px;
} }
QProgressBar::chunk:horizontal { QProgressBar::chunk:horizontal {
background-color: qlineargradient(spread:reflect, x1:1, y1:0.545, x2:1, y2:0, stop:0 rgba(28, 66, 111, 255), stop:1 rgba(37, 87, 146, 255)); background-color: qlineargradient(spread:reflect, x1:1, y1:0.545, x2:1, y2:0, stop:0 rgba(28, 66, 111, 255), stop:1 rgba(37, 87, 146, 255));
width: 15px;
} }
QFrame#titleBarFrame, QFrame#toolBarFrame QFrame#titleBarFrame, QFrame#toolBarFrame

View File

@ -12,6 +12,7 @@ DEFINES += TARGET=\\\"$TARGET\\\"
# #
#CONFIG += unfinished #CONFIG += unfinished
#CONFIG += debug #CONFIG += debug
#DEFINES *= SIGFPE_DEBUG
#QMAKE_CFLAGS += -fmudflap #QMAKE_CFLAGS += -fmudflap
#LIBS *= /usr/lib/gcc/x86_64-linux-gnu/4.4/libmudflap.a /usr/lib/gcc/x86_64-linux-gnu/4.4/libmudflapth.a #LIBS *= /usr/lib/gcc/x86_64-linux-gnu/4.4/libmudflap.a /usr/lib/gcc/x86_64-linux-gnu/4.4/libmudflapth.a
@ -196,7 +197,7 @@ win32 {
LIBS += -Wl,--export-all-symbols,--out-implib,lib/libretroshare-gui.a LIBS += -Wl,--export-all-symbols,--out-implib,lib/libretroshare-gui.a
# create lib directory # create lib directory
QMAKE_PRE_LINK = $(CHK_DIR_EXISTS) lib $(MKDIR) lib QMAKE_PRE_LINK = $(CHK_DIR_EXISTS) lib || $(MKDIR) lib
DEFINES *= WINDOWS_SYS WIN32_LEAN_AND_MEAN _USE_32BIT_TIME_T DEFINES *= WINDOWS_SYS WIN32_LEAN_AND_MEAN _USE_32BIT_TIME_T

View File

@ -167,6 +167,9 @@ Rshare::Rshare(QStringList args, int &argc, char **argv, const QString &dir)
std::cerr << "Rshare::Rshare Connection etablished. Waiting for disconnection." << std::endl; std::cerr << "Rshare::Rshare Connection etablished. Waiting for disconnection." << std::endl;
localSocket.waitForDisconnected(1000); localSocket.waitForDisconnected(1000);
newArgs.detach(); newArgs.detach();
std::cerr << "Rshare::Rshare Arguments was sended." << std::endl
<< " To disable it, in Options - General - Misc," << std::endl
<< " uncheck \"Use Local Server to get new Arguments\"." << std::endl;
::exit(EXIT_SUCCESS); // Terminate the program using STDLib's exit function ::exit(EXIT_SUCCESS); // Terminate the program using STDLib's exit function
} }
newArgs.detach(); newArgs.detach();

View File

@ -874,6 +874,12 @@ static void styleCreate(QDomDocument& doc
optAttr = doc.createAttribute("RSOptimized"); optAttr = doc.createAttribute("RSOptimized");
optAttr.setValue("v2"); optAttr.setValue("v2");
styleElem.attributes().setNamedItem(optAttr); styleElem.attributes().setNamedItem(optAttr);
if (flag & RSHTML_FORMATTEXT_NO_EMBED) {
QDomAttr noEmbedAttr;
noEmbedAttr = doc.createAttribute("NoEmbed");
noEmbedAttr.setValue("true");
styleElem.attributes().setNamedItem(noEmbedAttr);
}
} }
while(styleElem.childNodes().count()>0) { while(styleElem.childNodes().count()>0) {

View File

@ -31,19 +31,19 @@
#define HANDLE_RICH_TEXT_H_ #define HANDLE_RICH_TEXT_H_
/* Flags for RsHtml::formatText */ /* Flags for RsHtml::formatText */
#define RSHTML_FORMATTEXT_EMBED_SMILEYS 1 #define RSHTML_FORMATTEXT_EMBED_SMILEYS 0x0001//1
#define RSHTML_FORMATTEXT_EMBED_LINKS 2 #define RSHTML_FORMATTEXT_EMBED_LINKS 0x0002//2
#define RSHTML_FORMATTEXT_OPTIMIZE 4 #define RSHTML_FORMATTEXT_OPTIMIZE 0x0004//4
#define RSHTML_FORMATTEXT_REPLACE_LINKS 8 #define RSHTML_FORMATTEXT_REPLACE_LINKS 0x0008//8
#define RSHTML_FORMATTEXT_REMOVE_COLOR 16 #define RSHTML_FORMATTEXT_REMOVE_COLOR 0x0010//16
#define RSHTML_FORMATTEXT_FIX_COLORS 32 /* Make text readable */ #define RSHTML_FORMATTEXT_FIX_COLORS 0x0020//32 /* Make text readable */
#define RSHTML_FORMATTEXT_REMOVE_FONT_WEIGHT 64 /* Remove bold */ #define RSHTML_FORMATTEXT_REMOVE_FONT_WEIGHT 0x0040//64 /* Remove bold */
#define RSHTML_FORMATTEXT_REMOVE_FONT_STYLE 128 /* Remove italics */ #define RSHTML_FORMATTEXT_REMOVE_FONT_STYLE 0x0080//128 /* Remove italics */
#define RSHTML_FORMATTEXT_REMOVE_FONT_FAMILY 256 #define RSHTML_FORMATTEXT_REMOVE_FONT_FAMILY 0x0100//256
#define RSHTML_FORMATTEXT_REMOVE_FONT_SIZE 512 #define RSHTML_FORMATTEXT_REMOVE_FONT_SIZE 0x0200//512
#define RSHTML_FORMATTEXT_REMOVE_FONT (RSHTML_FORMATTEXT_REMOVE_FONT_WEIGHT | RSHTML_FORMATTEXT_REMOVE_FONT_STYLE | RSHTML_FORMATTEXT_REMOVE_FONT_FAMILY | RSHTML_FORMATTEXT_REMOVE_FONT_SIZE) #define RSHTML_FORMATTEXT_REMOVE_FONT (RSHTML_FORMATTEXT_REMOVE_FONT_WEIGHT | RSHTML_FORMATTEXT_REMOVE_FONT_STYLE | RSHTML_FORMATTEXT_REMOVE_FONT_FAMILY | RSHTML_FORMATTEXT_REMOVE_FONT_SIZE)
#define RSHTML_FORMATTEXT_CLEANSTYLE (RSHTML_FORMATTEXT_REMOVE_FONT | RSHTML_FORMATTEXT_REMOVE_COLOR) #define RSHTML_FORMATTEXT_CLEANSTYLE (RSHTML_FORMATTEXT_REMOVE_FONT | RSHTML_FORMATTEXT_REMOVE_COLOR)
#define RSHTML_FORMATTEXT_NO_EMBED 0x0400//1024
/* Flags for RsHtml::optimizeHtml */ /* Flags for RsHtml::optimizeHtml */
#define RSHTML_OPTIMIZEHTML_MASK (RSHTML_FORMATTEXT_CLEANSTYLE | RSHTML_FORMATTEXT_FIX_COLORS | RSHTML_FORMATTEXT_OPTIMIZE) #define RSHTML_OPTIMIZEHTML_MASK (RSHTML_FORMATTEXT_CLEANSTYLE | RSHTML_FORMATTEXT_FIX_COLORS | RSHTML_FORMATTEXT_OPTIMIZE)

View File

@ -5,26 +5,34 @@
#don't exit even if a command fails #don't exit even if a command fails
set +e set +e
OLDLANG=${LANG}
export LANG=C
SCRIPT_PATH=$(dirname "`readlink -f "${0}"`")
if (ls &> /dev/null); then if (ls &> /dev/null); then
echo "Retroshare Gui version : " > gui/help/version.html echo "Retroshare Gui version : " > ${SCRIPT_PATH}/gui/help/version.html
if ( /usr/bin/git log -n 1 &> /dev/null); then if ( /usr/bin/git log -n 1 &> /dev/null); then
#retrieve git information #retrieve git information
echo "Git version : $(git status | grep branch | cut -c 3-) $(git log -n 1 | grep commit)" >> gui/help/version.html echo "Git version : $(git status | grep branch | head -n 1 | cut -c 4-) $(git log -n 1 | grep commit)" >> ${SCRIPT_PATH}/gui/help/version.html
fi fi
if ( /usr/bin/git log -n 1 | grep svn &> /dev/null); then if ( /usr/bin/git log -n 1 | grep svn &> /dev/null); then
#retrieve git svn information #retrieve git svn information
echo "Svn version : $(git log -n 1 | awk '/svn/ {print $2}' | head -1)" >> gui/help/version.html echo "Svn version : $(git log -n 1 | awk '/svn/ {print $2}' | head -1)" >> ${SCRIPT_PATH}/gui/help/version.html
elif ( /usr/bin/git log -n 10 | grep svn &> /dev/null); then elif ( /usr/bin/git log -n 10 | grep svn &> /dev/null); then
#retrieve git svn information #retrieve git svn information
echo "Svn closest version : $(git log -n 10 | awk '/svn/ {print $2}' | head -1)" >> gui/help/version.html echo "Svn closest version : $(git log -n 10 | awk '/svn/ {print $2}' | head -1)" >> ${SCRIPT_PATH}/gui/help/version.html
fi fi
if ( /usr/bin/svn info &> /dev/null); then if ( /usr/bin/svn info &> /dev/null); then
echo "Svn version : $(svn info | awk '/^Revision:/ {print $NF}')" >> gui/help/version.html echo "Svn version : $(svn info | awk '/^Revision:/ {print $NF}')" >> ${SCRIPT_PATH}/gui/help/version.html
fi fi
date >> gui/help/version.html date >> ${SCRIPT_PATH}/gui/help/version.html
echo "" >> gui/help/version.html echo "" >> ${SCRIPT_PATH}/gui/help/version.html
echo "" >> gui/help/version.html echo "" >> ${SCRIPT_PATH}/gui/help/version.html
fi fi
export LANG=${OLDLANG}
echo "version_detail.sh scripts finished" echo "version_detail.sh scripts finished"
exit 0 exit 0