diff --git a/libretroshare/src/chat/distributedchat.cc b/libretroshare/src/chat/distributedchat.cc index 7a683c2eb..aad26967c 100644 --- a/libretroshare/src/chat/distributedchat.cc +++ b/libretroshare/src/chat/distributedchat.cc @@ -34,6 +34,7 @@ #include "pqi/p3historymgr.h" #include "retroshare/rspeers.h" #include "retroshare/rsiface.h" +#include "retroshare/rsreputations.h" #include "retroshare/rsidentity.h" #include "rsserver/p3face.h" #include "gxs/rsgixs.h" @@ -175,6 +176,12 @@ bool DistributedChatService::handleRecvChatLobbyMsgItem(RsChatMsgItem *ci) return false ; } } + if(rsReputations->isIdentityBanned(cli->signature.keyId)) + { + std::cerr << "(WW) Received lobby msg/item from banned identity " << cli->signature.keyId << ". Dropping it." << std::endl; + return false ; + } + if(!bounceLobbyObject(cli,cli->PeerId())) // forwards the message to friends, keeps track of subscribers, etc. return false; @@ -672,6 +679,11 @@ void DistributedChatService::handleRecvChatLobbyEventItem(RsChatLobbyEventItem * return ; } } + if(rsReputations->isIdentityBanned(item->signature.keyId)) + { + std::cerr << "(WW) Received lobby msg/item from banned identity " << item->signature.keyId << ". Dropping it." << std::endl; + return ; + } addTimeShiftStatistics((int)now - (int)item->sendTime) ; if(now+100 > (time_t) item->sendTime + MAX_KEEP_MSG_RECORD) // the message is older than the max cache keep minus 100 seconds ! It's too old, and is going to make an echo! diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index 8806b4e1c..64fe31f76 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -30,6 +30,7 @@ #include "rsgxsnetservice.h" #include "retroshare/rsconfig.h" +#include "retroshare/rsreputations.h" #include "retroshare/rsgxsflags.h" #include "retroshare/rsgxscircles.h" #include "pgp/pgpauxutils.h" @@ -1996,7 +1997,13 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr) std::cerr << ", no group meta found. Givign up." << std::endl; continue; } - + + if(rsReputations->isIdentityBanned(syncItem->authorId)) + { + std::cerr << ", Identity " << syncItem->authorId << " is banned. Not requesting message!" << std::endl; + continue ; + } + if(mReputations->haveReputation(syncItem->authorId) || noAuthor) { GixsReputation rep; @@ -2009,7 +2016,7 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr) // if author is required for this message, it will simply get dropped // at genexchange side of things - if(rep.score > (int)grpMeta->mReputationCutOff || noAuthor) + if(rep.score >= (int)grpMeta->mReputationCutOff || noAuthor) { #ifdef NXS_NET_DEBUG std::cerr << ", passed! Adding message to req list." << std::endl; @@ -2210,7 +2217,13 @@ void RsGxsNetService::locked_genReqGrpTransaction(NxsTransaction* tr) haveItem = true; latestVersion = grpSyncItem->publishTs > metaIter->second->mPublishTs; } - + + if(!grpSyncItem->authorId.isNull() && rsReputations->isIdentityBanned(grpSyncItem->authorId)) + { + std::cerr << " Identity " << grpSyncItem->authorId << " is banned. Not syncing group." << std::endl; + continue ; + } + if( (mGrpAutoSync && !haveItem) || latestVersion) { // determine if you need to check reputation diff --git a/libretroshare/src/gxs/rsgxsnetutils.cc b/libretroshare/src/gxs/rsgxsnetutils.cc index eb6dfb3d2..76dd8a68d 100644 --- a/libretroshare/src/gxs/rsgxsnetutils.cc +++ b/libretroshare/src/gxs/rsgxsnetutils.cc @@ -99,7 +99,7 @@ bool MsgRespPending::accepted() GixsReputation rep; if(getAuthorRep(rep, entry.mAuthorId, mPeerId)) { - if(rep.score > mCutOff) + if(rep.score >= mCutOff) { entry.mPassedVetting = true; count++; @@ -134,7 +134,7 @@ bool GrpRespPending::accepted() if(getAuthorRep(rep, entry.mAuthorId, mPeerId)) { - if(rep.score > mCutOff) + if(rep.score >= mCutOff) { entry.mPassedVetting = true; count++; diff --git a/libretroshare/src/libretroshare.pro b/libretroshare/src/libretroshare.pro index 5fd192e5b..9c0ee33e6 100644 --- a/libretroshare/src/libretroshare.pro +++ b/libretroshare/src/libretroshare.pro @@ -1,842 +1,843 @@ -!include("../../retroshare.pri"): error("Could not include file ../../retroshare.pri") - -TEMPLATE = lib -CONFIG += staticlib bitdht -CONFIG += create_prl -CONFIG -= qt -TARGET = retroshare -TARGET_PRL = libretroshare -DESTDIR = lib - -#CONFIG += dsdv - -profiling { - QMAKE_CXXFLAGS -= -fomit-frame-pointer - QMAKE_CXXFLAGS *= -pg -g -fno-omit-frame-pointer -} - -# treat warnings as error for better removing -#QMAKE_CFLAGS += -Werror -#QMAKE_CXXFLAGS += -Werror - -debug { -# DEFINES *= DEBUG -# DEFINES *= OPENDHT_DEBUG DHT_DEBUG CONN_DEBUG DEBUG_UDP_SORTER P3DISC_DEBUG DEBUG_UDP_LAYER FT_DEBUG EXTADDRSEARCH_DEBUG -# DEFINES *= CONTROL_DEBUG FT_DEBUG DEBUG_FTCHUNK P3TURTLE_DEBUG -# DEFINES *= P3TURTLE_DEBUG -# DEFINES *= NET_DEBUG -# DEFINES *= DISTRIB_DEBUG -# DEFINES *= P3TURTLE_DEBUG FT_DEBUG DEBUG_FTCHUNK MPLEX_DEBUG -# DEFINES *= STATUS_DEBUG SERV_DEBUG RSSERIAL_DEBUG #CONN_DEBUG - - QMAKE_CXXFLAGS -= -O2 -fomit-frame-pointer - QMAKE_CXXFLAGS *= -g -fno-omit-frame-pointer -} - -dsdv { -DEFINES *= SERVICES_DSDV -HEADERS += services/p3dsdv.h \ - serialiser/rstlvdsdv.h \ - serialiser/rsdsdvitems.h \ - retroshare/rsdsdv.h - -SOURCES *= serialiser/rstlvdsdv.cc \ - serialiser/rsdsdvitems.cc \ - services/p3dsdv.cc -} -bitdht { - -HEADERS += dht/p3bitdht.h \ - dht/connectstatebox.h \ - dht/stunaddrassist.h - -SOURCES += dht/p3bitdht.cc \ - dht/p3bitdht_interface.cc \ - dht/p3bitdht_peers.cc \ - dht/p3bitdht_peernet.cc \ - dht/p3bitdht_relay.cc \ - dht/connectstatebox.cc - -HEADERS += tcponudp/udppeer.h \ - tcponudp/bio_tou.h \ - tcponudp/tcppacket.h \ - tcponudp/tcpstream.h \ - tcponudp/tou.h \ - tcponudp/udpstunner.h \ - tcponudp/udprelay.h \ - -SOURCES += tcponudp/udppeer.cc \ - tcponudp/tcppacket.cc \ - tcponudp/tcpstream.cc \ - tcponudp/tou.cc \ - tcponudp/bss_tou.c \ - tcponudp/udpstunner.cc \ - tcponudp/udprelay.cc \ - - DEFINES *= RS_USE_BITDHT - - BITDHT_DIR = ../../libbitdht/src - DEPENDPATH += . $${BITDHT_DIR} - INCLUDEPATH += . $${BITDHT_DIR} - PRE_TARGETDEPS *= $${BITDHT_DIR}/lib/libbitdht.a - LIBS *= $${BITDHT_DIR}/lib/libbitdht.a -} - - - - -PUBLIC_HEADERS = retroshare/rsdisc.h \ - retroshare/rsexpr.h \ - retroshare/rsfiles.h \ - retroshare/rshistory.h \ - retroshare/rsids.h \ - retroshare/rsiface.h \ - retroshare/rsinit.h \ - retroshare/rsplugin.h \ - retroshare/rsloginhandler.h \ - retroshare/rsmsgs.h \ - retroshare/rsnotify.h \ - retroshare/rspeers.h \ - retroshare/rsrank.h \ - retroshare/rsstatus.h \ - retroshare/rsturtle.h \ - retroshare/rsbanlist.h \ - retroshare/rstypes.h \ - retroshare/rsdht.h \ - retroshare/rsrtt.h \ - retroshare/rsconfig.h \ - retroshare/rsversion.h \ - retroshare/rsservicecontrol.h \ - - -HEADERS += plugins/pluginmanager.h \ - plugins/dlfcn_win32.h \ - serialiser/rspluginitems.h \ - util/rsinitedptr.h - -HEADERS += $$PUBLIC_HEADERS - - -################################# Linux ########################################## -linux-* { - CONFIG += link_pkgconfig - - QMAKE_CXXFLAGS *= -Wall -D_FILE_OFFSET_BITS=64 - QMAKE_CC = g++ - - contains(CONFIG, NO_SQLCIPHER) { - DEFINES *= NO_SQLCIPHER - PKGCONFIG *= sqlite3 - } else { - SQLCIPHER_OK = $$system(pkg-config --exists sqlcipher && echo yes) - isEmpty(SQLCIPHER_OK) { - # We need a explicit path here, to force using the home version of sqlite3 that really encrypts the database. - exists(../../../lib/sqlcipher/.libs/libsqlcipher.a) { - LIBS += ../../../lib/sqlcipher/.libs/libsqlcipher.a - DEPENDPATH += ../../../lib/ - INCLUDEPATH += ../../../lib/ - } else { - error("libsqlcipher is not installed and libsqlcipher.a not found. SQLCIPHER is necessary for encrypted database, to build with unencrypted database, run: qmake CONFIG+=NO_SQLCIPHER") - } - } else { - # Workaround for broken sqlcipher packages, e.g. Ubuntu 14.04 - # https://bugs.launchpad.net/ubuntu/+source/sqlcipher/+bug/1493928 - # PKGCONFIG *= sqlcipher - LIBS *= -lsqlcipher - } - } - - #CONFIG += version_detail_bash_script - - # linux/bsd can use either - libupnp is more complete and packaged. - #CONFIG += upnp_miniupnpc - CONFIG += upnp_libupnp - - # Check if the systems libupnp has been Debian-patched - system(grep -E 'char[[:space:]]+PublisherUrl' /usr/include/upnp/upnp.h >/dev/null 2>&1) { - # Normal libupnp - } else { - # Patched libupnp or new unreleased version - DEFINES *= PATCHED_LIBUPNP - } - - DEFINES *= UBUNTU - PKGCONFIG *= gnome-keyring-1 - PKGCONFIG *= libssl libupnp - PKGCONFIG *= libcrypto zlib - LIBS *= -lpthread -ldl -} - -unix { - DEFINES *= PLUGIN_DIR=\"\\\"$${PLUGIN_DIR}\\\"\" - DEFINES *= DATA_DIR=\"\\\"$${DATA_DIR}\\\"\" - - ## where to put the librarys interface - #include_rsiface.path = "$${INC_DIR}" - #include_rsiface.files = $$PUBLIC_HEADERS - #INSTALLS += include_rsiface - - ## where to put the shared library itself - #target.path = "$$LIB_DIR" - #INSTALLS *= target -} - -linux-g++ { - OBJECTS_DIR = temp/linux-g++/obj -} - -linux-g++-64 { - OBJECTS_DIR = temp/linux-g++-64/obj -} - -version_detail_bash_script { - linux-* { - QMAKE_EXTRA_TARGETS += write_version_detail - PRE_TARGETDEPS = write_version_detail - write_version_detail.commands = ./version_detail.sh - } - win32 { - QMAKE_EXTRA_TARGETS += write_version_detail - PRE_TARGETDEPS = write_version_detail - write_version_detail.commands = $$PWD/version_detail.bat - } -} - -#################### Cross compilation for windows under Linux #################### - -win32-x-g++ { - OBJECTS_DIR = temp/win32xgcc/obj - DEFINES *= WINDOWS_SYS WIN32 WIN_CROSS_UBUNTU - QMAKE_CXXFLAGS *= -Wmissing-include-dirs - QMAKE_CC = i586-mingw32msvc-g++ - QMAKE_LIB = i586-mingw32msvc-ar - QMAKE_AR = i586-mingw32msvc-ar - DEFINES *= STATICLIB WIN32 - - CONFIG += upnp_miniupnpc - - SSL_DIR=../../../../openssl - UPNPC_DIR = ../../../../miniupnpc-1.3 - GPG_ERROR_DIR = ../../../../libgpg-error-1.7 - GPGME_DIR = ../../../../gpgme-1.1.8 - - INCLUDEPATH *= /usr/i586-mingw32msvc/include ${HOME}/.wine/drive_c/pthreads/include/ -} -################################# Windows ########################################## - -win32 { - QMAKE_CC = g++ - OBJECTS_DIR = temp/obj - MOC_DIR = temp/moc - DEFINES *= WINDOWS_SYS WIN32 STATICLIB MINGW WIN32_LEAN_AND_MEAN _USE_32BIT_TIME_T - DEFINES *= MINIUPNPC_VERSION=13 - # This defines the platform to be WinXP or later and is needed for getaddrinfo (_WIN32_WINNT_WINXP) - DEFINES *= WINVER=0x0501 - - # Switch on extra warnings - QMAKE_CFLAGS += -Wextra - QMAKE_CXXFLAGS += -Wextra - - # Switch off optimization for release version - QMAKE_CXXFLAGS_RELEASE -= -O2 - QMAKE_CXXFLAGS_RELEASE += -O0 - QMAKE_CFLAGS_RELEASE -= -O2 - QMAKE_CFLAGS_RELEASE += -O0 - - # Switch on optimization for debug version - #QMAKE_CXXFLAGS_DEBUG += -O2 - #QMAKE_CFLAGS_DEBUG += -O2 - - DEFINES += USE_CMD_ARGS - - CONFIG += upnp_miniupnpc - - LIBS += -lsqlcipher - - LIBS_DIR = $$PWD/../../../libs - - DEPENDPATH += . $$LIBS_DIR/include $$LIBS_DIR/include/miniupnpc - INCLUDEPATH += . $$LIBS_DIR/include $$LIBS_DIR/include/miniupnpc -} - -################################# MacOSX ########################################## - -mac { - QMAKE_CC = g++ - OBJECTS_DIR = temp/obj - MOC_DIR = temp/moc - #DEFINES = WINDOWS_SYS WIN32 STATICLIB MINGW - DEFINES *= MINIUPNPC_VERSION=13 - - CONFIG += upnp_miniupnpc - - # zeroconf disabled at the end of libretroshare.pro (but need the code) - #CONFIG += zeroconf - #CONFIG += zcnatassist - - # Beautiful Hack to fix 64bit file access. - QMAKE_CXXFLAGS *= -Dfseeko64=fseeko -Dftello64=ftello -Dfopen64=fopen -Dvstatfs64=vstatfs - - UPNPC_DIR = ../../../miniupnpc-1.3 - #GPG_ERROR_DIR = ../../../../libgpg-error-1.7 - #GPGME_DIR = ../../../../gpgme-1.1.8 - - INCLUDEPATH += . $${UPNPC_DIR} - - #INCLUDEPATH += . $${UPNPC_DIR} $${GPGME_DIR}/src $${GPG_ERROR_DIR}/src - - # We need a explicit path here, to force using the home version of sqlite3 that really encrypts the database. - LIBS += ../../../lib/libsqlcipher.a - #LIBS += -lsqlite3 -} - -################################# FreeBSD ########################################## - -freebsd-* { - INCLUDEPATH *= /usr/local/include/gpgme - INCLUDEPATH *= /usr/local/include/glib-2.0 - - QMAKE_CXXFLAGS *= -Dfseeko64=fseeko -Dftello64=ftello -Dstat64=stat -Dstatvfs64=statvfs -Dfopen64=fopen - - # linux/bsd can use either - libupnp is more complete and packaged. - #CONFIG += upnp_miniupnpc - CONFIG += upnp_libupnp -} - -################################# OpenBSD ########################################## - -openbsd-* { - INCLUDEPATH *= /usr/local/include - INCLUDEPATH += $$system(pkg-config --cflags glib-2.0 | sed -e "s/-I//g") - - QMAKE_CXXFLAGS *= -Dfseeko64=fseeko -Dftello64=ftello -Dstat64=stat -Dstatvfs64=statvfs -Dfopen64=fopen - - CONFIG += upnp_libupnp -} - -################################### COMMON stuff ################################## - -# openpgpsdk -OPENPGPSDK_DIR = ../../openpgpsdk/src -DEPENDPATH *= $${OPENPGPSDK_DIR} -INCLUDEPATH *= $${OPENPGPSDK_DIR} -PRE_TARGETDEPS *= $${OPENPGPSDK_DIR}/lib/libops.a -LIBS *= $${OPENPGPSDK_DIR}/lib/libops.a -lbz2 - -HEADERS += dbase/cachestrapper.h \ - dbase/fimonitor.h \ - dbase/findex.h \ - dbase/fistore.h - -HEADERS += ft/ftchunkmap.h \ - ft/ftcontroller.h \ - ft/ftdata.h \ - ft/ftdatamultiplex.h \ - ft/ftdbase.h \ - ft/ftextralist.h \ - ft/ftfilecreator.h \ - ft/ftfileprovider.h \ - ft/ftfilesearch.h \ - ft/ftsearch.h \ - ft/ftserver.h \ - ft/fttransfermodule.h \ - ft/ftturtlefiletransferitem.h - -HEADERS += chat/distantchat.h \ - chat/p3chatservice.h \ - chat/distributedchat.h \ - chat/rschatitems.h - -HEADERS += pqi/authssl.h \ - pqi/authgpg.h \ - pqi/rsmemory.h \ - pgp/pgphandler.h \ - pgp/pgpkeyutil.h \ - pgp/rsaes.h \ - pgp/rscertificate.h \ - pgp/pgpauxutils.h \ - pqi/p3cfgmgr.h \ - pqi/p3peermgr.h \ - pqi/p3linkmgr.h \ - pqi/p3netmgr.h \ - pqi/p3notify.h \ - pqi/p3upnpmgr.h \ - pqi/pqiqos.h \ - pqi/pqi.h \ - pqi/pqi_base.h \ - pqi/pqiarchive.h \ - pqi/pqiassist.h \ - pqi/pqibin.h \ - pqi/pqihandler.h \ - pqi/pqihash.h \ - pqi/p3historymgr.h \ - pqi/pqiindic.h \ - pqi/pqiipset.h \ - pqi/pqilistener.h \ - pqi/pqiloopback.h \ - pqi/pqimonitor.h \ - pqi/pqinetwork.h \ - pqi/pqiperson.h \ - pqi/pqipersongrp.h \ - pqi/pqiservice.h \ - pqi/pqissl.h \ - pqi/pqissllistener.h \ - pqi/pqisslpersongrp.h \ - pqi/pqissludp.h \ - pqi/pqisslproxy.h \ - pqi/pqistore.h \ - pqi/pqistreamer.h \ - pqi/pqithreadstreamer.h \ - pqi/pqiqosstreamer.h \ - pqi/sslfns.h \ - pqi/pqinetstatebox.h \ - pqi/p3servicecontrol.h \ - -# pqi/p3dhtmgr.h \ - -HEADERS += rsserver/p3face.h \ - rsserver/p3history.h \ - rsserver/p3msgs.h \ - rsserver/p3peers.h \ - rsserver/p3status.h \ - rsserver/rsaccounts.h \ - rsserver/p3serverconfig.h - -HEADERS += grouter/groutercache.h \ - grouter/rsgrouter.h \ - grouter/grouteritems.h \ - grouter/p3grouter.h \ - grouter/rsgroutermatrix.h \ - grouter/groutertypes.h \ - grouter/rsgrouterclient.h - -HEADERS += serialiser/itempriorities.h \ - serialiser/rsbaseserial.h \ - serialiser/rsfiletransferitems.h \ - serialiser/rsserviceserialiser.h \ - serialiser/rsconfigitems.h \ - serialiser/rshistoryitems.h \ - serialiser/rsmsgitems.h \ - serialiser/rsserial.h \ - serialiser/rsserviceids.h \ - serialiser/rsserviceitems.h \ - serialiser/rsstatusitems.h \ - serialiser/rstlvaddrs.h \ - serialiser/rstlvbase.h \ - serialiser/rstlvitem.h \ - serialiser/rstlvidset.h \ - serialiser/rstlvfileitem.h \ - serialiser/rstlvimage.h \ - serialiser/rstlvstring.h \ - serialiser/rstlvbinary.h \ - serialiser/rstlvkeys.h \ - serialiser/rstlvkeyvalue.h \ - serialiser/rstlvgenericparam.h \ - serialiser/rstlvgenericmap.h \ - serialiser/rstlvgenericmap.inl \ - serialiser/rstlvlist.h \ - serialiser/rstlvmaps.h \ - serialiser/rstlvbanlist.h \ - serialiser/rsbanlistitems.h \ - serialiser/rsbwctrlitems.h \ - serialiser/rsdiscovery2items.h \ - serialiser/rsheartbeatitems.h \ - serialiser/rsrttitems.h \ - serialiser/rsgxsrecognitems.h \ - serialiser/rsgxsupdateitems.h \ - serialiser/rsserviceinfoitems.h \ - -HEADERS += services/p3msgservice.h \ - services/p3service.h \ - services/p3statusservice.h \ - services/p3banlist.h \ - services/p3bwctrl.h \ - services/p3discovery2.h \ - services/p3heartbeat.h \ - services/p3rtt.h \ - services/p3serviceinfo.cc \ - -HEADERS += turtle/p3turtle.h \ - turtle/rsturtleitem.h \ - turtle/turtletypes.h \ - turtle/turtleclientservice.h - -HEADERS += util/folderiterator.h \ - util/rsdebug.h \ - util/rscompress.h \ - util/smallobject.h \ - util/rsdir.h \ - util/rsdiscspace.h \ - util/rsnet.h \ - util/extaddrfinder.h \ - util/dnsresolver.h \ - util/rsprint.h \ - util/rsstring.h \ - util/rsstd.h \ - util/rsthreads.h \ - util/rsversioninfo.h \ - util/rswin.h \ - util/rsrandom.h \ - util/radix64.h \ - util/pugiconfig.h \ - util/rsmemcache.h \ - util/rstickevent.h \ - util/rsrecogn.h \ - util/rsscopetimer.h - -SOURCES += dbase/cachestrapper.cc \ - dbase/fimonitor.cc \ - dbase/findex.cc \ - dbase/fistore.cc \ - dbase/rsexpr.cc - - -SOURCES += ft/ftchunkmap.cc \ - ft/ftcontroller.cc \ - ft/ftdatamultiplex.cc \ - ft/ftdbase.cc \ - ft/ftextralist.cc \ - ft/ftfilecreator.cc \ - ft/ftfileprovider.cc \ - ft/ftfilesearch.cc \ - ft/ftserver.cc \ - ft/fttransfermodule.cc \ - ft/ftturtlefiletransferitem.cc - -SOURCES += chat/distantchat.cc \ - chat/p3chatservice.cc \ - chat/distributedchat.cc \ - chat/rschatitems.cc - -SOURCES += pqi/authgpg.cc \ - pqi/authssl.cc \ - pgp/pgphandler.cc \ - pgp/pgpkeyutil.cc \ - pgp/rscertificate.cc \ - pgp/pgpauxutils.cc \ - pqi/p3cfgmgr.cc \ - pqi/p3peermgr.cc \ - pqi/p3linkmgr.cc \ - pqi/p3netmgr.cc \ - pqi/p3notify.cc \ - pqi/pqiqos.cc \ - pqi/pqiarchive.cc \ - pqi/pqibin.cc \ - pqi/pqihandler.cc \ - pqi/p3historymgr.cc \ - pqi/pqiipset.cc \ - pqi/pqiloopback.cc \ - pqi/pqimonitor.cc \ - pqi/pqinetwork.cc \ - pqi/pqiperson.cc \ - pqi/pqipersongrp.cc \ - pqi/pqiservice.cc \ - pqi/pqissl.cc \ - pqi/pqissllistener.cc \ - pqi/pqisslpersongrp.cc \ - pqi/pqissludp.cc \ - pqi/pqisslproxy.cc \ - pqi/pqistore.cc \ - pqi/pqistreamer.cc \ - pqi/pqithreadstreamer.cc \ - pqi/pqiqosstreamer.cc \ - pqi/sslfns.cc \ - pqi/pqinetstatebox.cc \ - pqi/p3servicecontrol.cc \ - -# pqi/p3dhtmgr.cc \ - -SOURCES += rsserver/p3face-config.cc \ - rsserver/p3face-server.cc \ - rsserver/p3face-info.cc \ - rsserver/p3history.cc \ - rsserver/p3msgs.cc \ - rsserver/p3peers.cc \ - rsserver/p3status.cc \ - rsserver/rsinit.cc \ - rsserver/rsaccounts.cc \ - rsserver/rsloginhandler.cc \ - rsserver/rstypes.cc \ - rsserver/p3serverconfig.cc - -SOURCES += grouter/p3grouter.cc \ - grouter/grouteritems.cc \ - grouter/groutermatrix.cc - -SOURCES += plugins/pluginmanager.cc \ - plugins/dlfcn_win32.cc \ - serialiser/rspluginitems.cc - -SOURCES += serialiser/rsbaseserial.cc \ - serialiser/rsfiletransferitems.cc \ - serialiser/rsserviceserialiser.cc \ - serialiser/rsconfigitems.cc \ - serialiser/rshistoryitems.cc \ - serialiser/rsmsgitems.cc \ - serialiser/rsserial.cc \ - serialiser/rsstatusitems.cc \ - serialiser/rstlvaddrs.cc \ - serialiser/rstlvbase.cc \ - serialiser/rstlvitem.cc \ - serialiser/rstlvidset.cc \ - serialiser/rstlvfileitem.cc \ - serialiser/rstlvimage.cc \ - serialiser/rstlvstring.cc \ - serialiser/rstlvbinary.cc \ - serialiser/rstlvkeys.cc \ - serialiser/rstlvkeyvalue.cc \ - serialiser/rstlvgenericparam.cc \ - serialiser/rstlvbanlist.cc \ - serialiser/rsbanlistitems.cc \ - serialiser/rsbwctrlitems.cc \ - serialiser/rsdiscovery2items.cc \ - serialiser/rsheartbeatitems.cc \ - serialiser/rsrttitems.cc \ - serialiser/rsgxsrecognitems.cc \ - serialiser/rsgxsupdateitems.cc \ - serialiser/rsserviceinfoitems.cc \ - -SOURCES += services/p3msgservice.cc \ - services/p3service.cc \ - services/p3statusservice.cc \ - services/p3banlist.cc \ - services/p3bwctrl.cc \ - services/p3discovery2.cc \ - services/p3heartbeat.cc \ - services/p3rtt.cc \ - services/p3serviceinfo.cc \ - -SOURCES += turtle/p3turtle.cc \ - turtle/rsturtleitem.cc -# turtle/turtlerouting.cc \ -# turtle/turtlesearch.cc \ -# turtle/turtletunnels.cc - - -SOURCES += util/folderiterator.cc \ - util/rsdebug.cc \ - util/rscompress.cc \ - util/smallobject.cc \ - util/rsdir.cc \ - util/rsdiscspace.cc \ - util/rsnet.cc \ - util/rsnet_ss.cc \ - util/extaddrfinder.cc \ - util/dnsresolver.cc \ - util/rsprint.cc \ - util/rsstring.cc \ - util/rsthreads.cc \ - util/rsversioninfo.cc \ - util/rswin.cc \ - util/rsaes.cc \ - util/rsrandom.cc \ - util/rstickevent.cc \ - util/rsrecogn.cc \ - util/rsscopetimer.cc - - -upnp_miniupnpc { - HEADERS += upnp/upnputil.h upnp/upnphandler_miniupnp.h - SOURCES += upnp/upnputil.c upnp/upnphandler_miniupnp.cc -} - -upnp_libupnp { - HEADERS += upnp/UPnPBase.h upnp/upnphandler_linux.h - SOURCES += upnp/UPnPBase.cpp upnp/upnphandler_linux.cc - DEFINES *= RS_USE_LIBUPNP -} - - - -zeroconf { - -HEADERS += zeroconf/p3zeroconf.h \ - -SOURCES += zeroconf/p3zeroconf.cc \ - -# Disable Zeroconf (we still need the code for zcnatassist -# DEFINES *= RS_ENABLE_ZEROCONF - -} - -# This is seperated from the above for windows/linux platforms. -# It is acceptable to build in zeroconf and have it not work, -# but unacceptable to rely on Apple's libraries for Upnp when we have alternatives. ' - -zcnatassist { - -HEADERS += zeroconf/p3zcnatassist.h \ - -SOURCES += zeroconf/p3zcnatassist.cc \ - - DEFINES *= RS_ENABLE_ZCNATASSIST - -} - -# new gxs cache system -# this should be disabled for releases until further notice. -DEFINES *= SQLITE_HAS_CODEC -DEFINES *= GXS_ENABLE_SYNC_MSGS - -HEADERS += serialiser/rsnxsitems.h \ - gxs/rsgds.h \ - gxs/rsgxs.h \ - gxs/rsdataservice.h \ - gxs/rsgxsnetservice.h \ - retroshare/rsgxsflags.h \ - retroshare/rsgxsifacetypes.h \ - gxs/rsgenexchange.h \ - gxs/rsnxsobserver.h \ - gxs/rsgxsdata.h \ - retroshare/rstokenservice.h \ - gxs/rsgxsdataaccess.h \ - retroshare/rsgxsservice.h \ - serialiser/rsgxsitems.h \ - util/retrodb.h \ - util/rsdbbind.h \ - gxs/rsgxsutil.h \ - util/contentvalue.h \ - gxs/gxssecurity.h \ - gxs/rsgxsifacehelper.h \ - gxs/gxstokenqueue.h \ - gxs/rsgxsnetutils.h \ - gxs/rsgxsiface.h \ - gxs/rsgxsrequesttypes.h - - -SOURCES += serialiser/rsnxsitems.cc \ - gxs/rsdataservice.cc \ - gxs/rsgenexchange.cc \ - gxs/rsgxsnetservice.cc \ - gxs/rsgxsdata.cc \ - serialiser/rsgxsitems.cc \ - gxs/rsgxsdataaccess.cc \ - util/retrodb.cc \ - util/contentvalue.cc \ - util/rsdbbind.cc \ - gxs/gxssecurity.cc \ - gxs/gxstokenqueue.cc \ - gxs/rsgxsnetutils.cc \ - gxs/rsgxsutil.cc \ - gxs/rsgxsrequesttypes.cc - - -# Identity Service -HEADERS += retroshare/rsidentity.h \ - gxs/rsgixs.h \ - services/p3idservice.h \ - serialiser/rsgxsiditems.h \ - services/p3gxsreputation.h \ - serialiser/rsgxsreputationitems.h \ - -SOURCES += services/p3idservice.cc \ - serialiser/rsgxsiditems.cc \ - services/p3gxsreputation.cc \ - serialiser/rsgxsreputationitems.cc \ - -# GxsCircles Service -HEADERS += services/p3gxscircles.h \ - serialiser/rsgxscircleitems.h \ - retroshare/rsgxscircles.h \ - -SOURCES += services/p3gxscircles.cc \ - serialiser/rsgxscircleitems.cc \ - -# GxsForums Service -HEADERS += retroshare/rsgxsforums.h \ - services/p3gxsforums.h \ - serialiser/rsgxsforumitems.h - -SOURCES += services/p3gxsforums.cc \ - serialiser/rsgxsforumitems.cc \ - -# GxsChannels Service -HEADERS += retroshare/rsgxschannels.h \ - services/p3gxschannels.h \ - services/p3gxscommon.h \ - serialiser/rsgxscommentitems.h \ - serialiser/rsgxschannelitems.h \ - -SOURCES += services/p3gxschannels.cc \ - services/p3gxscommon.cc \ - serialiser/rsgxscommentitems.cc \ - serialiser/rsgxschannelitems.cc \ - -wikipoos { - # Wiki Service - HEADERS += retroshare/rswiki.h \ - services/p3wiki.h \ - serialiser/rswikiitems.h - - SOURCES += services/p3wiki.cc \ - serialiser/rswikiitems.cc \ -} - -gxsthewire { - # Wire Service - HEADERS += retroshare/rswire.h \ - services/p3wire.h \ - serialiser/rswireitems.h - - SOURCES += services/p3wire.cc \ - serialiser/rswireitems.cc \ -} - -# Posted Service -HEADERS += services/p3postbase.h \ - services/p3posted.h \ - retroshare/rsposted.h \ - serialiser/rsposteditems.h - -SOURCES += services/p3postbase.cc \ - services/p3posted.cc \ - serialiser/rsposteditems.cc - -gxsphotoshare { - #Photo Service - HEADERS += services/p3photoservice.h \ - retroshare/rsphoto.h \ - serialiser/rsphotoitems.h \ - - SOURCES += services/p3photoservice.cc \ - serialiser/rsphotoitems.cc \ -} - - - - - - -########################################################################################################### -# OLD CONFIG OPTIONS. -# Not used much - but might be useful one day. -# - -testnetwork { - # used in rsserver/rsinit.cc Enabled Port Restrictions, and makes Proxy Port next to Dht Port. - DEFINES *= LOCALNET_TESTING - - # used in tcponudp/udprelay.cc Debugging Info for Relays. - DEFINES *= DEBUG_UDP_RELAY - - # used in tcponudp/udpstunner.[h | cc] enables local stun (careful - modifies class variables). - DEFINES *= UDPSTUN_ALLOW_LOCALNET - - # used in pqi/p3linkmgr.cc prints out extra debug. - DEFINES *= LINKMGR_DEBUG_LINKTYPE - - # used in dht/connectstatebox to reduce connection times and display debug. - # DEFINES *= TESTING_PERIODS - # DEFINES *= DEBUG_CONNECTBOX -} - - -test_bitdht { - # DISABLE TCP CONNECTIONS... - DEFINES *= P3CONNMGR_NO_TCP_CONNECTIONS - - # NO AUTO CONNECTIONS??? FOR TESTING DHT STATUS. - DEFINES *= P3CONNMGR_NO_AUTO_CONNECTION - - # ENABLED UDP NOW. -} +!include("../../retroshare.pri"): error("Could not include file ../../retroshare.pri") + +TEMPLATE = lib +CONFIG += staticlib bitdht +CONFIG += create_prl +CONFIG -= qt +TARGET = retroshare +TARGET_PRL = libretroshare +DESTDIR = lib + +#CONFIG += dsdv + +profiling { + QMAKE_CXXFLAGS -= -fomit-frame-pointer + QMAKE_CXXFLAGS *= -pg -g -fno-omit-frame-pointer +} + +# treat warnings as error for better removing +#QMAKE_CFLAGS += -Werror +#QMAKE_CXXFLAGS += -Werror + +debug { +# DEFINES *= DEBUG +# DEFINES *= OPENDHT_DEBUG DHT_DEBUG CONN_DEBUG DEBUG_UDP_SORTER P3DISC_DEBUG DEBUG_UDP_LAYER FT_DEBUG EXTADDRSEARCH_DEBUG +# DEFINES *= CONTROL_DEBUG FT_DEBUG DEBUG_FTCHUNK P3TURTLE_DEBUG +# DEFINES *= P3TURTLE_DEBUG +# DEFINES *= NET_DEBUG +# DEFINES *= DISTRIB_DEBUG +# DEFINES *= P3TURTLE_DEBUG FT_DEBUG DEBUG_FTCHUNK MPLEX_DEBUG +# DEFINES *= STATUS_DEBUG SERV_DEBUG RSSERIAL_DEBUG #CONN_DEBUG + + QMAKE_CXXFLAGS -= -O2 -fomit-frame-pointer + QMAKE_CXXFLAGS *= -g -fno-omit-frame-pointer +} + +dsdv { +DEFINES *= SERVICES_DSDV +HEADERS += services/p3dsdv.h \ + serialiser/rstlvdsdv.h \ + serialiser/rsdsdvitems.h \ + retroshare/rsdsdv.h + +SOURCES *= serialiser/rstlvdsdv.cc \ + serialiser/rsdsdvitems.cc \ + services/p3dsdv.cc +} +bitdht { + +HEADERS += dht/p3bitdht.h \ + dht/connectstatebox.h \ + dht/stunaddrassist.h + +SOURCES += dht/p3bitdht.cc \ + dht/p3bitdht_interface.cc \ + dht/p3bitdht_peers.cc \ + dht/p3bitdht_peernet.cc \ + dht/p3bitdht_relay.cc \ + dht/connectstatebox.cc + +HEADERS += tcponudp/udppeer.h \ + tcponudp/bio_tou.h \ + tcponudp/tcppacket.h \ + tcponudp/tcpstream.h \ + tcponudp/tou.h \ + tcponudp/udpstunner.h \ + tcponudp/udprelay.h \ + +SOURCES += tcponudp/udppeer.cc \ + tcponudp/tcppacket.cc \ + tcponudp/tcpstream.cc \ + tcponudp/tou.cc \ + tcponudp/bss_tou.c \ + tcponudp/udpstunner.cc \ + tcponudp/udprelay.cc \ + + DEFINES *= RS_USE_BITDHT + + BITDHT_DIR = ../../libbitdht/src + DEPENDPATH += . $${BITDHT_DIR} + INCLUDEPATH += . $${BITDHT_DIR} + PRE_TARGETDEPS *= $${BITDHT_DIR}/lib/libbitdht.a + LIBS *= $${BITDHT_DIR}/lib/libbitdht.a +} + + + + +PUBLIC_HEADERS = retroshare/rsdisc.h \ + retroshare/rsexpr.h \ + retroshare/rsfiles.h \ + retroshare/rshistory.h \ + retroshare/rsids.h \ + retroshare/rsiface.h \ + retroshare/rsinit.h \ + retroshare/rsplugin.h \ + retroshare/rsloginhandler.h \ + retroshare/rsmsgs.h \ + retroshare/rsnotify.h \ + retroshare/rspeers.h \ + retroshare/rsrank.h \ + retroshare/rsstatus.h \ + retroshare/rsturtle.h \ + retroshare/rsbanlist.h \ + retroshare/rstypes.h \ + retroshare/rsdht.h \ + retroshare/rsrtt.h \ + retroshare/rsconfig.h \ + retroshare/rsversion.h \ + retroshare/rsservicecontrol.h \ + + +HEADERS += plugins/pluginmanager.h \ + plugins/dlfcn_win32.h \ + serialiser/rspluginitems.h \ + util/rsinitedptr.h + +HEADERS += $$PUBLIC_HEADERS + + +################################# Linux ########################################## +linux-* { + CONFIG += link_pkgconfig + + QMAKE_CXXFLAGS *= -Wall -D_FILE_OFFSET_BITS=64 + QMAKE_CC = g++ + + contains(CONFIG, NO_SQLCIPHER) { + DEFINES *= NO_SQLCIPHER + PKGCONFIG *= sqlite3 + } else { + SQLCIPHER_OK = $$system(pkg-config --exists sqlcipher && echo yes) + isEmpty(SQLCIPHER_OK) { + # We need a explicit path here, to force using the home version of sqlite3 that really encrypts the database. + exists(../../../lib/sqlcipher/.libs/libsqlcipher.a) { + LIBS += ../../../lib/sqlcipher/.libs/libsqlcipher.a + DEPENDPATH += ../../../lib/ + INCLUDEPATH += ../../../lib/ + } else { + error("libsqlcipher is not installed and libsqlcipher.a not found. SQLCIPHER is necessary for encrypted database, to build with unencrypted database, run: qmake CONFIG+=NO_SQLCIPHER") + } + } else { + # Workaround for broken sqlcipher packages, e.g. Ubuntu 14.04 + # https://bugs.launchpad.net/ubuntu/+source/sqlcipher/+bug/1493928 + # PKGCONFIG *= sqlcipher + LIBS *= -lsqlcipher + } + } + + #CONFIG += version_detail_bash_script + + # linux/bsd can use either - libupnp is more complete and packaged. + #CONFIG += upnp_miniupnpc + CONFIG += upnp_libupnp + + # Check if the systems libupnp has been Debian-patched + system(grep -E 'char[[:space:]]+PublisherUrl' /usr/include/upnp/upnp.h >/dev/null 2>&1) { + # Normal libupnp + } else { + # Patched libupnp or new unreleased version + DEFINES *= PATCHED_LIBUPNP + } + + DEFINES *= UBUNTU + PKGCONFIG *= gnome-keyring-1 + PKGCONFIG *= libssl libupnp + PKGCONFIG *= libcrypto zlib + LIBS *= -lpthread -ldl +} + +unix { + DEFINES *= PLUGIN_DIR=\"\\\"$${PLUGIN_DIR}\\\"\" + DEFINES *= DATA_DIR=\"\\\"$${DATA_DIR}\\\"\" + + ## where to put the librarys interface + #include_rsiface.path = "$${INC_DIR}" + #include_rsiface.files = $$PUBLIC_HEADERS + #INSTALLS += include_rsiface + + ## where to put the shared library itself + #target.path = "$$LIB_DIR" + #INSTALLS *= target +} + +linux-g++ { + OBJECTS_DIR = temp/linux-g++/obj +} + +linux-g++-64 { + OBJECTS_DIR = temp/linux-g++-64/obj +} + +version_detail_bash_script { + linux-* { + QMAKE_EXTRA_TARGETS += write_version_detail + PRE_TARGETDEPS = write_version_detail + write_version_detail.commands = ./version_detail.sh + } + win32 { + QMAKE_EXTRA_TARGETS += write_version_detail + PRE_TARGETDEPS = write_version_detail + write_version_detail.commands = $$PWD/version_detail.bat + } +} + +#################### Cross compilation for windows under Linux #################### + +win32-x-g++ { + OBJECTS_DIR = temp/win32xgcc/obj + DEFINES *= WINDOWS_SYS WIN32 WIN_CROSS_UBUNTU + QMAKE_CXXFLAGS *= -Wmissing-include-dirs + QMAKE_CC = i586-mingw32msvc-g++ + QMAKE_LIB = i586-mingw32msvc-ar + QMAKE_AR = i586-mingw32msvc-ar + DEFINES *= STATICLIB WIN32 + + CONFIG += upnp_miniupnpc + + SSL_DIR=../../../../openssl + UPNPC_DIR = ../../../../miniupnpc-1.3 + GPG_ERROR_DIR = ../../../../libgpg-error-1.7 + GPGME_DIR = ../../../../gpgme-1.1.8 + + INCLUDEPATH *= /usr/i586-mingw32msvc/include ${HOME}/.wine/drive_c/pthreads/include/ +} +################################# Windows ########################################## + +win32 { + QMAKE_CC = g++ + OBJECTS_DIR = temp/obj + MOC_DIR = temp/moc + DEFINES *= WINDOWS_SYS WIN32 STATICLIB MINGW WIN32_LEAN_AND_MEAN _USE_32BIT_TIME_T + DEFINES *= MINIUPNPC_VERSION=13 + # This defines the platform to be WinXP or later and is needed for getaddrinfo (_WIN32_WINNT_WINXP) + DEFINES *= WINVER=0x0501 + + # Switch on extra warnings + QMAKE_CFLAGS += -Wextra + QMAKE_CXXFLAGS += -Wextra + + # Switch off optimization for release version + QMAKE_CXXFLAGS_RELEASE -= -O2 + QMAKE_CXXFLAGS_RELEASE += -O0 + QMAKE_CFLAGS_RELEASE -= -O2 + QMAKE_CFLAGS_RELEASE += -O0 + + # Switch on optimization for debug version + #QMAKE_CXXFLAGS_DEBUG += -O2 + #QMAKE_CFLAGS_DEBUG += -O2 + + DEFINES += USE_CMD_ARGS + + CONFIG += upnp_miniupnpc + + LIBS += -lsqlcipher + + LIBS_DIR = $$PWD/../../../libs + + DEPENDPATH += . $$LIBS_DIR/include $$LIBS_DIR/include/miniupnpc + INCLUDEPATH += . $$LIBS_DIR/include $$LIBS_DIR/include/miniupnpc +} + +################################# MacOSX ########################################## + +mac { + QMAKE_CC = g++ + OBJECTS_DIR = temp/obj + MOC_DIR = temp/moc + #DEFINES = WINDOWS_SYS WIN32 STATICLIB MINGW + DEFINES *= MINIUPNPC_VERSION=13 + + CONFIG += upnp_miniupnpc + + # zeroconf disabled at the end of libretroshare.pro (but need the code) + #CONFIG += zeroconf + #CONFIG += zcnatassist + + # Beautiful Hack to fix 64bit file access. + QMAKE_CXXFLAGS *= -Dfseeko64=fseeko -Dftello64=ftello -Dfopen64=fopen -Dvstatfs64=vstatfs + + UPNPC_DIR = ../../../miniupnpc-1.3 + #GPG_ERROR_DIR = ../../../../libgpg-error-1.7 + #GPGME_DIR = ../../../../gpgme-1.1.8 + + INCLUDEPATH += . $${UPNPC_DIR} + + #INCLUDEPATH += . $${UPNPC_DIR} $${GPGME_DIR}/src $${GPG_ERROR_DIR}/src + + # We need a explicit path here, to force using the home version of sqlite3 that really encrypts the database. + LIBS += ../../../lib/libsqlcipher.a + #LIBS += -lsqlite3 +} + +################################# FreeBSD ########################################## + +freebsd-* { + INCLUDEPATH *= /usr/local/include/gpgme + INCLUDEPATH *= /usr/local/include/glib-2.0 + + QMAKE_CXXFLAGS *= -Dfseeko64=fseeko -Dftello64=ftello -Dstat64=stat -Dstatvfs64=statvfs -Dfopen64=fopen + + # linux/bsd can use either - libupnp is more complete and packaged. + #CONFIG += upnp_miniupnpc + CONFIG += upnp_libupnp +} + +################################# OpenBSD ########################################## + +openbsd-* { + INCLUDEPATH *= /usr/local/include + INCLUDEPATH += $$system(pkg-config --cflags glib-2.0 | sed -e "s/-I//g") + + QMAKE_CXXFLAGS *= -Dfseeko64=fseeko -Dftello64=ftello -Dstat64=stat -Dstatvfs64=statvfs -Dfopen64=fopen + + CONFIG += upnp_libupnp +} + +################################### COMMON stuff ################################## + +# openpgpsdk +OPENPGPSDK_DIR = ../../openpgpsdk/src +DEPENDPATH *= $${OPENPGPSDK_DIR} +INCLUDEPATH *= $${OPENPGPSDK_DIR} +PRE_TARGETDEPS *= $${OPENPGPSDK_DIR}/lib/libops.a +LIBS *= $${OPENPGPSDK_DIR}/lib/libops.a -lbz2 + +HEADERS += dbase/cachestrapper.h \ + dbase/fimonitor.h \ + dbase/findex.h \ + dbase/fistore.h + +HEADERS += ft/ftchunkmap.h \ + ft/ftcontroller.h \ + ft/ftdata.h \ + ft/ftdatamultiplex.h \ + ft/ftdbase.h \ + ft/ftextralist.h \ + ft/ftfilecreator.h \ + ft/ftfileprovider.h \ + ft/ftfilesearch.h \ + ft/ftsearch.h \ + ft/ftserver.h \ + ft/fttransfermodule.h \ + ft/ftturtlefiletransferitem.h + +HEADERS += chat/distantchat.h \ + chat/p3chatservice.h \ + chat/distributedchat.h \ + chat/rschatitems.h + +HEADERS += pqi/authssl.h \ + pqi/authgpg.h \ + pqi/rsmemory.h \ + pgp/pgphandler.h \ + pgp/pgpkeyutil.h \ + pgp/rsaes.h \ + pgp/rscertificate.h \ + pgp/pgpauxutils.h \ + pqi/p3cfgmgr.h \ + pqi/p3peermgr.h \ + pqi/p3linkmgr.h \ + pqi/p3netmgr.h \ + pqi/p3notify.h \ + pqi/p3upnpmgr.h \ + pqi/pqiqos.h \ + pqi/pqi.h \ + pqi/pqi_base.h \ + pqi/pqiarchive.h \ + pqi/pqiassist.h \ + pqi/pqibin.h \ + pqi/pqihandler.h \ + pqi/pqihash.h \ + pqi/p3historymgr.h \ + pqi/pqiindic.h \ + pqi/pqiipset.h \ + pqi/pqilistener.h \ + pqi/pqiloopback.h \ + pqi/pqimonitor.h \ + pqi/pqinetwork.h \ + pqi/pqiperson.h \ + pqi/pqipersongrp.h \ + pqi/pqiservice.h \ + pqi/pqissl.h \ + pqi/pqissllistener.h \ + pqi/pqisslpersongrp.h \ + pqi/pqissludp.h \ + pqi/pqisslproxy.h \ + pqi/pqistore.h \ + pqi/pqistreamer.h \ + pqi/pqithreadstreamer.h \ + pqi/pqiqosstreamer.h \ + pqi/sslfns.h \ + pqi/pqinetstatebox.h \ + pqi/p3servicecontrol.h \ + +# pqi/p3dhtmgr.h \ + +HEADERS += rsserver/p3face.h \ + rsserver/p3history.h \ + rsserver/p3msgs.h \ + rsserver/p3peers.h \ + rsserver/p3status.h \ + rsserver/rsaccounts.h \ + rsserver/p3serverconfig.h + +HEADERS += grouter/groutercache.h \ + grouter/rsgrouter.h \ + grouter/grouteritems.h \ + grouter/p3grouter.h \ + grouter/rsgroutermatrix.h \ + grouter/groutertypes.h \ + grouter/rsgrouterclient.h + +HEADERS += serialiser/itempriorities.h \ + serialiser/rsbaseserial.h \ + serialiser/rsfiletransferitems.h \ + serialiser/rsserviceserialiser.h \ + serialiser/rsconfigitems.h \ + serialiser/rshistoryitems.h \ + serialiser/rsmsgitems.h \ + serialiser/rsserial.h \ + serialiser/rsserviceids.h \ + serialiser/rsserviceitems.h \ + serialiser/rsstatusitems.h \ + serialiser/rstlvaddrs.h \ + serialiser/rstlvbase.h \ + serialiser/rstlvitem.h \ + serialiser/rstlvidset.h \ + serialiser/rstlvfileitem.h \ + serialiser/rstlvimage.h \ + serialiser/rstlvstring.h \ + serialiser/rstlvbinary.h \ + serialiser/rstlvkeys.h \ + serialiser/rstlvkeyvalue.h \ + serialiser/rstlvgenericparam.h \ + serialiser/rstlvgenericmap.h \ + serialiser/rstlvgenericmap.inl \ + serialiser/rstlvlist.h \ + serialiser/rstlvmaps.h \ + serialiser/rstlvbanlist.h \ + serialiser/rsbanlistitems.h \ + serialiser/rsbwctrlitems.h \ + serialiser/rsdiscovery2items.h \ + serialiser/rsheartbeatitems.h \ + serialiser/rsrttitems.h \ + serialiser/rsgxsrecognitems.h \ + serialiser/rsgxsupdateitems.h \ + serialiser/rsserviceinfoitems.h \ + +HEADERS += services/p3msgservice.h \ + services/p3service.h \ + services/p3statusservice.h \ + services/p3banlist.h \ + services/p3bwctrl.h \ + services/p3discovery2.h \ + services/p3heartbeat.h \ + services/p3rtt.h \ + services/p3serviceinfo.cc \ + +HEADERS += turtle/p3turtle.h \ + turtle/rsturtleitem.h \ + turtle/turtletypes.h \ + turtle/turtleclientservice.h + +HEADERS += util/folderiterator.h \ + util/rsdebug.h \ + util/rscompress.h \ + util/smallobject.h \ + util/rsdir.h \ + util/rsdiscspace.h \ + util/rsnet.h \ + util/extaddrfinder.h \ + util/dnsresolver.h \ + util/rsprint.h \ + util/rsstring.h \ + util/rsstd.h \ + util/rsthreads.h \ + util/rsversioninfo.h \ + util/rswin.h \ + util/rsrandom.h \ + util/radix64.h \ + util/pugiconfig.h \ + util/rsmemcache.h \ + util/rstickevent.h \ + util/rsrecogn.h \ + util/rsscopetimer.h + +SOURCES += dbase/cachestrapper.cc \ + dbase/fimonitor.cc \ + dbase/findex.cc \ + dbase/fistore.cc \ + dbase/rsexpr.cc + + +SOURCES += ft/ftchunkmap.cc \ + ft/ftcontroller.cc \ + ft/ftdatamultiplex.cc \ + ft/ftdbase.cc \ + ft/ftextralist.cc \ + ft/ftfilecreator.cc \ + ft/ftfileprovider.cc \ + ft/ftfilesearch.cc \ + ft/ftserver.cc \ + ft/fttransfermodule.cc \ + ft/ftturtlefiletransferitem.cc + +SOURCES += chat/distantchat.cc \ + chat/p3chatservice.cc \ + chat/distributedchat.cc \ + chat/rschatitems.cc + +SOURCES += pqi/authgpg.cc \ + pqi/authssl.cc \ + pgp/pgphandler.cc \ + pgp/pgpkeyutil.cc \ + pgp/rscertificate.cc \ + pgp/pgpauxutils.cc \ + pqi/p3cfgmgr.cc \ + pqi/p3peermgr.cc \ + pqi/p3linkmgr.cc \ + pqi/p3netmgr.cc \ + pqi/p3notify.cc \ + pqi/pqiqos.cc \ + pqi/pqiarchive.cc \ + pqi/pqibin.cc \ + pqi/pqihandler.cc \ + pqi/p3historymgr.cc \ + pqi/pqiipset.cc \ + pqi/pqiloopback.cc \ + pqi/pqimonitor.cc \ + pqi/pqinetwork.cc \ + pqi/pqiperson.cc \ + pqi/pqipersongrp.cc \ + pqi/pqiservice.cc \ + pqi/pqissl.cc \ + pqi/pqissllistener.cc \ + pqi/pqisslpersongrp.cc \ + pqi/pqissludp.cc \ + pqi/pqisslproxy.cc \ + pqi/pqistore.cc \ + pqi/pqistreamer.cc \ + pqi/pqithreadstreamer.cc \ + pqi/pqiqosstreamer.cc \ + pqi/sslfns.cc \ + pqi/pqinetstatebox.cc \ + pqi/p3servicecontrol.cc \ + +# pqi/p3dhtmgr.cc \ + +SOURCES += rsserver/p3face-config.cc \ + rsserver/p3face-server.cc \ + rsserver/p3face-info.cc \ + rsserver/p3history.cc \ + rsserver/p3msgs.cc \ + rsserver/p3peers.cc \ + rsserver/p3status.cc \ + rsserver/rsinit.cc \ + rsserver/rsaccounts.cc \ + rsserver/rsloginhandler.cc \ + rsserver/rstypes.cc \ + rsserver/p3serverconfig.cc + +SOURCES += grouter/p3grouter.cc \ + grouter/grouteritems.cc \ + grouter/groutermatrix.cc + +SOURCES += plugins/pluginmanager.cc \ + plugins/dlfcn_win32.cc \ + serialiser/rspluginitems.cc + +SOURCES += serialiser/rsbaseserial.cc \ + serialiser/rsfiletransferitems.cc \ + serialiser/rsserviceserialiser.cc \ + serialiser/rsconfigitems.cc \ + serialiser/rshistoryitems.cc \ + serialiser/rsmsgitems.cc \ + serialiser/rsserial.cc \ + serialiser/rsstatusitems.cc \ + serialiser/rstlvaddrs.cc \ + serialiser/rstlvbase.cc \ + serialiser/rstlvitem.cc \ + serialiser/rstlvidset.cc \ + serialiser/rstlvfileitem.cc \ + serialiser/rstlvimage.cc \ + serialiser/rstlvstring.cc \ + serialiser/rstlvbinary.cc \ + serialiser/rstlvkeys.cc \ + serialiser/rstlvkeyvalue.cc \ + serialiser/rstlvgenericparam.cc \ + serialiser/rstlvbanlist.cc \ + serialiser/rsbanlistitems.cc \ + serialiser/rsbwctrlitems.cc \ + serialiser/rsdiscovery2items.cc \ + serialiser/rsheartbeatitems.cc \ + serialiser/rsrttitems.cc \ + serialiser/rsgxsrecognitems.cc \ + serialiser/rsgxsupdateitems.cc \ + serialiser/rsserviceinfoitems.cc \ + +SOURCES += services/p3msgservice.cc \ + services/p3service.cc \ + services/p3statusservice.cc \ + services/p3banlist.cc \ + services/p3bwctrl.cc \ + services/p3discovery2.cc \ + services/p3heartbeat.cc \ + services/p3rtt.cc \ + services/p3serviceinfo.cc \ + +SOURCES += turtle/p3turtle.cc \ + turtle/rsturtleitem.cc +# turtle/turtlerouting.cc \ +# turtle/turtlesearch.cc \ +# turtle/turtletunnels.cc + + +SOURCES += util/folderiterator.cc \ + util/rsdebug.cc \ + util/rscompress.cc \ + util/smallobject.cc \ + util/rsdir.cc \ + util/rsdiscspace.cc \ + util/rsnet.cc \ + util/rsnet_ss.cc \ + util/extaddrfinder.cc \ + util/dnsresolver.cc \ + util/rsprint.cc \ + util/rsstring.cc \ + util/rsthreads.cc \ + util/rsversioninfo.cc \ + util/rswin.cc \ + util/rsaes.cc \ + util/rsrandom.cc \ + util/rstickevent.cc \ + util/rsrecogn.cc \ + util/rsscopetimer.cc + + +upnp_miniupnpc { + HEADERS += upnp/upnputil.h upnp/upnphandler_miniupnp.h + SOURCES += upnp/upnputil.c upnp/upnphandler_miniupnp.cc +} + +upnp_libupnp { + HEADERS += upnp/UPnPBase.h upnp/upnphandler_linux.h + SOURCES += upnp/UPnPBase.cpp upnp/upnphandler_linux.cc + DEFINES *= RS_USE_LIBUPNP +} + + + +zeroconf { + +HEADERS += zeroconf/p3zeroconf.h \ + +SOURCES += zeroconf/p3zeroconf.cc \ + +# Disable Zeroconf (we still need the code for zcnatassist +# DEFINES *= RS_ENABLE_ZEROCONF + +} + +# This is seperated from the above for windows/linux platforms. +# It is acceptable to build in zeroconf and have it not work, +# but unacceptable to rely on Apple's libraries for Upnp when we have alternatives. ' + +zcnatassist { + +HEADERS += zeroconf/p3zcnatassist.h \ + +SOURCES += zeroconf/p3zcnatassist.cc \ + + DEFINES *= RS_ENABLE_ZCNATASSIST + +} + +# new gxs cache system +# this should be disabled for releases until further notice. + +DEFINES *= SQLITE_HAS_CODEC +DEFINES *= GXS_ENABLE_SYNC_MSGS + +HEADERS += serialiser/rsnxsitems.h \ + gxs/rsgds.h \ + gxs/rsgxs.h \ + gxs/rsdataservice.h \ + gxs/rsgxsnetservice.h \ + retroshare/rsgxsflags.h \ + retroshare/rsgxsifacetypes.h \ + gxs/rsgenexchange.h \ + gxs/rsnxsobserver.h \ + gxs/rsgxsdata.h \ + retroshare/rstokenservice.h \ + gxs/rsgxsdataaccess.h \ + retroshare/rsgxsservice.h \ + serialiser/rsgxsitems.h \ + util/retrodb.h \ + util/rsdbbind.h \ + gxs/rsgxsutil.h \ + util/contentvalue.h \ + gxs/gxssecurity.h \ + gxs/rsgxsifacehelper.h \ + gxs/gxstokenqueue.h \ + gxs/rsgxsnetutils.h \ + gxs/rsgxsiface.h \ + gxs/rsgxsrequesttypes.h + + +SOURCES += serialiser/rsnxsitems.cc \ + gxs/rsdataservice.cc \ + gxs/rsgenexchange.cc \ + gxs/rsgxsnetservice.cc \ + gxs/rsgxsdata.cc \ + serialiser/rsgxsitems.cc \ + gxs/rsgxsdataaccess.cc \ + util/retrodb.cc \ + util/contentvalue.cc \ + util/rsdbbind.cc \ + gxs/gxssecurity.cc \ + gxs/gxstokenqueue.cc \ + gxs/rsgxsnetutils.cc \ + gxs/rsgxsutil.cc \ + gxs/rsgxsrequesttypes.cc + + +# Identity Service +HEADERS += retroshare/rsidentity.h \ + gxs/rsgixs.h \ + services/p3idservice.h \ + serialiser/rsgxsiditems.h \ + services/p3gxsreputation.h \ + serialiser/rsgxsreputationitems.h \ + +SOURCES += services/p3idservice.cc \ + serialiser/rsgxsiditems.cc \ + services/p3gxsreputation.cc \ + serialiser/rsgxsreputationitems.cc \ + +# GxsCircles Service +HEADERS += services/p3gxscircles.h \ + serialiser/rsgxscircleitems.h \ + retroshare/rsgxscircles.h \ + +SOURCES += services/p3gxscircles.cc \ + serialiser/rsgxscircleitems.cc \ + +# GxsForums Service +HEADERS += retroshare/rsgxsforums.h \ + services/p3gxsforums.h \ + serialiser/rsgxsforumitems.h + +SOURCES += services/p3gxsforums.cc \ + serialiser/rsgxsforumitems.cc \ + +# GxsChannels Service +HEADERS += retroshare/rsgxschannels.h \ + services/p3gxschannels.h \ + services/p3gxscommon.h \ + serialiser/rsgxscommentitems.h \ + serialiser/rsgxschannelitems.h \ + +SOURCES += services/p3gxschannels.cc \ + services/p3gxscommon.cc \ + serialiser/rsgxscommentitems.cc \ + serialiser/rsgxschannelitems.cc \ + +wikipoos { + # Wiki Service + HEADERS += retroshare/rswiki.h \ + services/p3wiki.h \ + serialiser/rswikiitems.h + + SOURCES += services/p3wiki.cc \ + serialiser/rswikiitems.cc \ +} + +gxsthewire { + # Wire Service + HEADERS += retroshare/rswire.h \ + services/p3wire.h \ + serialiser/rswireitems.h + + SOURCES += services/p3wire.cc \ + serialiser/rswireitems.cc \ +} + +# Posted Service +HEADERS += services/p3postbase.h \ + services/p3posted.h \ + retroshare/rsposted.h \ + serialiser/rsposteditems.h + +SOURCES += services/p3postbase.cc \ + services/p3posted.cc \ + serialiser/rsposteditems.cc + +gxsphotoshare { + #Photo Service + HEADERS += services/p3photoservice.h \ + retroshare/rsphoto.h \ + serialiser/rsphotoitems.h \ + + SOURCES += services/p3photoservice.cc \ + serialiser/rsphotoitems.cc \ +} + + + + + + +########################################################################################################### +# OLD CONFIG OPTIONS. +# Not used much - but might be useful one day. +# + +testnetwork { + # used in rsserver/rsinit.cc Enabled Port Restrictions, and makes Proxy Port next to Dht Port. + DEFINES *= LOCALNET_TESTING + + # used in tcponudp/udprelay.cc Debugging Info for Relays. + DEFINES *= DEBUG_UDP_RELAY + + # used in tcponudp/udpstunner.[h | cc] enables local stun (careful - modifies class variables). + DEFINES *= UDPSTUN_ALLOW_LOCALNET + + # used in pqi/p3linkmgr.cc prints out extra debug. + DEFINES *= LINKMGR_DEBUG_LINKTYPE + + # used in dht/connectstatebox to reduce connection times and display debug. + # DEFINES *= TESTING_PERIODS + # DEFINES *= DEBUG_CONNECTBOX +} + + +test_bitdht { + # DISABLE TCP CONNECTIONS... + DEFINES *= P3CONNMGR_NO_TCP_CONNECTIONS + + # NO AUTO CONNECTIONS??? FOR TESTING DHT STATUS. + DEFINES *= P3CONNMGR_NO_AUTO_CONNECTION + + # ENABLED UDP NOW. +} diff --git a/libretroshare/src/retroshare/rsidentity.h b/libretroshare/src/retroshare/rsidentity.h index fec4d0944..d3ee14041 100644 --- a/libretroshare/src/retroshare/rsidentity.h +++ b/libretroshare/src/retroshare/rsidentity.h @@ -32,6 +32,7 @@ #include "retroshare/rstokenservice.h" #include "retroshare/rsgxsifacehelper.h" +#include "retroshare/rsreputations.h" #include "retroshare/rsids.h" #include "serialiser/rstlvimage.h" #include "retroshare/rsgxscommon.h" @@ -158,8 +159,7 @@ class RsIdentityDetails { public: RsIdentityDetails() - :mIsOwnId(false), mPgpLinked(false), mPgpKnown(false), - mReputation(), mLastUsageTS(0) { return; } + :mIsOwnId(false), mPgpLinked(false), mPgpKnown(false), mLastUsageTS(0) { return; } RsGxsId mId; @@ -175,8 +175,12 @@ public: // Recogn details. std::list mRecognTags; - // reputation details. - GxsReputation mReputation; + // Cyril: Reputation details. At some point we might want to merge information + // between the two into a single global score. Since the old reputation system + // is not finished yet, I leave this in place. We should decide what to do with it. + + GxsReputation mReputation_oldSystem; // this is the old "mReputation" field, which apparently is not used. + RsReputations::ReputationInfo mReputation; // avatar RsGxsImage mAvatar ; @@ -214,7 +218,7 @@ public: /********************************************************************************************/ /********************************************************************************************/ - + // For Other Services.... // It should be impossible for them to get a message which we don't have the identity. // Its a major error if we don't have the identity. diff --git a/libretroshare/src/retroshare/rsplugin.h b/libretroshare/src/retroshare/rsplugin.h index e8cb91714..6dc6dc05b 100644 --- a/libretroshare/src/retroshare/rsplugin.h +++ b/libretroshare/src/retroshare/rsplugin.h @@ -40,6 +40,7 @@ extern RsPluginHandler *rsPlugins ; class p3Service ; class RsServiceControl ; +class RsReputations ; class RsTurtle ; class RsDht ; class RsDisc ; @@ -116,6 +117,7 @@ public: RsUtil::inited_ptr mPgpAuxUtils; RsUtil::inited_ptr mGxsForums; RsUtil::inited_ptr mGxsChannels; + RsUtil::inited_ptr mReputations; }; class RsPlugin diff --git a/libretroshare/src/retroshare/rsreputations.h b/libretroshare/src/retroshare/rsreputations.h new file mode 100644 index 000000000..433eb8368 --- /dev/null +++ b/libretroshare/src/retroshare/rsreputations.h @@ -0,0 +1,58 @@ +/* + * libretroshare/src/services: rsreputation.h + * + * Services for RetroShare. + * + * Copyright 2015 by Cyril Soler + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License Version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "csoler@users.sourceforge.net". + * + */ + +#pragma once + +#include "retroshare/rsids.h" +#include "retroshare/rsgxsifacetypes.h" + +class RsReputations +{ +public: + // This is the interface file for the reputation system + // + enum Opinion { OPINION_NEGATIVE = 0, OPINION_NEUTRAL = 1, OPINION_POSITIVE = 2 } ; + enum Assessment { ASSESSMENT_BAD = 0, ASSESSMENT_OK = 1 } ; + + struct ReputationInfo + { + RsReputations::Opinion mOwnOpinion ; + float mOverallReputationScore ; + float mFriendAverage ; + RsReputations::Assessment mAssessment; // this should help clients in taking decisions + }; + + virtual bool setOwnOpinion(const RsGxsId& key_id, const Opinion& op) =0; + virtual bool getReputationInfo(const RsGxsId& id,ReputationInfo& info) =0 ; + + // This one is a proxy designed to allow fast checking of a GXS id. + // it basically returns true if assessment is not ASSESSMENT_OK + + virtual bool isIdentityBanned(const RsGxsId& id) =0; +}; + +// To access reputations from anywhere +// +extern RsReputations *rsReputations ; diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 833579c7d..9f6ba9b0b 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -819,6 +819,7 @@ bool RsInit::SetHiddenLocation(const std::string& hiddenaddress, uint16_t port) RsFiles *rsFiles = NULL; RsTurtle *rsTurtle = NULL ; +RsReputations *rsReputations = NULL ; #ifdef ENABLE_GROUTER RsGRouter *rsGRouter = NULL ; #endif @@ -847,6 +848,7 @@ RsGRouter *rsGRouter = NULL ; #endif #endif +#include "services/p3gxsreputation.h" #include "services/p3serviceinfo.h" #include "services/p3heartbeat.h" #include "services/p3discovery2.h" @@ -1357,6 +1359,11 @@ int RsServer::StartupRetroShare() mPosted->setNetworkExchangeService(posted_ns) ; + /**** Reputation system ****/ + + p3GxsReputation *mReputations = new p3GxsReputation(mLinkMgr) ; + rsReputations = mReputations ; + /**** Wiki GXS service ****/ @@ -1492,8 +1499,8 @@ int RsServer::StartupRetroShare() pqih -> addService(mDisc,true); pqih -> addService(msgSrv,true); pqih -> addService(chatSrv,true); - pqih -> addService(mStatusSrv,true); - + pqih -> addService(mStatusSrv,true); + pqih -> addService(mReputations,true); // set interfaces for plugins // @@ -1514,6 +1521,8 @@ int RsServer::StartupRetroShare() interfaces.mPgpAuxUtils = pgpAuxUtils; interfaces.mGxsForums = mGxsForums; interfaces.mGxsChannels = mGxsChannels; + interfaces.mReputations = mReputations; + mPluginsManager->setInterfaces(interfaces); // now add plugin objects inside the loop: @@ -1601,12 +1610,13 @@ int RsServer::StartupRetroShare() mConfigMgr->addConfiguration("peers.cfg", mPeerMgr); mConfigMgr->addConfiguration("general.cfg", mGeneralConfig); mConfigMgr->addConfiguration("msgs.cfg", msgSrv); - mConfigMgr->addConfiguration("chat.cfg", chatSrv); - mConfigMgr->addConfiguration("p3History.cfg", mHistoryMgr); - mConfigMgr->addConfiguration("p3Status.cfg", mStatusSrv); - mConfigMgr->addConfiguration("turtle.cfg", tr); - mConfigMgr->addConfiguration("banlist.cfg", mBanList); - mConfigMgr->addConfiguration("servicecontrol.cfg", serviceCtrl); + mConfigMgr->addConfiguration("chat.cfg", chatSrv); + mConfigMgr->addConfiguration("p3History.cfg", mHistoryMgr); + mConfigMgr->addConfiguration("p3Status.cfg", mStatusSrv); + mConfigMgr->addConfiguration("turtle.cfg", tr); + mConfigMgr->addConfiguration("banlist.cfg", mBanList); + mConfigMgr->addConfiguration("servicecontrol.cfg", serviceCtrl); + mConfigMgr->addConfiguration("reputations.cfg", mReputations); #ifdef ENABLE_GROUTER mConfigMgr->addConfiguration("grouter.cfg", gr); #endif diff --git a/libretroshare/src/serialiser/rsgxsreputationitems.cc b/libretroshare/src/serialiser/rsgxsreputationitems.cc index 7b56d4675..876d055f7 100644 --- a/libretroshare/src/serialiser/rsgxsreputationitems.cc +++ b/libretroshare/src/serialiser/rsgxsreputationitems.cc @@ -23,9 +23,9 @@ * */ +#include #include "serialiser/rsbaseserial.h" -#include "serialiser/rsbanlistitems.h" -#include "serialiser/rstlvbanlist.h" +#include "serialiser/rsgxsreputationitems.h" /*** #define RSSERIAL_DEBUG 1 @@ -35,170 +35,395 @@ /*************************************************************************/ -#ifdef SUSPENDED -RsBanListItem::~RsBanListItem() +bool RsReputationItem::serialise_header(void *data,uint32_t& pktsize,uint32_t& tlvsize, uint32_t& offset) const { - return; -} + tlvsize = serial_size() ; + offset = 0; -void RsBanListItem::clear() -{ - peerList.TlvClear(); -} - -std::ostream &RsBanListItem::print(std::ostream &out, uint16_t indent) -{ - printRsItemBase(out, "RsBanListItem", indent); - uint16_t int_Indent = indent + 2; - peerList.print(out, int_Indent); - - printRsItemEnd(out, "RsBanListItem", indent); - return out; -} - - -uint32_t RsBanListSerialiser::sizeList(RsBanListItem *item) -{ - uint32_t s = 8; /* header */ - s += item->peerList.TlvSize(); - - return s; -} - -/* serialise the data to the buffer */ -bool RsBanListSerialiser::serialiseList(RsBanListItem *item, void *data, uint32_t *pktsize) -{ - uint32_t tlvsize = sizeList(item); - uint32_t offset = 0; - - if (*pktsize < tlvsize) + if (pktsize < tlvsize) return false; /* not enough space */ - *pktsize = tlvsize; - - bool ok = true; - - ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + pktsize = tlvsize; + if(!setRsItemHeader(data, tlvsize, PacketId(), tlvsize)) + { + std::cerr << "RsReputationItem::serialise_header(): ERROR. Not enough size!" << std::endl; + return false ; + } #ifdef RSSERIAL_DEBUG - std::cerr << "RsDsdvSerialiser::serialiseRoute() Header: " << ok << std::endl; - std::cerr << "RsDsdvSerialiser::serialiseRoute() Size: " << tlvsize << std::endl; + std::cerr << "RsReputationItem::serialise() Header: " << ok << std::endl; #endif - - /* skip the header */ offset += 8; - /* add mandatory parts first */ - ok &= item->peerList.SetTlv(data, tlvsize, &offset); - - if (offset != tlvsize) - { - ok = false; -#ifdef RSSERIAL_DEBUG - std::cerr << "RsDsdvSerialiser::serialiseRoute() Size Error! " << std::endl; -#endif - } - - return ok; -} - -RsBanListItem *RsBanListSerialiser::deserialiseList(void *data, uint32_t *pktsize) -{ - /* get the type and size */ - uint32_t rstype = getRsItemId(data); - uint32_t tlvsize = getRsItemSize(data); - - uint32_t offset = 0; - - - if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || - (RS_SERVICE_TYPE_BANLIST != getRsItemService(rstype)) || - (RS_PKT_SUBTYPE_BANLIST_ITEM != getRsItemSubType(rstype))) - { - return NULL; /* wrong type */ - } - - if (*pktsize < tlvsize) /* check size */ - return NULL; /* not enough data */ - - /* set the packet length */ - *pktsize = tlvsize; - - bool ok = true; - - /* ready to load */ - RsBanListItem *item = new RsBanListItem(); - item->clear(); - - /* skip the header */ - offset += 8; - - /* add mandatory parts first */ - ok &= item->peerList.GetTlv(data, tlvsize, &offset); - - if (offset != tlvsize) - { - /* error */ - delete item; - return NULL; - } - - if (!ok) - { - delete item; - return NULL; - } - - return item; + return true ; } /*************************************************************************/ -uint32_t RsBanListSerialiser::size(RsItem *i) +void RsGxsReputationSetItem::clear() { - RsBanListItem *dri; - - if (NULL != (dri = dynamic_cast(i))) - { - return sizeList(dri); - } - return 0; + mOpinions.clear() ; } -bool RsBanListSerialiser::serialise(RsItem *i, void *data, uint32_t *pktsize) +void RsGxsReputationUpdateItem::clear() { - RsBanListItem *dri; - - if (NULL != (dri = dynamic_cast(i))) - { - return serialiseList(dri, data, pktsize); - } - return false; + mOpinions.clear() ; } -RsItem *RsBanListSerialiser::deserialise(void *data, uint32_t *pktsize) +/*************************************************************************/ +/*************************************************************************/ +/*************************************************************************/ + +std::ostream& RsGxsReputationConfigItem::print(std::ostream &out, uint16_t indent) +{ + printRsItemBase(out, "RsReputationConfigItem", indent); + uint16_t int_Indent = indent + 2; + + out << "mPeerId: " << mPeerId << std::endl; + out << "last update: " << time(NULL) - mLatestUpdate << " secs ago." << std::endl; + out << "last query : " << time(NULL) - mLastQuery << " secs ago." << std::endl; + + printRsItemEnd(out, "RsReputationConfigItem", indent); + return out; +} + +std::ostream& RsGxsReputationSetItem::print(std::ostream &out, uint16_t indent) +{ + printRsItemBase(out, "RsReputationSetItem", indent); + uint16_t int_Indent = indent + 2; + + out << "GxsId: " << mGxsId << std::endl; + out << "mOwnOpinion: " << mOwnOpinion << std::endl; + out << "mOwnOpinionTS : " << time(NULL) - mOwnOpinionTS << " secs ago." << std::endl; + out << "Opinions from neighbors: " << std::endl; + + for(std::map::const_iterator it(mOpinions.begin());it!=mOpinions.end();++it) + out << " " << it->first << ": " << it->second << std::endl; + + printRsItemEnd(out, "RsReputationSetItem", indent); + return out; +} +std::ostream& RsGxsReputationUpdateItem::print(std::ostream &out, uint16_t indent) +{ + printRsItemBase(out, "RsReputationUpdateItem", indent); + uint16_t int_Indent = indent + 2; + + out << "from: " << PeerId() << std::endl; + out << "last update: " << time(NULL) - mLatestUpdate << " secs ago." << std::endl; + + for(std::map::const_iterator it(mOpinions.begin());it!=mOpinions.end();++it) + out << " " << it->first << ": " << it->second << std::endl; + + printRsItemEnd(out, "RsReputationUpdateItem", indent); + return out; +} +std::ostream& RsGxsReputationRequestItem::print(std::ostream &out, uint16_t indent) +{ + printRsItemBase(out, "RsReputationRequestItem", indent); + uint16_t int_Indent = indent + 2; + + out << "last update: " << time(NULL) - mLastUpdate << " secs ago." << std::endl; + + printRsItemEnd(out, "RsReputationRequestItem", indent); + return out; +} +/*************************************************************************/ + +uint32_t RsGxsReputationConfigItem::serial_size() const +{ + uint32_t s = 8; /* header */ + + s += mPeerId.serial_size() ; // PeerId + s += 4 ; // mLatestUpdate + s += 4 ; // mLastQuery + + return s ; +} + +uint32_t RsGxsReputationSetItem::serial_size() const +{ + uint32_t s = 8; /* header */ + + s += mGxsId.serial_size() ; + s += 4 ; // mOwnOpinion + s += 4 ; // mOwnOpinionTS + + s += 4 ; // mOpinions.size() + + s += (4+RsPeerId::serial_size()) * mOpinions.size() ; + + return s ; +} + +uint32_t RsGxsReputationUpdateItem::serial_size() const +{ + uint32_t s = 8; /* header */ + + s += 4 ; // mLatestUpdate + s += 4 ; // mOpinions.size(); + + s += (RsGxsId::serial_size() + 4) * mOpinions.size() ; + + return s ; +} + +uint32_t RsGxsReputationRequestItem::serial_size() const +{ + uint32_t s = 8; /* header */ + + s += 4 ; // mLastUpdate + + return s; +} + +/*************************************************************************/ + +bool RsGxsReputationConfigItem::serialise(void *data, uint32_t& pktsize) const +{ + uint32_t tlvsize ; + uint32_t offset=0; + + if(!serialise_header(data,pktsize,tlvsize,offset)) + return false ; + + bool ok = true; + + ok &= mPeerId.serialise(data,tlvsize,offset) ; + ok &= setRawUInt32(data, tlvsize, &offset, mLatestUpdate); + ok &= setRawUInt32(data, tlvsize, &offset, mLastQuery); + + if (offset != tlvsize) + { + ok = false; + std::cerr << "RsGxsReputationConfigItem::serialisedata() size error! " << std::endl; + } + + return ok; +} +bool RsGxsReputationSetItem::serialise(void *data, uint32_t& pktsize) const +{ + uint32_t tlvsize ; + uint32_t offset=0; + + if(!serialise_header(data,pktsize,tlvsize,offset)) + return false ; + + bool ok = true; + + ok &= mGxsId.serialise(data,tlvsize,offset) ; + ok &= setRawUInt32(data, tlvsize, &offset, mOwnOpinion); + ok &= setRawUInt32(data, tlvsize, &offset, mOwnOpinionTS); + ok &= setRawUInt32(data, tlvsize, &offset, mOpinions.size()); + + for(std::map::const_iterator it(mOpinions.begin());it!=mOpinions.end();++it) + { + ok &= it->first.serialise(data,tlvsize,offset) ; + ok &= setRawUInt32(data, tlvsize, &offset, it->second) ; + } + + if (offset != tlvsize) + { + ok = false; + std::cerr << "RsGxsReputationSetItem::serialisedata() size error! " << std::endl; + } + + return ok; +} +bool RsGxsReputationUpdateItem::serialise(void *data, uint32_t& pktsize) const +{ + uint32_t tlvsize ; + uint32_t offset=0; + + if(!serialise_header(data,pktsize,tlvsize,offset)) + return false ; + + bool ok = true; + + ok &= setRawUInt32(data, tlvsize, &offset, mLatestUpdate); + ok &= setRawUInt32(data, tlvsize, &offset, mOpinions.size()); + + for(std::map::const_iterator it(mOpinions.begin());ok && it!=mOpinions.end();++it) + { + ok &= it->first.serialise(data, tlvsize, offset) ; + ok &= setRawUInt32(data, tlvsize, &offset, it->second) ; + } + + if (offset != tlvsize) + { + ok = false; + std::cerr << "RsGxsReputationUpdateItem::serialisedata() size error! " << std::endl; + } + + return ok; +} +/* serialise the data to the buffer */ +bool RsGxsReputationRequestItem::serialise(void *data, uint32_t& pktsize) const +{ + uint32_t tlvsize ; + uint32_t offset=0; + + if(!serialise_header(data,pktsize,tlvsize,offset)) + return false ; + + bool ok = true; + + ok &= setRawUInt32(data, tlvsize, &offset, mLastUpdate); + + if (offset != tlvsize) + { + ok = false; + std::cerr << "RsGxsReputationRequestItem::serialisedata() size error! " << std::endl; + } + + return ok; +} +/*************************************************************************/ + +RsGxsReputationConfigItem *RsGxsReputationSerialiser::deserialiseReputationConfigItem(void *data,uint32_t size) +{ + uint32_t offset = 8; // skip the header + uint32_t rssize = getRsItemSize(data); + bool ok = true ; + + RsGxsReputationConfigItem *item = new RsGxsReputationConfigItem() ; + + /* add mandatory parts first */ + ok &= item->mPeerId.deserialise(data, size, offset) ; + ok &= getRawUInt32(data, size, &offset, &item->mLatestUpdate); + ok &= getRawUInt32(data, size, &offset, &item->mLastQuery); + + if (offset != rssize || !ok) + { + std::cerr << __PRETTY_FUNCTION__ << ": error while deserialising! Item will be dropped." << std::endl; + delete item; + return NULL ; + } + + return item; +} + +RsGxsReputationSetItem *RsGxsReputationSerialiser::deserialiseReputationSetItem(void *data,uint32_t tlvsize) +{ + uint32_t offset = 8; // skip the header + uint32_t rssize = getRsItemSize(data); + bool ok = true ; + + RsGxsReputationSetItem *item = new RsGxsReputationSetItem() ; + + /* add mandatory parts first */ + ok &= item->mGxsId.deserialise(data, tlvsize, offset) ; + ok &= getRawUInt32(data, tlvsize, &offset, &item->mOwnOpinion); + ok &= getRawUInt32(data, tlvsize, &offset, &item->mOwnOpinionTS); + + uint32_t S ; + ok &= getRawUInt32(data, tlvsize, &offset, &S); + + for(int i=0;ok && imOpinions[pid] = op ; + } + + if (offset != rssize || !ok) + { + std::cerr << __PRETTY_FUNCTION__ << ": error while deserialising! Item will be dropped." << std::endl; + delete item; + return NULL ; + } + + return item; +} + +RsGxsReputationUpdateItem *RsGxsReputationSerialiser::deserialiseReputationUpdateItem(void *data,uint32_t tlvsize) +{ + uint32_t offset = 8; // skip the header + uint32_t rssize = getRsItemSize(data); + bool ok = true ; + + RsGxsReputationUpdateItem *item = new RsGxsReputationUpdateItem() ; + + /* add mandatory parts first */ + ok &= getRawUInt32(data, tlvsize, &offset, &item->mLatestUpdate); + + uint32_t S ; + ok &= getRawUInt32(data, tlvsize, &offset, &S) ; + + for(uint32_t i=0;ok && imOpinions[gid] = op ; + + } + + if (offset != rssize || !ok) + { + std::cerr << __PRETTY_FUNCTION__ << ": error while deserialising! Item will be dropped." << std::endl; + delete item; + return NULL ; + } + + return item; +} + +RsGxsReputationRequestItem *RsGxsReputationSerialiser::deserialiseReputationRequestItem(void *data,uint32_t tlvsize) +{ + uint32_t offset = 8; // skip the header + uint32_t rssize = getRsItemSize(data); + bool ok = true ; + + RsGxsReputationRequestItem *item = new RsGxsReputationRequestItem() ; + + /* add mandatory parts first */ + ok &= getRawUInt32(data, tlvsize, &offset, &item->mLastUpdate); + + if (offset != rssize || !ok) + { + std::cerr << __PRETTY_FUNCTION__ << ": error while deserialising! Item will be dropped." << std::endl; + delete item; + return NULL ; + } + + return item; +} +/*************************************************************************/ + +RsItem *RsGxsReputationSerialiser::deserialise(void *data, uint32_t *pktsize) { /* get the type and size */ uint32_t rstype = getRsItemId(data); - if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || - (RS_SERVICE_TYPE_BANLIST != getRsItemService(rstype))) - { - return NULL; /* wrong type */ - } + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || (RS_SERVICE_GXS_TYPE_REPUTATION != getRsItemService(rstype))) + { + std::cerr << "RsReputationSerialiser::deserialise(): wrong item type " << std::hex << rstype << std::dec << std::endl; + return NULL; /* wrong type */ + } switch(getRsItemSubType(rstype)) { - case RS_PKT_SUBTYPE_BANLIST_ITEM: - return deserialiseList(data, pktsize); - break; + case RS_PKT_SUBTYPE_GXS_REPUTATION_SET_ITEM : return deserialiseReputationSetItem (data, *pktsize); + case RS_PKT_SUBTYPE_GXS_REPUTATION_UPDATE_ITEM : return deserialiseReputationUpdateItem (data, *pktsize); + case RS_PKT_SUBTYPE_GXS_REPUTATION_REQUEST_ITEM: return deserialiseReputationRequestItem(data, *pktsize); + case RS_PKT_SUBTYPE_GXS_REPUTATION_CONFIG_ITEM : return deserialiseReputationConfigItem (data, *pktsize); + default: + std::cerr << "RsGxsReputationSerialiser::deserialise(): unknown item subtype " << std::hex<< rstype << std::dec << std::endl; return NULL; break; } } -#endif /*************************************************************************/ diff --git a/libretroshare/src/serialiser/rsgxsreputationitems.h b/libretroshare/src/serialiser/rsgxsreputationitems.h index b238217c9..16b90847c 100644 --- a/libretroshare/src/serialiser/rsgxsreputationitems.h +++ b/libretroshare/src/serialiser/rsgxsreputationitems.h @@ -32,88 +32,94 @@ #include "serialiser/rsserial.h" #include "retroshare/rsgxsifacetypes.h" -#define RS_PKT_SUBTYPE_GXSREPUTATION_CONFIG_ITEM 0x01 -#define RS_PKT_SUBTYPE_GXSREPUTATION_SET_ITEM 0x02 -#define RS_PKT_SUBTYPE_GXSREPUTATION_UPDATE_ITEM 0x03 -#define RS_PKT_SUBTYPE_GXSREPUTATION_REQUEST_ITEM 0x04 +#define RS_PKT_SUBTYPE_GXS_REPUTATION_CONFIG_ITEM 0x01 +#define RS_PKT_SUBTYPE_GXS_REPUTATION_SET_ITEM 0x02 +#define RS_PKT_SUBTYPE_GXS_REPUTATION_UPDATE_ITEM 0x03 +#define RS_PKT_SUBTYPE_GXS_REPUTATION_REQUEST_ITEM 0x04 /**************************************************************************/ - -class RsGxsReputationConfigItem: public RsItem +class RsReputationItem: public RsItem { public: - RsGxsReputationConfigItem() - :RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_GXS_TYPE_REPUTATION, - RS_PKT_SUBTYPE_GXSREPUTATION_CONFIG_ITEM) - { - setPriorityLevel(QOS_PRIORITY_RS_GXSREPUTATION_ITEM); - return; - } + RsReputationItem(uint8_t reputation_subtype) : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_GXS_TYPE_REPUTATION,reputation_subtype) + { + setPriorityLevel(QOS_PRIORITY_RS_GXSREPUTATION_ITEM); + } -virtual ~RsGxsReputationConfigItem(); -virtual void clear(); -std::ostream &print(std::ostream &out, uint16_t indent = 0); + virtual ~RsReputationItem() {} - std::string mPeerId; + virtual bool serialise(void *data,uint32_t& size) const = 0 ; + virtual uint32_t serial_size() const = 0 ; + + virtual void clear() = 0 ; + virtual std::ostream& print(std::ostream &out, uint16_t indent = 0) = 0; + + protected: + bool serialise_header(void *data, uint32_t& pktsize, uint32_t& tlvsize, uint32_t& offset) const; +}; + +class RsGxsReputationConfigItem: public RsReputationItem +{ +public: + RsGxsReputationConfigItem() :RsReputationItem(RS_PKT_SUBTYPE_GXS_REPUTATION_CONFIG_ITEM) {} + + virtual ~RsGxsReputationConfigItem() {} + virtual void clear() {} + std::ostream &print(std::ostream &out, uint16_t indent = 0); + + virtual bool serialise(void *data,uint32_t& size) const ; + virtual uint32_t serial_size() const ; + + RsPeerId mPeerId; uint32_t mLatestUpdate; // timestamp they returned. uint32_t mLastQuery; // when we sent out. }; -class RsGxsReputationSetItem: public RsItem +class RsGxsReputationSetItem: public RsReputationItem { - public: - RsGxsReputationSetItem() - :RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_GXS_TYPE_REPUTATION, - RS_PKT_SUBTYPE_GXSREPUTATION_SET_ITEM) - { - setPriorityLevel(QOS_PRIORITY_RS_GXSREPUTATION_ITEM); - return; - } +public: + RsGxsReputationSetItem() :RsReputationItem(RS_PKT_SUBTYPE_GXS_REPUTATION_SET_ITEM) {} -virtual ~RsGxsReputationSetItem(); -virtual void clear(); -std::ostream &print(std::ostream &out, uint16_t indent = 0); + virtual ~RsGxsReputationSetItem() {} + virtual void clear(); + std::ostream &print(std::ostream &out, uint16_t indent = 0); - std::string mGxsId; + virtual bool serialise(void *data,uint32_t& size) const ; + virtual uint32_t serial_size() const ; + + RsGxsId mGxsId; uint32_t mOwnOpinion; - uint32_t mOwnOpinionTs; - uint32_t mReputation; - std::map mOpinions; // RsPeerId -> Opinion. + uint32_t mOwnOpinionTS; + std::map mOpinions; // RsPeerId -> Opinion. }; -class RsGxsReputationUpdateItem: public RsItem +class RsGxsReputationUpdateItem: public RsReputationItem { - public: - RsGxsReputationUpdateItem() - :RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_GXS_TYPE_REPUTATION, - RS_PKT_SUBTYPE_GXSREPUTATION_UPDATE_ITEM) - { - setPriorityLevel(QOS_PRIORITY_RS_GXSREPUTATION_ITEM); - return; - } +public: + RsGxsReputationUpdateItem() :RsReputationItem(RS_PKT_SUBTYPE_GXS_REPUTATION_UPDATE_ITEM) {} -virtual ~RsGxsReputationUpdateItem(); -virtual void clear(); -std::ostream &print(std::ostream &out, uint16_t indent = 0); + virtual ~RsGxsReputationUpdateItem() {} + virtual void clear(); + std::ostream &print(std::ostream &out, uint16_t indent = 0); - std::map mOpinions; // GxsId -> Opinion. - uint32_t mLatestUpdate; + virtual bool serialise(void *data,uint32_t& size) const ; + virtual uint32_t serial_size() const ; + + uint32_t mLatestUpdate; + std::map mOpinions; // GxsId -> Opinion. }; -class RsGxsReputationRequestItem: public RsItem +class RsGxsReputationRequestItem: public RsReputationItem { - public: - RsGxsReputationRequestItem() - :RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_GXS_TYPE_REPUTATION, - RS_PKT_SUBTYPE_GXSREPUTATION_REQUEST_ITEM) - { - setPriorityLevel(QOS_PRIORITY_RS_GXSREPUTATION_ITEM); - return; - } +public: + RsGxsReputationRequestItem() :RsReputationItem(RS_PKT_SUBTYPE_GXS_REPUTATION_REQUEST_ITEM) {} -virtual ~RsGxsReputationRequestItem(); -virtual void clear(); -std::ostream &print(std::ostream &out, uint16_t indent = 0); + virtual ~RsGxsReputationRequestItem() {} + virtual void clear() {} + std::ostream &print(std::ostream &out, uint16_t indent = 0); + + virtual bool serialise(void *data,uint32_t& size) const ; + virtual uint32_t serial_size() const ; uint32_t mLastUpdate; }; @@ -121,39 +127,26 @@ std::ostream &print(std::ostream &out, uint16_t indent = 0); class RsGxsReputationSerialiser: public RsSerialType { - public: - RsGxsReputationSerialiser() - :RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_GXS_TYPE_REPUTATION) - { return; } -virtual ~RsGxsReputationSerialiser() - { return; } - -virtual uint32_t size(RsItem *); -virtual bool serialise (RsItem *item, void *data, uint32_t *size); -virtual RsItem * deserialise(void *data, uint32_t *size); +public: + RsGxsReputationSerialiser() :RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_GXS_TYPE_REPUTATION){} - private: - -virtual uint32_t sizeConfig(RsGxsReputationConfigItem *); -virtual bool serialiseConfig(RsGxsReputationConfigItem *item, void *data, uint32_t *size); -virtual RsGxsReputationConfigItem *deserialiseConfig(void *data, uint32_t *size); - - -virtual uint32_t sizeSet(RsGxsReputationSetItem *); -virtual bool serialiseSet(RsGxsReputationSetItem *item, void *data, uint32_t *size); -virtual RsGxsReputationSetItem *deserialiseSet(void *data, uint32_t *size); - - -virtual uint32_t sizeUpdate(RsGxsReputationUpdateItem *); -virtual bool serialiseUpdate(RsGxsReputationUpdateItem *item, void *data, uint32_t *size); -virtual RsGxsReputationUpdateItem *deserialiseUpdate(void *data, uint32_t *size); - - -virtual uint32_t sizeRequest(RsGxsReputationRequestItem *); -virtual bool serialiseRequest(RsGxsReputationRequestItem *item, void *data, uint32_t *size); -virtual RsGxsReputationRequestItem *deserialiseRequest(void *data, uint32_t *size); + virtual ~RsGxsReputationSerialiser(){} + virtual uint32_t size(RsItem *item) + { + return dynamic_cast(item)->serial_size() ; + } + virtual bool serialise (RsItem *item, void *data, uint32_t *size) + { + return dynamic_cast(item)->serialise(data,*size) ; + } + virtual RsItem * deserialise(void *data, uint32_t *size); +private: + static RsGxsReputationConfigItem *deserialiseReputationConfigItem (void *data, uint32_t size); + static RsGxsReputationSetItem *deserialiseReputationSetItem (void *data, uint32_t size); + static RsGxsReputationUpdateItem *deserialiseReputationUpdateItem (void *data, uint32_t size); + static RsGxsReputationRequestItem *deserialiseReputationRequestItem(void *data, uint32_t size); }; /**************************************************************************/ diff --git a/libretroshare/src/services/p3gxsreputation.cc b/libretroshare/src/services/p3gxsreputation.cc index 943569732..2bcdf2498 100644 --- a/libretroshare/src/services/p3gxsreputation.cc +++ b/libretroshare/src/services/p3gxsreputation.cc @@ -38,13 +38,6 @@ * #define DEBUG_REPUTATION 1 ****/ - -/* DEFINE INTERFACE POINTER! */ -//RsGxsReputation *rsGxsReputation = NULL; - -const int kMaximumPeerAge = 180; // half a year. -const int kMaximumSetSize = 100; - /************ IMPLEMENTATION NOTES ********************************* * * p3GxsReputation shares opinions / reputations with peers. @@ -61,8 +54,12 @@ const int kMaximumSetSize = 100; * last update -----------> * <----------- modified opinions. * - * This service will have to store a huge amount of data. - * need to workout how to reduce it. + * If not clever enough, this service will have to store a huge amount of data. + * To make things tractable we do this: + * - do not store reputations when no data is present, or when all friends are neutral + * - only send a neutral opinion when they are a true change over someone's opinion + * - only send a neutral opinion when it is a true change over someone's opinion + * - auto-clean reputations for default values * * std::map mReputations. * std::multimap mUpdated. @@ -70,55 +67,72 @@ const int kMaximumSetSize = 100; * std::map mConfig; * * Updates from p3GxsReputation -> p3IdService. - * - * * Updates from p3IdService -> p3GxsReputation. * + * Each peer locally stores reputations for all GXS ids. If not stored, a default value + * is used, corresponding to a neutral opinion. Peers also share their reputation level + * with their neighbor nodes. + * + * The calculation method is the following: + * + * Local values: + * Good: 2 + * Neutral: 1 + * Bad: 0 * + * Overall reputation score: + * + * if(own_opinion == 0) // means we dont' care + * r = average_of_friends_opinions + * else + * r = own_opinion + * + * Decisions based on reputation score: + * + * 0 x1 1 x2 2 + * | <-----------------------------------------------------------------------> | + * ---------+ + * Lobbies | Msgs dropped + * Forums | Msgs dropped + * Messages | Msgs dropped + * ---------+---------------------------------------------------------------------------- + * + * We select x1=0.5 + * + * => to kill an identity, either you, or at least 50% of your friends need to flag it + * as bad. + * Rules: + * * a single peer cannot drastically change the behavior of a given GXS id + * * it should be easy for many peers to globally kill a GXS id + * + * Typical examples: + * + * Friends | Friend average | Own | alpha | Score + * -----------+---------------------+----------+------------+-------------- + * 10 | 0.5 | 1 | 0.25 | 0.375 + * 10 | 1.0 | 1 | 0.25 | 1.0 + * 10 | 1.0 | 0 | 0.25 | 1.0 + * + * To check: + * [ ] Opinions are saved/loaded accross restart + * [ ] Opinions are transmitted to friends + * [ ] Opinions are transmitted to friends when updated + * + * To do: + * [ ] Add debug info + * [ ] Test the whole thing + * [X] Implement a system to allow not storing info when we don't have it */ -const int32_t REPUTATION_OFFSET = 100000; -const int32_t LOWER_LIMIT = -100; -const int32_t UPPER_LIMIT = 100; - -int32_t ConvertFromSerialised(uint32_t value, bool limit) -{ - int32_t converted = ((int32_t) value) - REPUTATION_OFFSET ; - if (limit) - { - if (converted < LOWER_LIMIT) - { - converted = LOWER_LIMIT; - } - if (converted > UPPER_LIMIT) - { - converted = UPPER_LIMIT; - } - } - return converted; -} - -uint32_t ConvertToSerialised(int32_t value, bool limit) -{ - if (limit) - { - if (value < LOWER_LIMIT) - { - value = LOWER_LIMIT; - } - if (value > UPPER_LIMIT) - { - value = UPPER_LIMIT; - } - } - - value += REPUTATION_OFFSET; - if (value < 0) - { - value = 0; - } - return (uint32_t) value; -} +static const uint32_t LOWER_LIMIT = 0; // used to filter valid Opinion values from serialized data +static const uint32_t UPPER_LIMIT = 2; // used to filter valid Opinion values from serialized data +static const float REPUTATION_ASSESSMENT_THRESHOLD_X1 = 0.5f ; // reputation under which the peer gets killed +static const int kMaximumPeerAge = 180; // half a year. +static const int kMaximumSetSize = 100; // max set of updates to send at once. +static const int ACTIVE_FRIENDS_UPDATE_PERIOD = 600 ; // 10 minutes +static const int ACTIVE_FRIENDS_ONLINE_DELAY = 86400*7 ; // 1 week. +static const int kReputationRequestPeriod = 600; // 10 mins +static const int kReputationStoreWait = 180; // 3 minutes. @@ -126,14 +140,15 @@ p3GxsReputation::p3GxsReputation(p3LinkMgr *lm) :p3Service(), p3Config(), mReputationMtx("p3GxsReputation"), mLinkMgr(lm) { - addSerialType(new RsGxsReputationSerialiser()); + addSerialType(new RsGxsReputationSerialiser()); - mRequestTime = 0; - mStoreTime = 0; - mReputationsUpdated = false; + mRequestTime = 0; + mStoreTime = 0; + mReputationsUpdated = false; + mLastActiveFriendsUpdate = 0 ; + mAverageActiveFriends = 0 ; } - const std::string GXS_REPUTATION_APP_NAME = "gxsreputation"; const uint16_t GXS_REPUTATION_APP_MAJOR_VERSION = 1; const uint16_t GXS_REPUTATION_APP_MINOR_VERSION = 0; @@ -150,13 +165,30 @@ RsServiceInfo p3GxsReputation::getServiceInfo() GXS_REPUTATION_MIN_MINOR_VERSION); } - - int p3GxsReputation::tick() { processIncoming(); sendPackets(); + time_t now = time(NULL); + + if(mLastActiveFriendsUpdate + ACTIVE_FRIENDS_UPDATE_PERIOD < now) + { + updateActiveFriends() ; + cleanup() ; + + mLastActiveFriendsUpdate = now ; + } + +#ifdef DEBUG_REPUTATION + static time_t last_debug_print = time(NULL) ; + + if(now > 10+last_debug_print) + { + last_debug_print = now ; + debug_print() ; + } +#endif return 0; } @@ -165,7 +197,53 @@ int p3GxsReputation::status() return 1; } +void p3GxsReputation::cleanup() +{ + // remove opinions from friends that havn't been seen online for more than the specified delay + +#ifdef DEBUG_REPUTATION + std::cerr << "p3GxsReputation::cleanup() " << std::endl; +#endif + std::cerr << __PRETTY_FUNCTION__ << ": not implemented. TODO!" << std::endl; +} +void p3GxsReputation::updateActiveFriends() +{ + RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ + + // keep track of who is recently connected. That will give a value to average friend + // for this, we count all friends that have been online in the last week. + + time_t now = time(NULL) ; + + std::list idList ; + mLinkMgr->getFriendList(idList) ; + + mAverageActiveFriends = 0 ; +#ifdef DEBUG_REPUTATION + std::cerr << " counting recently online peers." << std::endl; +#endif + + for(std::list::const_iterator it(idList.begin());it!=idList.end();++it) + { + RsPeerDetails details ; +#ifdef DEBUG_REPUTATION + std::cerr << " " << *it << ": last seen " << now - details.lastConnect << " secs ago" << std::endl; +#endif + + if(rsPeers->getPeerDetails(*it, details) && now < details.lastConnect + ACTIVE_FRIENDS_ONLINE_DELAY) + ++mAverageActiveFriends ; + } +#ifdef DEBUG_REPUTATION + std::cerr << " new count: " << mAverageActiveFriends << std::endl; +#endif + +} + +static RsReputations::Opinion safe_convert_uint32t_to_opinion(uint32_t op) +{ + return RsReputations::Opinion(std::min((uint32_t)op,UPPER_LIMIT)) ; +} /***** Implementation ******/ bool p3GxsReputation::processIncoming() @@ -184,40 +262,31 @@ bool p3GxsReputation::processIncoming() switch(item->PacketSubType()) { default: - case RS_PKT_SUBTYPE_GXSREPUTATION_CONFIG_ITEM: - case RS_PKT_SUBTYPE_GXSREPUTATION_SET_ITEM: + case RS_PKT_SUBTYPE_GXS_REPUTATION_CONFIG_ITEM: + case RS_PKT_SUBTYPE_GXS_REPUTATION_SET_ITEM: std::cerr << "p3GxsReputation::processingIncoming() Unknown Item"; std::cerr << std::endl; itemOk = false; break; - case RS_PKT_SUBTYPE_GXSREPUTATION_REQUEST_ITEM: + case RS_PKT_SUBTYPE_GXS_REPUTATION_REQUEST_ITEM: { - RsGxsReputationRequestItem *requestItem = - dynamic_cast(item); + RsGxsReputationRequestItem *requestItem = dynamic_cast(item); if (requestItem) - { SendReputations(requestItem); - } else - { itemOk = false; - } } break; - case RS_PKT_SUBTYPE_GXSREPUTATION_UPDATE_ITEM: + case RS_PKT_SUBTYPE_GXS_REPUTATION_UPDATE_ITEM: { - RsGxsReputationUpdateItem *updateItem = - dynamic_cast(item); + RsGxsReputationUpdateItem *updateItem = dynamic_cast(item); + if (updateItem) - { RecvReputations(updateItem); - } else - { itemOk = false; - } } break; } @@ -237,8 +306,9 @@ bool p3GxsReputation::processIncoming() bool p3GxsReputation::SendReputations(RsGxsReputationRequestItem *request) { - std::cerr << "p3GxsReputation::SendReputations()"; - std::cerr << std::endl; +#ifdef DEBUG_REPUTATION + std::cerr << "p3GxsReputation::SendReputations()" << std::endl; +#endif RsPeerId peerId = request->PeerId(); time_t last_update = request->mLastUpdate; @@ -252,12 +322,13 @@ bool p3GxsReputation::SendReputations(RsGxsReputationRequestItem *request) int count = 0; int totalcount = 0; RsGxsReputationUpdateItem *pkt = new RsGxsReputationUpdateItem(); + pkt->PeerId(peerId); for(;tit != mUpdated.end(); ++tit) { /* find */ - std::map::iterator rit; - rit = mReputations.find(tit->second); + std::map::iterator rit = mReputations.find(tit->second); + if (rit == mReputations.end()) { std::cerr << "p3GxsReputation::SendReputations() ERROR Missing Reputation"; @@ -275,8 +346,9 @@ bool p3GxsReputation::SendReputations(RsGxsReputationRequestItem *request) } RsGxsId gxsId = rit->first; - pkt->mOpinions[gxsId] = ConvertToSerialised(rit->second.mOwnOpinion, true); + pkt->mOpinions[gxsId] = rit->second.mOwnOpinion; pkt->mLatestUpdate = rit->second.mOwnOpinionTs; + if (pkt->mLatestUpdate == (uint32_t) now) { // if we could possibly get another Update at this point (same second). @@ -289,10 +361,13 @@ bool p3GxsReputation::SendReputations(RsGxsReputationRequestItem *request) if (count > kMaximumSetSize) { +#ifdef DEBUG_REPUTATION std::cerr << "p3GxsReputation::SendReputations() Sending Full Packet"; std::cerr << std::endl; +#endif sendItem(pkt); + pkt = new RsGxsReputationUpdateItem(); pkt->PeerId(peerId); count = 0; @@ -301,8 +376,10 @@ bool p3GxsReputation::SendReputations(RsGxsReputationRequestItem *request) if (!pkt->mOpinions.empty()) { +#ifdef DEBUG_REPUTATION std::cerr << "p3GxsReputation::SendReputations() Sending Final Packet"; std::cerr << std::endl; +#endif sendItem(pkt); } @@ -311,52 +388,125 @@ bool p3GxsReputation::SendReputations(RsGxsReputationRequestItem *request) delete pkt; } +#ifdef DEBUG_REPUTATION std::cerr << "p3GxsReputation::SendReputations() Total Count: " << totalcount; std::cerr << std::endl; +#endif return true; } +void p3GxsReputation::locked_updateOpinion(const RsPeerId& from,const RsGxsId& about,RsReputations::Opinion op) +{ + /* find matching Reputation */ + std::map::iterator rit = mReputations.find(about); + + RsReputations::Opinion new_opinion = safe_convert_uint32t_to_opinion(op); + RsReputations::Opinion old_opinion = RsReputations::OPINION_NEUTRAL ; // default if not set + + bool updated = false ; + +#ifdef DEBUG_REPUTATION + std::cerr << "p3GxsReputation::update opinion of " << about << " from " << from << " to " << op << std::endl; +#endif + // now 4 cases; + // Opinion already stored + // New opinion is same: nothing to do + // New opinion is different: if neutral, remove entry + // Nothing stored + // New opinion is neutral: nothing to do + // New opinion is != 1: create entry and store + + if (rit == mReputations.end()) + { +#ifdef DEBUG_REPUTATION + std::cerr << " no preview record"<< std::endl; +#endif + + if(new_opinion != RsReputations::OPINION_NEUTRAL) + { + mReputations[about] = Reputation(about); + rit = mReputations.find(about); + } + else + { +#ifdef DEBUG_REPUTATION + std::cerr << " no changes!"<< std::endl; +#endif + return ; // nothing to do + } + } + + Reputation& reputation = rit->second; + + std::map::iterator it2 = reputation.mOpinions.find(from) ; + + if(it2 == reputation.mOpinions.end()) + { + if(new_opinion != RsReputations::OPINION_NEUTRAL) + { + reputation.mOpinions[from] = new_opinion; // filters potentially tweaked reputation score sent by friend + updated = true ; + } + } + else + { + old_opinion = it2->second ; + + if(new_opinion == RsReputations::OPINION_NEUTRAL) + { + reputation.mOpinions.erase(it2) ; // don't store when the opinion is neutral + updated = true ; + } + else if(new_opinion != old_opinion) + { + it2->second = new_opinion ; + updated = true ; + } + } + + if(reputation.mOpinions.empty() && reputation.mOwnOpinion == RsReputations::OPINION_NEUTRAL) + { + mReputations.erase(rit) ; +#ifdef DEBUG_REPUTATION + std::cerr << " own is neutral and no opinions from friends => remove entry" << std::endl; +#endif + updated = true ; + } + else if(updated) + { +#ifdef DEBUG_REPUTATION + std::cerr << " reputation changed. re-calculating." << std::endl; +#endif + reputation.updateReputation(mAverageActiveFriends) ; + } + + if(updated) + IndicateConfigChanged() ; +} bool p3GxsReputation::RecvReputations(RsGxsReputationUpdateItem *item) { - std::cerr << "p3GxsReputation::RecvReputations()"; - std::cerr << std::endl; +#ifdef DEBUG_REPUTATION + std::cerr << "p3GxsReputation::RecvReputations() from " << item->PeerId() << std::endl; +#endif RsPeerId peerid = item->PeerId(); - std::map::iterator it; - for(it = item->mOpinions.begin(); it != item->mOpinions.end(); ++it) + for( std::map::iterator it = item->mOpinions.begin(); it != item->mOpinions.end(); ++it) { RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ - /* find matching Reputation */ - std::map::iterator rit; - RsGxsId gxsId(it->first); - - rit = mReputations.find(gxsId); - if (rit == mReputations.end()) - { - mReputations[gxsId] = Reputation(gxsId); - rit = mReputations.find(gxsId); - } - - Reputation &reputation = rit->second; - reputation.mOpinions[peerid] = ConvertFromSerialised(it->second, true); - - int previous = reputation.mReputation; - if (previous != reputation.CalculateReputation()) - { - // updated from the network. - mUpdatedReputations.insert(gxsId); - } + locked_updateOpinion(peerid,it->first,safe_convert_uint32t_to_opinion(it->second)); } - updateLatestUpdate(peerid, item->mLatestUpdate); + + updateLatestUpdate(peerid,item->mLatestUpdate); + return true; } -bool p3GxsReputation::updateLatestUpdate(RsPeerId peerid, time_t ts) +bool p3GxsReputation::updateLatestUpdate(RsPeerId peerid,time_t latest_update) { RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ @@ -367,11 +517,12 @@ bool p3GxsReputation::updateLatestUpdate(RsPeerId peerid, time_t ts) mConfig[peerid] = ReputationConfig(peerid); it = mConfig.find(peerid) ; } - it->second.mLatestUpdate = ts; + it->second.mLatestUpdate = latest_update ; mReputationsUpdated = true; // Switched to periodic save due to scale of data. - //IndicateConfigChanged(); + + IndicateConfigChanged(); return true; } @@ -380,14 +531,75 @@ bool p3GxsReputation::updateLatestUpdate(RsPeerId peerid, time_t ts) * Opinion ****/ -bool p3GxsReputation::updateOpinion(const RsGxsId& gxsid, int opinion) +bool p3GxsReputation::getReputationInfo(const RsGxsId& gxsid, RsReputations::ReputationInfo& info) { + RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ + +#ifdef DEBUG_REPUTATION + std::cerr << "getReputationInfo() for " << gxsid << std::endl; +#endif + + std::map::const_iterator it = mReputations.find(gxsid); + + if (it == mReputations.end()) + { + info.mOwnOpinion = RsReputations::OPINION_NEUTRAL ; + info.mFriendAverage = RsReputations::OPINION_NEUTRAL ; + info.mOverallReputationScore = float(RsReputations::OPINION_NEUTRAL) ; + info.mAssessment = RsReputations::ASSESSMENT_OK ; +#ifdef DEBUG_REPUTATION + std::cerr << " no information present. Returning default. OwnOp = " << info.mOwnOpinion << ", overall score=" << info.mAssessment << std::endl; +#endif + } + else + { + info.mOwnOpinion = RsReputations::Opinion(it->second.mOwnOpinion) ; + info.mOverallReputationScore = it->second.mReputation ; + info.mFriendAverage = it->second.mFriendAverage ; + + if(info.mOverallReputationScore > REPUTATION_ASSESSMENT_THRESHOLD_X1) + info.mAssessment = RsReputations::ASSESSMENT_OK ; + else + info.mAssessment = RsReputations::ASSESSMENT_BAD ; + +#ifdef DEBUG_REPUTATION + std::cerr << " information present. OwnOp = " << info.mOwnOpinion << ", overall score=" << info.mAssessment << std::endl; +#endif + } + + return true ; +} + +bool p3GxsReputation::isIdentityBanned(const RsGxsId &id) +{ + RsReputations::ReputationInfo info ; + + getReputationInfo(id,info) ; + +#ifdef DEBUG_REPUTATION + std::cerr << "isIdentityBanned(): returning " << (info.mAssessment == RsReputations::ASSESSMENT_BAD) << " for GXS id " << id << std::endl; +#endif + return info.mAssessment == RsReputations::ASSESSMENT_BAD ; +} + +bool p3GxsReputation::setOwnOpinion(const RsGxsId& gxsid, const RsReputations::Opinion& opinion) +{ +#ifdef DEBUG_REPUTATION + std::cerr << "setOwnOpinion(): for GXS id " << gxsid << " to " << opinion << std::endl; +#endif + if(gxsid.isNull()) + { + std::cerr << " ID " << gxsid << " is rejected. Look for a bug in calling method." << std::endl; + return false ; + } + RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ std::map::iterator rit; /* find matching Reputation */ rit = mReputations.find(gxsid); + if (rit == mReputations.end()) { mReputations[gxsid] = Reputation(gxsid); @@ -420,14 +632,15 @@ bool p3GxsReputation::updateOpinion(const RsGxsId& gxsid, int opinion) time_t now = time(NULL); reputation.mOwnOpinion = opinion; reputation.mOwnOpinionTs = now; - reputation.CalculateReputation(); + reputation.updateReputation(mAverageActiveFriends); mUpdated.insert(std::make_pair(now, gxsid)); mUpdatedReputations.insert(gxsid); - mReputationsUpdated = true; + // Switched to periodic save due to scale of data. - //IndicateConfigChanged(); + IndicateConfigChanged(); + return true; } @@ -448,6 +661,9 @@ bool p3GxsReputation::saveList(bool& cleanup, std::list &savelist) cleanup = true; RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ +#ifdef DEBUG_REPUTATION + std::cerr << "p3GxsReputation::saveList()" << std::endl; +#endif /* save */ std::map::iterator it; for(it = mConfig.begin(); it != mConfig.end(); ++it) @@ -459,7 +675,7 @@ bool p3GxsReputation::saveList(bool& cleanup, std::list &savelist) } RsGxsReputationConfigItem *item = new RsGxsReputationConfigItem(); - item->mPeerId = it->first.toStdString(); + item->mPeerId = it->first; item->mLatestUpdate = it->second.mLatestUpdate; item->mLastQuery = it->second.mLastQuery; savelist.push_back(item); @@ -470,16 +686,15 @@ bool p3GxsReputation::saveList(bool& cleanup, std::list &savelist) for(rit = mReputations.begin(); rit != mReputations.end(); ++rit, count++) { RsGxsReputationSetItem *item = new RsGxsReputationSetItem(); - item->mGxsId = rit->first.toStdString(); - item->mOwnOpinion = ConvertToSerialised(rit->second.mOwnOpinion, false); - item->mOwnOpinionTs = rit->second.mOwnOpinionTs; - item->mReputation = ConvertToSerialised(rit->second.mReputation, false); + item->mGxsId = rit->first; + item->mOwnOpinion = rit->second.mOwnOpinion; + item->mOwnOpinionTS = rit->second.mOwnOpinionTs; - std::map::iterator oit; + std::map::iterator oit; for(oit = rit->second.mOpinions.begin(); oit != rit->second.mOpinions.end(); ++oit) { // should be already limited. - item->mOpinions[oit->first.toStdString()] = ConvertToSerialised(oit->second, false); + item->mOpinions[oit->first] = (uint32_t)oit->second; } savelist.push_back(item); @@ -495,6 +710,9 @@ void p3GxsReputation::saveDone() bool p3GxsReputation::loadList(std::list& loadList) { +#ifdef DEBUG_REPUTATION + std::cerr << "p3GxsReputation::saveList()" << std::endl; +#endif std::list::iterator it; std::set peerSet; @@ -515,9 +733,8 @@ bool p3GxsReputation::loadList(std::list& loadList) } RsGxsReputationSetItem *set = dynamic_cast(*it); if (set) - { loadReputationSet(set, peerSet); - } + delete (*it); } @@ -530,6 +747,9 @@ bool p3GxsReputation::loadReputationSet(RsGxsReputationSetItem *item, const std: std::map::iterator rit; + if(item->mGxsId.isNull()) // just a protection against potential errors having put 00000 into ids. + return false ; + /* find matching Reputation */ RsGxsId gxsId(item->mGxsId); rit = mReputations.find(gxsId); @@ -542,26 +762,24 @@ bool p3GxsReputation::loadReputationSet(RsGxsReputationSetItem *item, const std: Reputation &reputation = mReputations[gxsId]; // install opinions. - std::map::const_iterator oit; + std::map::const_iterator oit; for(oit = item->mOpinions.begin(); oit != item->mOpinions.end(); ++oit) { // expensive ... but necessary. RsPeerId peerId(oit->first); if (peerSet.end() != peerSet.find(peerId)) - { - reputation.mOpinions[peerId] = ConvertFromSerialised(oit->second, true); - } + reputation.mOpinions[peerId] = safe_convert_uint32t_to_opinion(oit->second); } - reputation.mOwnOpinion = ConvertFromSerialised(item->mOwnOpinion, false); - reputation.mOwnOpinionTs = item->mOwnOpinionTs; + reputation.mOwnOpinion = item->mOwnOpinion; + reputation.mOwnOpinionTs = item->mOwnOpinionTS; // if dropping entries has changed the score -> must update. - int previous = ConvertFromSerialised(item->mReputation, false); - if (previous != reputation.CalculateReputation()) - { - mUpdatedReputations.insert(gxsId); - } + + float old_reputation = reputation.mReputation ; + + if(old_reputation != reputation.updateReputation(mAverageActiveFriends)) + mUpdatedReputations.insert(gxsId) ; mUpdated.insert(std::make_pair(reputation.mOwnOpinionTs, gxsId)); return true; @@ -572,9 +790,6 @@ bool p3GxsReputation::loadReputationSet(RsGxsReputationSetItem *item, const std: * Send Requests. ****/ -const int kReputationRequestPeriod = 3600; -const int kReputationStoreWait = 180; // 3 minutes. - int p3GxsReputation::sendPackets() { time_t now = time(NULL); @@ -585,7 +800,7 @@ int p3GxsReputation::sendPackets() storeTime = mStoreTime; } - if (now - requestTime > kReputationRequestPeriod) + if (now > requestTime + kReputationRequestPeriod) { sendReputationRequests(); @@ -629,48 +844,41 @@ void p3GxsReputation::sendReputationRequests() mLinkMgr->getOnlineList(idList); -#ifdef DEBUG_REPUTATION - std::cerr << "p3GxsReputation::sendReputationRequests()"; - std::cerr << std::endl; -#endif - /* prepare packets */ std::list::iterator it; for(it = idList.begin(); it != idList.end(); ++it) - { -#ifdef DEBUG_REPUTATION - std::cerr << "p3GxsReputation::sendReputationRequest() To: " << *it; - std::cerr << std::endl; -#endif sendReputationRequest(*it); - } } - - int p3GxsReputation::sendReputationRequest(RsPeerId peerid) { - std::cerr << "p3GxsReputation::sendReputationRequest(" << peerid << ")"; - std::cerr << std::endl; +#ifdef DEBUG_REPUTATION + std::cerr << " p3GxsReputation::sendReputationRequest(" << peerid << ") " ; +#endif + time_t now = time(NULL) ; /* */ - RsGxsReputationRequestItem *requestItem = - new RsGxsReputationRequestItem(); - + RsGxsReputationRequestItem *requestItem = new RsGxsReputationRequestItem(); requestItem->PeerId(peerid); { RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/ /* find the last timestamp we have */ - std::map::iterator it; - it = mConfig.find(peerid); + std::map::iterator it = mConfig.find(peerid); + if (it != mConfig.end()) { +#ifdef DEBUG_REPUTATION + std::cerr << " lastUpdate = " << now - it->second.mLatestUpdate << " secs ago. Requesting only more recent." << std::endl; +#endif requestItem->mLastUpdate = it->second.mLatestUpdate; } else { +#ifdef DEBUG_REPUTATION + std::cerr << " lastUpdate = never. Requesting all!" << std::endl; +#endif // get whole list. requestItem->mLastUpdate = 0; } @@ -680,4 +888,44 @@ int p3GxsReputation::sendReputationRequest(RsPeerId peerid) return 1; } +float Reputation::updateReputation(uint32_t average_active_friends) +{ + // the calculation of reputation makes the whole thing + + int friend_total = 0; + + // accounts for all friends. Neutral opinions count for 1-1=0 + + for(std::map::const_iterator it(mOpinions.begin());it!=mOpinions.end();++it) + friend_total += it->second - 1; + + if(mOpinions.empty()) // includes the case of no friends! + mFriendAverage = 1.0f ; + else + mFriendAverage = 1.0+friend_total / float(std::max(average_active_friends,(uint32_t)mOpinions.size())); + + if(mOwnOpinion == RsReputations::OPINION_NEUTRAL) + mReputation = mFriendAverage ; + else + mReputation = (float)mOwnOpinion ; + + return float(mOwnOpinion) ; +} + +void p3GxsReputation::debug_print() +{ + std::cerr << "Reputations database: " << std::endl; + std::cerr << " Average number of peers: " << mAverageActiveFriends << std::endl; + + time_t now = time(NULL) ; + + for(std::map::const_iterator it(mReputations.begin());it!=mReputations.end();++it) + { + std::cerr << " ID=" << it->first << ", own: " << it->second.mOwnOpinion << ", Friend average: " << it->second.mFriendAverage << ", global_score: " << it->second.mReputation + << ", last own update: " << now - it->second.mOwnOpinionTs << " secs ago." << std::endl; + + for(std::map::const_iterator it2(it->second.mOpinions.begin());it2!=it->second.mOpinions.end();++it2) + std::cerr << " " << it2->first << ": " << it2->second << std::endl; + } +} diff --git a/libretroshare/src/services/p3gxsreputation.h b/libretroshare/src/services/p3gxsreputation.h index 7456b004a..076e14003 100644 --- a/libretroshare/src/services/p3gxsreputation.h +++ b/libretroshare/src/services/p3gxsreputation.h @@ -35,6 +35,7 @@ #include "serialiser/rsgxsreputationitems.h" #include "retroshare/rsidentity.h" +#include "retroshare/rsreputations.h" #include "services/p3service.h" @@ -58,19 +59,19 @@ class Reputation { public: Reputation() - :mOwnOpinion(0), mOwnOpinionTs(0), mReputation(0) { return; } + :mOwnOpinion(RsReputations::OPINION_NEUTRAL), mOwnOpinionTs(0), mReputation(RsReputations::OPINION_NEUTRAL) { } Reputation(const RsGxsId& about) - :mGxsId(about), mOwnOpinion(0), mOwnOpinionTs(0), mReputation(0) { return; } + :mOwnOpinion(RsReputations::OPINION_NEUTRAL), mOwnOpinionTs(0), mReputation(RsReputations::OPINION_NEUTRAL) { } -int32_t CalculateReputation(); + float updateReputation(uint32_t average_active_friends); - RsGxsId mGxsId; - std::map mOpinions; + std::map mOpinions; int32_t mOwnOpinion; time_t mOwnOpinionTs; - int32_t mReputation; + float mFriendAverage ; + float mReputation; }; @@ -80,37 +81,25 @@ int32_t CalculateReputation(); * */ -class p3GxsReputation: public p3Service, public p3Config /* , public pqiMonitor */ +class p3GxsReputation: public p3Service, public p3Config, public RsReputations /* , public pqiMonitor */ { public: p3GxsReputation(p3LinkMgr *lm); virtual RsServiceInfo getServiceInfo(); - /***** Interface for p3idservice *****/ - - virtual bool updateOpinion(const RsGxsId& gxsid, int opinion); - + /***** Interface for RsReputations *****/ + virtual bool setOwnOpinion(const RsGxsId& key_id, const Opinion& op) ; + virtual bool getReputationInfo(const RsGxsId& id,ReputationInfo& info) ; + virtual bool isIdentityBanned(const RsGxsId& id) ; + /***** overloaded from p3Service *****/ - /*! - * This retrieves all chat msg items and also (important!) - * processes chat-status items that are in service item queue. chat msg item requests are also processed and not returned - * (important! also) notifications sent to notify base on receipt avatar, immediate status and custom status - * : notifyCustomState, notifyChatStatus, notifyPeerHasNewAvatar - * @see NotifyBase - - */ virtual int tick(); virtual int status(); - /*! * Interface stuff. */ - /*************** pqiMonitor callback ***********************/ - //virtual void statusChange(const std::list &plist); - - /************* from p3Config *******************/ virtual RsSerialiser *setupSerialiser() ; virtual bool saveList(bool& cleanup, std::list&) ; @@ -123,22 +112,27 @@ class p3GxsReputation: public p3Service, public p3Config /* , public pqiMonitor bool SendReputations(RsGxsReputationRequestItem *request); bool RecvReputations(RsGxsReputationUpdateItem *item); - bool updateLatestUpdate(RsPeerId peerid, time_t ts); + bool updateLatestUpdate(RsPeerId peerid, time_t latest_update); + void updateActiveFriends() ; + + // internal update of data. Takes care of cleaning empty boxes. + void locked_updateOpinion(const RsPeerId &from, const RsGxsId &about, RsReputations::Opinion op); + bool loadReputationSet(RsGxsReputationSetItem *item, const std::set &peerSet); - bool loadReputationSet(RsGxsReputationSetItem *item, - const std::set &peerSet); - - int sendPackets(); + int sendPackets(); + void cleanup(); void sendReputationRequests(); - int sendReputationRequest(RsPeerId peerid); - + int sendReputationRequest(RsPeerId peerid); + void debug_print() ; private: RsMutex mReputationMtx; + time_t mLastActiveFriendsUpdate; time_t mRequestTime; time_t mStoreTime; bool mReputationsUpdated; + uint32_t mAverageActiveFriends ; p3LinkMgr *mLinkMgr; @@ -148,7 +142,7 @@ class p3GxsReputation: public p3Service, public p3Config /* , public pqiMonitor std::multimap mUpdated; // set of Reputations to send to p3IdService. - std::set mUpdatedReputations; + std::set mUpdatedReputations; }; #endif //SERVICE_RSGXSREPUTATION_HEADER diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index 8eaa08928..f8683729b 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -412,6 +412,8 @@ bool p3IdService:: getIdDetails(const RsGxsId &id, RsIdentityDetails &details) // 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) details.mNickname = "[too long a name]" ; + + rsReputations->getReputationInfo(id,details.mReputation) ; return true; } @@ -421,6 +423,9 @@ bool p3IdService:: getIdDetails(const RsGxsId &id, RsIdentityDetails &details) { details = data.details; details.mLastUsageTS = locked_getLastUsageTS(id) ; + + rsReputations->getReputationInfo(id,details.mReputation) ; + return true; } } @@ -831,7 +836,7 @@ bool p3IdService::getReputation(const RsGxsId &id, GixsReputation &rep) if (mPublicKeyCache.fetch(id, data)) { rep.id = id; - rep.score = data.details.mReputation.mOverallScore; + rep.score = 0;//data.details.mReputation.mOverallScore; #ifdef DEBUG_IDS std::cerr << "p3IdService::getReputation() id: "; std::cerr << id.toStdString() << " score: " << @@ -1669,14 +1674,14 @@ void RsGxsIdCache::updateServiceString(std::string serviceString) } // copy over Reputation scores. - details.mReputation = ssdata.score.rep; + //details.mReputation = ssdata.score.rep; } else { details.mPgpKnown = false; details.mPgpId.clear(); - details.mReputation.updateIdScore(false, false); - details.mReputation.update(); + //details.mReputation.updateIdScore(false, false); + //details.mReputation.update(); } } diff --git a/retroshare-gui/src/gui/Identity/IdDialog.cpp b/retroshare-gui/src/gui/Identity/IdDialog.cpp index 1189b2d37..2d26c55b4 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDialog.cpp @@ -34,6 +34,7 @@ #include "gui/msgs/MessageComposer.h" #include +#include #include "retroshare/rsgxsflags.h" #include "retroshare/rsmsgs.h" #include @@ -91,19 +92,10 @@ IdDialog::IdDialog(QWidget *parent) : mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_GpgId); mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_GpgName); mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_Type); - mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_LastUsed); - mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->toolButton_Reputation); - mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->line_RatingOverall); - mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->line_RatingImplicit); - mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->line_RatingOwn); - mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->line_RatingPeers); - mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->repModButton); - mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->repMod_Accept); - mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->repMod_Ban); - mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->repMod_Negative); - mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->repMod_Positive); - mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->repMod_Custom); - mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->repMod_spinBox); + mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_LastUsed); + mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->ownOpinion_CB); + mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->overallOpinion_TF); + mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->neighborNodesOpinion_TF); mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_Nickname); mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_GpgName); @@ -112,23 +104,16 @@ IdDialog::IdDialog(QWidget *parent) : mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_GpgId); mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_Type); mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_GpgName); - mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_LastUsed); - mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->line_RatingOverall); - mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->line_RatingImplicit); - mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->line_RatingOwn); - mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->line_RatingPeers); + mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_LastUsed); + //mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->line_RatingOverall); mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_Nickname); mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_KeyId); // mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_GpgHash); mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_GpgId); mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_Type); - mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_GpgName); - mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_LastUsed); - mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->line_RatingOverall); - mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->line_RatingImplicit); - mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->line_RatingOwn); - mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->line_RatingPeers); + mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_GpgName); + mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_LastUsed); //mStateHelper->addWidget(IDDIALOG_REPLIST, ui->treeWidget_RepList); //mStateHelper->addLoadPlaceholder(IDDIALOG_REPLIST, ui->treeWidget_RepList); @@ -147,7 +132,7 @@ IdDialog::IdDialog(QWidget *parent) : connect(ui->filterComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(filterComboBoxChanged())); connect(ui->filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString))); - connect(ui->repModButton, SIGNAL(clicked()), this, SLOT(modifyReputation())); + connect(ui->ownOpinion_CB, SIGNAL(currentIndexChanged(int)), this, SLOT(modifyReputation())); connect(ui->messageButton, SIGNAL(clicked()), this, SLOT(sendMsg())); @@ -197,7 +182,7 @@ IdDialog::IdDialog(QWidget *parent) : // Hiding RepList until that part is finished. //ui->treeWidget_RepList->setVisible(false); - ui->toolButton_Reputation->setVisible(false); + #ifndef UNFINISHED ui->todoPushButton->hide() ; #endif @@ -225,8 +210,8 @@ IdDialog::IdDialog(QWidget *parent) : processSettings(true); // hide reputation sice it's currently unused - ui->reputationGroupBox->hide(); - ui->tweakGroupBox->hide(); + //ui->reputationGroupBox->hide(); + //ui->tweakGroupBox->hide(); } IdDialog::~IdDialog() @@ -652,36 +637,9 @@ void IdDialog::insertIdDetails(uint32_t token) else ui->lineEdit_Type->setText(tr("Anonymous identity")) ; - // if (isOwnId) -// { -// ui->radioButton_IdYourself->setChecked(true); -// } -// else if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID) -// { -// if (data.mPgpKnown) -// { -// if (rsPeers->isGPGAccepted(data.mPgpId)) -// { -// ui->radioButton_IdFriend->setChecked(true); -// } -// else -// { -// ui->radioButton_IdFOF->setChecked(true); -// } -// } -// else -// { -// ui->radioButton_IdOther->setChecked(true); -// } -// } -// else -// { -// ui->radioButton_IdPseudo->setChecked(true); -// } - if (isOwnId) { - mStateHelper->setWidgetEnabled(ui->toolButton_Reputation, false); + mStateHelper->setWidgetEnabled(ui->ownOpinion_CB, false); ui->editIdentity->setEnabled(true); ui->removeIdentity->setEnabled(true); ui->chatIdentity->setEnabled(false); @@ -690,7 +648,7 @@ void IdDialog::insertIdDetails(uint32_t token) else { // No Reputation yet! - mStateHelper->setWidgetEnabled(ui->toolButton_Reputation, /*true*/ false); + mStateHelper->setWidgetEnabled(ui->ownOpinion_CB, true); ui->editIdentity->setEnabled(false); ui->removeIdentity->setEnabled(false); ui->chatIdentity->setEnabled(true); @@ -698,9 +656,8 @@ void IdDialog::insertIdDetails(uint32_t token) } /* now fill in the reputation information */ - ui->line_RatingOverall->setText("Overall Rating TODO"); - ui->line_RatingOwn->setText("Own Rating TODO"); +#ifdef SUSPENDED if (data.mPgpKnown) { ui->line_RatingImplicit->setText(tr("+50 Known PGP")); @@ -713,25 +670,28 @@ void IdDialog::insertIdDetails(uint32_t token) { ui->line_RatingImplicit->setText(tr("+5 Anon Id")); } - - { - QString rating = QString::number(data.mReputation.mOverallScore); - ui->line_RatingOverall->setText(rating); - } - { QString rating = QString::number(data.mReputation.mIdScore); ui->line_RatingImplicit->setText(rating); } - { - QString rating = QString::number(data.mReputation.mOwnOpinion); - ui->line_RatingOwn->setText(rating); - } +#endif + RsReputations::ReputationInfo info ; + rsReputations->getReputationInfo(RsGxsId(data.mMeta.mGroupId),info) ; + + ui->neighborNodesOpinion_TF->setText(QString::number(info.mOverallReputationScore-1.0f)); + + ui->overallOpinion_TF->setText(QString::number(info.mOverallReputationScore-1.0f) +" ("+ + ((info.mAssessment == RsReputations::ASSESSMENT_OK)? tr("OK") : tr("Banned")) +")" ) ; + + switch(info.mOwnOpinion) { - QString rating = QString::number(data.mReputation.mPeerOpinion); - ui->line_RatingPeers->setText(rating); + case RsReputations::OPINION_NEGATIVE: ui->ownOpinion_CB->setCurrentIndex(0); break ; + case RsReputations::OPINION_NEUTRAL : ui->ownOpinion_CB->setCurrentIndex(1); break ; + case RsReputations::OPINION_POSITIVE: ui->ownOpinion_CB->setCurrentIndex(2); break ; + default: + std::cerr << "Unexpected value in own opinion: " << info.mOwnOpinion << std::endl; } } @@ -743,47 +703,38 @@ void IdDialog::modifyReputation() #endif RsGxsId id(ui->lineEdit_KeyId->text().toStdString()); + + RsReputations::Opinion op ; - int mod = 0; - if (ui->repMod_Accept->isChecked()) - { - mod += 100; - } - else if (ui->repMod_Positive->isChecked()) - { - mod += 10; - } - else if (ui->repMod_Negative->isChecked()) - { - mod += -10; - } - else if (ui->repMod_Ban->isChecked()) - { - mod += -100; - } - else if (ui->repMod_Custom->isChecked()) - { - mod += ui->repMod_spinBox->value(); - } - else - { - // invalid - return; - } + switch(ui->ownOpinion_CB->currentIndex()) + { + case 0: op = RsReputations::OPINION_NEGATIVE ; break ; + case 1: op = RsReputations::OPINION_NEUTRAL ; break ; + case 2: op = RsReputations::OPINION_POSITIVE ; break ; + default: + std::cerr << "Wrong value from opinion combobox. Bug??" << std::endl; + + } + rsReputations->setOwnOpinion(id,op) ; #ifdef ID_DEBUG std::cerr << "IdDialog::modifyReputation() ID: " << id << " Mod: " << mod; std::cerr << std::endl; #endif +#ifdef SUSPENDED + // Cyril: apparently the old reputation system was in used here. It's based on GXS data exchange, and probably not + // very efficient because of this. + uint32_t token; - if (!rsIdentity->submitOpinion(token, id, false, mod)) + if (!rsIdentity->submitOpinion(token, id, false, op)) { #ifdef ID_DEBUG std::cerr << "IdDialog::modifyReputation() Error submitting Opinion"; std::cerr << std::endl; #endif } +#endif #ifdef ID_DEBUG std::cerr << "IdDialog::modifyReputation() queuingRequest(), token: " << token; @@ -792,7 +743,7 @@ void IdDialog::modifyReputation() // trigger refresh when finished. // basic / anstype are not needed. - mIdQueue->queueRequest(token, 0, 0, IDDIALOG_REFRESH); + requestIdDetails(); return; } diff --git a/retroshare-gui/src/gui/Identity/IdDialog.ui b/retroshare-gui/src/gui/Identity/IdDialog.ui index 4109e6bcb..b6649e413 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.ui +++ b/retroshare-gui/src/gui/Identity/IdDialog.ui @@ -7,7 +7,7 @@ 0 0 826 - 752 + 757 @@ -483,7 +483,90 @@ - + + + + <html><head/><body><p>Average opinion of neighbor nodes about this identity. Negative is bad,</p><p>positive is good. Zero is neutral.</p></body></html> + + + true + + + + + + + Your opinion: + + + + + + + Neighbor nodes: + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Sans'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Your own opinion about an identity rules the visibility of that identity for yourself,</p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">and is shared among friends. A final score is calculated according to a formula that accounts your own opinion and your friends' opinions about someone:</p> +<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"> S = own_opinion * a + friends_opinion * (1-a)</p> +<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The factor 'a' depends on the type of ID. </p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">- anonymous IDs: </p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">- PGP-signed IDs by unknown PGP keys: a=</p> +<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The overall score is used in chat lobbies, forums and channels to decide on the actions to take for each specific identity:</p> +<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">S &lt; -0.5: Posts are not stored, nor forwarded </p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">S &lt; 0.2: Posts are hidden, but still transmitted</p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">S &lt; 0.0: </p> +<p style="-qt-paragraph-type:empty; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The overall rating is computed in such a way that it is not possible for a single person to deterministically change someone's status at neighbor nodes.</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> + + + 0 + + + + Negative + + + + ../icons/yellow_biohazard64.png../icons/yellow_biohazard64.png + + + + + Neutral + + + + + Positive + + + + + + + + <html><head/><body><p>Overall reputation score, accounting for yours and your friends'.</p><p>Negative is bad, positive is good. Zero is neutral. If the score is too low,</p><p>the identity is flagged as bad, and will be filtered out in forums, chat lobbies,</p><p>channels, etc.</p></body></html> + + + true + + + + @@ -492,158 +575,12 @@ - Overall - - - - - - - true - - - - - - - Implicit - - - - - - - true - - - - - - - Opinion - - - - - - - true - - - - - - - Peers - - - - - - - true + Overall: - - - - Qt::NoFocus - - - Edit reputation - - - - :/images/edit_24.png:/images/edit_24.png - - - - 24 - 24 - - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - - - - - 0 - 0 - - - - Tweak Opinion - - - - - - Accept (+100) - - - - - - - Positive (+10) - - - - - - - Negative (-10) - - - - - - - Ban (-100) - - - - - - - - - Custom - - - - - - - -100 - - - 100 - - - - - - - - - Modify - - - @@ -730,9 +667,6 @@ lineEdit_KeyId lineEdit_GpgId lineEdit_GpgName - line_RatingOverall - line_RatingImplicit - line_RatingOwn diff --git a/retroshare-gui/src/gui/gxs/GxsIdChooser.cpp b/retroshare-gui/src/gui/gxs/GxsIdChooser.cpp index 7fb83f131..71554f31a 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdChooser.cpp +++ b/retroshare-gui/src/gui/gxs/GxsIdChooser.cpp @@ -42,6 +42,8 @@ #define TYPE_UNKNOWN_ID 3 #define TYPE_CREATE_ID 4 +#define BANNED_ICON ":/icons/yellow_biohazard64.png" + #define IDCHOOSER_REFRESH 1 //#define IDCHOOSER_DEBUG @@ -148,6 +150,10 @@ static void loadPrivateIdsCallback(GxsIdDetailsType type, const RsIdentityDetail case GXS_ID_DETAILS_TYPE_DONE: GxsIdDetails::getIcons(details, icons); break; + + case GXS_ID_DETAILS_TYPE_BANNED: + icons.push_back(QIcon(BANNED_ICON)) ; + break; } chooser->setItemData(index, QString("%1_%2").arg((type == GXS_ID_DETAILS_TYPE_DONE) ? TYPE_FOUND_ID : TYPE_UNKNOWN_ID).arg(text), ROLE_SORT); diff --git a/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp b/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp index aab87ddf7..400498823 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp +++ b/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp @@ -29,6 +29,7 @@ #include #include "GxsIdDetails.h" #include "retroshare-gui/RsAutoUpdatePage.h" +#include "retroshare/rsreputations.h" #include @@ -40,6 +41,7 @@ #define IMAGE_PGPKNOWN ":/images/contact.png" #define IMAGE_PGPUNKNOWN ":/images/tags/pgp-unknown.png" #define IMAGE_ANON ":/images/tags/anon.png" +#define IMAGE_BANNED ":/icons/yellow_biohazard64.png" #define IMAGE_DEV_AMBASSADOR ":/images/tags/dev-ambassador.png" #define IMAGE_DEV_CONTRIBUTOR ":/images/tags/vote_down.png" @@ -821,6 +823,9 @@ QString GxsIdDetails::getNameForType(GxsIdDetailsType type, const RsIdentityDeta case GXS_ID_DETAILS_TYPE_DONE: return getName(details); + case GXS_ID_DETAILS_TYPE_BANNED: + return tr("[Banned]") ; + case GXS_ID_DETAILS_TYPE_FAILED: return getFailedText(details.mId); } @@ -873,7 +878,10 @@ bool GxsIdDetails::MakeIdDesc(const RsGxsId &id, bool doIcons, QString &str, QLi QString GxsIdDetails::getName(const RsIdentityDetails &details) { - QString name = QString::fromUtf8(details.mNickname.c_str()).left(RSID_MAXIMUM_NICKNAME_SIZE); + if(rsReputations->isIdentityBanned(details.mId)) + return tr("[Banned]") ; + + QString name = QString::fromUtf8(details.mNickname.c_str()).left(RSID_MAXIMUM_NICKNAME_SIZE); std::list::const_iterator it; for (it = details.mRecognTags.begin(); it != details.mRecognTags.end(); ++it) @@ -887,9 +895,18 @@ QString GxsIdDetails::getName(const RsIdentityDetails &details) QString GxsIdDetails::getComment(const RsIdentityDetails &details) { QString comment; +QString nickname ; -QString nickname = details.mNickname.empty()?tr("[Unknown]"):QString::fromUtf8(details.mNickname.c_str()).left(RSID_MAXIMUM_NICKNAME_SIZE) ; + bool banned = rsReputations->isIdentityBanned(details.mId) ; + + if(details.mNickname.empty()) + nickname = tr("[Unknown]") ; + else if(banned) + nickname = tr("[Banned]") ; + else + nickname = QString::fromUtf8(details.mNickname.c_str()).left(RSID_MAXIMUM_NICKNAME_SIZE) ; + comment = QString("%1:%2
%3:%4").arg(QApplication::translate("GxsIdDetails", "Identity name"), nickname, QApplication::translate("GxsIdDetails", "Identity Id"), @@ -903,7 +920,8 @@ QString nickname = details.mNickname.empty()?tr("[Unknown]"):QString::fromUtf8(d { /* look up real name */ std::string authorName = rsPeers->getGPGName(details.mPgpId); - comment += QString("%1 [%2]").arg(QString::fromUtf8(authorName.c_str()), QString::fromStdString(details.mPgpId.toStdString())); + + comment += QString("%1 [%2]").arg(QString::fromUtf8(authorName.c_str()), QString::fromStdString(details.mPgpId.toStdString())); } else comment += QApplication::translate("GxsIdDetails", "unknown Key"); @@ -918,6 +936,13 @@ void GxsIdDetails::getIcons(const RsIdentityDetails &details, QList &icon { QPixmap pix ; + if(rsReputations->isIdentityBanned(details.mId)) + { + icons.clear() ; + icons.push_back(QIcon(IMAGE_BANNED)) ; + return ; + } + if(icon_types & ICON_TYPE_AVATAR) { if(details.mAvatar.mSize == 0 || !pix.loadFromData(details.mAvatar.mData, details.mAvatar.mSize, "PNG")) diff --git a/retroshare-gui/src/gui/gxs/GxsIdDetails.h b/retroshare-gui/src/gui/gxs/GxsIdDetails.h index 06747e71e..3c9259ff3 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdDetails.h +++ b/retroshare-gui/src/gui/gxs/GxsIdDetails.h @@ -39,7 +39,8 @@ enum GxsIdDetailsType GXS_ID_DETAILS_TYPE_EMPTY, GXS_ID_DETAILS_TYPE_LOADING, GXS_ID_DETAILS_TYPE_DONE, - GXS_ID_DETAILS_TYPE_FAILED + GXS_ID_DETAILS_TYPE_FAILED, + GXS_ID_DETAILS_TYPE_BANNED }; typedef void (*GxsIdDetailsCallbackFunction)(GxsIdDetailsType type, const RsIdentityDetails &details, QObject *object, const QVariant &data); @@ -49,10 +50,11 @@ class GxsIdDetails : public QObject Q_OBJECT public: - static const int ICON_TYPE_AVATAR = 0x0001 ; - static const int ICON_TYPE_PGP = 0x0002 ; - static const int ICON_TYPE_RECOGN = 0x0004 ; - static const int ICON_TYPE_ALL = 0x0007 ; + static const int ICON_TYPE_AVATAR = 0x0001 ; + static const int ICON_TYPE_PGP = 0x0002 ; + static const int ICON_TYPE_RECOGN = 0x0004 ; + static const int ICON_TYPE_ALL = 0x0007 ; + static const int ICON_TYPE_REDACTED= 0x0008 ; GxsIdDetails(); virtual ~GxsIdDetails(); diff --git a/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp b/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp index c56ce96b1..60b0849ed 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp +++ b/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp @@ -25,6 +25,9 @@ #include "GxsIdTreeWidgetItem.h" #include "GxsIdDetails.h" #include "util/HandleRichText.h" +#include "retroshare/rsreputations.h" + +#define BANNED_IMAGE ":/icons/yellow_biohazard64.png" /** Constructor */ GxsIdRSTreeWidgetItem::GxsIdRSTreeWidgetItem(const RSTreeWidgetItemCompareRole *compareRole, uint32_t icon_mask,QTreeWidget *parent) @@ -71,6 +74,10 @@ static void fillGxsIdRSTreeWidgetItemCallback(GxsIdDetailsType type, const RsIde GxsIdDetails::getIcons(details, icons, item->iconTypeMask()); item->processResult(true); break; + + case GXS_ID_DETAILS_TYPE_BANNED: + icons.push_back(QIcon("BANNED_IMAGE")) ; + break ; } int column = item->idColumn(); @@ -139,28 +146,30 @@ void GxsIdRSTreeWidgetItem::setAvatar(const RsGxsImage &avatar) QVariant GxsIdRSTreeWidgetItem::data(int column, int role) const { - if (column == idColumn()) { - switch (role) { - case Qt::ToolTipRole: - { - QString t = RSTreeWidgetItem::data(column, role).toString(); + if (column == idColumn()) + { + if (role == Qt::ToolTipRole) + { + QString t = RSTreeWidgetItem::data(column, role).toString(); + QImage pix; - QImage pix; - if (mAvatar.mSize == 0 || !pix.loadFromData(mAvatar.mData, mAvatar.mSize, "PNG")) { - pix = GxsIdDetails::makeDefaultIcon(mId); - } + if(mId.isNull()) + return RSTreeWidgetItem::data(column, role); + else if(rsReputations->isIdentityBanned(mId)) + pix = QImage(BANNED_IMAGE) ; + else if (mAvatar.mSize == 0 || !pix.loadFromData(mAvatar.mData, mAvatar.mSize, "PNG")) + pix = GxsIdDetails::makeDefaultIcon(mId); - int S = QFontMetricsF(font(column)).height(); + int S = QFontMetricsF(font(column)).height(); - QString embeddedImage; - if (RsHtml::makeEmbeddedImage(pix.scaled(QSize(4*S,4*S), Qt::KeepAspectRatio, Qt::SmoothTransformation), embeddedImage, 8*S * 8*S)) { - t = "
" + embeddedImage + "" + t + "
"; - } + QString embeddedImage; + if (RsHtml::makeEmbeddedImage(pix.scaled(QSize(4*S,4*S), Qt::KeepAspectRatio, Qt::SmoothTransformation), embeddedImage, 8*S * 8*S)) { + t = "
" + embeddedImage + "" + t + "
"; + } - return t; - } - } - } + return t; + } + } - return RSTreeWidgetItem::data(column, role); + return RSTreeWidgetItem::data(column, role); } diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp index e51527860..16d7d5c6b 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp @@ -41,6 +41,7 @@ #include "util/QtVersion.h" #include +#include #include // These should be in retroshare/ folder. #include "retroshare/rsgxsflags.h" @@ -57,6 +58,7 @@ #define IMAGE_DOWNLOAD ":/images/start.png" #define IMAGE_DOWNLOADALL ":/images/startall.png" #define IMAGE_COPYLINK ":/images/copyrslink.png" +#define IMAGE_BIOHAZARD ":/icons/yellow_biohazard64.png" #define VIEW_LAST_POST 0 #define VIEW_THREADED 1 @@ -406,6 +408,10 @@ void GxsForumThreadWidget::threadListCustomPopupMenu(QPoint /*point*/) QAction *replyauthorAct = new QAction(QIcon(IMAGE_MESSAGEREPLY), tr("Reply with private message"), &contextMnu); connect(replyauthorAct, SIGNAL(triggered()), this, SLOT(replytomessage())); + QAction *flagasbadAct = new QAction(QIcon(IMAGE_BIOHAZARD), tr("Ban this author"), &contextMnu); + flagasbadAct->setToolTip(tr("This will block/hide messages from this person, and notify neighbor nodes.")) ; + connect(flagasbadAct, SIGNAL(triggered()), this, SLOT(flagpersonasbad())); + QAction *newthreadAct = new QAction(QIcon(IMAGE_MESSAGE), tr("Start New Thread"), &contextMnu); newthreadAct->setEnabled (IS_GROUP_SUBSCRIBED(mSubscribeFlags)); connect(newthreadAct , SIGNAL(triggered()), this, SLOT(createthread())); @@ -484,6 +490,8 @@ void GxsForumThreadWidget::threadListCustomPopupMenu(QPoint /*point*/) contextMnu.addAction(expandAll); contextMnu.addAction(collapseAll); + contextMnu.addSeparator(); + contextMnu.addAction(flagasbadAct); contextMnu.addSeparator(); contextMnu.addAction(replyauthorAct); @@ -725,6 +733,9 @@ void GxsForumThreadWidget::insertGroupData() case GXS_ID_DETAILS_TYPE_LOADING: author = GxsIdDetails::getLoadingText(details.mId); break; + case GXS_ID_DETAILS_TYPE_BANNED: + author = tr("[Banned]") ; + break ; case GXS_ID_DETAILS_TYPE_DONE: author = GxsIdDetails::getName(details); break; @@ -886,12 +897,21 @@ void GxsForumThreadWidget::fillThreadStatus(QString text) QTreeWidgetItem *GxsForumThreadWidget::convertMsgToThreadWidget(const RsGxsForumMsg &msg, bool useChildTS, uint32_t filterColumn) { - GxsIdRSTreeWidgetItem *item = new GxsIdRSTreeWidgetItem(mThreadCompareRole,GxsIdDetails::ICON_TYPE_ALL); + // Early check for a message that should be hidden because its author + // is flagged with a bad reputation + + + bool redacted = rsReputations->isIdentityBanned(msg.mMeta.mAuthorId) ; + + GxsIdRSTreeWidgetItem *item = new GxsIdRSTreeWidgetItem(mThreadCompareRole,GxsIdDetails::ICON_TYPE_ALL || (redacted?(GxsIdDetails::ICON_TYPE_REDACTED):0)); item->moveToThread(ui->threadTreeWidget->thread()); QString text; - item->setText(COLUMN_THREAD_TITLE, QString::fromUtf8(msg.mMeta.mMsgName.c_str())); + if(redacted) + item->setText(COLUMN_THREAD_TITLE, tr("[ ... Redacted message ... ]")); + else + item->setText(COLUMN_THREAD_TITLE, QString::fromUtf8(msg.mMeta.mMsgName.c_str())); QDateTime qtime; QString sort; @@ -961,18 +981,20 @@ QTreeWidgetItem *GxsForumThreadWidget::convertMsgToThreadWidget(const RsGxsForum } #endif item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS, msg.mMeta.mMsgStatus); - item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_MISSING, false); - + return item; } QTreeWidgetItem *GxsForumThreadWidget::generateMissingItem(const RsGxsMessageId &msgId) { GxsIdRSTreeWidgetItem *item = new GxsIdRSTreeWidgetItem(mThreadCompareRole,GxsIdDetails::ICON_TYPE_ALL); + item->setText(COLUMN_THREAD_TITLE, tr("[ ... Missing Message ... ]")); item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_MSGID, QString::fromStdString(msgId.toStdString())); item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_MISSING, true); + + item->setId(RsGxsId(), COLUMN_THREAD_AUTHOR, false); // fixed up columnId() return item; } @@ -1301,6 +1323,8 @@ void GxsForumThreadWidget::insertMessageData(const RsGxsForumMsg &msg) return; } + bool redacted = rsReputations->isIdentityBanned(msg.mMeta.mAuthorId) ; + mStateHelper->setActive(mTokenTypeMessageData, true); QTreeWidgetItem *item = ui->threadTreeWidget->currentItem(); @@ -1334,9 +1358,20 @@ void GxsForumThreadWidget::insertMessageData(const RsGxsForumMsg &msg) ui->by_text_label->show() ; ui->by_label->show() ; - QString extraTxt = RsHtml().formatText(ui->postText->document(), QString::fromUtf8(msg.mMsg.c_str()), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS); - + if(redacted) + { + QString extraTxt = tr("

