mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-07-26 07:55:44 -04:00
commit
0120234f92
23 changed files with 2157 additions and 1562 deletions
|
@ -34,6 +34,7 @@
|
||||||
#include "pqi/p3historymgr.h"
|
#include "pqi/p3historymgr.h"
|
||||||
#include "retroshare/rspeers.h"
|
#include "retroshare/rspeers.h"
|
||||||
#include "retroshare/rsiface.h"
|
#include "retroshare/rsiface.h"
|
||||||
|
#include "retroshare/rsreputations.h"
|
||||||
#include "retroshare/rsidentity.h"
|
#include "retroshare/rsidentity.h"
|
||||||
#include "rsserver/p3face.h"
|
#include "rsserver/p3face.h"
|
||||||
#include "gxs/rsgixs.h"
|
#include "gxs/rsgixs.h"
|
||||||
|
@ -175,6 +176,12 @@ bool DistributedChatService::handleRecvChatLobbyMsgItem(RsChatMsgItem *ci)
|
||||||
return false ;
|
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.
|
if(!bounceLobbyObject(cli,cli->PeerId())) // forwards the message to friends, keeps track of subscribers, etc.
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -672,6 +679,11 @@ void DistributedChatService::handleRecvChatLobbyEventItem(RsChatLobbyEventItem *
|
||||||
return ;
|
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) ;
|
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!
|
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!
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#include "rsgxsnetservice.h"
|
#include "rsgxsnetservice.h"
|
||||||
#include "retroshare/rsconfig.h"
|
#include "retroshare/rsconfig.h"
|
||||||
|
#include "retroshare/rsreputations.h"
|
||||||
#include "retroshare/rsgxsflags.h"
|
#include "retroshare/rsgxsflags.h"
|
||||||
#include "retroshare/rsgxscircles.h"
|
#include "retroshare/rsgxscircles.h"
|
||||||
#include "pgp/pgpauxutils.h"
|
#include "pgp/pgpauxutils.h"
|
||||||
|
@ -1997,6 +1998,12 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr)
|
||||||
continue;
|
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)
|
if(mReputations->haveReputation(syncItem->authorId) || noAuthor)
|
||||||
{
|
{
|
||||||
GixsReputation rep;
|
GixsReputation rep;
|
||||||
|
@ -2009,7 +2016,7 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr)
|
||||||
|
|
||||||
// if author is required for this message, it will simply get dropped
|
// if author is required for this message, it will simply get dropped
|
||||||
// at genexchange side of things
|
// at genexchange side of things
|
||||||
if(rep.score > (int)grpMeta->mReputationCutOff || noAuthor)
|
if(rep.score >= (int)grpMeta->mReputationCutOff || noAuthor)
|
||||||
{
|
{
|
||||||
#ifdef NXS_NET_DEBUG
|
#ifdef NXS_NET_DEBUG
|
||||||
std::cerr << ", passed! Adding message to req list." << std::endl;
|
std::cerr << ", passed! Adding message to req list." << std::endl;
|
||||||
|
@ -2211,6 +2218,12 @@ void RsGxsNetService::locked_genReqGrpTransaction(NxsTransaction* tr)
|
||||||
latestVersion = grpSyncItem->publishTs > metaIter->second->mPublishTs;
|
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)
|
if( (mGrpAutoSync && !haveItem) || latestVersion)
|
||||||
{
|
{
|
||||||
// determine if you need to check reputation
|
// determine if you need to check reputation
|
||||||
|
|
|
@ -99,7 +99,7 @@ bool MsgRespPending::accepted()
|
||||||
GixsReputation rep;
|
GixsReputation rep;
|
||||||
if(getAuthorRep(rep, entry.mAuthorId, mPeerId))
|
if(getAuthorRep(rep, entry.mAuthorId, mPeerId))
|
||||||
{
|
{
|
||||||
if(rep.score > mCutOff)
|
if(rep.score >= mCutOff)
|
||||||
{
|
{
|
||||||
entry.mPassedVetting = true;
|
entry.mPassedVetting = true;
|
||||||
count++;
|
count++;
|
||||||
|
@ -134,7 +134,7 @@ bool GrpRespPending::accepted()
|
||||||
|
|
||||||
if(getAuthorRep(rep, entry.mAuthorId, mPeerId))
|
if(getAuthorRep(rep, entry.mAuthorId, mPeerId))
|
||||||
{
|
{
|
||||||
if(rep.score > mCutOff)
|
if(rep.score >= mCutOff)
|
||||||
{
|
{
|
||||||
entry.mPassedVetting = true;
|
entry.mPassedVetting = true;
|
||||||
count++;
|
count++;
|
||||||
|
|
|
@ -675,6 +675,7 @@ SOURCES += zeroconf/p3zcnatassist.cc \
|
||||||
|
|
||||||
# new gxs cache system
|
# new gxs cache system
|
||||||
# this should be disabled for releases until further notice.
|
# this should be disabled for releases until further notice.
|
||||||
|
|
||||||
DEFINES *= SQLITE_HAS_CODEC
|
DEFINES *= SQLITE_HAS_CODEC
|
||||||
DEFINES *= GXS_ENABLE_SYNC_MSGS
|
DEFINES *= GXS_ENABLE_SYNC_MSGS
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
|
|
||||||
#include "retroshare/rstokenservice.h"
|
#include "retroshare/rstokenservice.h"
|
||||||
#include "retroshare/rsgxsifacehelper.h"
|
#include "retroshare/rsgxsifacehelper.h"
|
||||||
|
#include "retroshare/rsreputations.h"
|
||||||
#include "retroshare/rsids.h"
|
#include "retroshare/rsids.h"
|
||||||
#include "serialiser/rstlvimage.h"
|
#include "serialiser/rstlvimage.h"
|
||||||
#include "retroshare/rsgxscommon.h"
|
#include "retroshare/rsgxscommon.h"
|
||||||
|
@ -158,8 +159,7 @@ class RsIdentityDetails
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RsIdentityDetails()
|
RsIdentityDetails()
|
||||||
:mIsOwnId(false), mPgpLinked(false), mPgpKnown(false),
|
:mIsOwnId(false), mPgpLinked(false), mPgpKnown(false), mLastUsageTS(0) { return; }
|
||||||
mReputation(), mLastUsageTS(0) { return; }
|
|
||||||
|
|
||||||
RsGxsId mId;
|
RsGxsId mId;
|
||||||
|
|
||||||
|
@ -175,8 +175,12 @@ public:
|
||||||
// Recogn details.
|
// Recogn details.
|
||||||
std::list<RsRecognTag> mRecognTags;
|
std::list<RsRecognTag> mRecognTags;
|
||||||
|
|
||||||
// reputation details.
|
// Cyril: Reputation details. At some point we might want to merge information
|
||||||
GxsReputation mReputation;
|
// 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
|
// avatar
|
||||||
RsGxsImage mAvatar ;
|
RsGxsImage mAvatar ;
|
||||||
|
|
|
@ -40,6 +40,7 @@ extern RsPluginHandler *rsPlugins ;
|
||||||
|
|
||||||
class p3Service ;
|
class p3Service ;
|
||||||
class RsServiceControl ;
|
class RsServiceControl ;
|
||||||
|
class RsReputations ;
|
||||||
class RsTurtle ;
|
class RsTurtle ;
|
||||||
class RsDht ;
|
class RsDht ;
|
||||||
class RsDisc ;
|
class RsDisc ;
|
||||||
|
@ -116,6 +117,7 @@ public:
|
||||||
RsUtil::inited_ptr<PgpAuxUtils> mPgpAuxUtils;
|
RsUtil::inited_ptr<PgpAuxUtils> mPgpAuxUtils;
|
||||||
RsUtil::inited_ptr<RsGxsForums> mGxsForums;
|
RsUtil::inited_ptr<RsGxsForums> mGxsForums;
|
||||||
RsUtil::inited_ptr<RsGxsChannels> mGxsChannels;
|
RsUtil::inited_ptr<RsGxsChannels> mGxsChannels;
|
||||||
|
RsUtil::inited_ptr<RsReputations> mReputations;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RsPlugin
|
class RsPlugin
|
||||||
|
|
58
libretroshare/src/retroshare/rsreputations.h
Normal file
58
libretroshare/src/retroshare/rsreputations.h
Normal file
|
@ -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 ;
|
|
@ -819,6 +819,7 @@ bool RsInit::SetHiddenLocation(const std::string& hiddenaddress, uint16_t port)
|
||||||
|
|
||||||
RsFiles *rsFiles = NULL;
|
RsFiles *rsFiles = NULL;
|
||||||
RsTurtle *rsTurtle = NULL ;
|
RsTurtle *rsTurtle = NULL ;
|
||||||
|
RsReputations *rsReputations = NULL ;
|
||||||
#ifdef ENABLE_GROUTER
|
#ifdef ENABLE_GROUTER
|
||||||
RsGRouter *rsGRouter = NULL ;
|
RsGRouter *rsGRouter = NULL ;
|
||||||
#endif
|
#endif
|
||||||
|
@ -847,6 +848,7 @@ RsGRouter *rsGRouter = NULL ;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "services/p3gxsreputation.h"
|
||||||
#include "services/p3serviceinfo.h"
|
#include "services/p3serviceinfo.h"
|
||||||
#include "services/p3heartbeat.h"
|
#include "services/p3heartbeat.h"
|
||||||
#include "services/p3discovery2.h"
|
#include "services/p3discovery2.h"
|
||||||
|
@ -1357,6 +1359,11 @@ int RsServer::StartupRetroShare()
|
||||||
|
|
||||||
mPosted->setNetworkExchangeService(posted_ns) ;
|
mPosted->setNetworkExchangeService(posted_ns) ;
|
||||||
|
|
||||||
|
/**** Reputation system ****/
|
||||||
|
|
||||||
|
p3GxsReputation *mReputations = new p3GxsReputation(mLinkMgr) ;
|
||||||
|
rsReputations = mReputations ;
|
||||||
|
|
||||||
/**** Wiki GXS service ****/
|
/**** Wiki GXS service ****/
|
||||||
|
|
||||||
|
|
||||||
|
@ -1493,7 +1500,7 @@ int RsServer::StartupRetroShare()
|
||||||
pqih -> addService(msgSrv,true);
|
pqih -> addService(msgSrv,true);
|
||||||
pqih -> addService(chatSrv,true);
|
pqih -> addService(chatSrv,true);
|
||||||
pqih -> addService(mStatusSrv,true);
|
pqih -> addService(mStatusSrv,true);
|
||||||
|
pqih -> addService(mReputations,true);
|
||||||
|
|
||||||
// set interfaces for plugins
|
// set interfaces for plugins
|
||||||
//
|
//
|
||||||
|
@ -1514,6 +1521,8 @@ int RsServer::StartupRetroShare()
|
||||||
interfaces.mPgpAuxUtils = pgpAuxUtils;
|
interfaces.mPgpAuxUtils = pgpAuxUtils;
|
||||||
interfaces.mGxsForums = mGxsForums;
|
interfaces.mGxsForums = mGxsForums;
|
||||||
interfaces.mGxsChannels = mGxsChannels;
|
interfaces.mGxsChannels = mGxsChannels;
|
||||||
|
interfaces.mReputations = mReputations;
|
||||||
|
|
||||||
mPluginsManager->setInterfaces(interfaces);
|
mPluginsManager->setInterfaces(interfaces);
|
||||||
|
|
||||||
// now add plugin objects inside the loop:
|
// now add plugin objects inside the loop:
|
||||||
|
@ -1607,6 +1616,7 @@ int RsServer::StartupRetroShare()
|
||||||
mConfigMgr->addConfiguration("turtle.cfg", tr);
|
mConfigMgr->addConfiguration("turtle.cfg", tr);
|
||||||
mConfigMgr->addConfiguration("banlist.cfg", mBanList);
|
mConfigMgr->addConfiguration("banlist.cfg", mBanList);
|
||||||
mConfigMgr->addConfiguration("servicecontrol.cfg", serviceCtrl);
|
mConfigMgr->addConfiguration("servicecontrol.cfg", serviceCtrl);
|
||||||
|
mConfigMgr->addConfiguration("reputations.cfg", mReputations);
|
||||||
#ifdef ENABLE_GROUTER
|
#ifdef ENABLE_GROUTER
|
||||||
mConfigMgr->addConfiguration("grouter.cfg", gr);
|
mConfigMgr->addConfiguration("grouter.cfg", gr);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -23,9 +23,9 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include "serialiser/rsbaseserial.h"
|
#include "serialiser/rsbaseserial.h"
|
||||||
#include "serialiser/rsbanlistitems.h"
|
#include "serialiser/rsgxsreputationitems.h"
|
||||||
#include "serialiser/rstlvbanlist.h"
|
|
||||||
|
|
||||||
/***
|
/***
|
||||||
#define RSSERIAL_DEBUG 1
|
#define RSSERIAL_DEBUG 1
|
||||||
|
@ -35,116 +35,266 @@
|
||||||
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
|
||||||
#ifdef SUSPENDED
|
bool RsReputationItem::serialise_header(void *data,uint32_t& pktsize,uint32_t& tlvsize, uint32_t& offset) const
|
||||||
RsBanListItem::~RsBanListItem()
|
|
||||||
{
|
{
|
||||||
return;
|
tlvsize = serial_size() ;
|
||||||
|
offset = 0;
|
||||||
|
|
||||||
|
if (pktsize < tlvsize)
|
||||||
|
return false; /* not enough space */
|
||||||
|
|
||||||
|
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 << "RsReputationItem::serialise() Header: " << ok << std::endl;
|
||||||
|
#endif
|
||||||
|
offset += 8;
|
||||||
|
|
||||||
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RsBanListItem::clear()
|
/*************************************************************************/
|
||||||
|
|
||||||
|
void RsGxsReputationSetItem::clear()
|
||||||
{
|
{
|
||||||
peerList.TlvClear();
|
mOpinions.clear() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream &RsBanListItem::print(std::ostream &out, uint16_t indent)
|
void RsGxsReputationUpdateItem::clear()
|
||||||
{
|
{
|
||||||
printRsItemBase(out, "RsBanListItem", indent);
|
mOpinions.clear() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************/
|
||||||
|
/*************************************************************************/
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
std::ostream& RsGxsReputationConfigItem::print(std::ostream &out, uint16_t indent)
|
||||||
|
{
|
||||||
|
printRsItemBase(out, "RsReputationConfigItem", indent);
|
||||||
uint16_t int_Indent = indent + 2;
|
uint16_t int_Indent = indent + 2;
|
||||||
peerList.print(out, int_Indent);
|
|
||||||
|
|
||||||
printRsItemEnd(out, "RsBanListItem", indent);
|
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;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::ostream& RsGxsReputationSetItem::print(std::ostream &out, uint16_t indent)
|
||||||
|
{
|
||||||
|
printRsItemBase(out, "RsReputationSetItem", indent);
|
||||||
|
uint16_t int_Indent = indent + 2;
|
||||||
|
|
||||||
uint32_t RsBanListSerialiser::sizeList(RsBanListItem *item)
|
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<RsPeerId,uint32_t>::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<RsGxsId,uint32_t>::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 */
|
uint32_t s = 8; /* header */
|
||||||
s += item->peerList.TlvSize();
|
|
||||||
|
s += mPeerId.serial_size() ; // PeerId
|
||||||
|
s += 4 ; // mLatestUpdate
|
||||||
|
s += 4 ; // mLastQuery
|
||||||
|
|
||||||
return s ;
|
return s ;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* serialise the data to the buffer */
|
uint32_t RsGxsReputationSetItem::serial_size() const
|
||||||
bool RsBanListSerialiser::serialiseList(RsBanListItem *item, void *data, uint32_t *pktsize)
|
|
||||||
{
|
{
|
||||||
uint32_t tlvsize = sizeList(item);
|
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;
|
uint32_t offset=0;
|
||||||
|
|
||||||
if (*pktsize < tlvsize)
|
if(!serialise_header(data,pktsize,tlvsize,offset))
|
||||||
return false; /* not enough space */
|
return false ;
|
||||||
|
|
||||||
*pktsize = tlvsize;
|
|
||||||
|
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
|
|
||||||
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
|
ok &= mPeerId.serialise(data,tlvsize,offset) ;
|
||||||
|
ok &= setRawUInt32(data, tlvsize, &offset, mLatestUpdate);
|
||||||
#ifdef RSSERIAL_DEBUG
|
ok &= setRawUInt32(data, tlvsize, &offset, mLastQuery);
|
||||||
std::cerr << "RsDsdvSerialiser::serialiseRoute() Header: " << ok << std::endl;
|
|
||||||
std::cerr << "RsDsdvSerialiser::serialiseRoute() Size: " << tlvsize << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* skip the header */
|
|
||||||
offset += 8;
|
|
||||||
|
|
||||||
/* add mandatory parts first */
|
|
||||||
ok &= item->peerList.SetTlv(data, tlvsize, &offset);
|
|
||||||
|
|
||||||
if (offset != tlvsize)
|
if (offset != tlvsize)
|
||||||
{
|
{
|
||||||
ok = false;
|
ok = false;
|
||||||
#ifdef RSSERIAL_DEBUG
|
std::cerr << "RsGxsReputationConfigItem::serialisedata() size error! " << std::endl;
|
||||||
std::cerr << "RsDsdvSerialiser::serialiseRoute() Size Error! " << std::endl;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
bool RsGxsReputationSetItem::serialise(void *data, uint32_t& pktsize) const
|
||||||
RsBanListItem *RsBanListSerialiser::deserialiseList(void *data, uint32_t *pktsize)
|
|
||||||
{
|
{
|
||||||
/* get the type and size */
|
uint32_t tlvsize ;
|
||||||
uint32_t rstype = getRsItemId(data);
|
|
||||||
uint32_t tlvsize = getRsItemSize(data);
|
|
||||||
|
|
||||||
uint32_t offset=0;
|
uint32_t offset=0;
|
||||||
|
|
||||||
|
if(!serialise_header(data,pktsize,tlvsize,offset))
|
||||||
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
|
return false ;
|
||||||
(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;
|
bool ok = true;
|
||||||
|
|
||||||
/* ready to load */
|
ok &= mGxsId.serialise(data,tlvsize,offset) ;
|
||||||
RsBanListItem *item = new RsBanListItem();
|
ok &= setRawUInt32(data, tlvsize, &offset, mOwnOpinion);
|
||||||
item->clear();
|
ok &= setRawUInt32(data, tlvsize, &offset, mOwnOpinionTS);
|
||||||
|
ok &= setRawUInt32(data, tlvsize, &offset, mOpinions.size());
|
||||||
|
|
||||||
/* skip the header */
|
for(std::map<RsPeerId,uint32_t>::const_iterator it(mOpinions.begin());it!=mOpinions.end();++it)
|
||||||
offset += 8;
|
{
|
||||||
|
ok &= it->first.serialise(data,tlvsize,offset) ;
|
||||||
/* add mandatory parts first */
|
ok &= setRawUInt32(data, tlvsize, &offset, it->second) ;
|
||||||
ok &= item->peerList.GetTlv(data, tlvsize, &offset);
|
}
|
||||||
|
|
||||||
if (offset != tlvsize)
|
if (offset != tlvsize)
|
||||||
{
|
{
|
||||||
/* error */
|
ok = false;
|
||||||
delete item;
|
std::cerr << "RsGxsReputationSetItem::serialisedata() size error! " << std::endl;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ok)
|
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<RsGxsId,uint32_t>::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;
|
delete item;
|
||||||
return NULL ;
|
return NULL ;
|
||||||
}
|
}
|
||||||
|
@ -152,53 +302,128 @@ RsBanListItem *RsBanListSerialiser::deserialiseList(void *data, uint32_t *pktsiz
|
||||||
return item;
|
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 && i<S;++i)
|
||||||
|
{
|
||||||
|
RsPeerId pid ;
|
||||||
|
uint32_t op ;
|
||||||
|
|
||||||
|
ok &= pid.deserialise(data, tlvsize, offset) ;
|
||||||
|
ok &= getRawUInt32(data, tlvsize, &offset, &op);
|
||||||
|
|
||||||
|
if(ok)
|
||||||
|
item->mOpinions[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 && i<S;++i)
|
||||||
|
{
|
||||||
|
RsGxsId gid ;
|
||||||
|
uint32_t op ;
|
||||||
|
|
||||||
|
ok &= gid.deserialise(data, tlvsize, offset) ;
|
||||||
|
ok &= getRawUInt32(data, tlvsize, &offset, &op);
|
||||||
|
|
||||||
|
if(ok)
|
||||||
|
item->mOpinions[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;
|
||||||
|
}
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
|
||||||
uint32_t RsBanListSerialiser::size(RsItem *i)
|
RsItem *RsGxsReputationSerialiser::deserialise(void *data, uint32_t *pktsize)
|
||||||
{
|
|
||||||
RsBanListItem *dri;
|
|
||||||
|
|
||||||
if (NULL != (dri = dynamic_cast<RsBanListItem *>(i)))
|
|
||||||
{
|
|
||||||
return sizeList(dri);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RsBanListSerialiser::serialise(RsItem *i, void *data, uint32_t *pktsize)
|
|
||||||
{
|
|
||||||
RsBanListItem *dri;
|
|
||||||
|
|
||||||
if (NULL != (dri = dynamic_cast<RsBanListItem *>(i)))
|
|
||||||
{
|
|
||||||
return serialiseList(dri, data, pktsize);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
RsItem *RsBanListSerialiser::deserialise(void *data, uint32_t *pktsize)
|
|
||||||
{
|
{
|
||||||
/* get the type and size */
|
/* get the type and size */
|
||||||
uint32_t rstype = getRsItemId(data);
|
uint32_t rstype = getRsItemId(data);
|
||||||
|
|
||||||
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
|
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || (RS_SERVICE_GXS_TYPE_REPUTATION != getRsItemService(rstype)))
|
||||||
(RS_SERVICE_TYPE_BANLIST != getRsItemService(rstype)))
|
|
||||||
{
|
{
|
||||||
|
std::cerr << "RsReputationSerialiser::deserialise(): wrong item type " << std::hex << rstype << std::dec << std::endl;
|
||||||
return NULL; /* wrong type */
|
return NULL; /* wrong type */
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(getRsItemSubType(rstype))
|
switch(getRsItemSubType(rstype))
|
||||||
{
|
{
|
||||||
case RS_PKT_SUBTYPE_BANLIST_ITEM:
|
case RS_PKT_SUBTYPE_GXS_REPUTATION_SET_ITEM : return deserialiseReputationSetItem (data, *pktsize);
|
||||||
return deserialiseList(data, pktsize);
|
case RS_PKT_SUBTYPE_GXS_REPUTATION_UPDATE_ITEM : return deserialiseReputationUpdateItem (data, *pktsize);
|
||||||
break;
|
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:
|
default:
|
||||||
|
std::cerr << "RsGxsReputationSerialiser::deserialise(): unknown item subtype " << std::hex<< rstype << std::dec << std::endl;
|
||||||
return NULL;
|
return NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -32,89 +32,95 @@
|
||||||
#include "serialiser/rsserial.h"
|
#include "serialiser/rsserial.h"
|
||||||
#include "retroshare/rsgxsifacetypes.h"
|
#include "retroshare/rsgxsifacetypes.h"
|
||||||
|
|
||||||
#define RS_PKT_SUBTYPE_GXSREPUTATION_CONFIG_ITEM 0x01
|
#define RS_PKT_SUBTYPE_GXS_REPUTATION_CONFIG_ITEM 0x01
|
||||||
#define RS_PKT_SUBTYPE_GXSREPUTATION_SET_ITEM 0x02
|
#define RS_PKT_SUBTYPE_GXS_REPUTATION_SET_ITEM 0x02
|
||||||
#define RS_PKT_SUBTYPE_GXSREPUTATION_UPDATE_ITEM 0x03
|
#define RS_PKT_SUBTYPE_GXS_REPUTATION_UPDATE_ITEM 0x03
|
||||||
#define RS_PKT_SUBTYPE_GXSREPUTATION_REQUEST_ITEM 0x04
|
#define RS_PKT_SUBTYPE_GXS_REPUTATION_REQUEST_ITEM 0x04
|
||||||
|
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
|
class RsReputationItem: public RsItem
|
||||||
class RsGxsReputationConfigItem: public RsItem
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RsGxsReputationConfigItem()
|
RsReputationItem(uint8_t reputation_subtype) : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_GXS_TYPE_REPUTATION,reputation_subtype)
|
||||||
:RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_GXS_TYPE_REPUTATION,
|
|
||||||
RS_PKT_SUBTYPE_GXSREPUTATION_CONFIG_ITEM)
|
|
||||||
{
|
{
|
||||||
setPriorityLevel(QOS_PRIORITY_RS_GXSREPUTATION_ITEM);
|
setPriorityLevel(QOS_PRIORITY_RS_GXSREPUTATION_ITEM);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~RsGxsReputationConfigItem();
|
virtual ~RsReputationItem() {}
|
||||||
virtual void clear();
|
|
||||||
|
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);
|
std::ostream &print(std::ostream &out, uint16_t indent = 0);
|
||||||
|
|
||||||
std::string mPeerId;
|
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 mLatestUpdate; // timestamp they returned.
|
||||||
uint32_t mLastQuery; // when we sent out.
|
uint32_t mLastQuery; // when we sent out.
|
||||||
};
|
};
|
||||||
|
|
||||||
class RsGxsReputationSetItem: public RsItem
|
class RsGxsReputationSetItem: public RsReputationItem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RsGxsReputationSetItem()
|
RsGxsReputationSetItem() :RsReputationItem(RS_PKT_SUBTYPE_GXS_REPUTATION_SET_ITEM) {}
|
||||||
:RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_GXS_TYPE_REPUTATION,
|
|
||||||
RS_PKT_SUBTYPE_GXSREPUTATION_SET_ITEM)
|
|
||||||
{
|
|
||||||
setPriorityLevel(QOS_PRIORITY_RS_GXSREPUTATION_ITEM);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~RsGxsReputationSetItem();
|
virtual ~RsGxsReputationSetItem() {}
|
||||||
virtual void clear();
|
virtual void clear();
|
||||||
std::ostream &print(std::ostream &out, uint16_t indent = 0);
|
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 mOwnOpinion;
|
||||||
uint32_t mOwnOpinionTs;
|
uint32_t mOwnOpinionTS;
|
||||||
uint32_t mReputation;
|
std::map<RsPeerId, uint32_t> mOpinions; // RsPeerId -> Opinion.
|
||||||
std::map<std::string, uint32_t> mOpinions; // RsPeerId -> Opinion.
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class RsGxsReputationUpdateItem: public RsItem
|
class RsGxsReputationUpdateItem: public RsReputationItem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RsGxsReputationUpdateItem()
|
RsGxsReputationUpdateItem() :RsReputationItem(RS_PKT_SUBTYPE_GXS_REPUTATION_UPDATE_ITEM) {}
|
||||||
:RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_GXS_TYPE_REPUTATION,
|
|
||||||
RS_PKT_SUBTYPE_GXSREPUTATION_UPDATE_ITEM)
|
|
||||||
{
|
|
||||||
setPriorityLevel(QOS_PRIORITY_RS_GXSREPUTATION_ITEM);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~RsGxsReputationUpdateItem();
|
virtual ~RsGxsReputationUpdateItem() {}
|
||||||
virtual void clear();
|
virtual void clear();
|
||||||
std::ostream &print(std::ostream &out, uint16_t indent = 0);
|
std::ostream &print(std::ostream &out, uint16_t indent = 0);
|
||||||
|
|
||||||
std::map<RsGxsId, uint32_t> mOpinions; // GxsId -> Opinion.
|
virtual bool serialise(void *data,uint32_t& size) const ;
|
||||||
|
virtual uint32_t serial_size() const ;
|
||||||
|
|
||||||
uint32_t mLatestUpdate;
|
uint32_t mLatestUpdate;
|
||||||
|
std::map<RsGxsId, uint32_t> mOpinions; // GxsId -> Opinion.
|
||||||
};
|
};
|
||||||
|
|
||||||
class RsGxsReputationRequestItem: public RsItem
|
class RsGxsReputationRequestItem: public RsReputationItem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RsGxsReputationRequestItem()
|
RsGxsReputationRequestItem() :RsReputationItem(RS_PKT_SUBTYPE_GXS_REPUTATION_REQUEST_ITEM) {}
|
||||||
:RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_GXS_TYPE_REPUTATION,
|
|
||||||
RS_PKT_SUBTYPE_GXSREPUTATION_REQUEST_ITEM)
|
|
||||||
{
|
|
||||||
setPriorityLevel(QOS_PRIORITY_RS_GXSREPUTATION_ITEM);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~RsGxsReputationRequestItem();
|
virtual ~RsGxsReputationRequestItem() {}
|
||||||
virtual void clear();
|
virtual void clear() {}
|
||||||
std::ostream &print(std::ostream &out, uint16_t indent = 0);
|
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;
|
uint32_t mLastUpdate;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -122,38 +128,25 @@ std::ostream &print(std::ostream &out, uint16_t indent = 0);
|
||||||
class RsGxsReputationSerialiser: public RsSerialType
|
class RsGxsReputationSerialiser: public RsSerialType
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RsGxsReputationSerialiser()
|
RsGxsReputationSerialiser() :RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_GXS_TYPE_REPUTATION){}
|
||||||
:RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_GXS_TYPE_REPUTATION)
|
|
||||||
{ return; }
|
|
||||||
virtual ~RsGxsReputationSerialiser()
|
|
||||||
{ return; }
|
|
||||||
|
|
||||||
virtual uint32_t size(RsItem *);
|
virtual ~RsGxsReputationSerialiser(){}
|
||||||
virtual bool serialise (RsItem *item, void *data, uint32_t *size);
|
|
||||||
|
virtual uint32_t size(RsItem *item)
|
||||||
|
{
|
||||||
|
return dynamic_cast<RsReputationItem*>(item)->serial_size() ;
|
||||||
|
}
|
||||||
|
virtual bool serialise (RsItem *item, void *data, uint32_t *size)
|
||||||
|
{
|
||||||
|
return dynamic_cast<RsReputationItem*>(item)->serialise(data,*size) ;
|
||||||
|
}
|
||||||
virtual RsItem * deserialise(void *data, uint32_t *size);
|
virtual RsItem * deserialise(void *data, uint32_t *size);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static RsGxsReputationConfigItem *deserialiseReputationConfigItem (void *data, uint32_t size);
|
||||||
virtual uint32_t sizeConfig(RsGxsReputationConfigItem *);
|
static RsGxsReputationSetItem *deserialiseReputationSetItem (void *data, uint32_t size);
|
||||||
virtual bool serialiseConfig(RsGxsReputationConfigItem *item, void *data, uint32_t *size);
|
static RsGxsReputationUpdateItem *deserialiseReputationUpdateItem (void *data, uint32_t size);
|
||||||
virtual RsGxsReputationConfigItem *deserialiseConfig(void *data, uint32_t *size);
|
static RsGxsReputationRequestItem *deserialiseReputationRequestItem(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);
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
|
|
|
@ -38,13 +38,6 @@
|
||||||
* #define DEBUG_REPUTATION 1
|
* #define DEBUG_REPUTATION 1
|
||||||
****/
|
****/
|
||||||
|
|
||||||
|
|
||||||
/* DEFINE INTERFACE POINTER! */
|
|
||||||
//RsGxsReputation *rsGxsReputation = NULL;
|
|
||||||
|
|
||||||
const int kMaximumPeerAge = 180; // half a year.
|
|
||||||
const int kMaximumSetSize = 100;
|
|
||||||
|
|
||||||
/************ IMPLEMENTATION NOTES *********************************
|
/************ IMPLEMENTATION NOTES *********************************
|
||||||
*
|
*
|
||||||
* p3GxsReputation shares opinions / reputations with peers.
|
* p3GxsReputation shares opinions / reputations with peers.
|
||||||
|
@ -61,8 +54,12 @@ const int kMaximumSetSize = 100;
|
||||||
* last update ----------->
|
* last update ----------->
|
||||||
* <----------- modified opinions.
|
* <----------- modified opinions.
|
||||||
*
|
*
|
||||||
* This service will have to store a huge amount of data.
|
* If not clever enough, this service will have to store a huge amount of data.
|
||||||
* need to workout how to reduce it.
|
* 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<RsGxsId, Reputation> mReputations.
|
* std::map<RsGxsId, Reputation> mReputations.
|
||||||
* std::multimap<time_t, RsGxsId> mUpdated.
|
* std::multimap<time_t, RsGxsId> mUpdated.
|
||||||
|
@ -70,55 +67,72 @@ const int kMaximumSetSize = 100;
|
||||||
* std::map<RsPeerId, ReputationConfig> mConfig;
|
* std::map<RsPeerId, ReputationConfig> mConfig;
|
||||||
*
|
*
|
||||||
* Updates from p3GxsReputation -> p3IdService.
|
* Updates from p3GxsReputation -> p3IdService.
|
||||||
*
|
|
||||||
*
|
|
||||||
* Updates from p3IdService -> p3GxsReputation.
|
* 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;
|
static const uint32_t LOWER_LIMIT = 0; // used to filter valid Opinion values from serialized data
|
||||||
const int32_t LOWER_LIMIT = -100;
|
static const uint32_t UPPER_LIMIT = 2; // used to filter valid Opinion values from serialized data
|
||||||
const int32_t UPPER_LIMIT = 100;
|
static const float REPUTATION_ASSESSMENT_THRESHOLD_X1 = 0.5f ; // reputation under which the peer gets killed
|
||||||
|
static const int kMaximumPeerAge = 180; // half a year.
|
||||||
int32_t ConvertFromSerialised(uint32_t value, bool limit)
|
static const int kMaximumSetSize = 100; // max set of updates to send at once.
|
||||||
{
|
static const int ACTIVE_FRIENDS_UPDATE_PERIOD = 600 ; // 10 minutes
|
||||||
int32_t converted = ((int32_t) value) - REPUTATION_OFFSET ;
|
static const int ACTIVE_FRIENDS_ONLINE_DELAY = 86400*7 ; // 1 week.
|
||||||
if (limit)
|
static const int kReputationRequestPeriod = 600; // 10 mins
|
||||||
{
|
static const int kReputationStoreWait = 180; // 3 minutes.
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -131,9 +145,10 @@ p3GxsReputation::p3GxsReputation(p3LinkMgr *lm)
|
||||||
mRequestTime = 0;
|
mRequestTime = 0;
|
||||||
mStoreTime = 0;
|
mStoreTime = 0;
|
||||||
mReputationsUpdated = false;
|
mReputationsUpdated = false;
|
||||||
|
mLastActiveFriendsUpdate = 0 ;
|
||||||
|
mAverageActiveFriends = 0 ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::string GXS_REPUTATION_APP_NAME = "gxsreputation";
|
const std::string GXS_REPUTATION_APP_NAME = "gxsreputation";
|
||||||
const uint16_t GXS_REPUTATION_APP_MAJOR_VERSION = 1;
|
const uint16_t GXS_REPUTATION_APP_MAJOR_VERSION = 1;
|
||||||
const uint16_t GXS_REPUTATION_APP_MINOR_VERSION = 0;
|
const uint16_t GXS_REPUTATION_APP_MINOR_VERSION = 0;
|
||||||
|
@ -150,13 +165,30 @@ RsServiceInfo p3GxsReputation::getServiceInfo()
|
||||||
GXS_REPUTATION_MIN_MINOR_VERSION);
|
GXS_REPUTATION_MIN_MINOR_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int p3GxsReputation::tick()
|
int p3GxsReputation::tick()
|
||||||
{
|
{
|
||||||
processIncoming();
|
processIncoming();
|
||||||
sendPackets();
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,7 +197,53 @@ int p3GxsReputation::status()
|
||||||
return 1;
|
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<RsPeerId> idList ;
|
||||||
|
mLinkMgr->getFriendList(idList) ;
|
||||||
|
|
||||||
|
mAverageActiveFriends = 0 ;
|
||||||
|
#ifdef DEBUG_REPUTATION
|
||||||
|
std::cerr << " counting recently online peers." << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for(std::list<RsPeerId>::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 ******/
|
/***** Implementation ******/
|
||||||
|
|
||||||
bool p3GxsReputation::processIncoming()
|
bool p3GxsReputation::processIncoming()
|
||||||
|
@ -184,41 +262,32 @@ bool p3GxsReputation::processIncoming()
|
||||||
switch(item->PacketSubType())
|
switch(item->PacketSubType())
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
case RS_PKT_SUBTYPE_GXSREPUTATION_CONFIG_ITEM:
|
case RS_PKT_SUBTYPE_GXS_REPUTATION_CONFIG_ITEM:
|
||||||
case RS_PKT_SUBTYPE_GXSREPUTATION_SET_ITEM:
|
case RS_PKT_SUBTYPE_GXS_REPUTATION_SET_ITEM:
|
||||||
std::cerr << "p3GxsReputation::processingIncoming() Unknown Item";
|
std::cerr << "p3GxsReputation::processingIncoming() Unknown Item";
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
itemOk = false;
|
itemOk = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RS_PKT_SUBTYPE_GXSREPUTATION_REQUEST_ITEM:
|
case RS_PKT_SUBTYPE_GXS_REPUTATION_REQUEST_ITEM:
|
||||||
{
|
{
|
||||||
RsGxsReputationRequestItem *requestItem =
|
RsGxsReputationRequestItem *requestItem = dynamic_cast<RsGxsReputationRequestItem *>(item);
|
||||||
dynamic_cast<RsGxsReputationRequestItem *>(item);
|
|
||||||
if (requestItem)
|
if (requestItem)
|
||||||
{
|
|
||||||
SendReputations(requestItem);
|
SendReputations(requestItem);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
itemOk = false;
|
itemOk = false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RS_PKT_SUBTYPE_GXSREPUTATION_UPDATE_ITEM:
|
case RS_PKT_SUBTYPE_GXS_REPUTATION_UPDATE_ITEM:
|
||||||
{
|
{
|
||||||
RsGxsReputationUpdateItem *updateItem =
|
RsGxsReputationUpdateItem *updateItem = dynamic_cast<RsGxsReputationUpdateItem *>(item);
|
||||||
dynamic_cast<RsGxsReputationUpdateItem *>(item);
|
|
||||||
if (updateItem)
|
if (updateItem)
|
||||||
{
|
|
||||||
RecvReputations(updateItem);
|
RecvReputations(updateItem);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
itemOk = false;
|
itemOk = false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,8 +306,9 @@ bool p3GxsReputation::processIncoming()
|
||||||
|
|
||||||
bool p3GxsReputation::SendReputations(RsGxsReputationRequestItem *request)
|
bool p3GxsReputation::SendReputations(RsGxsReputationRequestItem *request)
|
||||||
{
|
{
|
||||||
std::cerr << "p3GxsReputation::SendReputations()";
|
#ifdef DEBUG_REPUTATION
|
||||||
std::cerr << std::endl;
|
std::cerr << "p3GxsReputation::SendReputations()" << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
RsPeerId peerId = request->PeerId();
|
RsPeerId peerId = request->PeerId();
|
||||||
time_t last_update = request->mLastUpdate;
|
time_t last_update = request->mLastUpdate;
|
||||||
|
@ -252,12 +322,13 @@ bool p3GxsReputation::SendReputations(RsGxsReputationRequestItem *request)
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int totalcount = 0;
|
int totalcount = 0;
|
||||||
RsGxsReputationUpdateItem *pkt = new RsGxsReputationUpdateItem();
|
RsGxsReputationUpdateItem *pkt = new RsGxsReputationUpdateItem();
|
||||||
|
|
||||||
pkt->PeerId(peerId);
|
pkt->PeerId(peerId);
|
||||||
for(;tit != mUpdated.end(); ++tit)
|
for(;tit != mUpdated.end(); ++tit)
|
||||||
{
|
{
|
||||||
/* find */
|
/* find */
|
||||||
std::map<RsGxsId, Reputation>::iterator rit;
|
std::map<RsGxsId, Reputation>::iterator rit = mReputations.find(tit->second);
|
||||||
rit = mReputations.find(tit->second);
|
|
||||||
if (rit == mReputations.end())
|
if (rit == mReputations.end())
|
||||||
{
|
{
|
||||||
std::cerr << "p3GxsReputation::SendReputations() ERROR Missing Reputation";
|
std::cerr << "p3GxsReputation::SendReputations() ERROR Missing Reputation";
|
||||||
|
@ -275,8 +346,9 @@ bool p3GxsReputation::SendReputations(RsGxsReputationRequestItem *request)
|
||||||
}
|
}
|
||||||
|
|
||||||
RsGxsId gxsId = rit->first;
|
RsGxsId gxsId = rit->first;
|
||||||
pkt->mOpinions[gxsId] = ConvertToSerialised(rit->second.mOwnOpinion, true);
|
pkt->mOpinions[gxsId] = rit->second.mOwnOpinion;
|
||||||
pkt->mLatestUpdate = rit->second.mOwnOpinionTs;
|
pkt->mLatestUpdate = rit->second.mOwnOpinionTs;
|
||||||
|
|
||||||
if (pkt->mLatestUpdate == (uint32_t) now)
|
if (pkt->mLatestUpdate == (uint32_t) now)
|
||||||
{
|
{
|
||||||
// if we could possibly get another Update at this point (same second).
|
// if we could possibly get another Update at this point (same second).
|
||||||
|
@ -289,10 +361,13 @@ bool p3GxsReputation::SendReputations(RsGxsReputationRequestItem *request)
|
||||||
|
|
||||||
if (count > kMaximumSetSize)
|
if (count > kMaximumSetSize)
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG_REPUTATION
|
||||||
std::cerr << "p3GxsReputation::SendReputations() Sending Full Packet";
|
std::cerr << "p3GxsReputation::SendReputations() Sending Full Packet";
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
sendItem(pkt);
|
sendItem(pkt);
|
||||||
|
|
||||||
pkt = new RsGxsReputationUpdateItem();
|
pkt = new RsGxsReputationUpdateItem();
|
||||||
pkt->PeerId(peerId);
|
pkt->PeerId(peerId);
|
||||||
count = 0;
|
count = 0;
|
||||||
|
@ -301,8 +376,10 @@ bool p3GxsReputation::SendReputations(RsGxsReputationRequestItem *request)
|
||||||
|
|
||||||
if (!pkt->mOpinions.empty())
|
if (!pkt->mOpinions.empty())
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG_REPUTATION
|
||||||
std::cerr << "p3GxsReputation::SendReputations() Sending Final Packet";
|
std::cerr << "p3GxsReputation::SendReputations() Sending Final Packet";
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
sendItem(pkt);
|
sendItem(pkt);
|
||||||
}
|
}
|
||||||
|
@ -311,52 +388,125 @@ bool p3GxsReputation::SendReputations(RsGxsReputationRequestItem *request)
|
||||||
delete pkt;
|
delete pkt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_REPUTATION
|
||||||
std::cerr << "p3GxsReputation::SendReputations() Total Count: " << totalcount;
|
std::cerr << "p3GxsReputation::SendReputations() Total Count: " << totalcount;
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void p3GxsReputation::locked_updateOpinion(const RsPeerId& from,const RsGxsId& about,RsReputations::Opinion op)
|
||||||
bool p3GxsReputation::RecvReputations(RsGxsReputationUpdateItem *item)
|
|
||||||
{
|
{
|
||||||
std::cerr << "p3GxsReputation::RecvReputations()";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
|
|
||||||
RsPeerId peerid = item->PeerId();
|
|
||||||
|
|
||||||
std::map<RsGxsId, uint32_t>::iterator it;
|
|
||||||
for(it = item->mOpinions.begin(); it != item->mOpinions.end(); ++it)
|
|
||||||
{
|
|
||||||
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
|
|
||||||
|
|
||||||
/* find matching Reputation */
|
/* find matching Reputation */
|
||||||
std::map<RsGxsId, Reputation>::iterator rit;
|
std::map<RsGxsId, Reputation>::iterator rit = mReputations.find(about);
|
||||||
RsGxsId gxsId(it->first);
|
|
||||||
|
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
|
||||||
|
|
||||||
rit = mReputations.find(gxsId);
|
|
||||||
if (rit == mReputations.end())
|
if (rit == mReputations.end())
|
||||||
{
|
{
|
||||||
mReputations[gxsId] = Reputation(gxsId);
|
#ifdef DEBUG_REPUTATION
|
||||||
rit = mReputations.find(gxsId);
|
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;
|
Reputation& reputation = rit->second;
|
||||||
reputation.mOpinions[peerid] = ConvertFromSerialised(it->second, true);
|
|
||||||
|
|
||||||
int previous = reputation.mReputation;
|
std::map<RsPeerId,RsReputations::Opinion>::iterator it2 = reputation.mOpinions.find(from) ;
|
||||||
if (previous != reputation.CalculateReputation())
|
|
||||||
|
if(it2 == reputation.mOpinions.end())
|
||||||
{
|
{
|
||||||
// updated from the network.
|
if(new_opinion != RsReputations::OPINION_NEUTRAL)
|
||||||
mUpdatedReputations.insert(gxsId);
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_REPUTATION
|
||||||
|
std::cerr << "p3GxsReputation::RecvReputations() from " << item->PeerId() << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
RsPeerId peerid = item->PeerId();
|
||||||
|
|
||||||
|
for( std::map<RsGxsId, uint32_t>::iterator it = item->mOpinions.begin(); it != item->mOpinions.end(); ++it)
|
||||||
|
{
|
||||||
|
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
|
||||||
|
|
||||||
|
locked_updateOpinion(peerid,it->first,safe_convert_uint32t_to_opinion(it->second));
|
||||||
|
}
|
||||||
|
|
||||||
updateLatestUpdate(peerid,item->mLatestUpdate);
|
updateLatestUpdate(peerid,item->mLatestUpdate);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool p3GxsReputation::updateLatestUpdate(RsPeerId peerid, time_t ts)
|
bool p3GxsReputation::updateLatestUpdate(RsPeerId peerid,time_t latest_update)
|
||||||
{
|
{
|
||||||
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
|
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
|
||||||
|
|
||||||
|
@ -367,11 +517,12 @@ bool p3GxsReputation::updateLatestUpdate(RsPeerId peerid, time_t ts)
|
||||||
mConfig[peerid] = ReputationConfig(peerid);
|
mConfig[peerid] = ReputationConfig(peerid);
|
||||||
it = mConfig.find(peerid) ;
|
it = mConfig.find(peerid) ;
|
||||||
}
|
}
|
||||||
it->second.mLatestUpdate = ts;
|
it->second.mLatestUpdate = latest_update ;
|
||||||
|
|
||||||
mReputationsUpdated = true;
|
mReputationsUpdated = true;
|
||||||
// Switched to periodic save due to scale of data.
|
// Switched to periodic save due to scale of data.
|
||||||
//IndicateConfigChanged();
|
|
||||||
|
IndicateConfigChanged();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -380,14 +531,75 @@ bool p3GxsReputation::updateLatestUpdate(RsPeerId peerid, time_t ts)
|
||||||
* Opinion
|
* Opinion
|
||||||
****/
|
****/
|
||||||
|
|
||||||
bool p3GxsReputation::updateOpinion(const RsGxsId& gxsid, int opinion)
|
bool p3GxsReputation::getReputationInfo(const RsGxsId& gxsid, RsReputations::ReputationInfo& info)
|
||||||
{
|
{
|
||||||
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
|
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
|
||||||
|
|
||||||
|
#ifdef DEBUG_REPUTATION
|
||||||
|
std::cerr << "getReputationInfo() for " << gxsid << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::map<RsGxsId,Reputation>::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<RsGxsId, Reputation>::iterator rit;
|
std::map<RsGxsId, Reputation>::iterator rit;
|
||||||
|
|
||||||
/* find matching Reputation */
|
/* find matching Reputation */
|
||||||
rit = mReputations.find(gxsid);
|
rit = mReputations.find(gxsid);
|
||||||
|
|
||||||
if (rit == mReputations.end())
|
if (rit == mReputations.end())
|
||||||
{
|
{
|
||||||
mReputations[gxsid] = Reputation(gxsid);
|
mReputations[gxsid] = Reputation(gxsid);
|
||||||
|
@ -420,14 +632,15 @@ bool p3GxsReputation::updateOpinion(const RsGxsId& gxsid, int opinion)
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
reputation.mOwnOpinion = opinion;
|
reputation.mOwnOpinion = opinion;
|
||||||
reputation.mOwnOpinionTs = now;
|
reputation.mOwnOpinionTs = now;
|
||||||
reputation.CalculateReputation();
|
reputation.updateReputation(mAverageActiveFriends);
|
||||||
|
|
||||||
mUpdated.insert(std::make_pair(now, gxsid));
|
mUpdated.insert(std::make_pair(now, gxsid));
|
||||||
mUpdatedReputations.insert(gxsid);
|
mUpdatedReputations.insert(gxsid);
|
||||||
|
|
||||||
mReputationsUpdated = true;
|
mReputationsUpdated = true;
|
||||||
|
|
||||||
// Switched to periodic save due to scale of data.
|
// Switched to periodic save due to scale of data.
|
||||||
//IndicateConfigChanged();
|
IndicateConfigChanged();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -448,6 +661,9 @@ bool p3GxsReputation::saveList(bool& cleanup, std::list<RsItem*> &savelist)
|
||||||
cleanup = true;
|
cleanup = true;
|
||||||
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
|
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
|
||||||
|
|
||||||
|
#ifdef DEBUG_REPUTATION
|
||||||
|
std::cerr << "p3GxsReputation::saveList()" << std::endl;
|
||||||
|
#endif
|
||||||
/* save */
|
/* save */
|
||||||
std::map<RsPeerId, ReputationConfig>::iterator it;
|
std::map<RsPeerId, ReputationConfig>::iterator it;
|
||||||
for(it = mConfig.begin(); it != mConfig.end(); ++it)
|
for(it = mConfig.begin(); it != mConfig.end(); ++it)
|
||||||
|
@ -459,7 +675,7 @@ bool p3GxsReputation::saveList(bool& cleanup, std::list<RsItem*> &savelist)
|
||||||
}
|
}
|
||||||
|
|
||||||
RsGxsReputationConfigItem *item = new RsGxsReputationConfigItem();
|
RsGxsReputationConfigItem *item = new RsGxsReputationConfigItem();
|
||||||
item->mPeerId = it->first.toStdString();
|
item->mPeerId = it->first;
|
||||||
item->mLatestUpdate = it->second.mLatestUpdate;
|
item->mLatestUpdate = it->second.mLatestUpdate;
|
||||||
item->mLastQuery = it->second.mLastQuery;
|
item->mLastQuery = it->second.mLastQuery;
|
||||||
savelist.push_back(item);
|
savelist.push_back(item);
|
||||||
|
@ -470,16 +686,15 @@ bool p3GxsReputation::saveList(bool& cleanup, std::list<RsItem*> &savelist)
|
||||||
for(rit = mReputations.begin(); rit != mReputations.end(); ++rit, count++)
|
for(rit = mReputations.begin(); rit != mReputations.end(); ++rit, count++)
|
||||||
{
|
{
|
||||||
RsGxsReputationSetItem *item = new RsGxsReputationSetItem();
|
RsGxsReputationSetItem *item = new RsGxsReputationSetItem();
|
||||||
item->mGxsId = rit->first.toStdString();
|
item->mGxsId = rit->first;
|
||||||
item->mOwnOpinion = ConvertToSerialised(rit->second.mOwnOpinion, false);
|
item->mOwnOpinion = rit->second.mOwnOpinion;
|
||||||
item->mOwnOpinionTs = rit->second.mOwnOpinionTs;
|
item->mOwnOpinionTS = rit->second.mOwnOpinionTs;
|
||||||
item->mReputation = ConvertToSerialised(rit->second.mReputation, false);
|
|
||||||
|
|
||||||
std::map<RsPeerId, int32_t>::iterator oit;
|
std::map<RsPeerId, RsReputations::Opinion>::iterator oit;
|
||||||
for(oit = rit->second.mOpinions.begin(); oit != rit->second.mOpinions.end(); ++oit)
|
for(oit = rit->second.mOpinions.begin(); oit != rit->second.mOpinions.end(); ++oit)
|
||||||
{
|
{
|
||||||
// should be already limited.
|
// 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);
|
savelist.push_back(item);
|
||||||
|
@ -495,6 +710,9 @@ void p3GxsReputation::saveDone()
|
||||||
|
|
||||||
bool p3GxsReputation::loadList(std::list<RsItem *>& loadList)
|
bool p3GxsReputation::loadList(std::list<RsItem *>& loadList)
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG_REPUTATION
|
||||||
|
std::cerr << "p3GxsReputation::saveList()" << std::endl;
|
||||||
|
#endif
|
||||||
std::list<RsItem *>::iterator it;
|
std::list<RsItem *>::iterator it;
|
||||||
std::set<RsPeerId> peerSet;
|
std::set<RsPeerId> peerSet;
|
||||||
|
|
||||||
|
@ -515,9 +733,8 @@ bool p3GxsReputation::loadList(std::list<RsItem *>& loadList)
|
||||||
}
|
}
|
||||||
RsGxsReputationSetItem *set = dynamic_cast<RsGxsReputationSetItem *>(*it);
|
RsGxsReputationSetItem *set = dynamic_cast<RsGxsReputationSetItem *>(*it);
|
||||||
if (set)
|
if (set)
|
||||||
{
|
|
||||||
loadReputationSet(set, peerSet);
|
loadReputationSet(set, peerSet);
|
||||||
}
|
|
||||||
delete (*it);
|
delete (*it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -530,6 +747,9 @@ bool p3GxsReputation::loadReputationSet(RsGxsReputationSetItem *item, const std:
|
||||||
|
|
||||||
std::map<RsGxsId, Reputation>::iterator rit;
|
std::map<RsGxsId, Reputation>::iterator rit;
|
||||||
|
|
||||||
|
if(item->mGxsId.isNull()) // just a protection against potential errors having put 00000 into ids.
|
||||||
|
return false ;
|
||||||
|
|
||||||
/* find matching Reputation */
|
/* find matching Reputation */
|
||||||
RsGxsId gxsId(item->mGxsId);
|
RsGxsId gxsId(item->mGxsId);
|
||||||
rit = mReputations.find(gxsId);
|
rit = mReputations.find(gxsId);
|
||||||
|
@ -542,26 +762,24 @@ bool p3GxsReputation::loadReputationSet(RsGxsReputationSetItem *item, const std:
|
||||||
Reputation &reputation = mReputations[gxsId];
|
Reputation &reputation = mReputations[gxsId];
|
||||||
|
|
||||||
// install opinions.
|
// install opinions.
|
||||||
std::map<std::string, uint32_t>::const_iterator oit;
|
std::map<RsPeerId, uint32_t>::const_iterator oit;
|
||||||
for(oit = item->mOpinions.begin(); oit != item->mOpinions.end(); ++oit)
|
for(oit = item->mOpinions.begin(); oit != item->mOpinions.end(); ++oit)
|
||||||
{
|
{
|
||||||
// expensive ... but necessary.
|
// expensive ... but necessary.
|
||||||
RsPeerId peerId(oit->first);
|
RsPeerId peerId(oit->first);
|
||||||
if (peerSet.end() != peerSet.find(peerId))
|
if (peerSet.end() != peerSet.find(peerId))
|
||||||
{
|
reputation.mOpinions[peerId] = safe_convert_uint32t_to_opinion(oit->second);
|
||||||
reputation.mOpinions[peerId] = ConvertFromSerialised(oit->second, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
reputation.mOwnOpinion = ConvertFromSerialised(item->mOwnOpinion, false);
|
reputation.mOwnOpinion = item->mOwnOpinion;
|
||||||
reputation.mOwnOpinionTs = item->mOwnOpinionTs;
|
reputation.mOwnOpinionTs = item->mOwnOpinionTS;
|
||||||
|
|
||||||
// if dropping entries has changed the score -> must update.
|
// if dropping entries has changed the score -> must update.
|
||||||
int previous = ConvertFromSerialised(item->mReputation, false);
|
|
||||||
if (previous != reputation.CalculateReputation())
|
float old_reputation = reputation.mReputation ;
|
||||||
{
|
|
||||||
|
if(old_reputation != reputation.updateReputation(mAverageActiveFriends))
|
||||||
mUpdatedReputations.insert(gxsId) ;
|
mUpdatedReputations.insert(gxsId) ;
|
||||||
}
|
|
||||||
|
|
||||||
mUpdated.insert(std::make_pair(reputation.mOwnOpinionTs, gxsId));
|
mUpdated.insert(std::make_pair(reputation.mOwnOpinionTs, gxsId));
|
||||||
return true;
|
return true;
|
||||||
|
@ -572,9 +790,6 @@ bool p3GxsReputation::loadReputationSet(RsGxsReputationSetItem *item, const std:
|
||||||
* Send Requests.
|
* Send Requests.
|
||||||
****/
|
****/
|
||||||
|
|
||||||
const int kReputationRequestPeriod = 3600;
|
|
||||||
const int kReputationStoreWait = 180; // 3 minutes.
|
|
||||||
|
|
||||||
int p3GxsReputation::sendPackets()
|
int p3GxsReputation::sendPackets()
|
||||||
{
|
{
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
|
@ -585,7 +800,7 @@ int p3GxsReputation::sendPackets()
|
||||||
storeTime = mStoreTime;
|
storeTime = mStoreTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (now - requestTime > kReputationRequestPeriod)
|
if (now > requestTime + kReputationRequestPeriod)
|
||||||
{
|
{
|
||||||
sendReputationRequests();
|
sendReputationRequests();
|
||||||
|
|
||||||
|
@ -629,48 +844,41 @@ void p3GxsReputation::sendReputationRequests()
|
||||||
|
|
||||||
mLinkMgr->getOnlineList(idList);
|
mLinkMgr->getOnlineList(idList);
|
||||||
|
|
||||||
#ifdef DEBUG_REPUTATION
|
|
||||||
std::cerr << "p3GxsReputation::sendReputationRequests()";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* prepare packets */
|
/* prepare packets */
|
||||||
std::list<RsPeerId>::iterator it;
|
std::list<RsPeerId>::iterator it;
|
||||||
for(it = idList.begin(); it != idList.end(); ++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);
|
sendReputationRequest(*it);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int p3GxsReputation::sendReputationRequest(RsPeerId peerid)
|
int p3GxsReputation::sendReputationRequest(RsPeerId peerid)
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG_REPUTATION
|
||||||
std::cerr << " p3GxsReputation::sendReputationRequest(" << peerid << ") " ;
|
std::cerr << " p3GxsReputation::sendReputationRequest(" << peerid << ") " ;
|
||||||
std::cerr << std::endl;
|
#endif
|
||||||
|
time_t now = time(NULL) ;
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
RsGxsReputationRequestItem *requestItem =
|
RsGxsReputationRequestItem *requestItem = new RsGxsReputationRequestItem();
|
||||||
new RsGxsReputationRequestItem();
|
|
||||||
|
|
||||||
requestItem->PeerId(peerid);
|
requestItem->PeerId(peerid);
|
||||||
|
|
||||||
{
|
{
|
||||||
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
|
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
|
||||||
|
|
||||||
/* find the last timestamp we have */
|
/* find the last timestamp we have */
|
||||||
std::map<RsPeerId, ReputationConfig>::iterator it;
|
std::map<RsPeerId, ReputationConfig>::iterator it = mConfig.find(peerid);
|
||||||
it = mConfig.find(peerid);
|
|
||||||
if (it != mConfig.end())
|
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;
|
requestItem->mLastUpdate = it->second.mLatestUpdate;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG_REPUTATION
|
||||||
|
std::cerr << " lastUpdate = never. Requesting all!" << std::endl;
|
||||||
|
#endif
|
||||||
// get whole list.
|
// get whole list.
|
||||||
requestItem->mLastUpdate = 0;
|
requestItem->mLastUpdate = 0;
|
||||||
}
|
}
|
||||||
|
@ -680,4 +888,44 @@ int p3GxsReputation::sendReputationRequest(RsPeerId peerid)
|
||||||
return 1;
|
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<RsPeerId,RsReputations::Opinion>::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<RsGxsId,Reputation>::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<RsPeerId,RsReputations::Opinion>::const_iterator it2(it->second.mOpinions.begin());it2!=it->second.mOpinions.end();++it2)
|
||||||
|
std::cerr << " " << it2->first << ": " << it2->second << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include "serialiser/rsgxsreputationitems.h"
|
#include "serialiser/rsgxsreputationitems.h"
|
||||||
|
|
||||||
#include "retroshare/rsidentity.h"
|
#include "retroshare/rsidentity.h"
|
||||||
|
#include "retroshare/rsreputations.h"
|
||||||
#include "services/p3service.h"
|
#include "services/p3service.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -58,19 +59,19 @@ class Reputation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Reputation()
|
Reputation()
|
||||||
:mOwnOpinion(0), mOwnOpinionTs(0), mReputation(0) { return; }
|
:mOwnOpinion(RsReputations::OPINION_NEUTRAL), mOwnOpinionTs(0), mReputation(RsReputations::OPINION_NEUTRAL) { }
|
||||||
|
|
||||||
Reputation(const RsGxsId& about)
|
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<RsPeerId, RsReputations::Opinion> mOpinions;
|
||||||
std::map<RsPeerId, int32_t> mOpinions;
|
|
||||||
int32_t mOwnOpinion;
|
int32_t mOwnOpinion;
|
||||||
time_t mOwnOpinionTs;
|
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:
|
public:
|
||||||
p3GxsReputation(p3LinkMgr *lm);
|
p3GxsReputation(p3LinkMgr *lm);
|
||||||
virtual RsServiceInfo getServiceInfo();
|
virtual RsServiceInfo getServiceInfo();
|
||||||
|
|
||||||
/***** Interface for p3idservice *****/
|
/***** Interface for RsReputations *****/
|
||||||
|
virtual bool setOwnOpinion(const RsGxsId& key_id, const Opinion& op) ;
|
||||||
virtual bool updateOpinion(const RsGxsId& gxsid, int opinion);
|
virtual bool getReputationInfo(const RsGxsId& id,ReputationInfo& info) ;
|
||||||
|
virtual bool isIdentityBanned(const RsGxsId& id) ;
|
||||||
|
|
||||||
/***** overloaded from p3Service *****/
|
/***** 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 tick();
|
||||||
virtual int status();
|
virtual int status();
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Interface stuff.
|
* Interface stuff.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*************** pqiMonitor callback ***********************/
|
|
||||||
//virtual void statusChange(const std::list<pqipeer> &plist);
|
|
||||||
|
|
||||||
|
|
||||||
/************* from p3Config *******************/
|
/************* from p3Config *******************/
|
||||||
virtual RsSerialiser *setupSerialiser() ;
|
virtual RsSerialiser *setupSerialiser() ;
|
||||||
virtual bool saveList(bool& cleanup, std::list<RsItem*>&) ;
|
virtual bool saveList(bool& cleanup, std::list<RsItem*>&) ;
|
||||||
|
@ -123,22 +112,27 @@ class p3GxsReputation: public p3Service, public p3Config /* , public pqiMonitor
|
||||||
|
|
||||||
bool SendReputations(RsGxsReputationRequestItem *request);
|
bool SendReputations(RsGxsReputationRequestItem *request);
|
||||||
bool RecvReputations(RsGxsReputationUpdateItem *item);
|
bool RecvReputations(RsGxsReputationUpdateItem *item);
|
||||||
bool updateLatestUpdate(RsPeerId peerid, time_t ts);
|
bool updateLatestUpdate(RsPeerId peerid, time_t latest_update);
|
||||||
|
void updateActiveFriends() ;
|
||||||
|
|
||||||
bool loadReputationSet(RsGxsReputationSetItem *item,
|
// internal update of data. Takes care of cleaning empty boxes.
|
||||||
const std::set<RsPeerId> &peerSet);
|
void locked_updateOpinion(const RsPeerId &from, const RsGxsId &about, RsReputations::Opinion op);
|
||||||
|
bool loadReputationSet(RsGxsReputationSetItem *item, const std::set<RsPeerId> &peerSet);
|
||||||
|
|
||||||
int sendPackets();
|
int sendPackets();
|
||||||
|
void cleanup();
|
||||||
void sendReputationRequests();
|
void sendReputationRequests();
|
||||||
int sendReputationRequest(RsPeerId peerid);
|
int sendReputationRequest(RsPeerId peerid);
|
||||||
|
void debug_print() ;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RsMutex mReputationMtx;
|
RsMutex mReputationMtx;
|
||||||
|
|
||||||
|
time_t mLastActiveFriendsUpdate;
|
||||||
time_t mRequestTime;
|
time_t mRequestTime;
|
||||||
time_t mStoreTime;
|
time_t mStoreTime;
|
||||||
bool mReputationsUpdated;
|
bool mReputationsUpdated;
|
||||||
|
uint32_t mAverageActiveFriends ;
|
||||||
|
|
||||||
p3LinkMgr *mLinkMgr;
|
p3LinkMgr *mLinkMgr;
|
||||||
|
|
||||||
|
|
|
@ -413,6 +413,8 @@ bool p3IdService:: getIdDetails(const RsGxsId &id, RsIdentityDetails &details)
|
||||||
if(details.mNickname.length() > RSID_MAXIMUM_NICKNAME_SIZE*4)
|
if(details.mNickname.length() > RSID_MAXIMUM_NICKNAME_SIZE*4)
|
||||||
details.mNickname = "[too long a name]" ;
|
details.mNickname = "[too long a name]" ;
|
||||||
|
|
||||||
|
rsReputations->getReputationInfo(id,details.mReputation) ;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -421,6 +423,9 @@ bool p3IdService:: getIdDetails(const RsGxsId &id, RsIdentityDetails &details)
|
||||||
{
|
{
|
||||||
details = data.details;
|
details = data.details;
|
||||||
details.mLastUsageTS = locked_getLastUsageTS(id) ;
|
details.mLastUsageTS = locked_getLastUsageTS(id) ;
|
||||||
|
|
||||||
|
rsReputations->getReputationInfo(id,details.mReputation) ;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -831,7 +836,7 @@ bool p3IdService::getReputation(const RsGxsId &id, GixsReputation &rep)
|
||||||
if (mPublicKeyCache.fetch(id, data))
|
if (mPublicKeyCache.fetch(id, data))
|
||||||
{
|
{
|
||||||
rep.id = id;
|
rep.id = id;
|
||||||
rep.score = data.details.mReputation.mOverallScore;
|
rep.score = 0;//data.details.mReputation.mOverallScore;
|
||||||
#ifdef DEBUG_IDS
|
#ifdef DEBUG_IDS
|
||||||
std::cerr << "p3IdService::getReputation() id: ";
|
std::cerr << "p3IdService::getReputation() id: ";
|
||||||
std::cerr << id.toStdString() << " score: " <<
|
std::cerr << id.toStdString() << " score: " <<
|
||||||
|
@ -1669,14 +1674,14 @@ void RsGxsIdCache::updateServiceString(std::string serviceString)
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy over Reputation scores.
|
// copy over Reputation scores.
|
||||||
details.mReputation = ssdata.score.rep;
|
//details.mReputation = ssdata.score.rep;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
details.mPgpKnown = false;
|
details.mPgpKnown = false;
|
||||||
details.mPgpId.clear();
|
details.mPgpId.clear();
|
||||||
details.mReputation.updateIdScore(false, false);
|
//details.mReputation.updateIdScore(false, false);
|
||||||
details.mReputation.update();
|
//details.mReputation.update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include "gui/msgs/MessageComposer.h"
|
#include "gui/msgs/MessageComposer.h"
|
||||||
|
|
||||||
#include <retroshare/rspeers.h>
|
#include <retroshare/rspeers.h>
|
||||||
|
#include <retroshare/rsreputations.h>
|
||||||
#include "retroshare/rsgxsflags.h"
|
#include "retroshare/rsgxsflags.h"
|
||||||
#include "retroshare/rsmsgs.h"
|
#include "retroshare/rsmsgs.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -92,18 +93,9 @@ IdDialog::IdDialog(QWidget *parent) :
|
||||||
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_GpgName);
|
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_GpgName);
|
||||||
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_Type);
|
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_Type);
|
||||||
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_LastUsed);
|
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->lineEdit_LastUsed);
|
||||||
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->toolButton_Reputation);
|
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->ownOpinion_CB);
|
||||||
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->line_RatingOverall);
|
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->overallOpinion_TF);
|
||||||
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->line_RatingImplicit);
|
mStateHelper->addWidget(IDDIALOG_IDDETAILS, ui->neighborNodesOpinion_TF);
|
||||||
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->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_Nickname);
|
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_Nickname);
|
||||||
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_GpgName);
|
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_GpgName);
|
||||||
|
@ -113,10 +105,7 @@ IdDialog::IdDialog(QWidget *parent) :
|
||||||
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_Type);
|
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_Type);
|
||||||
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_GpgName);
|
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_GpgName);
|
||||||
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_LastUsed);
|
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->lineEdit_LastUsed);
|
||||||
mStateHelper->addLoadPlaceholder(IDDIALOG_IDDETAILS, ui->line_RatingOverall);
|
//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->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_Nickname);
|
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_Nickname);
|
||||||
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_KeyId);
|
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_KeyId);
|
||||||
|
@ -125,10 +114,6 @@ IdDialog::IdDialog(QWidget *parent) :
|
||||||
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_Type);
|
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_Type);
|
||||||
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_GpgName);
|
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_GpgName);
|
||||||
mStateHelper->addClear(IDDIALOG_IDDETAILS, ui->lineEdit_LastUsed);
|
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->addWidget(IDDIALOG_REPLIST, ui->treeWidget_RepList);
|
//mStateHelper->addWidget(IDDIALOG_REPLIST, ui->treeWidget_RepList);
|
||||||
//mStateHelper->addLoadPlaceholder(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->filterComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(filterComboBoxChanged()));
|
||||||
connect(ui->filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString)));
|
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()));
|
connect(ui->messageButton, SIGNAL(clicked()), this, SLOT(sendMsg()));
|
||||||
|
|
||||||
|
@ -197,7 +182,7 @@ IdDialog::IdDialog(QWidget *parent) :
|
||||||
|
|
||||||
// Hiding RepList until that part is finished.
|
// Hiding RepList until that part is finished.
|
||||||
//ui->treeWidget_RepList->setVisible(false);
|
//ui->treeWidget_RepList->setVisible(false);
|
||||||
ui->toolButton_Reputation->setVisible(false);
|
|
||||||
#ifndef UNFINISHED
|
#ifndef UNFINISHED
|
||||||
ui->todoPushButton->hide() ;
|
ui->todoPushButton->hide() ;
|
||||||
#endif
|
#endif
|
||||||
|
@ -225,8 +210,8 @@ IdDialog::IdDialog(QWidget *parent) :
|
||||||
processSettings(true);
|
processSettings(true);
|
||||||
|
|
||||||
// hide reputation sice it's currently unused
|
// hide reputation sice it's currently unused
|
||||||
ui->reputationGroupBox->hide();
|
//ui->reputationGroupBox->hide();
|
||||||
ui->tweakGroupBox->hide();
|
//ui->tweakGroupBox->hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
IdDialog::~IdDialog()
|
IdDialog::~IdDialog()
|
||||||
|
@ -652,36 +637,9 @@ void IdDialog::insertIdDetails(uint32_t token)
|
||||||
else
|
else
|
||||||
ui->lineEdit_Type->setText(tr("Anonymous identity")) ;
|
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)
|
if (isOwnId)
|
||||||
{
|
{
|
||||||
mStateHelper->setWidgetEnabled(ui->toolButton_Reputation, false);
|
mStateHelper->setWidgetEnabled(ui->ownOpinion_CB, false);
|
||||||
ui->editIdentity->setEnabled(true);
|
ui->editIdentity->setEnabled(true);
|
||||||
ui->removeIdentity->setEnabled(true);
|
ui->removeIdentity->setEnabled(true);
|
||||||
ui->chatIdentity->setEnabled(false);
|
ui->chatIdentity->setEnabled(false);
|
||||||
|
@ -690,7 +648,7 @@ void IdDialog::insertIdDetails(uint32_t token)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// No Reputation yet!
|
// No Reputation yet!
|
||||||
mStateHelper->setWidgetEnabled(ui->toolButton_Reputation, /*true*/ false);
|
mStateHelper->setWidgetEnabled(ui->ownOpinion_CB, true);
|
||||||
ui->editIdentity->setEnabled(false);
|
ui->editIdentity->setEnabled(false);
|
||||||
ui->removeIdentity->setEnabled(false);
|
ui->removeIdentity->setEnabled(false);
|
||||||
ui->chatIdentity->setEnabled(true);
|
ui->chatIdentity->setEnabled(true);
|
||||||
|
@ -698,9 +656,8 @@ void IdDialog::insertIdDetails(uint32_t token)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* now fill in the reputation information */
|
/* 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)
|
if (data.mPgpKnown)
|
||||||
{
|
{
|
||||||
ui->line_RatingImplicit->setText(tr("+50 Known PGP"));
|
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"));
|
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);
|
QString rating = QString::number(data.mReputation.mIdScore);
|
||||||
ui->line_RatingImplicit->setText(rating);
|
ui->line_RatingImplicit->setText(rating);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
#endif
|
||||||
QString rating = QString::number(data.mReputation.mOwnOpinion);
|
|
||||||
ui->line_RatingOwn->setText(rating);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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);
|
case RsReputations::OPINION_NEGATIVE: ui->ownOpinion_CB->setCurrentIndex(0); break ;
|
||||||
ui->line_RatingPeers->setText(rating);
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -744,46 +704,37 @@ void IdDialog::modifyReputation()
|
||||||
|
|
||||||
RsGxsId id(ui->lineEdit_KeyId->text().toStdString());
|
RsGxsId id(ui->lineEdit_KeyId->text().toStdString());
|
||||||
|
|
||||||
int mod = 0;
|
RsReputations::Opinion op ;
|
||||||
if (ui->repMod_Accept->isChecked())
|
|
||||||
|
switch(ui->ownOpinion_CB->currentIndex())
|
||||||
{
|
{
|
||||||
mod += 100;
|
case 0: op = RsReputations::OPINION_NEGATIVE ; break ;
|
||||||
}
|
case 1: op = RsReputations::OPINION_NEUTRAL ; break ;
|
||||||
else if (ui->repMod_Positive->isChecked())
|
case 2: op = RsReputations::OPINION_POSITIVE ; break ;
|
||||||
{
|
default:
|
||||||
mod += 10;
|
std::cerr << "Wrong value from opinion combobox. Bug??" << std::endl;
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
rsReputations->setOwnOpinion(id,op) ;
|
||||||
|
|
||||||
#ifdef ID_DEBUG
|
#ifdef ID_DEBUG
|
||||||
std::cerr << "IdDialog::modifyReputation() ID: " << id << " Mod: " << mod;
|
std::cerr << "IdDialog::modifyReputation() ID: " << id << " Mod: " << mod;
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
#endif
|
#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;
|
uint32_t token;
|
||||||
if (!rsIdentity->submitOpinion(token, id, false, mod))
|
if (!rsIdentity->submitOpinion(token, id, false, op))
|
||||||
{
|
{
|
||||||
#ifdef ID_DEBUG
|
#ifdef ID_DEBUG
|
||||||
std::cerr << "IdDialog::modifyReputation() Error submitting Opinion";
|
std::cerr << "IdDialog::modifyReputation() Error submitting Opinion";
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef ID_DEBUG
|
#ifdef ID_DEBUG
|
||||||
std::cerr << "IdDialog::modifyReputation() queuingRequest(), token: " << token;
|
std::cerr << "IdDialog::modifyReputation() queuingRequest(), token: " << token;
|
||||||
|
@ -792,7 +743,7 @@ void IdDialog::modifyReputation()
|
||||||
|
|
||||||
// trigger refresh when finished.
|
// trigger refresh when finished.
|
||||||
// basic / anstype are not needed.
|
// basic / anstype are not needed.
|
||||||
mIdQueue->queueRequest(token, 0, 0, IDDIALOG_REFRESH);
|
requestIdDetails();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>826</width>
|
<width>826</width>
|
||||||
<height>752</height>
|
<height>757</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
|
@ -483,7 +483,90 @@
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
<item row="0" column="0">
|
<item row="2" column="1">
|
||||||
|
<widget class="QLineEdit" name="neighborNodesOpinion_TF">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><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></string>
|
||||||
|
</property>
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_6">
|
||||||
|
<property name="text">
|
||||||
|
<string>Your opinion:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label_5">
|
||||||
|
<property name="text">
|
||||||
|
<string>Neighbor nodes:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QComboBox" name="ownOpinion_CB">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><!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></string>
|
||||||
|
</property>
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Negative</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset>
|
||||||
|
<normaloff>../icons/yellow_biohazard64.png</normaloff>../icons/yellow_biohazard64.png</iconset>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Neutral</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Positive</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QLineEdit" name="overallOpinion_TF">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string><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></string>
|
||||||
|
</property>
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
<widget class="QLabel" name="label_2">
|
<widget class="QLabel" name="label_2">
|
||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
|
@ -492,158 +575,12 @@
|
||||||
</font>
|
</font>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Overall</string>
|
<string>Overall:</string>
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QLineEdit" name="line_RatingOverall">
|
|
||||||
<property name="readOnly">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QLabel" name="label_11">
|
|
||||||
<property name="text">
|
|
||||||
<string>Implicit</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QLineEdit" name="line_RatingImplicit">
|
|
||||||
<property name="readOnly">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QLabel" name="label_6">
|
|
||||||
<property name="text">
|
|
||||||
<string>Opinion</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="QLineEdit" name="line_RatingOwn">
|
|
||||||
<property name="readOnly">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0">
|
|
||||||
<widget class="QLabel" name="label_5">
|
|
||||||
<property name="text">
|
|
||||||
<string>Peers</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="1">
|
|
||||||
<widget class="QLineEdit" name="line_RatingPeers">
|
|
||||||
<property name="readOnly">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="toolButton_Reputation">
|
|
||||||
<property name="focusPolicy">
|
|
||||||
<enum>Qt::NoFocus</enum>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Edit reputation</string>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset resource="../images.qrc">
|
|
||||||
<normaloff>:/images/edit_24.png</normaloff>:/images/edit_24.png</iconset>
|
|
||||||
</property>
|
|
||||||
<property name="iconSize">
|
|
||||||
<size>
|
|
||||||
<width>24</width>
|
|
||||||
<height>24</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolButtonStyle">
|
|
||||||
<enum>Qt::ToolButtonTextBesideIcon</enum>
|
|
||||||
</property>
|
|
||||||
<property name="autoRaise">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="tweakGroupBox">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="title">
|
|
||||||
<string>Tweak Opinion</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="QRadioButton" name="repMod_Accept">
|
|
||||||
<property name="text">
|
|
||||||
<string>Accept (+100)</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QRadioButton" name="repMod_Positive">
|
|
||||||
<property name="text">
|
|
||||||
<string>Positive (+10)</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QRadioButton" name="repMod_Negative">
|
|
||||||
<property name="text">
|
|
||||||
<string>Negative (-10)</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QRadioButton" name="repMod_Ban">
|
|
||||||
<property name="text">
|
|
||||||
<string>Ban (-100)</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="QRadioButton" name="repMod_Custom">
|
|
||||||
<property name="text">
|
|
||||||
<string>Custom</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QSpinBox" name="repMod_spinBox">
|
|
||||||
<property name="minimum">
|
|
||||||
<number>-100</number>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>100</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="repModButton">
|
|
||||||
<property name="text">
|
|
||||||
<string>Modify</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -730,9 +667,6 @@
|
||||||
<tabstop>lineEdit_KeyId</tabstop>
|
<tabstop>lineEdit_KeyId</tabstop>
|
||||||
<tabstop>lineEdit_GpgId</tabstop>
|
<tabstop>lineEdit_GpgId</tabstop>
|
||||||
<tabstop>lineEdit_GpgName</tabstop>
|
<tabstop>lineEdit_GpgName</tabstop>
|
||||||
<tabstop>line_RatingOverall</tabstop>
|
|
||||||
<tabstop>line_RatingImplicit</tabstop>
|
|
||||||
<tabstop>line_RatingOwn</tabstop>
|
|
||||||
</tabstops>
|
</tabstops>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="../images.qrc"/>
|
<include location="../images.qrc"/>
|
||||||
|
|
|
@ -42,6 +42,8 @@
|
||||||
#define TYPE_UNKNOWN_ID 3
|
#define TYPE_UNKNOWN_ID 3
|
||||||
#define TYPE_CREATE_ID 4
|
#define TYPE_CREATE_ID 4
|
||||||
|
|
||||||
|
#define BANNED_ICON ":/icons/yellow_biohazard64.png"
|
||||||
|
|
||||||
#define IDCHOOSER_REFRESH 1
|
#define IDCHOOSER_REFRESH 1
|
||||||
|
|
||||||
//#define IDCHOOSER_DEBUG
|
//#define IDCHOOSER_DEBUG
|
||||||
|
@ -148,6 +150,10 @@ static void loadPrivateIdsCallback(GxsIdDetailsType type, const RsIdentityDetail
|
||||||
case GXS_ID_DETAILS_TYPE_DONE:
|
case GXS_ID_DETAILS_TYPE_DONE:
|
||||||
GxsIdDetails::getIcons(details, icons);
|
GxsIdDetails::getIcons(details, icons);
|
||||||
break;
|
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);
|
chooser->setItemData(index, QString("%1_%2").arg((type == GXS_ID_DETAILS_TYPE_DONE) ? TYPE_FOUND_ID : TYPE_UNKNOWN_ID).arg(text), ROLE_SORT);
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "GxsIdDetails.h"
|
#include "GxsIdDetails.h"
|
||||||
#include "retroshare-gui/RsAutoUpdatePage.h"
|
#include "retroshare-gui/RsAutoUpdatePage.h"
|
||||||
|
#include "retroshare/rsreputations.h"
|
||||||
|
|
||||||
#include <retroshare/rspeers.h>
|
#include <retroshare/rspeers.h>
|
||||||
|
|
||||||
|
@ -40,6 +41,7 @@
|
||||||
#define IMAGE_PGPKNOWN ":/images/contact.png"
|
#define IMAGE_PGPKNOWN ":/images/contact.png"
|
||||||
#define IMAGE_PGPUNKNOWN ":/images/tags/pgp-unknown.png"
|
#define IMAGE_PGPUNKNOWN ":/images/tags/pgp-unknown.png"
|
||||||
#define IMAGE_ANON ":/images/tags/anon.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_AMBASSADOR ":/images/tags/dev-ambassador.png"
|
||||||
#define IMAGE_DEV_CONTRIBUTOR ":/images/tags/vote_down.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:
|
case GXS_ID_DETAILS_TYPE_DONE:
|
||||||
return getName(details);
|
return getName(details);
|
||||||
|
|
||||||
|
case GXS_ID_DETAILS_TYPE_BANNED:
|
||||||
|
return tr("[Banned]") ;
|
||||||
|
|
||||||
case GXS_ID_DETAILS_TYPE_FAILED:
|
case GXS_ID_DETAILS_TYPE_FAILED:
|
||||||
return getFailedText(details.mId);
|
return getFailedText(details.mId);
|
||||||
}
|
}
|
||||||
|
@ -873,6 +878,9 @@ bool GxsIdDetails::MakeIdDesc(const RsGxsId &id, bool doIcons, QString &str, QLi
|
||||||
|
|
||||||
QString GxsIdDetails::getName(const RsIdentityDetails &details)
|
QString GxsIdDetails::getName(const RsIdentityDetails &details)
|
||||||
{
|
{
|
||||||
|
if(rsReputations->isIdentityBanned(details.mId))
|
||||||
|
return tr("[Banned]") ;
|
||||||
|
|
||||||
QString name = QString::fromUtf8(details.mNickname.c_str()).left(RSID_MAXIMUM_NICKNAME_SIZE);
|
QString name = QString::fromUtf8(details.mNickname.c_str()).left(RSID_MAXIMUM_NICKNAME_SIZE);
|
||||||
|
|
||||||
std::list<RsRecognTag>::const_iterator it;
|
std::list<RsRecognTag>::const_iterator it;
|
||||||
|
@ -887,8 +895,17 @@ QString GxsIdDetails::getName(const RsIdentityDetails &details)
|
||||||
QString GxsIdDetails::getComment(const RsIdentityDetails &details)
|
QString GxsIdDetails::getComment(const RsIdentityDetails &details)
|
||||||
{
|
{
|
||||||
QString comment;
|
QString comment;
|
||||||
|
QString nickname ;
|
||||||
|
|
||||||
|
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) ;
|
||||||
|
|
||||||
QString nickname = details.mNickname.empty()?tr("[Unknown]"):QString::fromUtf8(details.mNickname.c_str()).left(RSID_MAXIMUM_NICKNAME_SIZE) ;
|
|
||||||
|
|
||||||
comment = QString("%1:%2<br/>%3:%4").arg(QApplication::translate("GxsIdDetails", "Identity name"),
|
comment = QString("%1:%2<br/>%3:%4").arg(QApplication::translate("GxsIdDetails", "Identity name"),
|
||||||
nickname,
|
nickname,
|
||||||
|
@ -903,6 +920,7 @@ QString nickname = details.mNickname.empty()?tr("[Unknown]"):QString::fromUtf8(d
|
||||||
{
|
{
|
||||||
/* look up real name */
|
/* look up real name */
|
||||||
std::string authorName = rsPeers->getGPGName(details.mPgpId);
|
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
|
else
|
||||||
|
@ -918,6 +936,13 @@ void GxsIdDetails::getIcons(const RsIdentityDetails &details, QList<QIcon> &icon
|
||||||
{
|
{
|
||||||
QPixmap pix ;
|
QPixmap pix ;
|
||||||
|
|
||||||
|
if(rsReputations->isIdentityBanned(details.mId))
|
||||||
|
{
|
||||||
|
icons.clear() ;
|
||||||
|
icons.push_back(QIcon(IMAGE_BANNED)) ;
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
if(icon_types & ICON_TYPE_AVATAR)
|
if(icon_types & ICON_TYPE_AVATAR)
|
||||||
{
|
{
|
||||||
if(details.mAvatar.mSize == 0 || !pix.loadFromData(details.mAvatar.mData, details.mAvatar.mSize, "PNG"))
|
if(details.mAvatar.mSize == 0 || !pix.loadFromData(details.mAvatar.mData, details.mAvatar.mSize, "PNG"))
|
||||||
|
|
|
@ -39,7 +39,8 @@ enum GxsIdDetailsType
|
||||||
GXS_ID_DETAILS_TYPE_EMPTY,
|
GXS_ID_DETAILS_TYPE_EMPTY,
|
||||||
GXS_ID_DETAILS_TYPE_LOADING,
|
GXS_ID_DETAILS_TYPE_LOADING,
|
||||||
GXS_ID_DETAILS_TYPE_DONE,
|
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);
|
typedef void (*GxsIdDetailsCallbackFunction)(GxsIdDetailsType type, const RsIdentityDetails &details, QObject *object, const QVariant &data);
|
||||||
|
@ -53,6 +54,7 @@ public:
|
||||||
static const int ICON_TYPE_PGP = 0x0002 ;
|
static const int ICON_TYPE_PGP = 0x0002 ;
|
||||||
static const int ICON_TYPE_RECOGN = 0x0004 ;
|
static const int ICON_TYPE_RECOGN = 0x0004 ;
|
||||||
static const int ICON_TYPE_ALL = 0x0007 ;
|
static const int ICON_TYPE_ALL = 0x0007 ;
|
||||||
|
static const int ICON_TYPE_REDACTED= 0x0008 ;
|
||||||
|
|
||||||
GxsIdDetails();
|
GxsIdDetails();
|
||||||
virtual ~GxsIdDetails();
|
virtual ~GxsIdDetails();
|
||||||
|
|
|
@ -25,6 +25,9 @@
|
||||||
#include "GxsIdTreeWidgetItem.h"
|
#include "GxsIdTreeWidgetItem.h"
|
||||||
#include "GxsIdDetails.h"
|
#include "GxsIdDetails.h"
|
||||||
#include "util/HandleRichText.h"
|
#include "util/HandleRichText.h"
|
||||||
|
#include "retroshare/rsreputations.h"
|
||||||
|
|
||||||
|
#define BANNED_IMAGE ":/icons/yellow_biohazard64.png"
|
||||||
|
|
||||||
/** Constructor */
|
/** Constructor */
|
||||||
GxsIdRSTreeWidgetItem::GxsIdRSTreeWidgetItem(const RSTreeWidgetItemCompareRole *compareRole, uint32_t icon_mask,QTreeWidget *parent)
|
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());
|
GxsIdDetails::getIcons(details, icons, item->iconTypeMask());
|
||||||
item->processResult(true);
|
item->processResult(true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GXS_ID_DETAILS_TYPE_BANNED:
|
||||||
|
icons.push_back(QIcon("BANNED_IMAGE")) ;
|
||||||
|
break ;
|
||||||
}
|
}
|
||||||
|
|
||||||
int column = item->idColumn();
|
int column = item->idColumn();
|
||||||
|
@ -139,16 +146,19 @@ void GxsIdRSTreeWidgetItem::setAvatar(const RsGxsImage &avatar)
|
||||||
|
|
||||||
QVariant GxsIdRSTreeWidgetItem::data(int column, int role) const
|
QVariant GxsIdRSTreeWidgetItem::data(int column, int role) const
|
||||||
{
|
{
|
||||||
if (column == idColumn()) {
|
if (column == idColumn())
|
||||||
switch (role) {
|
{
|
||||||
case Qt::ToolTipRole:
|
if (role == Qt::ToolTipRole)
|
||||||
{
|
{
|
||||||
QString t = RSTreeWidgetItem::data(column, role).toString();
|
QString t = RSTreeWidgetItem::data(column, role).toString();
|
||||||
|
|
||||||
QImage pix;
|
QImage pix;
|
||||||
if (mAvatar.mSize == 0 || !pix.loadFromData(mAvatar.mData, mAvatar.mSize, "PNG")) {
|
|
||||||
|
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);
|
pix = GxsIdDetails::makeDefaultIcon(mId);
|
||||||
}
|
|
||||||
|
|
||||||
int S = QFontMetricsF(font(column)).height();
|
int S = QFontMetricsF(font(column)).height();
|
||||||
|
|
||||||
|
@ -160,7 +170,6 @@ QVariant GxsIdRSTreeWidgetItem::data(int column, int role) const
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return RSTreeWidgetItem::data(column, role);
|
return RSTreeWidgetItem::data(column, role);
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include "util/QtVersion.h"
|
#include "util/QtVersion.h"
|
||||||
|
|
||||||
#include <retroshare/rsgxsforums.h>
|
#include <retroshare/rsgxsforums.h>
|
||||||
|
#include <retroshare/rsreputations.h>
|
||||||
#include <retroshare/rspeers.h>
|
#include <retroshare/rspeers.h>
|
||||||
// These should be in retroshare/ folder.
|
// These should be in retroshare/ folder.
|
||||||
#include "retroshare/rsgxsflags.h"
|
#include "retroshare/rsgxsflags.h"
|
||||||
|
@ -57,6 +58,7 @@
|
||||||
#define IMAGE_DOWNLOAD ":/images/start.png"
|
#define IMAGE_DOWNLOAD ":/images/start.png"
|
||||||
#define IMAGE_DOWNLOADALL ":/images/startall.png"
|
#define IMAGE_DOWNLOADALL ":/images/startall.png"
|
||||||
#define IMAGE_COPYLINK ":/images/copyrslink.png"
|
#define IMAGE_COPYLINK ":/images/copyrslink.png"
|
||||||
|
#define IMAGE_BIOHAZARD ":/icons/yellow_biohazard64.png"
|
||||||
|
|
||||||
#define VIEW_LAST_POST 0
|
#define VIEW_LAST_POST 0
|
||||||
#define VIEW_THREADED 1
|
#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);
|
QAction *replyauthorAct = new QAction(QIcon(IMAGE_MESSAGEREPLY), tr("Reply with private message"), &contextMnu);
|
||||||
connect(replyauthorAct, SIGNAL(triggered()), this, SLOT(replytomessage()));
|
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);
|
QAction *newthreadAct = new QAction(QIcon(IMAGE_MESSAGE), tr("Start New Thread"), &contextMnu);
|
||||||
newthreadAct->setEnabled (IS_GROUP_SUBSCRIBED(mSubscribeFlags));
|
newthreadAct->setEnabled (IS_GROUP_SUBSCRIBED(mSubscribeFlags));
|
||||||
connect(newthreadAct , SIGNAL(triggered()), this, SLOT(createthread()));
|
connect(newthreadAct , SIGNAL(triggered()), this, SLOT(createthread()));
|
||||||
|
@ -484,6 +490,8 @@ void GxsForumThreadWidget::threadListCustomPopupMenu(QPoint /*point*/)
|
||||||
contextMnu.addAction(expandAll);
|
contextMnu.addAction(expandAll);
|
||||||
contextMnu.addAction(collapseAll);
|
contextMnu.addAction(collapseAll);
|
||||||
|
|
||||||
|
contextMnu.addSeparator();
|
||||||
|
contextMnu.addAction(flagasbadAct);
|
||||||
contextMnu.addSeparator();
|
contextMnu.addSeparator();
|
||||||
contextMnu.addAction(replyauthorAct);
|
contextMnu.addAction(replyauthorAct);
|
||||||
|
|
||||||
|
@ -725,6 +733,9 @@ void GxsForumThreadWidget::insertGroupData()
|
||||||
case GXS_ID_DETAILS_TYPE_LOADING:
|
case GXS_ID_DETAILS_TYPE_LOADING:
|
||||||
author = GxsIdDetails::getLoadingText(details.mId);
|
author = GxsIdDetails::getLoadingText(details.mId);
|
||||||
break;
|
break;
|
||||||
|
case GXS_ID_DETAILS_TYPE_BANNED:
|
||||||
|
author = tr("[Banned]") ;
|
||||||
|
break ;
|
||||||
case GXS_ID_DETAILS_TYPE_DONE:
|
case GXS_ID_DETAILS_TYPE_DONE:
|
||||||
author = GxsIdDetails::getName(details);
|
author = GxsIdDetails::getName(details);
|
||||||
break;
|
break;
|
||||||
|
@ -886,11 +897,20 @@ void GxsForumThreadWidget::fillThreadStatus(QString text)
|
||||||
|
|
||||||
QTreeWidgetItem *GxsForumThreadWidget::convertMsgToThreadWidget(const RsGxsForumMsg &msg, bool useChildTS, uint32_t filterColumn)
|
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());
|
item->moveToThread(ui->threadTreeWidget->thread());
|
||||||
|
|
||||||
QString text;
|
QString text;
|
||||||
|
|
||||||
|
if(redacted)
|
||||||
|
item->setText(COLUMN_THREAD_TITLE, tr("[ ... Redacted message ... ]"));
|
||||||
|
else
|
||||||
item->setText(COLUMN_THREAD_TITLE, QString::fromUtf8(msg.mMeta.mMsgName.c_str()));
|
item->setText(COLUMN_THREAD_TITLE, QString::fromUtf8(msg.mMeta.mMsgName.c_str()));
|
||||||
|
|
||||||
QDateTime qtime;
|
QDateTime qtime;
|
||||||
|
@ -961,7 +981,6 @@ QTreeWidgetItem *GxsForumThreadWidget::convertMsgToThreadWidget(const RsGxsForum
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS, msg.mMeta.mMsgStatus);
|
item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_STATUS, msg.mMeta.mMsgStatus);
|
||||||
|
|
||||||
item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_MISSING, false);
|
item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_MISSING, false);
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
|
@ -970,10 +989,13 @@ QTreeWidgetItem *GxsForumThreadWidget::convertMsgToThreadWidget(const RsGxsForum
|
||||||
QTreeWidgetItem *GxsForumThreadWidget::generateMissingItem(const RsGxsMessageId &msgId)
|
QTreeWidgetItem *GxsForumThreadWidget::generateMissingItem(const RsGxsMessageId &msgId)
|
||||||
{
|
{
|
||||||
GxsIdRSTreeWidgetItem *item = new GxsIdRSTreeWidgetItem(mThreadCompareRole,GxsIdDetails::ICON_TYPE_ALL);
|
GxsIdRSTreeWidgetItem *item = new GxsIdRSTreeWidgetItem(mThreadCompareRole,GxsIdDetails::ICON_TYPE_ALL);
|
||||||
|
|
||||||
item->setText(COLUMN_THREAD_TITLE, tr("[ ... Missing Message ... ]"));
|
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_MSGID, QString::fromStdString(msgId.toStdString()));
|
||||||
item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_MISSING, true);
|
item->setData(COLUMN_THREAD_DATA, ROLE_THREAD_MISSING, true);
|
||||||
|
|
||||||
|
item->setId(RsGxsId(), COLUMN_THREAD_AUTHOR, false); // fixed up columnId()
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1301,6 +1323,8 @@ void GxsForumThreadWidget::insertMessageData(const RsGxsForumMsg &msg)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool redacted = rsReputations->isIdentityBanned(msg.mMeta.mAuthorId) ;
|
||||||
|
|
||||||
mStateHelper->setActive(mTokenTypeMessageData, true);
|
mStateHelper->setActive(mTokenTypeMessageData, true);
|
||||||
|
|
||||||
QTreeWidgetItem *item = ui->threadTreeWidget->currentItem();
|
QTreeWidgetItem *item = ui->threadTreeWidget->currentItem();
|
||||||
|
@ -1334,9 +1358,20 @@ void GxsForumThreadWidget::insertMessageData(const RsGxsForumMsg &msg)
|
||||||
ui->by_text_label->show() ;
|
ui->by_text_label->show() ;
|
||||||
ui->by_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("<p><font color=\"#ff0000\"><b>The author of this message (with ID %1) is banned.</b>").arg(QString::fromStdString(msg.mMeta.mAuthorId.toStdString())) ;
|
||||||
|
extraTxt += tr("<UL><li><b><font color=\"#ff0000\">Messages from this author are not forwarded. </font></b></li>") ;
|
||||||
|
extraTxt += tr("<li><b><font color=\"#ff0000\">Messages from this author are replaced by this text. </font></b></li></ul>") ;
|
||||||
|
extraTxt += tr("<p><b><font color=\"#ff0000\">You can force the visibility and forwarding of messages by setting a different opinion for that Id in People's tab.</font></b></p>") ;
|
||||||
|
|
||||||
ui->postText->setHtml(extraTxt);
|
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()));
|
//ui->threadTitle->setText(QString::fromUtf8(msg.mMeta.mMsgName.c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1685,6 +1720,34 @@ static QString buildReplyHeader(const RsMsgMetaData &meta)
|
||||||
return header;
|
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<RsGxsMessageId> &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()
|
void GxsForumThreadWidget::replytomessage()
|
||||||
{
|
{
|
||||||
if (groupId().isNull() || mThreadId.isNull()) {
|
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<RsGxsForumMsg> 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);
|
loadMsgData_ReplyMessage(req.mToken);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (req.mUserType == mTokenTypeBanAuthor) {
|
||||||
|
loadMsgData_BanAuthor(req.mToken);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GxsMessageFrameWidget::loadRequest(queue, req);
|
GxsMessageFrameWidget::loadRequest(queue, req);
|
||||||
|
|
|
@ -101,6 +101,7 @@ private slots:
|
||||||
void downloadAllFiles();
|
void downloadAllFiles();
|
||||||
|
|
||||||
void changedViewBox();
|
void changedViewBox();
|
||||||
|
void flagpersonasbad();
|
||||||
|
|
||||||
void filterColumnChanged(int column);
|
void filterColumnChanged(int column);
|
||||||
void filterItems(const QString &text);
|
void filterItems(const QString &text);
|
||||||
|
@ -140,6 +141,7 @@ private:
|
||||||
void loadMessageData(const uint32_t &token);
|
void loadMessageData(const uint32_t &token);
|
||||||
void requestMsgData_ReplyMessage(const RsGxsGrpMsgIdPair &msgId);
|
void requestMsgData_ReplyMessage(const RsGxsGrpMsgIdPair &msgId);
|
||||||
void loadMsgData_ReplyMessage(const uint32_t &token);
|
void loadMsgData_ReplyMessage(const uint32_t &token);
|
||||||
|
void loadMsgData_BanAuthor(const uint32_t &token);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RsGxsGroupId mLastForumID;
|
RsGxsGroupId mLastForumID;
|
||||||
|
@ -159,6 +161,7 @@ private:
|
||||||
uint32_t mTokenTypeInsertThreads;
|
uint32_t mTokenTypeInsertThreads;
|
||||||
uint32_t mTokenTypeMessageData;
|
uint32_t mTokenTypeMessageData;
|
||||||
uint32_t mTokenTypeReplyMessage;
|
uint32_t mTokenTypeReplyMessage;
|
||||||
|
uint32_t mTokenTypeBanAuthor;
|
||||||
|
|
||||||
/* Color definitions (for standard see qss.default) */
|
/* Color definitions (for standard see qss.default) */
|
||||||
QColor mTextColorRead;
|
QColor mTextColorRead;
|
||||||
|
|
|
@ -60,5 +60,6 @@
|
||||||
<file>icons/user-busy_64.png</file>
|
<file>icons/user-busy_64.png</file>
|
||||||
<file>icons/user-offline_64.png</file>
|
<file>icons/user-offline_64.png</file>
|
||||||
<file>icons/user-online_64.png</file>
|
<file>icons/user-online_64.png</file>
|
||||||
|
<file>icons/yellow_biohazard64.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
BIN
retroshare-gui/src/gui/icons/yellow_biohazard64.png
Normal file
BIN
retroshare-gui/src/gui/icons/yellow_biohazard64.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.9 KiB |
Loading…
Add table
Add a link
Reference in a new issue