The author of this message (with ID %1) is banned.").arg(QString::fromStdString(msg.mMeta.mAuthorId.toStdString())) ; + extraTxt += tr("

  • Messages from this author are not forwarded.
  • ") ; + extraTxt += tr("
  • Messages from this author are replaced by this text.
") ; + extraTxt += tr("

You can force the visibility and forwarding of messages by setting a different opinion for that Id in People's tab.

") ; + ui->postText->setHtml(extraTxt); + } + else + { + QString extraTxt = RsHtml().formatText(ui->postText->document(), QString::fromUtf8(msg.mMsg.c_str()), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS); + ui->postText->setHtml(extraTxt); + } //ui->threadTitle->setText(QString::fromUtf8(msg.mMeta.mMsgName.c_str())); } @@ -1685,6 +1720,34 @@ static QString buildReplyHeader(const RsMsgMetaData &meta) return header; } +void GxsForumThreadWidget::flagpersonasbad() +{ + // no need to use the token system for that, since we just need to find out the author's name, which is in the item. + + if (groupId().isNull() || mThreadId.isNull()) { + QMessageBox::information(this, tr("RetroShare"),tr("You cant reply to a non-existant Message")); + return; + } + + // Get Message ... then complete replyMessageData(). + RsGxsGrpMsgIdPair postId = std::make_pair(groupId(), mThreadId); + + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA; + +#ifdef DEBUG_FORUMS + std::cerr << "GxsForumThreadWidget::requestMsgData_BanAuthor(" << postId.first << "," << postId.second << ")"; + std::cerr << std::endl; +#endif + + GxsMsgReq msgIds; + std::vector &vect = msgIds[postId.first]; + vect.push_back(postId.second); + + uint32_t token; + mTokenQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts, msgIds, mTokenTypeBanAuthor); +} + void GxsForumThreadWidget::replytomessage() { if (groupId().isNull() || mThreadId.isNull()) { @@ -1966,6 +2029,37 @@ void GxsForumThreadWidget::loadMsgData_ReplyMessage(const uint32_t &token) } } +void GxsForumThreadWidget::loadMsgData_BanAuthor(const uint32_t &token) +{ +#ifdef DEBUG_FORUMS + std::cerr << "GxsForumThreadWidget::loadMsgData_BanAuthor()"; + std::cerr << std::endl; +#endif + + std::vector msgs; + if (rsGxsForums->getMsgData(token, msgs)) + { + if (msgs.size() != 1) + { + std::cerr << "GxsForumThreadWidget::loadMsgData_ReplyMessage() ERROR Wrong number of answers"; + std::cerr << std::endl; + return; + } + + std::cerr << " banning author id " << msgs[0].mMeta.mAuthorId << std::endl; + rsReputations->setOwnOpinion(msgs[0].mMeta.mAuthorId,RsReputations::OPINION_NEGATIVE) ; + } + else + { + std::cerr << "GxsForumThreadWidget::loadMsgData_ReplyMessage() ERROR Missing Message Data..."; + std::cerr << std::endl; + } + updateDisplay(true) ; + + // we should also update the icons so that they changed to the icon for banned peers. + + std::cerr << __PRETTY_FUNCTION__ << ": need to implement the update of GxsTreeWidgetItems icons too." << std::endl; +} /*********************** **** **** **** ***********************/ /*********************** **** **** **** ***********************/ @@ -1993,6 +2087,11 @@ void GxsForumThreadWidget::loadRequest(const TokenQueue *queue, const TokenReque loadMsgData_ReplyMessage(req.mToken); return; } + + if (req.mUserType == mTokenTypeBanAuthor) { + loadMsgData_BanAuthor(req.mToken); + return; + } } GxsMessageFrameWidget::loadRequest(queue, req); diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h index 311024f07..7048e7925 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.h @@ -66,7 +66,7 @@ protected: /* GxsMessageFrameWidget */ virtual void setAllMessagesReadDo(bool read, uint32_t &token); - + private slots: /** Create the context popup menu and it's submenus */ void threadListCustomPopupMenu(QPoint point); @@ -101,6 +101,7 @@ private slots: void downloadAllFiles(); void changedViewBox(); + void flagpersonasbad(); void filterColumnChanged(int column); void filterItems(const QString &text); @@ -140,6 +141,7 @@ private: void loadMessageData(const uint32_t &token); void requestMsgData_ReplyMessage(const RsGxsGrpMsgIdPair &msgId); void loadMsgData_ReplyMessage(const uint32_t &token); + void loadMsgData_BanAuthor(const uint32_t &token); private: RsGxsGroupId mLastForumID; @@ -159,6 +161,7 @@ private: uint32_t mTokenTypeInsertThreads; uint32_t mTokenTypeMessageData; uint32_t mTokenTypeReplyMessage; + uint32_t mTokenTypeBanAuthor; /* Color definitions (for standard see qss.default) */ QColor mTextColorRead; @@ -170,7 +173,7 @@ private: RsGxsMessageId mNavigatePendingMsgId; QList mIgnoredMsgId; - Ui::GxsForumThreadWidget *ui; + Ui::GxsForumThreadWidget *ui; }; #endif // GXSFORUMTHREADWIDGET_H diff --git a/retroshare-gui/src/gui/icons.qrc b/retroshare-gui/src/gui/icons.qrc index 8840c6087..3cee5d1d2 100644 --- a/retroshare-gui/src/gui/icons.qrc +++ b/retroshare-gui/src/gui/icons.qrc @@ -60,5 +60,6 @@ icons/user-busy_64.png icons/user-offline_64.png icons/user-online_64.png + icons/yellow_biohazard64.png diff --git a/retroshare-gui/src/gui/icons/yellow_biohazard64.png b/retroshare-gui/src/gui/icons/yellow_biohazard64.png new file mode 100644 index 000000000..edb6fb3f2 Binary files /dev/null and b/retroshare-gui/src/gui/icons/yellow_biohazard64.png differ