mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-07-23 14:41:04 -04:00
Merging branches/v0.6-initdev into trunk.
These split at 6672 -> 7075, so quite a bit merge. libretroshare compiles - but untested. retroshare-gui needs GenCertDialog.ui and IdEditDialog.ui to be properly merged. (compile errors). some plugins will be broken. retroshare-nogui is untested. git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@7078 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
commit
c0738eec7f
407 changed files with 23716 additions and 50779 deletions
|
@ -136,14 +136,14 @@ bool p3BanList::recvBanItem(RsBanListItem *item)
|
|||
for(it = item->peerList.entries.begin(); it != item->peerList.entries.end(); it++)
|
||||
{
|
||||
// Order is important!.
|
||||
updated = (addBanEntry(item->PeerId(), it->addr, it->level,
|
||||
updated = (addBanEntry(item->PeerId(), it->addr.addr, it->level,
|
||||
it->reason, it->age) || updated);
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
|
||||
/* overloaded from pqiNetAssistSharePeer */
|
||||
void p3BanList::updatePeer(std::string /*id*/, struct sockaddr_in addr, int /*type*/, int /*reason*/, int age)
|
||||
void p3BanList::updatePeer(std::string /*id*/, const struct sockaddr_storage &addr, int /*type*/, int /*reason*/, int age)
|
||||
{
|
||||
std::string ownId = mLinkMgr->getOwnId();
|
||||
|
||||
|
@ -160,7 +160,7 @@ void p3BanList::updatePeer(std::string /*id*/, struct sockaddr_in addr, int /*ty
|
|||
}
|
||||
|
||||
|
||||
bool p3BanList::addBanEntry(const std::string &peerId, const struct sockaddr_in &addr, int level, uint32_t reason, uint32_t age)
|
||||
bool p3BanList::addBanEntry(const std::string &peerId, const struct sockaddr_storage &addr, int level, uint32_t reason, uint32_t age)
|
||||
{
|
||||
RsStackMutex stack(mBanMtx); /****** LOCKED MUTEX *******/
|
||||
|
||||
|
@ -174,10 +174,10 @@ bool p3BanList::addBanEntry(const std::string &peerId, const struct sockaddr_in
|
|||
#endif
|
||||
|
||||
/* Only Accept it - if external address */
|
||||
if (!isExternalNet(&(addr.sin_addr)))
|
||||
if (!sockaddr_storage_isExternalNet(addr))
|
||||
{
|
||||
#ifdef DEBUG_BANLIST
|
||||
std::cerr << "p3BanList::addBanEntry() Ignoring Non External Addr: " << rs_inet_ntoa(addr.sin_addr);
|
||||
std::cerr << "p3BanList::addBanEntry() Ignoring Non External Addr: " << sockaddr_storage_iptostring(addr);
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
|
@ -197,8 +197,14 @@ bool p3BanList::addBanEntry(const std::string &peerId, const struct sockaddr_in
|
|||
updated = true;
|
||||
}
|
||||
|
||||
std::map<uint32_t, BanListPeer>::iterator mit;
|
||||
mit = it->second.mBanPeers.find(addr.sin_addr.s_addr);
|
||||
// index is FAMILY + IP - the rest should be Zeros..
|
||||
struct sockaddr_storage bannedaddr;
|
||||
sockaddr_storage_clear(bannedaddr);
|
||||
sockaddr_storage_copyip(bannedaddr, addr);
|
||||
sockaddr_storage_setport(bannedaddr, 0);
|
||||
|
||||
std::map<struct sockaddr_storage, BanListPeer>::iterator mit;
|
||||
mit = it->second.mBanPeers.find(bannedaddr);
|
||||
if (mit == it->second.mBanPeers.end())
|
||||
{
|
||||
/* add in */
|
||||
|
@ -208,7 +214,8 @@ bool p3BanList::addBanEntry(const std::string &peerId, const struct sockaddr_in
|
|||
blp.level = level;
|
||||
blp.mTs = now - age;
|
||||
|
||||
it->second.mBanPeers[addr.sin_addr.s_addr] = blp;
|
||||
|
||||
it->second.mBanPeers[bannedaddr] = blp;
|
||||
it->second.mLastUpdate = now;
|
||||
updated = true;
|
||||
}
|
||||
|
@ -266,7 +273,7 @@ int p3BanList::condenseBanSources_locked()
|
|||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
std::map<uint32_t, BanListPeer>::const_iterator lit;
|
||||
std::map<struct sockaddr_storage, BanListPeer>::const_iterator lit;
|
||||
for(lit = it->second.mBanPeers.begin();
|
||||
lit != it->second.mBanPeers.end(); lit++)
|
||||
{
|
||||
|
@ -276,7 +283,7 @@ int p3BanList::condenseBanSources_locked()
|
|||
#ifdef DEBUG_BANLIST_CONDENSE
|
||||
std::cerr << "p3BanList::condenseBanSources_locked()";
|
||||
std::cerr << " Ignoring Out-Of-Date Entry for: ";
|
||||
std::cerr << rs_inet_ntoa(lit->second.addr.sin_addr);
|
||||
std::cerr << sockaddr_storage_iptostring(lit->second.addr);
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
continue;
|
||||
|
@ -289,19 +296,25 @@ int p3BanList::condenseBanSources_locked()
|
|||
lvl++;
|
||||
}
|
||||
|
||||
struct sockaddr_storage bannedaddr;
|
||||
sockaddr_storage_clear(bannedaddr);
|
||||
sockaddr_storage_copyip(bannedaddr, lit->second.addr);
|
||||
sockaddr_storage_setport(bannedaddr, 0);
|
||||
|
||||
|
||||
/* check if it exists in the Set already */
|
||||
std::map<uint32_t, BanListPeer>::iterator sit;
|
||||
sit = mBanSet.find(lit->second.addr.sin_addr.s_addr);
|
||||
std::map<struct sockaddr_storage, BanListPeer>::iterator sit;
|
||||
sit = mBanSet.find(bannedaddr);
|
||||
if ((sit == mBanSet.end()) || (lvl < sit->second.level))
|
||||
{
|
||||
BanListPeer bp = lit->second;
|
||||
bp.level = lvl;
|
||||
bp.addr.sin_port = 0;
|
||||
mBanSet[lit->second.addr.sin_addr.s_addr] = bp;
|
||||
sockaddr_storage_setport(bp.addr, 0);
|
||||
mBanSet[bannedaddr] = bp;
|
||||
#ifdef DEBUG_BANLIST_CONDENSE
|
||||
std::cerr << "p3BanList::condenseBanSources_locked()";
|
||||
std::cerr << " Added New Entry for: ";
|
||||
std::cerr << rs_inet_ntoa(lit->second.addr.sin_addr);
|
||||
std::cerr << sockaddr_storage_iptostring(bannedaddr);
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
@ -310,7 +323,7 @@ int p3BanList::condenseBanSources_locked()
|
|||
#ifdef DEBUG_BANLIST_CONDENSE
|
||||
std::cerr << "p3BanList::condenseBanSources_locked()";
|
||||
std::cerr << " Merging Info for: ";
|
||||
std::cerr << rs_inet_ntoa(lit->second.addr.sin_addr);
|
||||
std::cerr << sockaddr_storage_iptostring(bannedaddr);
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
/* update if necessary */
|
||||
|
@ -405,7 +418,7 @@ int p3BanList::sendBanSet(std::string peerid)
|
|||
|
||||
{
|
||||
RsStackMutex stack(mBanMtx); /****** LOCKED MUTEX *******/
|
||||
std::map<uint32_t, BanListPeer>::iterator it;
|
||||
std::map<struct sockaddr_storage, BanListPeer>::iterator it;
|
||||
for(it = mBanSet.begin(); it != mBanSet.end(); it++)
|
||||
{
|
||||
if (it->second.level >= RSBANLIST_SOURCE_FRIEND)
|
||||
|
@ -414,7 +427,7 @@ int p3BanList::sendBanSet(std::string peerid)
|
|||
}
|
||||
|
||||
RsTlvBanListEntry bi;
|
||||
bi.addr = it->second.addr;
|
||||
bi.addr.addr = it->second.addr;
|
||||
bi.reason = it->second.reason;
|
||||
bi.level = it->second.level;
|
||||
bi.age = now - it->second.mTs;
|
||||
|
@ -435,10 +448,10 @@ int p3BanList::printBanSet_locked(std::ostream &out)
|
|||
|
||||
time_t now = time(NULL);
|
||||
|
||||
std::map<uint32_t, BanListPeer>::iterator it;
|
||||
std::map<struct sockaddr_storage, BanListPeer>::iterator it;
|
||||
for(it = mBanSet.begin(); it != mBanSet.end(); it++)
|
||||
{
|
||||
out << "Ban: " << rs_inet_ntoa(it->second.addr.sin_addr);
|
||||
out << "Ban: " << sockaddr_storage_iptostring(it->second.addr);
|
||||
out << " Reason: " << it->second.reason;
|
||||
out << " Level: " << it->second.level;
|
||||
if (it->second.level > RSBANLIST_SOURCE_FRIEND)
|
||||
|
@ -465,12 +478,12 @@ int p3BanList::printBanSources_locked(std::ostream &out)
|
|||
out << " LastUpdate: " << now - it->second.mLastUpdate;
|
||||
out << std::endl;
|
||||
|
||||
std::map<uint32_t, BanListPeer>::const_iterator lit;
|
||||
std::map<struct sockaddr_storage, BanListPeer>::const_iterator lit;
|
||||
for(lit = it->second.mBanPeers.begin();
|
||||
lit != it->second.mBanPeers.end(); lit++)
|
||||
{
|
||||
out << "\t";
|
||||
out << "Ban: " << rs_inet_ntoa(lit->second.addr.sin_addr);
|
||||
out << "Ban: " << sockaddr_storage_iptostring(lit->second.addr);
|
||||
out << " Reason: " << lit->second.reason;
|
||||
out << " Level: " << lit->second.level;
|
||||
out << " Age: " << now - lit->second.mTs;
|
||||
|
|
|
@ -42,7 +42,7 @@ class BanListPeer
|
|||
{
|
||||
public:
|
||||
|
||||
struct sockaddr_in addr;
|
||||
struct sockaddr_storage addr;
|
||||
uint32_t reason; // Dup Self, Dup Friend
|
||||
int level; // LOCAL, FRIEND, FoF.
|
||||
time_t mTs;
|
||||
|
@ -54,7 +54,7 @@ class BanList
|
|||
|
||||
std::string mPeerId; /* from */
|
||||
time_t mLastUpdate;
|
||||
std::map<uint32_t, BanListPeer> mBanPeers;
|
||||
std::map<struct sockaddr_storage, BanListPeer> mBanPeers;
|
||||
};
|
||||
|
||||
|
||||
|
@ -74,7 +74,7 @@ class p3BanList: /* public RsBanList, */ public p3Service, public pqiNetAssistPe
|
|||
|
||||
/***** overloaded from pqiNetAssistPeerShare *****/
|
||||
|
||||
virtual void updatePeer(std::string id, struct sockaddr_in addr, int type, int reason, int age);
|
||||
virtual void updatePeer(std::string id, const struct sockaddr_storage &addr, int type, int reason, int age);
|
||||
|
||||
|
||||
/***** overloaded from p3Service *****/
|
||||
|
@ -93,7 +93,7 @@ class p3BanList: /* public RsBanList, */ public p3Service, public pqiNetAssistPe
|
|||
bool processIncoming();
|
||||
|
||||
bool recvBanItem(RsBanListItem *item);
|
||||
bool addBanEntry(const std::string &peerId, const struct sockaddr_in &addr,
|
||||
bool addBanEntry(const std::string &peerId, const struct sockaddr_storage &addr,
|
||||
int level, uint32_t reason, uint32_t age);
|
||||
void sendBanLists();
|
||||
int sendBanSet(std::string peerid);
|
||||
|
@ -123,7 +123,7 @@ class p3BanList: /* public RsBanList, */ public p3Service, public pqiNetAssistPe
|
|||
|
||||
time_t mSentListTime;
|
||||
std::map<std::string, BanList> mBanSources;
|
||||
std::map<uint32_t, BanListPeer> mBanSet;
|
||||
std::map<struct sockaddr_storage, BanListPeer> mBanSet;
|
||||
|
||||
p3LinkMgr *mLinkMgr;
|
||||
p3NetMgr *mNetMgr;
|
||||
|
|
|
@ -1,404 +0,0 @@
|
|||
/*
|
||||
* libretroshare/src/services: p3Blogs.cc
|
||||
*
|
||||
* RetroShare C++ Interface.
|
||||
*
|
||||
* Copyright 2008 by Robert Fernie.
|
||||
*
|
||||
* 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 "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#include "services/p3blogs.h"
|
||||
#include "util/rsdir.h"
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const BlogInfo &info)
|
||||
{
|
||||
std::string name(info.blogName.begin(), info.blogName.end());
|
||||
std::string desc(info.blogDesc.begin(), info.blogDesc.end());
|
||||
|
||||
out << "BlogInfo:";
|
||||
out << std::endl;
|
||||
out << "BlogId: " << info.blogId << std::endl;
|
||||
out << "BlogName: " << name << std::endl;
|
||||
out << "BlogDesc: " << desc << std::endl;
|
||||
out << "BlogFlags: " << info.blogFlags << std::endl;
|
||||
out << "Pop: " << info.pop << std::endl;
|
||||
out << "LastPost: " << info.lastPost << std::endl;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const BlogMsgSummary &info)
|
||||
{
|
||||
out << "BlogMsgSummary:";
|
||||
out << std::endl;
|
||||
out << "BlogId: " << info.blogId << std::endl;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const BlogMsgInfo &info)
|
||||
{
|
||||
out << "BlogMsgInfo:";
|
||||
out << std::endl;
|
||||
out << "BlogId: " << info.blogId << std::endl;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
RsBlogs *rsBlogs = NULL;
|
||||
|
||||
|
||||
/* Blogs will be initially stored for 1 year
|
||||
* remember 2^16 = 64K max units in store period.
|
||||
* PUBPERIOD * 2^16 = max STORE PERIOD */
|
||||
#define BLOG_STOREPERIOD (90*24*3600) /* 30 * 24 * 3600 - secs in a year */
|
||||
#define BLOG_PUBPERIOD 600 /* 10 minutes ... (max = 455 days) */
|
||||
|
||||
p3Blogs::p3Blogs(uint16_t type, CacheStrapper *cs,
|
||||
CacheTransfer *cft,
|
||||
std::string srcdir, std::string storedir)
|
||||
:p3GroupDistrib(type, cs, cft, srcdir, storedir, "",
|
||||
CONFIG_TYPE_QBLOG, BLOG_STOREPERIOD, BLOG_PUBPERIOD)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
p3Blogs::~p3Blogs()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/****************************************/
|
||||
|
||||
bool p3Blogs::blogsChanged(std::list<std::string> &blogIds)
|
||||
{
|
||||
return groupsChanged(blogIds);
|
||||
}
|
||||
|
||||
|
||||
bool p3Blogs::getBlogInfo(std::string cId, BlogInfo &ci)
|
||||
{
|
||||
RsStackMutex stack(distribMtx); /***** STACK LOCKED MUTEX *****/
|
||||
|
||||
/* extract details */
|
||||
GroupInfo *gi = locked_getGroupInfo(cId);
|
||||
|
||||
if (!gi)
|
||||
return false;
|
||||
|
||||
ci.blogId = gi->grpId;
|
||||
ci.blogName = gi->grpName;
|
||||
ci.blogDesc = gi->grpDesc;
|
||||
|
||||
ci.blogFlags = gi->flags;
|
||||
|
||||
ci.pop = gi->sources.size();
|
||||
ci.lastPost = gi->lastPost;
|
||||
|
||||
ci.pngChanImage = gi->grpIcon.pngImageData;
|
||||
|
||||
if(ci.pngChanImage != NULL)
|
||||
ci.pngImageLen = gi->grpIcon.imageSize;
|
||||
else
|
||||
ci.pngImageLen = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool p3Blogs::getBlogList(std::list<BlogInfo> &blogList)
|
||||
{
|
||||
std::list<std::string> grpIds;
|
||||
std::list<std::string>::iterator it;
|
||||
|
||||
getAllGroupList(grpIds);
|
||||
|
||||
for(it = grpIds.begin(); it != grpIds.end(); it++)
|
||||
{
|
||||
BlogInfo ci;
|
||||
if (getBlogInfo(*it, ci))
|
||||
{
|
||||
blogList.push_back(ci);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool p3Blogs::getBlogMsgList(std::string cId, std::list<BlogMsgSummary> &msgs)
|
||||
{
|
||||
std::list<std::string> msgIds;
|
||||
std::list<std::string>::iterator it;
|
||||
|
||||
getAllMsgList(cId, msgIds);
|
||||
|
||||
RsStackMutex stack(distribMtx); /***** STACK LOCKED MUTEX *****/
|
||||
for(it = msgIds.begin(); it != msgIds.end(); it++)
|
||||
{
|
||||
/* get details */
|
||||
RsDistribMsg *msg = locked_getGroupMsg(cId, *it);
|
||||
RsBlogMsg *cmsg = dynamic_cast<RsBlogMsg *>(msg);
|
||||
if (!cmsg)
|
||||
continue;
|
||||
|
||||
BlogMsgSummary tis;
|
||||
|
||||
tis.blogId = msg->grpId;
|
||||
tis.msgId = msg->msgId;
|
||||
tis.ts = msg->timestamp;
|
||||
|
||||
/* the rest must be gotten from the derived Msg */
|
||||
|
||||
tis.subject = cmsg->subject;
|
||||
tis.msg = cmsg->message;
|
||||
|
||||
msgs.push_back(tis);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3Blogs::getBlogMessage(std::string fId, std::string mId, BlogMsgInfo &info)
|
||||
{
|
||||
std::list<std::string> msgIds;
|
||||
std::list<std::string>::iterator it;
|
||||
|
||||
RsStackMutex stack(distribMtx); /***** STACK LOCKED MUTEX *****/
|
||||
|
||||
RsDistribMsg *msg = locked_getGroupMsg(fId, mId);
|
||||
RsBlogMsg *cmsg = dynamic_cast<RsBlogMsg *>(msg);
|
||||
if (!cmsg)
|
||||
return false;
|
||||
|
||||
|
||||
info.blogId = msg->grpId;
|
||||
info.msgId = msg->msgId;
|
||||
info.ts = msg->timestamp;
|
||||
|
||||
/* the rest must be gotten from the derived Msg */
|
||||
|
||||
info.subject = cmsg->subject;
|
||||
info.msg = cmsg->message;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3Blogs::BlogMessageSend(BlogMsgInfo &info)
|
||||
{
|
||||
|
||||
RsBlogMsg *cmsg = new RsBlogMsg();
|
||||
cmsg->grpId = info.blogId;
|
||||
|
||||
cmsg->subject = info.subject;
|
||||
cmsg->message = info.msg;
|
||||
cmsg->timestamp = time(NULL);
|
||||
|
||||
std::string msgId = publishMsg(cmsg, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3Blogs::BlogMessageReply(BlogMsgInfo& reply){
|
||||
|
||||
// ensure it has a value
|
||||
if(isReply(reply)){
|
||||
std::cerr << "p3Blogs::BlogMessageReply()" << " This is not a reply " << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// also check that msgId exists for group
|
||||
|
||||
return BlogMessageSend(reply);
|
||||
}
|
||||
|
||||
bool p3Blogs::isReply(BlogMsgInfo& info){
|
||||
|
||||
// if replies list is empty then this is not a reply to a blog
|
||||
return !info.msgIdReply.empty();
|
||||
}
|
||||
|
||||
std::string p3Blogs::createBlog(std::wstring blogName, std::wstring blogDesc, uint32_t blogFlags,
|
||||
unsigned char* pngImageData, uint32_t imageSize)
|
||||
{
|
||||
|
||||
std::string id = createGroup(blogName, blogDesc, blogFlags, pngImageData, imageSize);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
RsSerialType *p3Blogs::createSerialiser()
|
||||
{
|
||||
return new RsBlogSerialiser();
|
||||
}
|
||||
|
||||
bool p3Blogs::locked_checkDistribMsg(RsDistribMsg *msg)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
RsDistribGrp *p3Blogs::locked_createPublicDistribGrp(GroupInfo &info)
|
||||
{
|
||||
RsDistribGrp *grp = NULL; //new RsChannelGrp();
|
||||
|
||||
return grp;
|
||||
}
|
||||
|
||||
RsDistribGrp *p3Blogs::locked_createPrivateDistribGrp(GroupInfo &info)
|
||||
{
|
||||
RsDistribGrp *grp = NULL; //new RsChannelGrp();
|
||||
|
||||
return grp;
|
||||
}
|
||||
|
||||
|
||||
bool p3Blogs::blogSubscribe(std::string cId, bool subscribe)
|
||||
{
|
||||
std::cerr << "p3Blogs::channelSubscribe() ";
|
||||
std::cerr << cId;
|
||||
std::cerr << std::endl;
|
||||
|
||||
return subscribeToGroup(cId, subscribe);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************************/
|
||||
/****************** Event Feedback (Overloaded form p3distrib) *************************/
|
||||
/***************************************************************************************/
|
||||
/* only download in the first week of channel
|
||||
* older stuff can be manually downloaded.
|
||||
*/
|
||||
|
||||
const uint32_t DOWNLOAD_PERIOD = 7 * 24 * 3600;
|
||||
|
||||
/* This is called when we receive a msg, and also recalled
|
||||
*
|
||||
*/
|
||||
|
||||
bool p3Blogs::locked_eventDuplicateMsg(GroupInfo *grp, RsDistribMsg *msg, const std::string& id, bool historical)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3Blogs::locked_eventNewMsg(GroupInfo *grp, RsDistribMsg *msg, const std::string& id, bool historical)
|
||||
{
|
||||
std::string grpId = msg->grpId;
|
||||
std::string msgId = msg->msgId;
|
||||
std::string nullId;
|
||||
|
||||
std::cerr << "p3Blogs::locked_eventNewMsg() ";
|
||||
std::cerr << " grpId: " << grpId;
|
||||
std::cerr << " msgId: " << msgId;
|
||||
std::cerr << " peerId: " << id;
|
||||
std::cerr << std::endl;
|
||||
|
||||
if (!historical)
|
||||
{
|
||||
getPqiNotify()->AddFeedItem(RS_FEED_ITEM_BLOG_MSG, grpId, msgId, nullId);
|
||||
}
|
||||
|
||||
/* request the files
|
||||
* NB: This could result in duplicates.
|
||||
* which must be handled by ft side.
|
||||
*
|
||||
* this is exactly what DuplicateMsg does.
|
||||
* */
|
||||
return locked_eventDuplicateMsg(grp, msg, id, historical);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void p3Blogs::locked_notifyGroupChanged(GroupInfo &grp, uint32_t flags, bool historical)
|
||||
{
|
||||
std::string grpId = grp.grpId;
|
||||
std::string msgId;
|
||||
std::string nullId;
|
||||
|
||||
std::cerr << "p3Blogs::locked_notifyGroupChanged() ";
|
||||
std::cerr << grpId;
|
||||
std::cerr << " flags:" << flags;
|
||||
std::cerr << std::endl;
|
||||
|
||||
switch(flags)
|
||||
{
|
||||
case GRP_NEW_UPDATE:
|
||||
std::cerr << "p3Blogs::locked_notifyGroupChanged() NEW UPDATE";
|
||||
std::cerr << std::endl;
|
||||
if (!historical)
|
||||
{
|
||||
getPqiNotify()->AddFeedItem(RS_FEED_ITEM_BLOG_NEW, grpId, msgId, nullId);
|
||||
}
|
||||
break;
|
||||
case GRP_UPDATE:
|
||||
std::cerr << "p3Blogs::locked_notifyGroupChanged() UPDATE";
|
||||
std::cerr << std::endl;
|
||||
if (!historical)
|
||||
{
|
||||
getPqiNotify()->AddFeedItem(RS_FEED_ITEM_BLOG_UPDATE, grpId, msgId, nullId);
|
||||
}
|
||||
break;
|
||||
case GRP_LOAD_KEY:
|
||||
std::cerr << "p3Blogs::locked_notifyGroupChanged() LOAD_KEY";
|
||||
std::cerr << std::endl;
|
||||
break;
|
||||
case GRP_NEW_MSG:
|
||||
std::cerr << "p3Blogs::locked_notifyGroupChanged() NEW MSG";
|
||||
std::cerr << std::endl;
|
||||
break;
|
||||
case GRP_SUBSCRIBED:
|
||||
std::cerr << "p3Blogs::locked_notifyGroupChanged() SUBSCRIBED";
|
||||
std::cerr << std::endl;
|
||||
break;
|
||||
case GRP_UNSUBSCRIBED:
|
||||
std::cerr << "p3Blogs::locked_notifyGroupChanged() UNSUBSCRIBED";
|
||||
std::cerr << std::endl;
|
||||
|
||||
/* won't stop downloads... */
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
std::cerr << "p3Blogs::locked_notifyGroupChanged() Unknown DEFAULT";
|
||||
std::cerr << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
return p3GroupDistrib::locked_notifyGroupChanged(grp, flags);
|
||||
}
|
||||
|
||||
//TODO: if you want to enable config saving and loading implement this
|
||||
bool p3Blogs::childLoadList(std::list<RsItem* >& configSaves)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//TODO:
|
||||
std::list<RsItem *> p3Blogs::childSaveList()
|
||||
{
|
||||
std::list<RsItem *> saveL;
|
||||
|
||||
return saveL;
|
||||
}
|
||||
|
||||
/****************************************/
|
||||
|
||||
|
||||
|
|
@ -1,137 +0,0 @@
|
|||
#ifndef RS_P3_BLOGS_INTERFACE_H
|
||||
#define RS_P3_BLOGS_INTERFACE_H
|
||||
|
||||
/*
|
||||
* libretroshare/src/services: p3blogs.h
|
||||
*
|
||||
* RetroShare C++ Interface.
|
||||
*
|
||||
* Copyright 2008 by Robert Fernie.
|
||||
*
|
||||
* 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 "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#include "retroshare/rsblogs.h"
|
||||
#include "retroshare/rsfiles.h"
|
||||
#include "distrib/p3distrib.h"
|
||||
|
||||
#include "serialiser/rstlvtypes.h"
|
||||
#include "serialiser/rsblogitems.h"
|
||||
|
||||
/*!
|
||||
* implements the blog interface using the distrib service. it allows users to send blogs using
|
||||
* retroshare's cache service. its use
|
||||
*/
|
||||
class p3Blogs: public p3GroupDistrib, public RsBlogs
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* @param CacheStrapper needed to push blogs onto the cache service
|
||||
* @param CacheTransfer maintains distrib servi
|
||||
* @param srcdir
|
||||
* @param storedir
|
||||
*/
|
||||
p3Blogs(uint16_t type, CacheStrapper *cs, CacheTransfer *cft,
|
||||
std::string srcdir, std::string storedir);
|
||||
virtual ~p3Blogs();
|
||||
|
||||
/****************************************/
|
||||
/********* rsBlogs Interface ***********/
|
||||
|
||||
|
||||
/**
|
||||
* check if any of the blogs has been changed
|
||||
* @param blogIds list blogs by ids to be checked
|
||||
* @return false if changed and vice versa
|
||||
*/
|
||||
virtual bool blogsChanged(std::list<std::string> &blogIds);
|
||||
|
||||
/**
|
||||
* creates a new blog
|
||||
*/
|
||||
virtual std::string createBlog(std::wstring blogName, std::wstring blogDesc, uint32_t blogFlags,
|
||||
unsigned char* pngImageData, uint32_t imageSize);
|
||||
|
||||
/**
|
||||
* @param cId the id for the blog
|
||||
* @param BloogInfo blog information is stored here
|
||||
*/
|
||||
virtual bool getBlogInfo(std::string cId, BlogInfo &ci);
|
||||
|
||||
/**
|
||||
* get list of blogs from the group peer belongs to
|
||||
*/
|
||||
virtual bool getBlogList(std::list<BlogInfo> &blogList);
|
||||
|
||||
/**
|
||||
* Returns a list of all the messages sent
|
||||
* @param cId group id
|
||||
* @param msgs
|
||||
*/
|
||||
virtual bool getBlogMsgList(std::string cId, std::list<BlogMsgSummary> &msgs);
|
||||
virtual bool getBlogMessage(std::string cId, std::string mId, BlogMsgInfo &msg);
|
||||
|
||||
virtual bool BlogMessageSend(BlogMsgInfo &info);
|
||||
|
||||
/**
|
||||
* subscribes or unsubscribes peer to a blog message
|
||||
* @param cId the id of the blog message peer wants to subscribe
|
||||
* @param subscribe set to true to subscribe, false otherwise
|
||||
*/
|
||||
virtual bool blogSubscribe(std::string cId, bool subscribe);
|
||||
|
||||
|
||||
/**
|
||||
* send a reply to a blog msg, ensure msgIdReply has valid id to a message
|
||||
*/
|
||||
virtual bool BlogMessageReply(BlogMsgInfo &info);
|
||||
|
||||
/**
|
||||
* check if a particular blog is a reply
|
||||
* @return false if not a reply, true otherwise
|
||||
*/
|
||||
virtual bool isReply(BlogMsgInfo& info);
|
||||
|
||||
|
||||
/***************************************************************************************/
|
||||
/****************** Event Feedback (Overloaded form p3distrib) *************************/
|
||||
/***************************************************************************************/
|
||||
|
||||
protected:
|
||||
virtual void locked_notifyGroupChanged(GroupInfo &info, uint32_t flags, bool historical);
|
||||
virtual bool locked_eventNewMsg(GroupInfo *, RsDistribMsg *, const std::string&, bool historical);
|
||||
virtual bool locked_eventDuplicateMsg(GroupInfo *, RsDistribMsg *, const std::string&, bool historical);
|
||||
|
||||
|
||||
/****************************************/
|
||||
/********* Overloaded Functions *********/
|
||||
|
||||
virtual RsSerialType *createSerialiser();
|
||||
|
||||
virtual bool locked_checkDistribMsg(RsDistribMsg *msg);
|
||||
virtual RsDistribGrp *locked_createPublicDistribGrp(GroupInfo &info);
|
||||
virtual RsDistribGrp *locked_createPrivateDistribGrp(GroupInfo &info);
|
||||
virtual bool childLoadList(std::list<RsItem* >& configSaves);
|
||||
virtual std::list<RsItem *> childSaveList();
|
||||
/****************************************/
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load diff
|
@ -1,130 +0,0 @@
|
|||
#ifndef RS_P3_CHANNELS_INTERFACE_H
|
||||
#define RS_P3_CHANNELS_INTERFACE_H
|
||||
|
||||
/*
|
||||
* libretroshare/src/services: p3channels.h
|
||||
*
|
||||
* RetroShare C++ Interface.
|
||||
*
|
||||
* Copyright 2008 by Robert Fernie.
|
||||
*
|
||||
* 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 "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#include "retroshare/rschannels.h"
|
||||
#include "retroshare/rsfiles.h"
|
||||
#include "distrib/p3distrib.h"
|
||||
|
||||
#include "serialiser/rstlvtypes.h"
|
||||
#include "serialiser/rschannelitems.h"
|
||||
|
||||
#define RS_CHAN_STATUS_MASK 0x000f
|
||||
#define RS_CHAN_STATUS_AUTO_DL 0x0002
|
||||
|
||||
typedef std::map<std::string, uint32_t> statMap;
|
||||
typedef std::map<std::string, statMap> chanStatMap;
|
||||
|
||||
//! Channels is a distributed 'feed' service
|
||||
/*!
|
||||
* Implementations of rschannels interface
|
||||
* @see RsChannels for definition of implemented interface
|
||||
*/
|
||||
class p3Channels: public p3GroupDistrib, public RsChannels
|
||||
{
|
||||
public:
|
||||
|
||||
p3Channels(uint16_t type, CacheStrapper *cs, CacheTransfer *cft, RsFiles *files,
|
||||
std::string srcdir, std::string storedir, std::string channelsdir);
|
||||
virtual ~p3Channels();
|
||||
|
||||
/*!
|
||||
* cleans up dowloaded files older than one month,
|
||||
* should be called during shutdown of rs
|
||||
*/
|
||||
void cleanUpOldFiles();
|
||||
|
||||
/****************************************/
|
||||
/********* rsChannels Interface ***********/
|
||||
|
||||
virtual bool channelsChanged(std::list<std::string> &chanIds);
|
||||
|
||||
virtual std::string createChannel(std::wstring chanName, std::wstring chanDesc, uint32_t chanFlags,
|
||||
unsigned char* pngImageData, uint32_t size);
|
||||
|
||||
virtual bool getChannelInfo(const std::string &cId, ChannelInfo &ci);
|
||||
virtual bool getChannelList(std::list<ChannelInfo> &chanList);
|
||||
virtual bool getChannelMsgList(const std::string &cId, std::list<ChannelMsgSummary> &msgs);
|
||||
virtual bool getChannelMessage(const std::string &cId, const std::string &mId, ChannelMsgInfo &msg);
|
||||
|
||||
virtual bool ChannelMessageSend(ChannelMsgInfo &info);
|
||||
virtual bool setMessageStatus(const std::string& cId, const std::string& mId, const uint32_t status, const uint32_t statusMask);
|
||||
virtual bool getMessageStatus(const std::string& cId, const std::string& mId, uint32_t& status);
|
||||
|
||||
virtual bool getMessageCount(const std::string &cId, unsigned int &newCount, unsigned int &unreadCount);
|
||||
virtual bool channelSubscribe(const std::string &cId, bool subscribe, bool autoDl);
|
||||
virtual bool channelExtraFileHash(const std::string &path, const std::string &chId, FileInfo& fInfo);
|
||||
virtual bool channelExtraFileRemove(const std::string &hash, const std::string &chId);
|
||||
virtual bool channelRestoreKeys(const std::string &chId);
|
||||
virtual bool channelShareKeys(const std::string &chId, std::list<std::string>& peers);
|
||||
virtual bool channelEditInfo(const std::string &chId, ChannelInfo &ci);
|
||||
virtual void getPubKeysAvailableGrpIds(std::list<std::string>& grpIds);
|
||||
virtual bool channelSetAutoDl(const std::string& chId, bool autoDl);
|
||||
virtual bool channelGetAutoDl(const std::string& chId, bool& autoDl);
|
||||
virtual bool channelSetDestinationDirectory(const std::string& chId,const std::string& dest_dir) ;
|
||||
|
||||
/***************************************************************************************/
|
||||
/****************** Event Feedback (Overloaded form p3distrib) *************************/
|
||||
/***************************************************************************************/
|
||||
|
||||
protected:
|
||||
virtual void locked_notifyGroupChanged(GroupInfo &info, uint32_t flags, bool historical);
|
||||
virtual bool locked_eventNewMsg(GroupInfo *, RsDistribMsg *, const std::string&, bool historical);
|
||||
virtual bool locked_eventDuplicateMsg(GroupInfo *, RsDistribMsg *, const std::string&, bool historical);
|
||||
|
||||
|
||||
/****************************************/
|
||||
/********* Overloaded Functions *********/
|
||||
|
||||
virtual RsSerialType *createSerialiser();
|
||||
|
||||
virtual bool locked_checkDistribMsg(RsDistribMsg *msg);
|
||||
|
||||
virtual bool childLoadList(std::list<RsItem* >& configSaves);
|
||||
virtual std::list<RsItem *> childSaveList();
|
||||
|
||||
|
||||
/****************************************/
|
||||
|
||||
private:
|
||||
|
||||
void processChanReadStatus(RsChannelReadStatus* drs);
|
||||
void addChannelReadStatusEntry(const std::string& cId);
|
||||
void removeChannelReadStatusEntry(const std::string& cId);
|
||||
RsFiles *mRsFiles;
|
||||
std::string mChannelsDir;
|
||||
std::list<RsItem *> saveList;
|
||||
|
||||
std::list<RsChannelReadStatus *> mReadStatus;
|
||||
|
||||
chanStatMap mMsgReadStatus;
|
||||
statMap mChannelStatus;
|
||||
std::map<std::string,std::string> mDestinationDirectories ;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -128,8 +128,8 @@ int p3ChatService::tick()
|
|||
if (visible_lobbies_tmp.size()==0){
|
||||
last_req_chat_lobby_list = now-LOBBY_LIST_AUTO_UPDATE_TIME+MIN_DELAY_BETWEEN_PUBLIC_LOBBY_REQ;
|
||||
} else {
|
||||
last_req_chat_lobby_list = now ;
|
||||
}
|
||||
last_req_chat_lobby_list = now ;
|
||||
}
|
||||
}
|
||||
|
||||
// Flush items that could not be sent, probably because of a Mutex protected zone.
|
||||
|
@ -149,7 +149,7 @@ int p3ChatService::status()
|
|||
|
||||
/***************** Chat Stuff **********************/
|
||||
|
||||
int p3ChatService::sendPublicChat(const std::wstring &msg)
|
||||
int p3ChatService::sendPublicChat(const std::string &msg)
|
||||
{
|
||||
/* go through all the peers */
|
||||
|
||||
|
@ -468,7 +468,7 @@ bool p3ChatService::isOnline(const std::string& id)
|
|||
return true ;
|
||||
}
|
||||
|
||||
bool p3ChatService::sendPrivateChat(const std::string &id, const std::wstring &msg)
|
||||
bool p3ChatService::sendPrivateChat(const std::string &id, const std::string &msg)
|
||||
{
|
||||
// look into ID. Is it a peer, or a chat lobby?
|
||||
|
||||
|
@ -627,7 +627,7 @@ bool p3ChatService::locked_checkAndRebuildPartialMessage(RsChatLobbyMsgItem *ci)
|
|||
if(it != _pendingPartialLobbyMessages.end())
|
||||
{
|
||||
#ifdef CHAT_DEBUG
|
||||
std::cerr << " Pending message found. Aappending it." << std::endl;
|
||||
std::cerr << " Pending message found. Appending it." << std::endl;
|
||||
#endif
|
||||
// Yes, there is. Add the item to the list of stored sub-items
|
||||
|
||||
|
@ -651,7 +651,7 @@ bool p3ChatService::locked_checkAndRebuildPartialMessage(RsChatLobbyMsgItem *ci)
|
|||
#ifdef CHAT_DEBUG
|
||||
std::cerr << " Message is complete ! Re-forming it and returning true." << std::endl;
|
||||
#endif
|
||||
std::wstring msg ;
|
||||
std::string msg ;
|
||||
uint32_t flags = 0 ;
|
||||
|
||||
for(uint32_t i=0;i<it->second.size();++i)
|
||||
|
@ -705,6 +705,7 @@ void p3ChatService::receiveChatQueue()
|
|||
while(NULL != (item=recvItem()))
|
||||
handleIncomingItem(item) ;
|
||||
}
|
||||
|
||||
class MsgCounter
|
||||
{
|
||||
public:
|
||||
|
@ -809,7 +810,6 @@ void p3ChatService::handleIncomingItem(RsItem *item)
|
|||
case RS_PKT_SUBTYPE_CHAT_LOBBY_UNSUBSCRIBE: handleFriendUnsubscribeLobby (dynamic_cast<RsChatLobbyUnsubscribeItem *>(item)) ; break ;
|
||||
case RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_REQUEST: handleRecvChatLobbyListRequest(dynamic_cast<RsChatLobbyListRequestItem *>(item)) ; break ;
|
||||
case RS_PKT_SUBTYPE_CHAT_LOBBY_LIST: handleRecvChatLobbyList (dynamic_cast<RsChatLobbyListItem *>(item)) ; break ;
|
||||
case RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_deprecated: handleRecvChatLobbyList (dynamic_cast<RsChatLobbyListItem_deprecated *>(item)) ; break ;
|
||||
|
||||
default:
|
||||
{
|
||||
|
@ -870,96 +870,8 @@ void p3ChatService::handleRecvChatLobbyListRequest(RsChatLobbyListRequestItem *c
|
|||
std::cerr << " Sending list to " << clr->PeerId() << std::endl;
|
||||
#endif
|
||||
sendItem(item);
|
||||
|
||||
// *********** Also send an item in old formats. To be removed.
|
||||
|
||||
RsChatLobbyListItem_deprecated *itemd = new RsChatLobbyListItem_deprecated;
|
||||
RsChatLobbyListItem_deprecated2 *itemd2 = new RsChatLobbyListItem_deprecated2;
|
||||
|
||||
for(uint32_t i=0;i<item->lobby_ids.size();++i)
|
||||
if(item->lobby_privacy_levels[i] == RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC)
|
||||
{
|
||||
itemd->lobby_ids.push_back(item->lobby_ids[i]) ;
|
||||
itemd->lobby_names.push_back(item->lobby_names[i]) ;
|
||||
itemd->lobby_counts.push_back(item->lobby_counts[i]) ;
|
||||
|
||||
itemd2->lobby_ids.push_back(item->lobby_ids[i]) ;
|
||||
itemd2->lobby_names.push_back(item->lobby_names[i]) ;
|
||||
itemd2->lobby_counts.push_back(item->lobby_counts[i]) ;
|
||||
itemd2->lobby_topics.push_back(item->lobby_topics[i]) ;
|
||||
}
|
||||
|
||||
itemd->PeerId(clr->PeerId()) ;
|
||||
itemd2->PeerId(clr->PeerId()) ;
|
||||
|
||||
sendItem(itemd) ;
|
||||
sendItem(itemd2) ;
|
||||
|
||||
// End of part to remove in future versions. *************
|
||||
}
|
||||
void p3ChatService::handleRecvChatLobbyList(RsChatLobbyListItem_deprecated *item)
|
||||
{
|
||||
if(item->lobby_ids.size() > MAX_ALLOWED_LOBBIES_IN_LIST_WARNING)
|
||||
std::cerr << "Warning: Peer " << item->PeerId() << "(" << rsPeers->getPeerName(item->PeerId()) << ") is sending a lobby list of " << item->lobby_ids.size() << " lobbies. This is unusual, and probably a attempt to crash you." << std::endl;
|
||||
|
||||
{
|
||||
time_t now = time(NULL) ;
|
||||
|
||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
for(uint32_t i=0;i<item->lobby_ids.size() && i < MAX_ALLOWED_LOBBIES_IN_LIST_WARNING;++i)
|
||||
{
|
||||
VisibleChatLobbyRecord& rec(_visible_lobbies[item->lobby_ids[i]]) ;
|
||||
|
||||
rec.lobby_id = item->lobby_ids[i] ;
|
||||
rec.lobby_name = item->lobby_names[i] ;
|
||||
rec.participating_friends.insert(item->PeerId()) ;
|
||||
|
||||
if(_should_reset_lobby_counts)
|
||||
rec.total_number_of_peers = item->lobby_counts[i] ;
|
||||
else
|
||||
rec.total_number_of_peers = std::max(rec.total_number_of_peers,item->lobby_counts[i]) ;
|
||||
|
||||
rec.last_report_time = now ;
|
||||
rec.lobby_privacy_level = RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC ;
|
||||
}
|
||||
}
|
||||
|
||||
RsServer::notify()->notifyListChange(NOTIFY_LIST_CHAT_LOBBY_LIST, NOTIFY_TYPE_ADD) ;
|
||||
_should_reset_lobby_counts = false ;
|
||||
}
|
||||
void p3ChatService::handleRecvChatLobbyList(RsChatLobbyListItem_deprecated2 *item)
|
||||
{
|
||||
if(item->lobby_ids.size() > MAX_ALLOWED_LOBBIES_IN_LIST_WARNING)
|
||||
std::cerr << "Warning: Peer " << item->PeerId() << "(" << rsPeers->getPeerName(item->PeerId()) << ") is sending a lobby list of " << item->lobby_ids.size() << " lobbies. This is unusual, and probably a attempt to crash you." << std::endl;
|
||||
|
||||
{
|
||||
time_t now = time(NULL) ;
|
||||
|
||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
for(uint32_t i=0;i<item->lobby_ids.size() && i < MAX_ALLOWED_LOBBIES_IN_LIST_WARNING;++i)
|
||||
{
|
||||
VisibleChatLobbyRecord& rec(_visible_lobbies[item->lobby_ids[i]]) ;
|
||||
|
||||
rec.lobby_id = item->lobby_ids[i] ;
|
||||
rec.lobby_name = item->lobby_names[i] ;
|
||||
rec.lobby_topic = item->lobby_topics[i] ;
|
||||
rec.participating_friends.insert(item->PeerId()) ;
|
||||
|
||||
if(_should_reset_lobby_counts)
|
||||
rec.total_number_of_peers = item->lobby_counts[i] ;
|
||||
else
|
||||
rec.total_number_of_peers = std::max(rec.total_number_of_peers,item->lobby_counts[i]) ;
|
||||
|
||||
rec.last_report_time = now ;
|
||||
rec.lobby_privacy_level = RS_CHAT_LOBBY_PRIVACY_LEVEL_PUBLIC ;
|
||||
}
|
||||
}
|
||||
|
||||
RsServer::notify()->notifyListChange(NOTIFY_LIST_CHAT_LOBBY_LIST, NOTIFY_TYPE_ADD) ;
|
||||
_should_reset_lobby_counts = false ;
|
||||
}
|
||||
void p3ChatService::handleRecvChatLobbyList(RsChatLobbyListItem *item)
|
||||
{
|
||||
if(item->lobby_ids.size() > MAX_ALLOWED_LOBBIES_IN_LIST_WARNING)
|
||||
|
@ -1175,10 +1087,9 @@ bool p3ChatService::checkForMessageSecurity(RsChatMsgItem *ci)
|
|||
// Remove too big messages
|
||||
if (ci->message.length() > 6000 && (ci->chatFlags & RS_CHAT_FLAG_LOBBY))
|
||||
{
|
||||
wchar_t tmp[300];
|
||||
mbstowcs(tmp, rsPeers->getPeerName(ci->PeerId()).c_str(), 299);
|
||||
|
||||
ci->message = std::wstring(L"**** Security warning: Message bigger than 6000 characters, forwarded to you by ") + tmp + L", dropped. ****";
|
||||
ci->message = "**** Security warning: Message bigger than 6000 characters, forwarded to you by ";
|
||||
ci->message += rsPeers->getPeerName(ci->PeerId());
|
||||
ci->message += ", dropped. ****";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1212,23 +1123,18 @@ bool p3ChatService::checkForMessageSecurity(RsChatMsgItem *ci)
|
|||
// https://en.wikipedia.org/wiki/Billion_laughs
|
||||
// This should be done for all incoming HTML messages (also in forums
|
||||
// etc.) so this should be a function in some other file.
|
||||
wchar_t tmp[10];
|
||||
mbstowcs(tmp, "<!", 9);
|
||||
|
||||
if (ci->message.find(tmp) != std::string::npos)
|
||||
if (ci->message.find("<!") != std::string::npos)
|
||||
{
|
||||
// Drop any message with "<!doctype" or "<!entity"...
|
||||
// TODO: check what happens with partial messages
|
||||
//
|
||||
std::wcout << "handleRecvChatMsgItem: " << ci->message << std::endl;
|
||||
std::wcout << "**********" << std::endl;
|
||||
std::wcout << "********** entity attack by " << ci->PeerId().c_str() << std::endl;
|
||||
std::wcout << "**********" << std::endl;
|
||||
std::cout << "handleRecvChatMsgItem: " << ci->message << std::endl;
|
||||
std::cout << "**********" << std::endl;
|
||||
std::cout << "********** entity attack by " << ci->PeerId().c_str() << std::endl;
|
||||
std::cout << "**********" << std::endl;
|
||||
|
||||
wchar_t tmp2[300];
|
||||
mbstowcs(tmp2, rsPeers->getPeerName(ci->PeerId()).c_str(), 299);
|
||||
|
||||
ci->message = std::wstring(L"**** This message (from peer id ") + tmp2 + L") has been removed because it contains the string \"<!\".****" ;
|
||||
ci->message = "**** This message (from peer id " + rsPeers->getPeerName(ci->PeerId()) + ") has been removed because it contains the string \"<!\".****" ;
|
||||
return false;
|
||||
}
|
||||
// For a future whitelist:
|
||||
|
@ -1365,8 +1271,9 @@ bool p3ChatService::handleRecvChatMsgItem(RsChatMsgItem *ci)
|
|||
ci->chatFlags |= RS_CHAT_FLAG_AVATAR_AVAILABLE ;
|
||||
}
|
||||
|
||||
std::string message;
|
||||
librs::util::ConvertUtf16ToUtf8(ci->message, message);
|
||||
std::string message = ci->message;
|
||||
//librs::util::ConvertUtf16ToUtf8(ci->message, message);
|
||||
|
||||
if (ci->chatFlags & RS_CHAT_FLAG_PRIVATE) {
|
||||
/* notify private chat message */
|
||||
RsServer::notify()->AddPopupMessage(popupChatFlag, ci->PeerId(), name, message);
|
||||
|
@ -1910,7 +1817,7 @@ void p3ChatService::sendAvatarJpegData(const std::string& peer_id)
|
|||
RsChatAvatarItem *ci = makeOwnAvatarItem();
|
||||
ci->PeerId(peer_id);
|
||||
|
||||
// take avatar, and embed it into a std::wstring.
|
||||
// take avatar, and embed it into a std::string.
|
||||
//
|
||||
#ifdef CHAT_DEBUG
|
||||
std::cerr << "p3ChatService::sending avatar image to peer" << peer_id << ", image size = " << ci->image_size << std::endl ;
|
||||
|
@ -2374,7 +2281,7 @@ bool p3ChatService::locked_initLobbyBouncableObject(const ChatLobbyId& lobby_id,
|
|||
return true ;
|
||||
}
|
||||
|
||||
bool p3ChatService::sendLobbyChat(const std::string &id, const std::wstring& msg, const ChatLobbyId& lobby_id)
|
||||
bool p3ChatService::sendLobbyChat(const std::string &id, const std::string& msg, const ChatLobbyId& lobby_id)
|
||||
{
|
||||
#ifdef CHAT_DEBUG
|
||||
std::cerr << "Sending chat lobby message to lobby " << std::hex << lobby_id << std::dec << std::endl;
|
||||
|
@ -2697,7 +2604,7 @@ bool p3ChatService::acceptLobbyInvite(const ChatLobbyId& lobby_id)
|
|||
item->lobby_id = entry.lobby_id ;
|
||||
item->msg_id = 0 ;
|
||||
item->nick = "Lobby management" ;
|
||||
item->message = std::wstring(L"Welcome to chat lobby") ;
|
||||
item->message = std::string("Welcome to chat lobby") ;
|
||||
item->PeerId(entry.virtual_peer_id) ;
|
||||
item->chatFlags = RS_CHAT_FLAG_PRIVATE | RS_CHAT_FLAG_LOBBY ;
|
||||
|
||||
|
|
|
@ -70,14 +70,14 @@ class p3ChatService: public p3Service, public p3Config, public pqiMonitor, publi
|
|||
/*!
|
||||
* public chat sent to all peers
|
||||
*/
|
||||
int sendPublicChat(const std::wstring &msg);
|
||||
int sendPublicChat(const std::string &msg);
|
||||
|
||||
/********* RsMsgs ***********/
|
||||
/*!
|
||||
* chat is sent to specifc peer
|
||||
* @param id peer to send chat msg to
|
||||
*/
|
||||
bool sendPrivateChat(const std::string &id, const std::wstring &msg);
|
||||
bool sendPrivateChat(const std::string &id, const std::string &msg);
|
||||
|
||||
/*!
|
||||
* can be used to send 'immediate' status msgs, these status updates are meant for immediate use by peer (not saved by rs)
|
||||
|
@ -226,8 +226,6 @@ class p3ChatService: public p3Service, public p3Config, public pqiMonitor, publi
|
|||
void handleRecvChatAvatarItem(RsChatAvatarItem *item) ;
|
||||
void handleRecvChatLobbyListRequest(RsChatLobbyListRequestItem *item) ;
|
||||
void handleRecvChatLobbyList(RsChatLobbyListItem *item) ;
|
||||
void handleRecvChatLobbyList(RsChatLobbyListItem_deprecated *item) ;
|
||||
void handleRecvChatLobbyList(RsChatLobbyListItem_deprecated2 *item) ;
|
||||
void handleRecvChatLobbyEventItem(RsChatLobbyEventItem *item) ;
|
||||
|
||||
/// Checks that the lobby object is not flooding a lobby.
|
||||
|
@ -249,7 +247,7 @@ class p3ChatService: public p3Service, public p3Config, public pqiMonitor, publi
|
|||
|
||||
/// receive and handle chat lobby item
|
||||
bool recvLobbyChat(RsChatLobbyMsgItem*,const std::string& src_peer_id) ;
|
||||
bool sendLobbyChat(const std::string &id, const std::wstring&, const ChatLobbyId&) ;
|
||||
bool sendLobbyChat(const std::string &id, const std::string&, const ChatLobbyId&) ;
|
||||
void handleRecvLobbyInvite(RsChatLobbyInviteItem*) ;
|
||||
void checkAndRedirectMsgToLobby(RsChatMsgItem*) ;
|
||||
void handleConnectionChallenge(RsChatLobbyConnectChallengeItem *item) ;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,178 +0,0 @@
|
|||
/*
|
||||
* libretroshare/src/services: p3disc.h
|
||||
*
|
||||
* Services for RetroShare.
|
||||
*
|
||||
* Copyright 2004-2008 by Robert Fernie.
|
||||
*
|
||||
* 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 "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MRK_PQI_AUTODISC_H
|
||||
#define MRK_PQI_AUTODISC_H
|
||||
|
||||
// The AutoDiscovery Class
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
|
||||
// system specific network headers
|
||||
#include "pqi/pqinetwork.h"
|
||||
|
||||
#include "pqi/pqi.h"
|
||||
#include "pqi/pqipersongrp.h"
|
||||
|
||||
class p3ConnectMgr;
|
||||
|
||||
#include "pqi/pqimonitor.h"
|
||||
#include "serialiser/rsdiscitems.h"
|
||||
#include "services/p3service.h"
|
||||
#include "pqi/authgpg.h"
|
||||
|
||||
class autoserver
|
||||
{
|
||||
public:
|
||||
autoserver()
|
||||
:ts(0), discFlags(0) { return;}
|
||||
|
||||
std::string id;
|
||||
struct sockaddr_in localAddr;
|
||||
struct sockaddr_in remoteAddr;
|
||||
|
||||
time_t ts;
|
||||
uint32_t discFlags;
|
||||
};
|
||||
|
||||
|
||||
class autoneighbour: public autoserver
|
||||
{
|
||||
public:
|
||||
autoneighbour()
|
||||
:autoserver(), authoritative(false) {}
|
||||
|
||||
bool authoritative;
|
||||
bool validAddrs;
|
||||
|
||||
std::map<std::string, autoserver> neighbour_of;
|
||||
|
||||
};
|
||||
|
||||
class p3PeerMgr;
|
||||
class p3LinkMgr;
|
||||
class p3NetMgr;
|
||||
|
||||
|
||||
class p3disc: public p3Service, public pqiMonitor, public p3Config, public AuthGPGService
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
p3disc(p3PeerMgr *pm, p3LinkMgr *lm, p3NetMgr *nm, pqipersongrp *persGrp);
|
||||
|
||||
/************* from pqiMonitor *******************/
|
||||
virtual void statusChange(const std::list<pqipeer> &plist);
|
||||
/************* from pqiMonitor *******************/
|
||||
|
||||
int tick();
|
||||
|
||||
/* GUI requires access */
|
||||
bool potentialGPGproxies(const std::string& id, std::list<std::string> &proxyGPGIds);
|
||||
bool potentialproxies(const std::string& id, std::list<std::string> &proxyIds);
|
||||
void getversions(std::map<std::string, std::string> &versions);
|
||||
void getWaitingDiscCount(unsigned int *sendCount, unsigned int *recvCount);
|
||||
|
||||
/************* from AuthGPService ****************/
|
||||
virtual AuthGPGOperation *getGPGOperation();
|
||||
virtual void setGPGOperation(AuthGPGOperation *operation);
|
||||
|
||||
protected:
|
||||
/*****************************************************************/
|
||||
/*********************** p3config ******************************/
|
||||
/* Key Functions to be overloaded for Full Configuration */
|
||||
virtual RsSerialiser *setupSerialiser();
|
||||
virtual bool saveList(bool &cleanup, std::list<RsItem *>&);
|
||||
virtual bool loadList(std::list<RsItem *>& load);
|
||||
/*****************************************************************/
|
||||
|
||||
private:
|
||||
|
||||
|
||||
void sendAllInfoToJustConnectedPeer(const std::string &id);
|
||||
void sendJustConnectedPeerInfoToAllPeer(const std::string &id);
|
||||
|
||||
/* Network Output */
|
||||
//void sendOwnDetails(std::string to);
|
||||
void sendOwnVersion(std::string to);
|
||||
RsDiscReply *createDiscReply(const std::string &to, const std::string &about);
|
||||
//void sendPeerIssuer(std::string to, std::string about);
|
||||
void sendHeartbeat(std::string to);
|
||||
void askInfoToAllPeers(std::string about);
|
||||
|
||||
/* Network Input */
|
||||
int handleIncoming();
|
||||
void recvAskInfo(RsDiscAskInfo *item);
|
||||
void recvPeerDetails(RsDiscReply *item, const std::string &certGpgId);
|
||||
//void recvPeerIssuerMsg(RsDiscIssuer *item);
|
||||
void recvPeerVersionMsg(RsDiscVersion *item);
|
||||
void recvHeartbeatMsg(RsDiscHeartbeat *item);
|
||||
void recvDiscReply(RsDiscReply *dri);
|
||||
|
||||
void removeFriend(std::string ssl_id); //keep tracks of removed friend so we're not gonna add them again immediately
|
||||
|
||||
/* handle network shape */
|
||||
int addDiscoveryData(const std::string& fromId, const std::string& aboutId,
|
||||
const std::string& fromGPGId,const std::string& aboutGPGId,
|
||||
const struct sockaddr_in& laddr, const struct sockaddr_in& raddr,
|
||||
uint32_t flags, time_t ts,bool& new_info);
|
||||
|
||||
//int idServers();
|
||||
|
||||
private:
|
||||
|
||||
p3PeerMgr *mPeerMgr;
|
||||
p3LinkMgr *mLinkMgr;
|
||||
p3NetMgr *mNetMgr;
|
||||
|
||||
pqipersongrp *mPqiPersonGrp;
|
||||
|
||||
/* data */
|
||||
RsMutex mDiscMtx;
|
||||
|
||||
time_t mLastSentHeartbeatTime;
|
||||
bool mDiscEnabled;
|
||||
|
||||
//std::map<std::string, time_t> deletedSSLFriendsIds;
|
||||
|
||||
|
||||
std::map<std::string, std::list<std::string> > mSendIdList;
|
||||
std::list<RsDiscReply*> mPendingDiscReplyInList;
|
||||
|
||||
// Neighbors at the gpg level.
|
||||
std::map<std::string,std::set<std::string> > gpg_neighbors ;
|
||||
|
||||
// Original mapping.
|
||||
std::map<std::string, autoneighbour> neighbours;
|
||||
|
||||
// Rs Version.
|
||||
std::map<std::string, std::string> versions;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // MRK_PQI_AUTODISC_H
|
1281
libretroshare/src/services/p3discovery2.cc
Normal file
1281
libretroshare/src/services/p3discovery2.cc
Normal file
File diff suppressed because it is too large
Load diff
151
libretroshare/src/services/p3discovery2.h
Normal file
151
libretroshare/src/services/p3discovery2.h
Normal file
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* libretroshare/src/services: p3discovery2.h
|
||||
*
|
||||
* Services for RetroShare.
|
||||
*
|
||||
* Copyright 2004-2013 by Robert Fernie.
|
||||
*
|
||||
* 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.1 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 "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MRK_SERVICES_DISCOVERY2_H
|
||||
#define MRK_SERVICES_DISCOVERY2_H
|
||||
|
||||
// Discovery2: Improved discovery service.
|
||||
|
||||
#include "retroshare/rsdisc.h"
|
||||
|
||||
#include "pqi/p3peermgr.h"
|
||||
#include "pqi/p3linkmgr.h"
|
||||
#include "pqi/p3netmgr.h"
|
||||
|
||||
#include "pqi/pqimonitor.h"
|
||||
#include "serialiser/rsdiscovery2items.h"
|
||||
#include "services/p3service.h"
|
||||
#include "pqi/authgpg.h"
|
||||
|
||||
|
||||
|
||||
typedef std::string PGPID;
|
||||
typedef std::string SSLID;
|
||||
|
||||
class DiscSslInfo
|
||||
{
|
||||
public:
|
||||
DiscSslInfo() { mDiscStatus = 0; }
|
||||
uint16_t mDiscStatus;
|
||||
};
|
||||
|
||||
class DiscPeerInfo
|
||||
{
|
||||
public:
|
||||
DiscPeerInfo() {}
|
||||
|
||||
std::string mVersion;
|
||||
//uint32_t mStatus;
|
||||
};
|
||||
|
||||
class DiscPgpInfo
|
||||
{
|
||||
public:
|
||||
DiscPgpInfo() {}
|
||||
|
||||
void mergeFriendList(const std::list<PGPID> &friends);
|
||||
|
||||
//PGPID mPgpId;
|
||||
std::set<PGPID> mFriendSet;
|
||||
std::map<SSLID, DiscSslInfo> mSslIds;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class p3discovery2: public RsDisc, public p3Service, public pqiMonitor, public AuthGPGService
|
||||
{
|
||||
public:
|
||||
|
||||
p3discovery2(p3PeerMgr *peerMgr, p3LinkMgr *linkMgr, p3NetMgr *netMgr);
|
||||
virtual ~p3discovery2();
|
||||
|
||||
/************* from pqiMonitor *******************/
|
||||
virtual void statusChange(const std::list<pqipeer> &plist);
|
||||
/************* from pqiMonitor *******************/
|
||||
|
||||
int tick();
|
||||
|
||||
/* external interface */
|
||||
virtual bool getDiscFriends(const std::string &id, std::list<std::string> &friends);
|
||||
virtual bool getDiscPgpFriends(const std::string &pgpid, std::list<std::string> &gpg_friends);
|
||||
virtual bool getPeerVersion(const std::string &id, std::string &version);
|
||||
virtual bool getWaitingDiscCount(unsigned int *sendCount, unsigned int *recvCount);
|
||||
|
||||
/************* from AuthGPService ****************/
|
||||
virtual AuthGPGOperation *getGPGOperation();
|
||||
virtual void setGPGOperation(AuthGPGOperation *operation);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
PGPID getPGPId(const SSLID &id);
|
||||
|
||||
int handleIncoming();
|
||||
void updatePgpFriendList();
|
||||
|
||||
void addFriend(const SSLID &sslId);
|
||||
void removeFriend(const SSLID &sslId);
|
||||
|
||||
void updatePeerAddresses(const RsDiscContactItem *item);
|
||||
void updatePeerAddressList(const RsDiscContactItem *item);
|
||||
|
||||
void sendOwnContactInfo(const SSLID &sslid);
|
||||
void recvOwnContactInfo(const SSLID &fromId, const RsDiscContactItem *item);
|
||||
|
||||
void sendPGPList(const SSLID &toId);
|
||||
void processPGPList(const SSLID &fromId, const RsDiscPgpListItem *item);
|
||||
|
||||
void processContactInfo(const SSLID &fromId, const RsDiscContactItem *info);
|
||||
|
||||
void requestPGPCertificate(const PGPID &aboutId, const SSLID &toId);
|
||||
void recvPGPCertificateRequest(const SSLID &fromId, const RsDiscPgpListItem *item);
|
||||
void sendPGPCertificate(const PGPID &aboutId, const SSLID &toId);
|
||||
void recvPGPCertificate(const SSLID &fromId, RsDiscPgpCertItem *item);
|
||||
|
||||
bool setPeerVersion(const SSLID &peerId, const std::string &version);
|
||||
|
||||
private:
|
||||
|
||||
p3PeerMgr *mPeerMgr;
|
||||
p3LinkMgr *mLinkMgr;
|
||||
p3NetMgr *mNetMgr;
|
||||
|
||||
/* data */
|
||||
RsMutex mDiscMtx;
|
||||
|
||||
void updatePeers_locked(const SSLID &aboutId);
|
||||
void sendContactInfo_locked(const PGPID &aboutId, const SSLID &toId);
|
||||
|
||||
time_t mLastPgpUpdate;
|
||||
|
||||
std::map<PGPID, DiscPgpInfo> mFriendList;
|
||||
std::map<SSLID, DiscPeerInfo> mLocationMap;
|
||||
|
||||
std::list<RsDiscPgpCertItem *> mPendingDiscPgpCertInList;
|
||||
std::list<RsDiscPgpCertItem *> mPendingDiscPgpCertOutList;
|
||||
};
|
||||
|
||||
|
||||
#endif // MRK_SERVICES_DISCOVERY2_H
|
|
@ -1,816 +0,0 @@
|
|||
/*
|
||||
* libretroshare/src/services: rsforums.cc
|
||||
*
|
||||
* RetroShare C++ Interface.
|
||||
*
|
||||
* Copyright 2007-2008 by Robert Fernie.
|
||||
*
|
||||
* 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 "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#include "services/p3forums.h"
|
||||
#include "pqi/authssl.h"
|
||||
#include "util/rsdir.h"
|
||||
#include "rsserver/p3face.h"
|
||||
|
||||
uint32_t convertToInternalFlags(uint32_t extFlags);
|
||||
uint32_t convertToExternalFlags(uint32_t intFlags);
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const ForumInfo &info)
|
||||
{
|
||||
std::string name(info.forumName.begin(), info.forumName.end());
|
||||
std::string desc(info.forumDesc.begin(), info.forumDesc.end());
|
||||
|
||||
out << "ForumInfo:";
|
||||
out << std::endl;
|
||||
out << "ForumId: " << info.forumId << std::endl;
|
||||
out << "ForumName: " << name << std::endl;
|
||||
out << "ForumDesc: " << desc << std::endl;
|
||||
out << "ForumFlags: " << info.forumFlags << std::endl;
|
||||
out << "Pop: " << info.pop << std::endl;
|
||||
out << "LastPost: " << info.lastPost << std::endl;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const ThreadInfoSummary &/*info*/)
|
||||
{
|
||||
out << "ThreadInfoSummary:";
|
||||
out << std::endl;
|
||||
//out << "ForumId: " << forumId << std::endl;
|
||||
//out << "ThreadId: " << threadId << std::endl;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const ForumMsgInfo &/*info*/)
|
||||
{
|
||||
out << "ForumMsgInfo:";
|
||||
out << std::endl;
|
||||
//out << "ForumId: " << forumId << std::endl;
|
||||
//out << "ThreadId: " << threadId << std::endl;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
RsForums *rsForums = NULL;
|
||||
|
||||
|
||||
/* Forums will be initially stored for 1 year
|
||||
* remember 2^16 = 64K max units in store period.
|
||||
* PUBPERIOD * 2^16 = max STORE PERIOD */
|
||||
#define FORUM_STOREPERIOD (365*24*3600) /* 365 * 24 * 3600 - secs in a year */
|
||||
#define FORUM_PUBPERIOD 600 /* 10 minutes ... (max = 455 days) */
|
||||
|
||||
p3Forums::p3Forums(uint16_t type, CacheStrapper *cs, CacheTransfer *cft,
|
||||
std::string srcdir, std::string storedir, std::string forumDir)
|
||||
:p3GroupDistrib(type, cs, cft, srcdir, storedir, forumDir,
|
||||
CONFIG_TYPE_FORUMS, FORUM_STOREPERIOD, FORUM_PUBPERIOD),
|
||||
mForumsDir(forumDir)
|
||||
{
|
||||
|
||||
/* create chanDir */
|
||||
if (!RsDirUtil::checkCreateDirectory(mForumsDir)) {
|
||||
std::cerr << "p3Channels() Failed to create forums Directory: " << mForumsDir << std::endl;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
p3Forums::~p3Forums()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/****************************************/
|
||||
|
||||
bool p3Forums::forumsChanged(std::list<std::string> &forumIds)
|
||||
{
|
||||
return groupsChanged(forumIds);
|
||||
}
|
||||
|
||||
bool p3Forums::getForumInfo(const std::string &fId, ForumInfo &fi)
|
||||
{
|
||||
RsStackMutex stack(distribMtx); /***** STACK LOCKED MUTEX *****/
|
||||
|
||||
/* extract details */
|
||||
GroupInfo *gi = locked_getGroupInfo(fId);
|
||||
|
||||
if (!gi)
|
||||
return false;
|
||||
|
||||
fi.forumId = gi->grpId;
|
||||
fi.forumName = gi->grpName;
|
||||
fi.forumDesc = gi->grpDesc;
|
||||
fi.forumFlags = gi->grpFlags;
|
||||
|
||||
fi.subscribeFlags = gi->flags;
|
||||
|
||||
fi.pop = gi->sources.size();
|
||||
fi.lastPost = gi->lastPost;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* allows peers to change information for the forum:
|
||||
* can only change name and descriptions
|
||||
*
|
||||
*/
|
||||
bool p3Forums::setForumInfo(const std::string &fId, ForumInfo &fi)
|
||||
{
|
||||
GroupInfo gi;
|
||||
|
||||
RsStackMutex stack(distribMtx);
|
||||
|
||||
gi.grpName = fi.forumName;
|
||||
gi.grpDesc = fi.forumDesc;
|
||||
|
||||
return locked_editGroup(fId, gi);
|
||||
}
|
||||
|
||||
bool p3Forums::getForumList(std::list<ForumInfo> &forumList)
|
||||
{
|
||||
std::list<std::string> grpIds;
|
||||
std::list<std::string>::iterator it;
|
||||
|
||||
getAllGroupList(grpIds);
|
||||
|
||||
for(it = grpIds.begin(); it != grpIds.end(); it++)
|
||||
{
|
||||
ForumInfo fi;
|
||||
if (getForumInfo(*it, fi))
|
||||
{
|
||||
forumList.push_back(fi);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3Forums::getForumThreadList(const std::string &fId, std::list<ThreadInfoSummary> &msgs)
|
||||
{
|
||||
std::list<std::string> msgIds;
|
||||
std::list<std::string>::iterator it;
|
||||
|
||||
getParentMsgList(fId, "", msgIds);
|
||||
|
||||
std::list<std::string> msgDummyIds;
|
||||
getDummyParentMsgList(fId, "", msgDummyIds);
|
||||
|
||||
RsStackMutex stack(distribMtx); /***** STACK LOCKED MUTEX *****/
|
||||
for(it = msgIds.begin(); it != msgIds.end(); it++)
|
||||
{
|
||||
/* get details */
|
||||
RsDistribMsg *msg = locked_getGroupMsg(fId, *it);
|
||||
RsForumMsg *fmsg = dynamic_cast<RsForumMsg *>(msg);
|
||||
if (!fmsg)
|
||||
continue;
|
||||
|
||||
ThreadInfoSummary tis;
|
||||
|
||||
tis.forumId = msg->grpId;
|
||||
tis.msgId = msg->msgId;
|
||||
tis.parentId = ""; // always NULL (see request)
|
||||
tis.threadId = msg->msgId; // these are the thread heads!
|
||||
|
||||
tis.ts = msg->timestamp;
|
||||
tis.childTS = msg->childTS;
|
||||
|
||||
/* the rest must be gotten from the derived Msg */
|
||||
|
||||
tis.title = fmsg->title;
|
||||
tis.msg = fmsg->msg;
|
||||
|
||||
msgs.push_back(tis);
|
||||
}
|
||||
|
||||
// now add dummy msgs.
|
||||
for(it = msgDummyIds.begin(); it != msgDummyIds.end(); it++)
|
||||
{
|
||||
/* get details */
|
||||
RsDistribDummyMsg *msg = locked_getGroupDummyMsg(fId, *it);
|
||||
ThreadInfoSummary tis;
|
||||
|
||||
tis.forumId = fId;
|
||||
tis.msgId = msg->msgId;
|
||||
tis.parentId = ""; // always NULL (see request)
|
||||
tis.threadId = msg->msgId; // these are the thread heads!
|
||||
|
||||
tis.ts = msg->timestamp;
|
||||
tis.childTS = msg->childTS;
|
||||
|
||||
/* dummy msg */
|
||||
tis.title = L"[ ... Missing Message ... ]";
|
||||
tis.msg = L"Placeholder for missing Message";
|
||||
tis.msgflags |= RS_DISTRIB_MISSING_MSG;
|
||||
|
||||
msgs.push_back(tis);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3Forums::getForumThreadMsgList(const std::string &fId, const std::string &pId, std::list<ThreadInfoSummary> &msgs)
|
||||
{
|
||||
std::list<std::string> msgIds;
|
||||
std::list<std::string>::iterator it;
|
||||
|
||||
getParentMsgList(fId, pId, msgIds);
|
||||
|
||||
std::list<std::string> msgDummyIds;
|
||||
getDummyParentMsgList(fId, pId, msgDummyIds);
|
||||
|
||||
RsStackMutex stack(distribMtx); /***** STACK LOCKED MUTEX *****/
|
||||
for(it = msgIds.begin(); it != msgIds.end(); it++)
|
||||
{
|
||||
/* get details */
|
||||
RsDistribMsg *msg = locked_getGroupMsg(fId, *it);
|
||||
RsForumMsg *fmsg = dynamic_cast<RsForumMsg *>(msg);
|
||||
if (!fmsg)
|
||||
continue;
|
||||
|
||||
ThreadInfoSummary tis;
|
||||
|
||||
tis.forumId = msg->grpId;
|
||||
tis.msgId = msg->msgId;
|
||||
tis.parentId = msg->parentId;
|
||||
tis.threadId = msg->threadId;
|
||||
|
||||
tis.ts = msg->timestamp;
|
||||
tis.childTS = msg->childTS;
|
||||
|
||||
/* the rest must be gotten from the derived Msg */
|
||||
|
||||
tis.title = fmsg->title;
|
||||
tis.msg = fmsg->msg;
|
||||
|
||||
if (fmsg->personalSignature.keyId.empty() == false) {
|
||||
tis.msgflags |= RS_DISTRIB_AUTHEN_REQ;
|
||||
}
|
||||
|
||||
msgs.push_back(tis);
|
||||
}
|
||||
|
||||
// now add dummy msgs.
|
||||
for(it = msgDummyIds.begin(); it != msgDummyIds.end(); it++)
|
||||
{
|
||||
/* get details */
|
||||
RsDistribDummyMsg *msg = locked_getGroupDummyMsg(fId, *it);
|
||||
ThreadInfoSummary tis;
|
||||
|
||||
tis.forumId = fId;
|
||||
tis.msgId = msg->msgId;
|
||||
tis.parentId = msg->parentId;
|
||||
tis.threadId = msg->threadId;
|
||||
|
||||
tis.ts = msg->timestamp;
|
||||
tis.childTS = msg->childTS;
|
||||
|
||||
/* dummy msg */
|
||||
tis.title = L"[ ... Missing Message ... ]";
|
||||
tis.msg = L"Placeholder for missing Message";
|
||||
tis.msgflags |= RS_DISTRIB_MISSING_MSG;
|
||||
|
||||
msgs.push_back(tis);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3Forums::getForumMessage(const std::string &fId, const std::string &mId, ForumMsgInfo &info)
|
||||
{
|
||||
processCacheOptReq(fId);
|
||||
|
||||
RsStackMutex stack(distribMtx); /***** STACK LOCKED MUTEX *****/
|
||||
|
||||
RsDistribMsg *msg = locked_getGroupMsg(fId, mId);
|
||||
RsForumMsg *fmsg = dynamic_cast<RsForumMsg *>(msg);
|
||||
if (!fmsg)
|
||||
{
|
||||
/* try for a dummy msg */
|
||||
RsDistribDummyMsg *dmsg = locked_getGroupDummyMsg(fId, mId);
|
||||
if (!dmsg)
|
||||
return false;
|
||||
|
||||
/* fill in the dummy msg */
|
||||
info.forumId = fId;
|
||||
info.msgId = dmsg->msgId;
|
||||
info.parentId = dmsg->parentId;
|
||||
info.threadId = dmsg->threadId;
|
||||
|
||||
info.ts = dmsg->timestamp;
|
||||
info.childTS = dmsg->childTS;
|
||||
|
||||
info.title = L"[ ... Missing Message ... ]";
|
||||
info.msg = L"Placeholder for missing Message";
|
||||
info.msgflags |= RS_DISTRIB_MISSING_MSG;
|
||||
|
||||
info.srcId = "";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
info.forumId = msg->grpId;
|
||||
info.msgId = msg->msgId;
|
||||
info.parentId = msg->parentId;
|
||||
info.threadId = msg->threadId;
|
||||
|
||||
info.ts = msg->timestamp;
|
||||
info.childTS = msg->childTS;
|
||||
|
||||
/* the rest must be gotten from the derived Msg */
|
||||
|
||||
info.title = fmsg->title;
|
||||
info.msg = fmsg->msg;
|
||||
// should only use actual signature ....
|
||||
//info.srcId = fmsg->srcId;
|
||||
info.srcId = fmsg->personalSignature.keyId;
|
||||
|
||||
if (fmsg->personalSignature.keyId.empty() == false) {
|
||||
info.msgflags |= RS_DISTRIB_AUTHEN_REQ;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3Forums::ForumMessageSend(ForumMsgInfo &info)
|
||||
{
|
||||
bool signIt = (info.msgflags == RS_DISTRIB_AUTHEN_REQ);
|
||||
|
||||
std::string mId = createForumMsg(info.forumId, info.parentId,
|
||||
info.title, info.msg, signIt);
|
||||
|
||||
if (mId.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// return id
|
||||
info.msgId = mId;
|
||||
|
||||
return setMessageStatus(info.forumId, mId, FORUM_MSG_STATUS_READ | FORUM_MSG_STATUS_LOAD_EMBEDDED_IMAGES, FORUM_MSG_STATUS_MASK);
|
||||
}
|
||||
|
||||
bool p3Forums::setMessageStatus(const std::string& fId,const std::string& mId,const uint32_t status, const uint32_t statusMask)
|
||||
{
|
||||
bool changed = false;
|
||||
uint32_t newStatus = 0;
|
||||
|
||||
{
|
||||
RsStackMutex stack(distribMtx); /***** STACK LOCKED MUTEX *****/
|
||||
|
||||
std::map<std::string, RsForumReadStatus*>::iterator mit = mReadStatus.find(fId);
|
||||
if (mit != mReadStatus.end())
|
||||
{
|
||||
RsForumReadStatus* rsi = mit->second;
|
||||
uint32_t oldStatus = rsi->msgReadStatus[mId];
|
||||
rsi->msgReadStatus[mId] &= ~statusMask;
|
||||
rsi->msgReadStatus[mId] |= (status & statusMask);
|
||||
|
||||
newStatus = rsi->msgReadStatus[mId];
|
||||
if (oldStatus != newStatus) {
|
||||
changed = true;
|
||||
}
|
||||
} else {
|
||||
// if forum id does not exist create one
|
||||
RsForumReadStatus* rsi = new RsForumReadStatus();
|
||||
rsi->forumId = fId;
|
||||
rsi->msgReadStatus[mId] = status & statusMask;
|
||||
mReadStatus[fId] = rsi;
|
||||
mSaveList.push_back(rsi);
|
||||
|
||||
newStatus = rsi->msgReadStatus[mId];
|
||||
changed = true;
|
||||
}
|
||||
|
||||
IndicateConfigChanged();
|
||||
} /******* UNLOCKED ********/
|
||||
|
||||
if (changed) {
|
||||
RsServer::notify()->notifyListChange(NOTIFY_LIST_FORUMLIST_LOCKED, NOTIFY_TYPE_MOD);
|
||||
RsServer::notify()->notifyForumMsgReadSatusChanged(fId, mId, newStatus);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3Forums::getMessageStatus(const std::string& fId, const std::string& mId, uint32_t& status)
|
||||
{
|
||||
status = 0;
|
||||
|
||||
RsStackMutex stack(distribMtx);
|
||||
|
||||
std::map<std::string, RsForumReadStatus*>::iterator fit = mReadStatus.find(fId);
|
||||
|
||||
if (fit == mReadStatus.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::map<std::string, uint32_t >::iterator rit = fit->second->msgReadStatus.find(mId);
|
||||
|
||||
if(rit != fit->second->msgReadStatus.end())
|
||||
{
|
||||
status = rit->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool p3Forums::forumRestoreKeys(const std::string& fIds)
|
||||
{
|
||||
return p3GroupDistrib::restoreGrpKeys(fIds);
|
||||
}
|
||||
|
||||
|
||||
std::string p3Forums::createForum(const std::wstring &forumName, const std::wstring &forumDesc, uint32_t forumFlags)
|
||||
{
|
||||
|
||||
std::string id = createGroup(forumName, forumDesc,
|
||||
convertToInternalFlags(forumFlags), NULL, 0);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
std::string p3Forums::createForumMsg(std::string fId, std::string pId,
|
||||
std::wstring title, std::wstring msg, bool signIt)
|
||||
{
|
||||
|
||||
RsForumMsg *fmsg = new RsForumMsg();
|
||||
fmsg->grpId = fId;
|
||||
fmsg->parentId = pId;
|
||||
processCacheOptReq(fId);
|
||||
|
||||
{
|
||||
RsStackMutex stack(distribMtx); /***** STACK LOCKED MUTEX *****/
|
||||
|
||||
RsDistribMsg *msg = locked_getGroupMsg(fId, pId);
|
||||
if (!msg)
|
||||
{
|
||||
fmsg->parentId = "";
|
||||
fmsg->threadId = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (msg->parentId == "")
|
||||
{
|
||||
fmsg->threadId = fmsg->parentId;
|
||||
}
|
||||
else
|
||||
{
|
||||
fmsg->threadId = msg->threadId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fmsg->title = title;
|
||||
fmsg->msg = msg;
|
||||
if (signIt)
|
||||
{
|
||||
fmsg->srcId = AuthSSL::getAuthSSL()->OwnId();
|
||||
}
|
||||
fmsg->timestamp = time(NULL);
|
||||
|
||||
std::string msgId = publishMsg(fmsg, signIt);
|
||||
|
||||
if (msgId.empty()) {
|
||||
delete(fmsg);
|
||||
}
|
||||
|
||||
return msgId;
|
||||
}
|
||||
|
||||
RsSerialType *p3Forums::createSerialiser()
|
||||
{
|
||||
return new RsForumSerialiser();
|
||||
}
|
||||
|
||||
bool p3Forums::locked_checkDistribMsg(RsDistribMsg */*msg*/)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
RsDistribGrp *p3Forums::locked_createPublicDistribGrp(GroupInfo &/*info*/)
|
||||
{
|
||||
RsDistribGrp *grp = NULL; //new RsForumGrp();
|
||||
|
||||
return grp;
|
||||
}
|
||||
|
||||
RsDistribGrp *p3Forums::locked_createPrivateDistribGrp(GroupInfo &/*info*/)
|
||||
{
|
||||
RsDistribGrp *grp = NULL; //new RsForumGrp();
|
||||
|
||||
return grp;
|
||||
}
|
||||
|
||||
|
||||
uint32_t convertToInternalFlags(uint32_t extFlags)
|
||||
{
|
||||
return extFlags;
|
||||
}
|
||||
|
||||
uint32_t convertToExternalFlags(uint32_t intFlags)
|
||||
{
|
||||
return intFlags;
|
||||
}
|
||||
|
||||
bool p3Forums::forumSubscribe(const std::string &fId, bool subscribe)
|
||||
{
|
||||
return subscribeToGroup(fId, subscribe);
|
||||
}
|
||||
|
||||
bool p3Forums::getMessageCount(const std::string &fId, unsigned int &newCount, unsigned int &unreadCount)
|
||||
{
|
||||
newCount = 0;
|
||||
unreadCount = 0;
|
||||
|
||||
std::list<std::string> grpIds;
|
||||
|
||||
if (fId.empty()) {
|
||||
// count all messages of all subscribed forums
|
||||
getAllGroupList(grpIds);
|
||||
} else {
|
||||
// count all messages of one forum
|
||||
grpIds.push_back(fId);
|
||||
}
|
||||
|
||||
std::list<std::string>::iterator git;
|
||||
for (git = grpIds.begin(); git != grpIds.end(); git++) {
|
||||
std::string fId = *git;
|
||||
uint32_t grpFlags;
|
||||
|
||||
{
|
||||
// only flag is needed
|
||||
RsStackMutex stack(distribMtx); /***** STACK LOCKED MUTEX *****/
|
||||
GroupInfo *gi = locked_getGroupInfo(fId);
|
||||
if (gi == NULL) {
|
||||
return false;
|
||||
}
|
||||
grpFlags = gi->flags;
|
||||
} /******* UNLOCKED ********/
|
||||
|
||||
if (grpFlags & (RS_DISTRIB_ADMIN | RS_DISTRIB_SUBSCRIBED)) {
|
||||
std::list<std::string> msgIds;
|
||||
if (getAllMsgList(fId, msgIds)) {
|
||||
|
||||
RsStackMutex stack(distribMtx); /***** STACK LOCKED MUTEX *****/
|
||||
|
||||
std::map<std::string, RsForumReadStatus*>::iterator fit = mReadStatus.find(fId);
|
||||
if (fit == mReadStatus.end()) {
|
||||
// no status available -> all messages are new
|
||||
newCount += msgIds.size();
|
||||
unreadCount += msgIds.size();
|
||||
continue;
|
||||
}
|
||||
|
||||
std::list<std::string>::iterator mit;
|
||||
for (mit = msgIds.begin(); mit != msgIds.end(); mit++) {
|
||||
std::map<std::string, uint32_t >::iterator rit = fit->second->msgReadStatus.find(*mit);
|
||||
|
||||
if (rit == fit->second->msgReadStatus.end()) {
|
||||
// no status available -> message is new
|
||||
newCount++;
|
||||
unreadCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rit->second & FORUM_MSG_STATUS_READ) {
|
||||
// message is not new
|
||||
if (rit->second & FORUM_MSG_STATUS_UNREAD_BY_USER) {
|
||||
// message is unread
|
||||
unreadCount++;
|
||||
}
|
||||
} else {
|
||||
newCount++;
|
||||
unreadCount++;
|
||||
}
|
||||
}
|
||||
} /******* UNLOCKED ********/
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/***************************************************************************************/
|
||||
/****************** Event Feedback (Overloaded form p3distrib) *************************/
|
||||
/***************************************************************************************/
|
||||
|
||||
void p3Forums::locked_notifyGroupChanged(GroupInfo &grp, uint32_t flags, bool historical)
|
||||
{
|
||||
const std::string &grpId = grp.grpId;
|
||||
std::string msgId;
|
||||
std::string nullId;
|
||||
|
||||
switch(flags)
|
||||
{
|
||||
case GRP_NEW_UPDATE:
|
||||
if (!historical)
|
||||
{
|
||||
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_FORUM_NEW, grpId, msgId, nullId);
|
||||
}
|
||||
RsServer::notify()->notifyListChange(NOTIFY_LIST_FORUMLIST_LOCKED, NOTIFY_TYPE_ADD);
|
||||
break;
|
||||
case GRP_UPDATE:
|
||||
if (!historical)
|
||||
{
|
||||
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_FORUM_UPDATE, grpId, msgId, nullId);
|
||||
}
|
||||
RsServer::notify()->notifyListChange(NOTIFY_LIST_FORUMLIST_LOCKED, NOTIFY_TYPE_MOD);
|
||||
break;
|
||||
case GRP_LOAD_KEY:
|
||||
break;
|
||||
case GRP_NEW_MSG:
|
||||
RsServer::notify()->notifyListChange(NOTIFY_LIST_FORUMLIST_LOCKED, NOTIFY_TYPE_ADD);
|
||||
break;
|
||||
case GRP_SUBSCRIBED:
|
||||
RsServer::notify()->notifyListChange(NOTIFY_LIST_FORUMLIST_LOCKED, NOTIFY_TYPE_ADD);
|
||||
break;
|
||||
case GRP_UNSUBSCRIBED:
|
||||
RsServer::notify()->notifyListChange(NOTIFY_LIST_FORUMLIST_LOCKED, NOTIFY_TYPE_DEL);
|
||||
break;
|
||||
}
|
||||
return p3GroupDistrib::locked_notifyGroupChanged(grp, flags, historical);
|
||||
}
|
||||
|
||||
bool p3Forums::locked_eventDuplicateMsg(GroupInfo */*grp*/, RsDistribMsg */*msg*/, const std::string& /*id*/, bool /*historical*/)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3Forums::forumShareKeys(std::string fId, std::list<std::string>& peers)
|
||||
{
|
||||
|
||||
#ifdef FORUM_DEBUG
|
||||
std::cerr << "p3Forums::forumShareKeys() " << fId << std::endl;
|
||||
#endif
|
||||
|
||||
return sharePubKey(fId, peers);
|
||||
}
|
||||
|
||||
bool p3Forums::locked_eventNewMsg(GroupInfo */*grp*/, RsDistribMsg *msg, const std::string& /*id*/, bool historical)
|
||||
{
|
||||
std::string grpId = msg->grpId;
|
||||
std::string msgId = msg->msgId;
|
||||
std::string nullId;
|
||||
|
||||
if (!historical)
|
||||
{
|
||||
RsServer::notify()->AddFeedItem(RS_FEED_ITEM_FORUM_MSG, grpId, msgId, nullId);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************/
|
||||
|
||||
void p3Forums::loadDummyData()
|
||||
{
|
||||
ForumInfo fi;
|
||||
std::string forumId;
|
||||
std::string msgId;
|
||||
time_t now = time(NULL);
|
||||
|
||||
fi.forumId = "FID1234";
|
||||
fi.forumName = L"Forum 1";
|
||||
fi.forumDesc = L"Forum 1";
|
||||
fi.forumFlags = RS_DISTRIB_ADMIN;
|
||||
fi.pop = 2;
|
||||
fi.lastPost = now - 123;
|
||||
|
||||
forumId = createForum(fi.forumName, fi.forumDesc, fi.forumFlags);
|
||||
|
||||
fi.forumId = "FID2345";
|
||||
fi.forumName = L"Forum 2";
|
||||
fi.forumDesc = L"Forum 2";
|
||||
fi.forumFlags = RS_DISTRIB_SUBSCRIBED;
|
||||
fi.pop = 3;
|
||||
fi.lastPost = now - 1234;
|
||||
|
||||
forumId = createForum(fi.forumName, fi.forumDesc, fi.forumFlags);
|
||||
msgId = createForumMsg(forumId, "", L"WELCOME TO Forum1", L"Hello!", true);
|
||||
msgId = createForumMsg(forumId, msgId, L"Love this forum", L"Hello2!", true);
|
||||
|
||||
return;
|
||||
|
||||
/* ignore this */
|
||||
|
||||
fi.forumId = "FID3456";
|
||||
fi.forumName = L"Forum 3";
|
||||
fi.forumDesc = L"Forum 3";
|
||||
fi.forumFlags = 0;
|
||||
fi.pop = 3;
|
||||
fi.lastPost = now - 1234;
|
||||
|
||||
forumId = createForum(fi.forumName, fi.forumDesc, fi.forumFlags);
|
||||
|
||||
fi.forumId = "FID4567";
|
||||
fi.forumName = L"Forum 4";
|
||||
fi.forumDesc = L"Forum 4";
|
||||
fi.forumFlags = 0;
|
||||
fi.pop = 5;
|
||||
fi.lastPost = now - 1234;
|
||||
|
||||
forumId = createForum(fi.forumName, fi.forumDesc, fi.forumFlags);
|
||||
|
||||
fi.forumId = "FID5678";
|
||||
fi.forumName = L"Forum 5";
|
||||
fi.forumDesc = L"Forum 5";
|
||||
fi.forumFlags = 0;
|
||||
fi.pop = 1;
|
||||
fi.lastPost = now - 1234;
|
||||
|
||||
forumId = createForum(fi.forumName, fi.forumDesc, fi.forumFlags);
|
||||
|
||||
fi.forumId = "FID6789";
|
||||
fi.forumName = L"Forum 6";
|
||||
fi.forumDesc = L"Forum 6";
|
||||
fi.forumFlags = 0;
|
||||
fi.pop = 2;
|
||||
fi.lastPost = now - 1234;
|
||||
|
||||
forumId = createForum(fi.forumName, fi.forumDesc, fi.forumFlags);
|
||||
|
||||
fi.forumId = "FID7890";
|
||||
fi.forumName = L"Forum 7";
|
||||
fi.forumDesc = L"Forum 7";
|
||||
fi.forumFlags = 0;
|
||||
fi.pop = 4;
|
||||
fi.lastPost = now - 1234;
|
||||
|
||||
forumId = createForum(fi.forumName, fi.forumDesc, fi.forumFlags);
|
||||
|
||||
fi.forumId = "FID8901";
|
||||
fi.forumName = L"Forum 8";
|
||||
fi.forumDesc = L"Forum 8";
|
||||
fi.forumFlags = 0;
|
||||
fi.pop = 3;
|
||||
fi.lastPost = now - 1234;
|
||||
|
||||
forumId = createForum(fi.forumName, fi.forumDesc, fi.forumFlags);
|
||||
|
||||
fi.forumId = "FID9012";
|
||||
fi.forumName = L"Forum 9";
|
||||
fi.forumDesc = L"Forum 9";
|
||||
fi.forumFlags = 0;
|
||||
fi.pop = 2;
|
||||
fi.lastPost = now - 1234;
|
||||
|
||||
forumId = createForum(fi.forumName, fi.forumDesc, fi.forumFlags);
|
||||
|
||||
fi.forumId = "FID9123";
|
||||
fi.forumName = L"Forum 10";
|
||||
fi.forumDesc = L"Forum 10";
|
||||
fi.forumFlags = 0;
|
||||
fi.pop = 1;
|
||||
fi.lastPost = now - 1234;
|
||||
|
||||
forumId = createForum(fi.forumName, fi.forumDesc, fi.forumFlags);
|
||||
}
|
||||
|
||||
std::list<RsItem* > p3Forums::childSaveList()
|
||||
{
|
||||
return mSaveList;
|
||||
}
|
||||
|
||||
bool p3Forums::childLoadList(std::list<RsItem* >& configSaves)
|
||||
{
|
||||
RsForumReadStatus* drs = NULL;
|
||||
std::list<RsItem* >::iterator it;
|
||||
|
||||
for(it = configSaves.begin(); it != configSaves.end(); it++)
|
||||
{
|
||||
if(NULL != (drs = dynamic_cast<RsForumReadStatus* >(*it)))
|
||||
{
|
||||
mReadStatus[drs->forumId] = drs;
|
||||
mSaveList.push_back(drs);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "p3Forums::childLoadList(): Configs items loaded were incorrect!"
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
|
@ -1,105 +0,0 @@
|
|||
#ifndef RS_P3_FORUMS_INTERFACE_H
|
||||
#define RS_P3_FORUMS_INTERFACE_H
|
||||
|
||||
/*
|
||||
* libretroshare/src/services: p3forums.h
|
||||
*
|
||||
* RetroShare C++ Interface.
|
||||
*
|
||||
* Copyright 2008 by Robert Fernie.
|
||||
*
|
||||
* 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 "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#include "retroshare/rsforums.h"
|
||||
#include "distrib/p3distrib.h"
|
||||
#include "serialiser/rsforumitems.h"
|
||||
|
||||
|
||||
|
||||
class p3Forums: public p3GroupDistrib, public RsForums
|
||||
{
|
||||
public:
|
||||
|
||||
p3Forums(uint16_t type, CacheStrapper *cs, CacheTransfer *cft,
|
||||
std::string srcdir, std::string storedir, std::string forumdir);
|
||||
virtual ~p3Forums();
|
||||
|
||||
void loadDummyData();
|
||||
|
||||
/****************************************/
|
||||
/********* rsForums Interface ***********/
|
||||
|
||||
virtual bool forumsChanged(std::list<std::string> &forumIds);
|
||||
|
||||
virtual std::string createForum(const std::wstring &forumName, const std::wstring &forumDesc, uint32_t forumFlags);
|
||||
|
||||
virtual bool getForumInfo(const std::string &fId, ForumInfo &fi);
|
||||
virtual bool setForumInfo(const std::string &fId, ForumInfo &fi);
|
||||
virtual bool getForumList(std::list<ForumInfo> &forumList);
|
||||
virtual bool getForumThreadList(const std::string &fId, std::list<ThreadInfoSummary> &msgs);
|
||||
virtual bool getForumThreadMsgList(const std::string &fId, const std::string &tId, std::list<ThreadInfoSummary> &msgs);
|
||||
virtual bool getForumMessage(const std::string &fId, const std::string &mId, ForumMsgInfo &msg);
|
||||
virtual bool ForumMessageSend(ForumMsgInfo &info);
|
||||
virtual bool setMessageStatus(const std::string& fId, const std::string& mId, const uint32_t status, const uint32_t statusMask);
|
||||
virtual bool getMessageStatus(const std::string& fId, const std::string& mId, uint32_t& status);
|
||||
virtual bool forumRestoreKeys(const std::string& fId);
|
||||
virtual bool forumShareKeys(std::string fId, std::list<std::string>& peers);
|
||||
virtual bool forumSubscribe(const std::string &fId, bool subscribe);
|
||||
|
||||
virtual bool getMessageCount(const std::string &fId, unsigned int &newCount, unsigned int &unreadCount);
|
||||
|
||||
/***************************************************************************************/
|
||||
/****************** Event Feedback (Overloaded form p3distrib) *************************/
|
||||
/***************************************************************************************/
|
||||
|
||||
virtual void locked_notifyGroupChanged(GroupInfo &grp, uint32_t flags, bool historical);
|
||||
virtual bool locked_eventDuplicateMsg(GroupInfo *, RsDistribMsg *, const std::string&, bool historical);
|
||||
virtual bool locked_eventNewMsg(GroupInfo *, RsDistribMsg *, const std::string&, bool historical);
|
||||
|
||||
|
||||
/****************************************/
|
||||
/********* Overloaded Functions *********/
|
||||
|
||||
//virtual RsSerialiser *setupSerialiser();
|
||||
//virtual pqistreamer *createStreamer(BinInterface *bio, std::string src, uint32_t bioflags);
|
||||
virtual RsSerialType *createSerialiser();
|
||||
|
||||
virtual bool locked_checkDistribMsg(RsDistribMsg *msg);
|
||||
virtual RsDistribGrp *locked_createPublicDistribGrp(GroupInfo &info);
|
||||
virtual RsDistribGrp *locked_createPrivateDistribGrp(GroupInfo &info);
|
||||
virtual bool childLoadList(std::list<RsItem *>& );
|
||||
virtual std::list<RsItem *> childSaveList();
|
||||
|
||||
|
||||
/****************************************/
|
||||
|
||||
std::string createForumMsg(std::string fId, std::string pId,
|
||||
std::wstring title, std::wstring msg, bool signIt);
|
||||
|
||||
private:
|
||||
|
||||
std::string mForumsDir;
|
||||
std::list<RsItem *> mSaveList; // store save data
|
||||
|
||||
std::map<std::string, RsForumReadStatus*> mReadStatus;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load diff
|
@ -1,151 +0,0 @@
|
|||
/*
|
||||
* libretroshare/src/services: p3gamelauncher.h
|
||||
*
|
||||
* Services for RetroShare.
|
||||
*
|
||||
* Copyright 2004-2008 by Robert Fernie.
|
||||
*
|
||||
* 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 "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SERVICE_GAME_LAUNCHER_HEADER
|
||||
#define SERVICE_GAME_LAUNCHER_HEADER
|
||||
|
||||
/*
|
||||
* A central point to setup games between peers.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
#include "services/p3service.h"
|
||||
#include "serialiser/rsgameitems.h"
|
||||
#include "retroshare/rsgame.h"
|
||||
|
||||
class p3LinkMgr;
|
||||
|
||||
|
||||
class gameAvail
|
||||
{
|
||||
uint32_t serviceId;
|
||||
std::string gameName;
|
||||
uint16_t minPlayers;
|
||||
uint16_t maxPlayers;
|
||||
};
|
||||
|
||||
class gameStatus
|
||||
{
|
||||
public:
|
||||
|
||||
uint32_t serviceId;
|
||||
std::string gameId;
|
||||
std::wstring gameName;
|
||||
|
||||
bool areServer; /* are we the server? */
|
||||
std::string serverId; /* if not, who is? */
|
||||
|
||||
uint16_t numPlayers;
|
||||
std::list<std::string> allowedPeers; /* who can play ( controlled by server) */
|
||||
std::list<std::string> interestedPeers; /* who wants to play ( controlled by server) */
|
||||
std::list<std::string> peerIds; /* in order of turns */
|
||||
|
||||
uint32_t state;
|
||||
};
|
||||
|
||||
class p3GameService;
|
||||
|
||||
/* We're going to add the external Interface - directly on here! */
|
||||
|
||||
class p3GameLauncher: public p3Service, public RsGameLauncher
|
||||
{
|
||||
public:
|
||||
p3GameLauncher(p3LinkMgr *lm);
|
||||
|
||||
/***** EXTERNAL RsGameLauncher Interface *******/
|
||||
/* server commands */
|
||||
virtual std::string createGame(uint32_t gameType, std::wstring name);
|
||||
virtual bool deleteGame(std::string gameId);
|
||||
virtual bool inviteGame(std::string gameId);
|
||||
virtual bool playGame(std::string gameId);
|
||||
//virtual bool quitGame(std::string gameId);
|
||||
|
||||
virtual bool invitePeer(std::string gameId, std::string peerId);
|
||||
virtual bool uninvitePeer(std::string gameId, std::string peerId);
|
||||
virtual bool confirmPeer(std::string gameId, std::string peerId,
|
||||
int16_t pos = -1);
|
||||
virtual bool unconfirmPeer(std::string gameId, std::string peerId);
|
||||
|
||||
/* client commands */
|
||||
virtual bool interestedPeer(std::string gameId);
|
||||
virtual bool uninterestedPeer(std::string gameId);
|
||||
|
||||
/* get details */
|
||||
virtual bool getGameList(std::list<RsGameInfo> &gameList);
|
||||
virtual bool getGameDetail(std::string gameId, RsGameDetail &detail);
|
||||
/***** EXTERNAL RsGameLauncher Interface *******/
|
||||
|
||||
/* support functions */
|
||||
private:
|
||||
std::string newGame(uint16_t srvId, std::wstring name);
|
||||
bool confirmGame(std::string gameId);
|
||||
bool quitGame(std::string gameId);
|
||||
bool inviteResponse(std::string gameId, bool interested);
|
||||
|
||||
|
||||
/* p3Service Overloaded */
|
||||
virtual int tick();
|
||||
virtual int status();
|
||||
|
||||
/* add in the Game */
|
||||
int addGameService(p3GameService *game);
|
||||
/* notify gameService/peers */
|
||||
|
||||
//int getGameList(std::list<gameAvail> &games);
|
||||
//int getGamesCurrent(std::list<std::string> &games);
|
||||
//int getGameDetails(std::string gid, gameStatus &status);
|
||||
|
||||
/**** GUI Interface ****/
|
||||
|
||||
bool resumeGame(std::string gameId);
|
||||
|
||||
/**** Network Interface ****/
|
||||
int checkIncoming();
|
||||
int handleIncoming(RsGameItem *gi);
|
||||
|
||||
int handleClientStart(RsGameItem *gi); /* START msg */
|
||||
int handleClientInvited(RsGameItem *gi); /* REJECT msg */
|
||||
int handleClientReady(RsGameItem *gi); /* CONFIRM / REJECT / PLAY msg */
|
||||
int handleClientActive(RsGameItem *gi); /* PAUSE / QUIT msg */
|
||||
|
||||
int handleServerSetup(RsGameItem *gi); /* INTERESTED / REJECT msg */
|
||||
int handleServerActive(RsGameItem *gi); /* PAUSE / QUIT msg */
|
||||
|
||||
int sendRejectMsg(RsGameItem *gi); /* --- error msg */
|
||||
void cleanupGame(std::string gameId); /* remove from list */
|
||||
bool checkGameProperties(uint16_t serviceId, uint16_t players);
|
||||
|
||||
std::map<uint16_t, p3GameService *> gameList;
|
||||
std::map<std::string, gameStatus> gamesCurrent;
|
||||
|
||||
p3LinkMgr *mLinkMgr;
|
||||
std::string mOwnId;
|
||||
};
|
||||
|
||||
#endif // SERVICE_GAME_LAUNCHER_HEADER
|
|
@ -1,90 +0,0 @@
|
|||
/*
|
||||
* libretroshare/src/services: p3gameservice.h
|
||||
*
|
||||
* Services for RetroShare.
|
||||
*
|
||||
* Copyright 2004-2008 by Robert Fernie.
|
||||
*
|
||||
* 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 "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef P3_SERVICE_GAME_HEADER
|
||||
#define P3_SERVICE_GAME_HEADER
|
||||
|
||||
/*
|
||||
* A central point to setup games between peers.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
#include "services/p3service.h"
|
||||
|
||||
class StoredGame
|
||||
{
|
||||
public:
|
||||
std::string gameId;
|
||||
time_t startTime;
|
||||
std::list<std::string> peerIds; /* in order of turns */
|
||||
};
|
||||
|
||||
class p3GameLauncher;
|
||||
class p3Service;
|
||||
|
||||
class p3GameService
|
||||
{
|
||||
public:
|
||||
|
||||
p3GameService(uint16_t sId, std::string name, uint16_t min, uint16_t max, p3GameLauncher *l)
|
||||
:serviceId(sId), gameName(name), minPlayers(min), maxPlayers(max),
|
||||
service(NULL), launcher(l)
|
||||
{ return; }
|
||||
|
||||
virtual ~p3GameService()
|
||||
{ return; }
|
||||
|
||||
/*************** Game Interface ******************/
|
||||
/* saved games */
|
||||
virtual void getSavedGames(std::list<StoredGame> &gList);
|
||||
|
||||
/* start a game */
|
||||
virtual void startGame(StoredGame &newGame, bool resume);
|
||||
virtual void quitGame(std::string gameId);
|
||||
virtual void deleteGame(std::string gameId);
|
||||
/*************** Game Interface ******************/
|
||||
|
||||
/* details for the Launcher */
|
||||
uint16_t getServiceId() { return serviceId; }
|
||||
std::string getGameName() { return gameName; }
|
||||
uint16_t getMinPlayers() { return minPlayers; }
|
||||
uint16_t getMaxPlayers() { return maxPlayers; }
|
||||
p3GameLauncher *getLauncher() { return launcher; }
|
||||
|
||||
private:
|
||||
|
||||
uint16_t serviceId;
|
||||
std::string gameName;
|
||||
uint16_t minPlayers, maxPlayers;
|
||||
|
||||
p3Service *service;
|
||||
p3GameLauncher *launcher;
|
||||
};
|
||||
|
||||
#endif // P3_SERVICE_GAME_HEADER
|
|
@ -1165,7 +1165,7 @@ bool p3GxsChannels::generateVote(uint32_t &token, const RsGxsGroupId &grpId, con
|
|||
|
||||
uint32_t idx = (uint32_t) (ownIds.size() * RSRandom::random_f32());
|
||||
uint32_t i = 0;
|
||||
for(it = ownIds.begin(); (it != ownIds.end()) && (i < idx); it++, i++);
|
||||
for(it = ownIds.begin(); (it != ownIds.end()) && (i < idx); it++, i++) ;
|
||||
|
||||
if (it != ownIds.end())
|
||||
{
|
||||
|
|
|
@ -1511,7 +1511,7 @@ void p3GxsCircles::generateDummyCircle()
|
|||
|
||||
int selection = (RSRandom::random_u32() % npgps);
|
||||
std::list<RsGxsId>::iterator it = mDummyPgpLinkedIds.begin();
|
||||
for(int j = 0; (it != mDummyPgpLinkedIds.end()) && (j < selection); j++, it++);
|
||||
for(int j = 0; (it != mDummyPgpLinkedIds.end()) && (j < selection); j++, it++) ;
|
||||
if (it != mDummyPgpLinkedIds.end())
|
||||
{
|
||||
idset.insert(*it);
|
||||
|
@ -1525,7 +1525,7 @@ void p3GxsCircles::generateDummyCircle()
|
|||
int selection = (RSRandom::random_u32() % mDummyOwnIds.size());
|
||||
std::list<RsGxsId>::iterator it = mDummyOwnIds.begin();
|
||||
mDummyOwnIds.push_back(*it);
|
||||
for(int j = 0; (it != mDummyOwnIds.end()) && (j < selection); j++, it++);
|
||||
for(int j = 0; (it != mDummyOwnIds.end()) && (j < selection); j++, it++) ;
|
||||
if (it != mDummyOwnIds.end())
|
||||
{
|
||||
idset.insert(*it);
|
||||
|
|
|
@ -215,6 +215,21 @@ bool p3GxsForums::createGroup(uint32_t &token, RsGxsForumGroup &group)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool p3GxsForums::updateGroup(uint32_t &token, RsGxsGroupUpdateMeta& meta, RsGxsForumGroup &group)
|
||||
{
|
||||
std::cerr << "p3GxsForums::updateGroup()" << std::endl;
|
||||
|
||||
if(meta.getGroupId().empty())
|
||||
return false;
|
||||
|
||||
RsGxsForumGroupItem* grpItem = new RsGxsForumGroupItem();
|
||||
grpItem->mGroup = group;
|
||||
grpItem->meta = group.mMeta;
|
||||
grpItem->meta.mGroupId = meta.getGroupId();
|
||||
|
||||
RsGenExchange::updateGroup(token, meta, grpItem);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3GxsForums::createMsg(uint32_t &token, RsGxsForumMsg &msg)
|
||||
{
|
||||
|
@ -423,7 +438,7 @@ bool p3GxsForums::generateMessage(uint32_t &token, const RsGxsGroupId &grpId, co
|
|||
|
||||
uint32_t idx = (uint32_t) (ownIds.size() * RSRandom::random_f32());
|
||||
int i = 0;
|
||||
for(it = ownIds.begin(); (it != ownIds.end()) && (i < idx); it++, i++);
|
||||
for(it = ownIds.begin(); (it != ownIds.end()) && (i < idx); it++, i++) ;
|
||||
|
||||
if (it != ownIds.end())
|
||||
{
|
||||
|
|
|
@ -74,6 +74,13 @@ virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgI
|
|||
virtual bool createGroup(uint32_t &token, RsGxsForumGroup &group);
|
||||
virtual bool createMsg(uint32_t &token, RsGxsForumMsg &msg);
|
||||
|
||||
/*!
|
||||
* To update forum group with new information
|
||||
* @param token the token used to check completion status of update
|
||||
* @param group group to be updated, groupId element must be set or will be rejected
|
||||
* @return false groupId not set, true if set and accepted (still check token for completion)
|
||||
*/
|
||||
virtual bool updateGroup(uint32_t &token, RsGxsGroupUpdateMeta& meta, RsGxsForumGroup &group);
|
||||
|
||||
|
||||
private:
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,191 +0,0 @@
|
|||
/*
|
||||
* libretroshare/src/services p3gxsservice.h
|
||||
*
|
||||
* Generic Service Support Class for RetroShare.
|
||||
*
|
||||
* Copyright 2012 by Robert Fernie.
|
||||
*
|
||||
* 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 "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef P3_GXS_SERVICE_HEADER
|
||||
#define P3_GXS_SERVICE_HEADER
|
||||
|
||||
#include "services/p3service.h"
|
||||
#include "retroshare/rsidentityVEG.h"
|
||||
|
||||
/*
|
||||
* This class provides useful generic support for GXS style services.
|
||||
* I expect much of this will be incorporated into the base GXS.
|
||||
*
|
||||
*/
|
||||
|
||||
#define GXS_REQUEST_STATUS_FAILED 0
|
||||
#define GXS_REQUEST_STATUS_PENDING 1
|
||||
#define GXS_REQUEST_STATUS_PARTIAL 2
|
||||
#define GXS_REQUEST_STATUS_FINISHED_INCOMPLETE 3
|
||||
#define GXS_REQUEST_STATUS_COMPLETE 4
|
||||
#define GXS_REQUEST_STATUS_DONE 5 // ONCE ALL DATA RETRIEVED.
|
||||
|
||||
#define GXS_REQUEST_TYPE_GROUPS 0x00010000
|
||||
#define GXS_REQUEST_TYPE_MSGS 0x00020000
|
||||
#define GXS_REQUEST_TYPE_MSGRELATED 0x00040000
|
||||
|
||||
class gxsRequest
|
||||
{
|
||||
public:
|
||||
uint32_t token;
|
||||
uint32_t reqTime;
|
||||
|
||||
uint32_t ansType;
|
||||
uint32_t reqType;
|
||||
RsTokReqOptionsVEG Options;
|
||||
|
||||
uint32_t status;
|
||||
|
||||
std::list<std::string> inList;
|
||||
std::list<std::string> outList;
|
||||
//std::map<std::string, void *> readyData;
|
||||
};
|
||||
|
||||
|
||||
class p3GxsServiceVEG: public p3Service
|
||||
{
|
||||
protected:
|
||||
|
||||
p3GxsServiceVEG(uint16_t type);
|
||||
|
||||
public:
|
||||
|
||||
//virtual ~p3Service() { p3Service::~p3Service(); return; }
|
||||
|
||||
bool generateToken(uint32_t &token);
|
||||
bool storeRequest(const uint32_t &token, const uint32_t &ansType, const RsTokReqOptionsVEG &opts, const uint32_t &type, const std::list<std::string> &ids);
|
||||
bool clearRequest(const uint32_t &token);
|
||||
|
||||
bool updateRequestStatus(const uint32_t &token, const uint32_t &status);
|
||||
bool updateRequestInList(const uint32_t &token, std::list<std::string> ids);
|
||||
bool updateRequestOutList(const uint32_t &token, std::list<std::string> ids);
|
||||
//bool updateRequestData(const uint32_t &token, std::map<std::string, void *> data);
|
||||
bool checkRequestStatus(const uint32_t &token, uint32_t &status, uint32_t &reqtype, uint32_t &anstype, time_t &ts);
|
||||
|
||||
// special ones for testing (not in final design)
|
||||
bool tokenList(std::list<uint32_t> &tokens);
|
||||
bool popRequestInList(const uint32_t &token, std::string &id);
|
||||
bool popRequestOutList(const uint32_t &token, std::string &id);
|
||||
bool loadRequestOutList(const uint32_t &token, std::list<std::string> &ids);
|
||||
|
||||
virtual bool fakeprocessrequests();
|
||||
|
||||
protected:
|
||||
|
||||
RsMutex mReqMtx;
|
||||
|
||||
uint32_t mNextToken;
|
||||
|
||||
std::map<uint32_t, gxsRequest> mRequests;
|
||||
|
||||
};
|
||||
|
||||
|
||||
class GxsDataProxyVEG
|
||||
{
|
||||
public:
|
||||
|
||||
GxsDataProxyVEG();
|
||||
|
||||
virtual bool getGroupList( uint32_t &token, const RsTokReqOptionsVEG &opts, const std::list<std::string> &groupIds, std::list<std::string> &outGroupIds);
|
||||
virtual bool getMsgList( uint32_t &token, const RsTokReqOptionsVEG &opts, const std::list<std::string> &groupIds, std::list<std::string> &outMsgIds);
|
||||
virtual bool getMsgRelatedList(uint32_t &token, const RsTokReqOptionsVEG &opts, const std::list<std::string> &msgIds, std::list<std::string> &outMsgIds);
|
||||
|
||||
|
||||
/* This functions return a token - which can be used to retrieve the RsGroupMetaData, later
|
||||
* This is required, as signatures and keys might have to be generated in the background
|
||||
* Though at the moment: for this test system it won't change anything? FIXME.
|
||||
*/
|
||||
virtual bool createGroup(void *groupData);
|
||||
virtual bool createMsg(void *msgData);
|
||||
|
||||
/* These Functions must be overloaded to complete the service */
|
||||
virtual bool convertGroupToMetaData(void *groupData, RsGroupMetaData &meta);
|
||||
virtual bool convertMsgToMetaData(void *groupData, RsMsgMetaData &meta);
|
||||
|
||||
/* extract Data */
|
||||
bool getGroupSummary(const std::list<std::string> &groupIds, std::list<RsGroupMetaData> &groupSummary);
|
||||
bool getMsgSummary(const std::list<std::string> &msgIds, std::list<RsMsgMetaData> &msgSummary);
|
||||
|
||||
bool getGroupSummary(const std::string &groupId, RsGroupMetaData &groupSummary);
|
||||
bool getMsgSummary(const std::string &msgId, RsMsgMetaData &msgSummary);
|
||||
|
||||
//bool getGroupData(const std::list<std::string> &groupIds, std::list<void *> &groupData);
|
||||
//bool getMsgData(const std::list<std::string> &msgIds, std::list<void *> &msgData);
|
||||
bool getGroupData(const std::string &groupId, void * &groupData);
|
||||
bool getMsgData(const std::string &msgId, void * &msgData);
|
||||
|
||||
bool isUniqueGroup(const std::string &groupId);
|
||||
bool isUniqueMsg(const std::string &msgId);
|
||||
|
||||
|
||||
/* Handle Status & Subscribe Modes */
|
||||
// This is removed as redundant - use getGroupList - with OptFlags to find these.
|
||||
//virtual bool requestGroupsChanged(uint32_t &token); //std::list<std::string> &groupIds);
|
||||
|
||||
// Get Message Status - is retrived via MessageSummary.
|
||||
// These operations could have a token, but for the moment we are going to assume
|
||||
// they are async and always succeed - (or fail silently).
|
||||
virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask);
|
||||
virtual bool setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask);
|
||||
virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask);
|
||||
|
||||
virtual bool setMessageServiceString(const std::string &msgId, const std::string &str);
|
||||
virtual bool setGroupServiceString(const std::string &grpId, const std::string &str);
|
||||
|
||||
protected:
|
||||
|
||||
bool filterGroupList(const RsTokReqOptionsVEG &opts, std::list<std::string> &groupIds);
|
||||
bool filterMsgList(const RsTokReqOptionsVEG &opts, std::list<std::string> &msgIds);
|
||||
|
||||
|
||||
RsMutex mDataMtx;
|
||||
|
||||
std::map<std::string, void *> mGroupData;
|
||||
std::map<std::string, void *> mMsgData;
|
||||
|
||||
std::map<std::string, RsGroupMetaData> mGroupMetaData;
|
||||
std::map<std::string, RsMsgMetaData> mMsgMetaData;
|
||||
|
||||
};
|
||||
|
||||
|
||||
class p3GxsDataServiceVEG: public p3GxsServiceVEG
|
||||
{
|
||||
public:
|
||||
|
||||
p3GxsDataServiceVEG(uint16_t type, GxsDataProxyVEG *proxy);
|
||||
virtual bool fakeprocessrequests();
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
GxsDataProxyVEG *mProxy;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // P3_GXS_SERVICE_HEADER
|
||||
|
124
libretroshare/src/services/p3heartbeat.cc
Normal file
124
libretroshare/src/services/p3heartbeat.cc
Normal file
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* libretroshare/src/services: p3heartbeat.cc
|
||||
*
|
||||
* Services for RetroShare.
|
||||
*
|
||||
* Copyright 2004-2013 by Robert Fernie.
|
||||
*
|
||||
* 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.1 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 "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#include "services/p3heartbeat.h"
|
||||
#include "serialiser/rsheartbeatitems.h"
|
||||
|
||||
#define HEART_DEBUG 1
|
||||
|
||||
|
||||
p3heartbeat::p3heartbeat(p3LinkMgr *linkMgr, pqipersongrp *pqipg)
|
||||
:p3Service(RS_SERVICE_TYPE_HEARTBEAT), mLinkMgr(linkMgr), mPqiPersonGrp(pqipg),
|
||||
mHeartMtx("p3heartbeat")
|
||||
{
|
||||
RsStackMutex stack(mHeartMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
addSerialType(new RsHeartbeatSerialiser());
|
||||
|
||||
#ifdef HEART_DEBUG
|
||||
std::cerr << "p3heartbeat::p3heartbeat()";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
mLastHeartbeat = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
p3heartbeat::~p3heartbeat()
|
||||
{
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
int p3heartbeat::tick()
|
||||
{
|
||||
//send a heartbeat to all connected peers
|
||||
RsStackMutex stack(mHeartMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
if (time(NULL) - mLastHeartbeat > HEARTBEAT_REPEAT_TIME)
|
||||
{
|
||||
mLastHeartbeat = time(NULL);
|
||||
|
||||
std::list<std::string> peers;
|
||||
std::list<std::string>::const_iterator pit;
|
||||
|
||||
mLinkMgr->getOnlineList(peers);
|
||||
for (pit = peers.begin(); pit != peers.end(); ++pit)
|
||||
{
|
||||
sendHeartbeat(*pit);
|
||||
}
|
||||
}
|
||||
|
||||
int nhandled = 0;
|
||||
RsItem *item = NULL;
|
||||
|
||||
// While messages read
|
||||
while(NULL != (item = recvItem()))
|
||||
{
|
||||
RsHeartbeatItem *beat = NULL;
|
||||
nhandled++;
|
||||
|
||||
// if discovery reply then respond if haven't already.
|
||||
if (NULL != (beat = dynamic_cast<RsHeartbeatItem *> (item)))
|
||||
{
|
||||
recvHeartbeat(beat->PeerId());
|
||||
}
|
||||
else
|
||||
{
|
||||
// unknown.
|
||||
}
|
||||
|
||||
delete item;
|
||||
}
|
||||
|
||||
return nhandled ;
|
||||
}
|
||||
|
||||
void p3heartbeat::sendHeartbeat(const std::string &toId)
|
||||
{
|
||||
|
||||
#ifdef HEART_DEBUG
|
||||
std::cerr << "p3heartbeat::sendHeartbeat() to " << toId;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
RsHeartbeatItem *item = new RsHeartbeatItem();
|
||||
item->PeerId(toId);
|
||||
sendItem(item);
|
||||
}
|
||||
|
||||
|
||||
void p3heartbeat::recvHeartbeat(const std::string &fromId)
|
||||
{
|
||||
|
||||
#ifdef HEART_DEBUG
|
||||
std::cerr << "p3heartbeat::recvHeartbeat() from " << fromId;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
mPqiPersonGrp->tagHeartbeatRecvd(fromId);
|
||||
}
|
||||
|
||||
|
61
libretroshare/src/services/p3heartbeat.h
Normal file
61
libretroshare/src/services/p3heartbeat.h
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* libretroshare/src/services: p3heartbeat.h
|
||||
*
|
||||
* Services for RetroShare.
|
||||
*
|
||||
* Copyright 2004-2013 by Robert Fernie.
|
||||
*
|
||||
* 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.1 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 "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MRK_SERVICES_HEARTBEAT_H
|
||||
#define MRK_SERVICES_HEARTBEAT_H
|
||||
|
||||
// Moved Heartbeat to a seperate service.
|
||||
|
||||
#include "pqi/p3linkmgr.h"
|
||||
#include "pqi/pqipersongrp.h"
|
||||
#include "services/p3service.h"
|
||||
|
||||
|
||||
class p3heartbeat: public p3Service
|
||||
{
|
||||
public:
|
||||
|
||||
p3heartbeat(p3LinkMgr *linkMgr, pqipersongrp *pqipg);
|
||||
virtual ~p3heartbeat();
|
||||
|
||||
int tick();
|
||||
|
||||
private:
|
||||
|
||||
void sendHeartbeat(const std::string &toId);
|
||||
void recvHeartbeat(const std::string &fromId);
|
||||
|
||||
private:
|
||||
|
||||
p3LinkMgr *mLinkMgr;
|
||||
pqipersongrp *mPqiPersonGrp;
|
||||
|
||||
/* data */
|
||||
RsMutex mHeartMtx;
|
||||
|
||||
time_t mLastHeartbeat;
|
||||
};
|
||||
|
||||
#endif // MRK_SERVICES_HEARTBEAT_H
|
File diff suppressed because it is too large
Load diff
|
@ -38,9 +38,12 @@
|
|||
|
||||
#include "util/rsmemcache.h"
|
||||
#include "util/rstickevent.h"
|
||||
#include "util/rsrecogn.h"
|
||||
|
||||
#include "pqi/authgpg.h"
|
||||
|
||||
#include "serialiser/rsgxsrecognitems.h"
|
||||
|
||||
/*
|
||||
* Identity Service
|
||||
*
|
||||
|
@ -73,6 +76,27 @@ virtual std::string save() const;
|
|||
std::string pgpId;
|
||||
};
|
||||
|
||||
class SSGxsIdRecognTags: public SSBit
|
||||
{
|
||||
public:
|
||||
SSGxsIdRecognTags()
|
||||
:tagFlags(0), publishTs(0), lastCheckTs(0) { return; }
|
||||
|
||||
virtual bool load(const std::string &input);
|
||||
virtual std::string save() const;
|
||||
|
||||
void setTags(bool processed, bool pending, uint32_t flags);
|
||||
|
||||
bool tagsProcessed() const; // have we processed?
|
||||
bool tagsPending() const; // should we reprocess?
|
||||
bool tagValid(int i) const;
|
||||
|
||||
uint32_t tagFlags;
|
||||
time_t publishTs;
|
||||
time_t lastCheckTs;
|
||||
};
|
||||
|
||||
|
||||
class SSGxsIdScore: public SSBit
|
||||
{
|
||||
public:
|
||||
|
@ -113,11 +137,14 @@ virtual std::string save() const;
|
|||
// pgphash status
|
||||
SSGxsIdPgp pgp;
|
||||
|
||||
// recogTags.
|
||||
SSGxsIdRecognTags recogntags;
|
||||
|
||||
// reputation score.
|
||||
SSGxsIdScore score;
|
||||
SSGxsIdCumulator opinion;
|
||||
SSGxsIdCumulator reputation;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#define ID_LOCAL_STATUS_FULL_CALC_FLAG 0x00010000
|
||||
|
@ -133,10 +160,14 @@ class RsGxsIdCache
|
|||
{
|
||||
public:
|
||||
RsGxsIdCache();
|
||||
RsGxsIdCache(const RsGxsIdGroupItem *item, const RsTlvSecurityKey &in_pkey);
|
||||
RsGxsIdCache(const RsGxsIdGroupItem *item, const RsTlvSecurityKey &in_pkey,
|
||||
const std::list<RsRecognTag> &tagList);
|
||||
|
||||
void updateServiceString(std::string serviceString);
|
||||
|
||||
time_t mPublishTs;
|
||||
std::list<RsRecognTag> mRecognTags; // Only partially validated.
|
||||
|
||||
RsIdentityDetails details;
|
||||
RsTlvSecurityKey pubkey;
|
||||
};
|
||||
|
@ -165,6 +196,12 @@ static uint32_t idAuthenPolicy();
|
|||
virtual void service_tick(); // needed for background processing.
|
||||
|
||||
|
||||
/*!
|
||||
* Design hack, id service must be constructed first as it
|
||||
* is need for construction of subsequent net services
|
||||
*/
|
||||
void setNes(RsNetworkExchangeService* nes);
|
||||
|
||||
/* General Interface is provided by RsIdentity / RsGxsIfaceImpl. */
|
||||
|
||||
/* Data Specific Interface */
|
||||
|
@ -175,6 +212,7 @@ virtual bool getMsgData(const uint32_t &token, std::vector<RsGxsIdOpinion> &opin
|
|||
|
||||
// These are local - and not exposed via RsIdentity.
|
||||
virtual bool createGroup(uint32_t& token, RsGxsIdGroup &group);
|
||||
virtual bool updateGroup(uint32_t& token, RsGxsIdGroup &group);
|
||||
virtual bool createMsg(uint32_t& token, RsGxsIdOpinion &opinion);
|
||||
|
||||
/**************** RsIdentity External Interface.
|
||||
|
@ -197,6 +235,13 @@ virtual bool getOwnIds(std::list<RsGxsId> &ownIds);
|
|||
virtual bool submitOpinion(uint32_t& token, RsIdOpinion &opinion);
|
||||
virtual bool createIdentity(uint32_t& token, RsIdentityParameters ¶ms);
|
||||
|
||||
virtual bool updateIdentity(uint32_t& token, RsGxsIdGroup &group);
|
||||
|
||||
virtual bool parseRecognTag(const RsGxsId &id, const std::string &nickname,
|
||||
const std::string &tag, RsRecognTagDetails &details);
|
||||
virtual bool getRecognTagRequest(const RsGxsId &id, const std::string &comment,
|
||||
uint16_t tag_class, uint16_t tag_type, std::string &tag);
|
||||
|
||||
|
||||
/**************** RsGixs Implementation
|
||||
* Notes:
|
||||
|
@ -219,7 +264,7 @@ virtual int getPrivateKey(const RsGxsId &id, RsTlvSecurityKey &key);
|
|||
|
||||
// get Reputation.
|
||||
virtual bool haveReputation(const RsGxsId &id);
|
||||
virtual bool loadReputation(const RsGxsId &id);
|
||||
virtual bool loadReputation(const RsGxsId &id, const std::list<std::string>& peers);
|
||||
virtual bool getReputation(const RsGxsId &id, GixsReputation &rep);
|
||||
|
||||
|
||||
|
@ -245,16 +290,20 @@ virtual void handle_event(uint32_t event_type, const std::string &elabel);
|
|||
*/
|
||||
int cache_tick();
|
||||
|
||||
bool cache_request_load(const RsGxsId &id);
|
||||
bool cache_request_load(const RsGxsId &id, const std::list<std::string>& peers = std::list<std::string>());
|
||||
bool cache_start_load();
|
||||
bool cache_load_for_token(uint32_t token);
|
||||
|
||||
bool cache_store(const RsGxsIdGroupItem *item);
|
||||
bool cache_update_if_cached(const RsGxsId &id, std::string serviceString);
|
||||
|
||||
bool isPendingNetworkRequest(const RsGxsId& gxsId) const;
|
||||
void requestIdsFromNet();
|
||||
|
||||
// Mutex protected.
|
||||
|
||||
std::list<RsGxsId> mCacheLoad_ToCache;
|
||||
//std::list<RsGxsId> mCacheLoad_ToCache;
|
||||
std::map<RsGxsId, std::list<std::string> > mCacheLoad_ToCache, mPendingCache;
|
||||
|
||||
// Switching to RsMemCache for Key Caching.
|
||||
RsMemCache<RsGxsId, RsGxsIdCache> mPublicKeyCache;
|
||||
|
@ -303,6 +352,39 @@ virtual void handle_event(uint32_t event_type, const std::string &elabel);
|
|||
std::map<PGPIdType, PGPFingerprintType> mPgpFingerprintMap;
|
||||
std::list<RsGxsIdGroup> mGroupsToProcess;
|
||||
|
||||
/************************************************************************
|
||||
* recogn processing.
|
||||
*
|
||||
*/
|
||||
bool recogn_schedule();
|
||||
bool recogn_start();
|
||||
bool recogn_handlerequest(uint32_t token);
|
||||
bool recogn_process();
|
||||
|
||||
// helper functions.
|
||||
bool recogn_extract_taginfo(const RsGxsIdGroupItem *item, std::list<RsGxsRecognTagItem *> &tagItems);
|
||||
bool cache_process_recogntaginfo(const RsGxsIdGroupItem *item, std::list<RsRecognTag> &tagList);
|
||||
|
||||
bool recogn_checktag(const RsGxsId &id, const std::string &nickname, RsGxsRecognTagItem *item, bool doSignCheck, bool &isPending);
|
||||
|
||||
void loadRecognKeys();
|
||||
|
||||
/************************************************************************
|
||||
* for getting identities that are not present
|
||||
*
|
||||
*/
|
||||
void checkPeerForIdentities();
|
||||
|
||||
/* MUTEX PROTECTED DATA (mIdMtx - maybe should use a 2nd?) */
|
||||
|
||||
bool checkRecognSignature_locked(std::string encoded, RSA &key, std::string signature);
|
||||
bool getRecognKey_locked(std::string signer, RSA &key);
|
||||
|
||||
std::list<RsGxsGroupId> mRecognGroupIds;
|
||||
std::list<RsGxsIdGroupItem *> mRecognGroupsToProcess;
|
||||
std::map<std::string, RsGxsRecognSignerItem *> mRecognSignKeys;
|
||||
std::map<std::string, uint32_t> mRecognOldSignKeys;
|
||||
|
||||
/************************************************************************
|
||||
* Below is the background task for processing opinions => reputations
|
||||
*
|
||||
|
@ -348,6 +430,12 @@ std::string genRandomId(int len = 20);
|
|||
std::vector<RsGxsGroupChange*> mGroupChange;
|
||||
std::vector<RsGxsMsgChange*> mMsgChange;
|
||||
|
||||
private:
|
||||
|
||||
std::map<uint32_t, std::set<RsGxsGroupId> > mIdsPendingCache;
|
||||
std::map<uint32_t, std::list<RsGxsGroupId> > mGroupNotPresent;
|
||||
std::map<RsGxsId, std::list<std::string> > mIdsNotPresent;
|
||||
RsNetworkExchangeService* mNes;
|
||||
};
|
||||
|
||||
#endif // P3_IDENTITY_SERVICE_HEADER
|
||||
|
|
|
@ -166,14 +166,10 @@ void p3MsgService::processMsg(RsMsgItem *mi, bool incoming)
|
|||
p3Notify *notify = RsServer::notify();
|
||||
if (notify)
|
||||
{
|
||||
std::string title, message;
|
||||
librs::util::ConvertUtf16ToUtf8(mi->subject, title);
|
||||
librs::util::ConvertUtf16ToUtf8(mi->message, message);
|
||||
|
||||
if(mi->msgFlags & RS_MSG_FLAGS_ENCRYPTED)
|
||||
notify->AddPopupMessage(RS_POPUP_ENCRYPTED_MSG, mi->PeerId(), title, message);
|
||||
notify->AddPopupMessage(RS_POPUP_ENCRYPTED_MSG, mi->PeerId(), mi->subject, mi->message);
|
||||
else
|
||||
notify->AddPopupMessage(RS_POPUP_MSG, mi->PeerId(), title, message);
|
||||
notify->AddPopupMessage(RS_POPUP_MSG, mi->PeerId(), mi->subject, mi->message);
|
||||
|
||||
std::string out;
|
||||
rs_sprintf(out, "%lu", mi->msgId);
|
||||
|
@ -707,12 +703,12 @@ void p3MsgService::loadWelcomeMsg()
|
|||
msg -> recvTime = time(NULL);
|
||||
msg -> msgFlags = RS_MSG_FLAGS_NEW;
|
||||
|
||||
msg -> subject = L"Welcome to Retroshare";
|
||||
msg -> subject = "Welcome to Retroshare";
|
||||
|
||||
msg -> message = L"Send and receive messages with your friends...\n";
|
||||
msg -> message += L"These can hold recommendations from your local shared files.\n\n";
|
||||
msg -> message += L"Add recommendations through the Local Files Dialog.\n\n";
|
||||
msg -> message += L"Enjoy.";
|
||||
msg -> message = "Send and receive messages with your friends...\n";
|
||||
msg -> message += "These can hold recommendations from your local shared files.\n\n";
|
||||
msg -> message += "Add recommendations through the Local Files Dialog.\n\n";
|
||||
msg -> message += "Enjoy.";
|
||||
|
||||
msg -> msgId = getNewUniqueMsgId();
|
||||
|
||||
|
@ -1110,7 +1106,7 @@ bool p3MsgService::MessageSend(MessageInfo &info)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool p3MsgService::SystemMessage(const std::wstring &title, const std::wstring &message, uint32_t systemFlag)
|
||||
bool p3MsgService::SystemMessage(const std::string &title, const std::string &message, uint32_t systemFlag)
|
||||
{
|
||||
if ((systemFlag & RS_MSG_SYSTEM) == 0) {
|
||||
/* no flag specified */
|
||||
|
@ -1884,22 +1880,21 @@ bool p3MsgService::encryptMessage(const std::string& pgp_id,RsMsgItem *item)
|
|||
#endif
|
||||
// Now turn the binary encrypted chunk into a readable radix string.
|
||||
//
|
||||
#ifdef DEBUG_DISTANT_MSG
|
||||
std::cerr << " Converting to radix64" << std::endl;
|
||||
#endif
|
||||
std::string armoured_data ;
|
||||
Radix64::encode((char *)encrypted_data,encrypted_size,armoured_data) ;
|
||||
delete[] encrypted_data ;
|
||||
|
||||
std::wstring encrypted_msg ;
|
||||
|
||||
#ifdef DEBUG_DISTANT_MSG
|
||||
std::cerr << " Converting to radix64" << std::endl;
|
||||
#endif
|
||||
if(!librs::util::ConvertUtf8ToUtf16(armoured_data,encrypted_msg))
|
||||
return false;
|
||||
//std::wstring encrypted_msg = armoured_data;
|
||||
//if(!librs::util::ConvertUtf8ToUtf16(armoured_data,encrypted_msg))
|
||||
// return false;
|
||||
|
||||
// wipe the item clean and replace the message by the encrypted data.
|
||||
|
||||
item->message = encrypted_msg ;
|
||||
item->subject = L"" ;
|
||||
item->message = armoured_data ;
|
||||
item->subject = "" ;
|
||||
item->msgcc.ids.clear() ;
|
||||
item->msgbcc.ids.clear() ;
|
||||
item->msgto.ids.clear() ;
|
||||
|
@ -1925,11 +1920,13 @@ bool p3MsgService::decryptMessage(const std::string& mId)
|
|||
|
||||
std::map<uint32_t, RsMsgItem *>::iterator mit = imsg.find(msgId);
|
||||
|
||||
if(mit == imsg.end() || !librs::util::ConvertUtf16ToUtf8(mit->second->message,encrypted_string))
|
||||
if(mit == imsg.end())
|
||||
{
|
||||
std::cerr << "Can't find this message in msg list. Id=" << mId << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
encrypted_string = mit->second->message ;
|
||||
}
|
||||
|
||||
char *encrypted_data ;
|
||||
|
|
|
@ -75,7 +75,7 @@ bool getMsgParentId(const std::string &msgId, std::string &msgParentId);
|
|||
bool setMsgParentId(uint32_t msgId, uint32_t msgParentId);
|
||||
|
||||
bool MessageSend(MessageInfo &info);
|
||||
bool SystemMessage(const std::wstring &title, const std::wstring &message, uint32_t systemFlag);
|
||||
bool SystemMessage(const std::string &title, const std::string &message, uint32_t systemFlag);
|
||||
bool MessageToDraft(MessageInfo &info, const std::string &msgParentId);
|
||||
bool MessageToTrash(const std::string &mid, bool bTrash);
|
||||
|
||||
|
|
723
libretroshare/src/services/p3postbase.cc
Normal file
723
libretroshare/src/services/p3postbase.cc
Normal file
|
@ -0,0 +1,723 @@
|
|||
/*
|
||||
* libretroshare/src/services p3posted.cc
|
||||
*
|
||||
* Posted interface for RetroShare.
|
||||
*
|
||||
* Copyright 2012-2012 by Robert Fernie.
|
||||
*
|
||||
* 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.1 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 "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#include <retroshare/rsidentity.h>
|
||||
|
||||
#include "retroshare/rsgxsflags.h"
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "services/p3postbase.h"
|
||||
#include "serialiser/rsgxscommentitems.h"
|
||||
|
||||
// For Dummy Msgs.
|
||||
#include "util/rsrandom.h"
|
||||
#include "util/rsstring.h"
|
||||
|
||||
/****
|
||||
* #define POSTBASE_DEBUG 1
|
||||
****/
|
||||
|
||||
#define POSTBASE_BACKGROUND_PROCESSING 0x0002
|
||||
#define PROCESSING_START_PERIOD 30
|
||||
#define PROCESSING_INC_PERIOD 15
|
||||
|
||||
#define POSTBASE_ALL_GROUPS 0x0011
|
||||
#define POSTBASE_UNPROCESSED_MSGS 0x0012
|
||||
#define POSTBASE_ALL_MSGS 0x0013
|
||||
#define POSTBASE_BG_POST_META 0x0014
|
||||
/********************************************************************************/
|
||||
/******************* Startup / Tick ******************************************/
|
||||
/********************************************************************************/
|
||||
|
||||
p3PostBase::p3PostBase(RsGeneralDataService *gds, RsNetworkExchangeService *nes, RsGixs* gixs,
|
||||
RsSerialType* serviceSerialiser, uint16_t serviceType)
|
||||
: RsGenExchange(gds, nes, serviceSerialiser, serviceType, gixs, postBaseAuthenPolicy()), GxsTokenQueue(this), RsTickEvent(), mPostBaseMtx("PostBaseMtx")
|
||||
{
|
||||
mBgProcessing = false;
|
||||
|
||||
mCommentService = new p3GxsCommentService(this, serviceType);
|
||||
RsTickEvent::schedule_in(POSTBASE_BACKGROUND_PROCESSING, PROCESSING_START_PERIOD);
|
||||
}
|
||||
|
||||
|
||||
uint32_t p3PostBase::postBaseAuthenPolicy()
|
||||
{
|
||||
uint32_t policy = 0;
|
||||
uint32_t flag = 0;
|
||||
|
||||
flag = GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN | GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN;
|
||||
RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PUBLIC_GRP_BITS);
|
||||
|
||||
flag |= GXS_SERV::MSG_AUTHEN_ROOT_PUBLISH_SIGN | GXS_SERV::MSG_AUTHEN_CHILD_PUBLISH_SIGN;
|
||||
RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::RESTRICTED_GRP_BITS);
|
||||
RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::PRIVATE_GRP_BITS);
|
||||
|
||||
flag = 0;
|
||||
RsGenExchange::setAuthenPolicyFlag(flag, policy, RsGenExchange::GRP_OPTION_BITS);
|
||||
|
||||
return policy;
|
||||
}
|
||||
|
||||
void p3PostBase::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
||||
{
|
||||
std::cerr << "p3PostBase::notifyChanges()";
|
||||
std::cerr << std::endl;
|
||||
|
||||
std::vector<RsGxsNotify *> changesForGUI;
|
||||
std::vector<RsGxsNotify *>::iterator it;
|
||||
|
||||
for(it = changes.begin(); it != changes.end(); it++)
|
||||
{
|
||||
RsGxsGroupChange *groupChange = dynamic_cast<RsGxsGroupChange *>(*it);
|
||||
RsGxsMsgChange *msgChange = dynamic_cast<RsGxsMsgChange *>(*it);
|
||||
if (msgChange)
|
||||
{
|
||||
std::cerr << "p3PostBase::notifyChanges() Found Message Change Notification";
|
||||
std::cerr << std::endl;
|
||||
|
||||
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> > &msgChangeMap = msgChange->msgChangeMap;
|
||||
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> >::iterator mit;
|
||||
for(mit = msgChangeMap.begin(); mit != msgChangeMap.end(); mit++)
|
||||
{
|
||||
std::cerr << "p3PostBase::notifyChanges() Msgs for Group: " << mit->first;
|
||||
std::cerr << std::endl;
|
||||
// To start with we are just going to trigger updates on these groups.
|
||||
// FUTURE OPTIMISATION.
|
||||
// It could be taken a step further and directly request these msgs for an update.
|
||||
addGroupForProcessing(mit->first);
|
||||
}
|
||||
delete msgChange;
|
||||
}
|
||||
|
||||
/* pass on Group Changes to GUI */
|
||||
if (groupChange)
|
||||
{
|
||||
std::cerr << "p3PostBase::notifyChanges() Found Group Change Notification";
|
||||
std::cerr << std::endl;
|
||||
|
||||
std::list<RsGxsGroupId> &groupList = groupChange->mGrpIdList;
|
||||
std::list<RsGxsGroupId>::iterator git;
|
||||
for(git = groupList.begin(); git != groupList.end(); git++)
|
||||
{
|
||||
std::cerr << "p3PostBase::notifyChanges() Incoming Group: " << *git;
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
changesForGUI.push_back(groupChange);
|
||||
}
|
||||
}
|
||||
changes.clear();
|
||||
receiveHelperChanges(changesForGUI);
|
||||
|
||||
std::cerr << "p3PostBase::notifyChanges() -> receiveChanges()";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
|
||||
void p3PostBase::service_tick()
|
||||
{
|
||||
RsTickEvent::tick_events();
|
||||
GxsTokenQueue::checkRequests();
|
||||
|
||||
mCommentService->comment_tick();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/********************************************************************************************/
|
||||
/********************************************************************************************/
|
||||
|
||||
void p3PostBase::setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read)
|
||||
{
|
||||
uint32_t mask = GXS_SERV::GXS_MSG_STATUS_UNREAD | GXS_SERV::GXS_MSG_STATUS_UNPROCESSED;
|
||||
uint32_t status = GXS_SERV::GXS_MSG_STATUS_UNREAD;
|
||||
if (read)
|
||||
{
|
||||
status = 0;
|
||||
}
|
||||
|
||||
setMsgStatusFlags(token, msgId, status, mask);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Overloaded from RsTickEvent for Event callbacks.
|
||||
void p3PostBase::handle_event(uint32_t event_type, const std::string & /* elabel */)
|
||||
{
|
||||
std::cerr << "p3PostBase::handle_event(" << event_type << ")";
|
||||
std::cerr << std::endl;
|
||||
|
||||
// stuff.
|
||||
switch(event_type)
|
||||
{
|
||||
case POSTBASE_BACKGROUND_PROCESSING:
|
||||
background_tick();
|
||||
break;
|
||||
|
||||
default:
|
||||
/* error */
|
||||
std::cerr << "p3PostBase::handle_event() Unknown Event Type: " << event_type;
|
||||
std::cerr << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************************
|
||||
* Background Calculations.
|
||||
*
|
||||
* Get list of change groups from Notify....
|
||||
* this doesn't imclude your own submissions (at this point).
|
||||
* So they will not be processed until someone else changes something.
|
||||
* TODO FIX: Must push for that change.
|
||||
*
|
||||
* Eventually, we should just be able to get the new messages from Notify,
|
||||
* and only process them!
|
||||
*/
|
||||
|
||||
void p3PostBase::background_tick()
|
||||
{
|
||||
|
||||
#if 0
|
||||
{
|
||||
RsStackMutex stack(mPostBaseMtx); /********** STACK LOCKED MTX ******/
|
||||
if (mBgGroupList.empty())
|
||||
{
|
||||
background_requestAllGroups();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
background_requestUnprocessedGroup();
|
||||
|
||||
RsTickEvent::schedule_in(POSTBASE_BACKGROUND_PROCESSING, PROCESSING_INC_PERIOD);
|
||||
|
||||
}
|
||||
|
||||
bool p3PostBase::background_requestAllGroups()
|
||||
{
|
||||
std::cerr << "p3PostBase::background_requestAllGroups()";
|
||||
std::cerr << std::endl;
|
||||
|
||||
uint32_t ansType = RS_TOKREQ_ANSTYPE_LIST;
|
||||
RsTokReqOptions opts;
|
||||
opts.mReqType = GXS_REQUEST_TYPE_GROUP_IDS;
|
||||
|
||||
uint32_t token = 0;
|
||||
RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts);
|
||||
GxsTokenQueue::queueRequest(token, POSTBASE_ALL_GROUPS);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void p3PostBase::background_loadGroups(const uint32_t &token)
|
||||
{
|
||||
/* get messages */
|
||||
std::cerr << "p3PostBase::background_loadGroups()";
|
||||
std::cerr << std::endl;
|
||||
|
||||
std::list<RsGxsGroupId> groupList;
|
||||
bool ok = RsGenExchange::getGroupList(token, groupList);
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::list<RsGxsGroupId>::iterator it;
|
||||
for(it = groupList.begin(); it != groupList.end(); it++)
|
||||
{
|
||||
addGroupForProcessing(*it);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void p3PostBase::addGroupForProcessing(RsGxsGroupId grpId)
|
||||
{
|
||||
#ifdef POSTBASE_DEBUG
|
||||
std::cerr << "p3PostBase::addGroupForProcessing(" << grpId << ")";
|
||||
std::cerr << std::endl;
|
||||
#endif // POSTBASE_DEBUG
|
||||
|
||||
{
|
||||
RsStackMutex stack(mPostBaseMtx); /********** STACK LOCKED MTX ******/
|
||||
// no point having multiple lookups queued.
|
||||
if (mBgGroupList.end() == std::find(mBgGroupList.begin(),
|
||||
mBgGroupList.end(), grpId))
|
||||
{
|
||||
mBgGroupList.push_back(grpId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void p3PostBase::background_requestUnprocessedGroup()
|
||||
{
|
||||
#ifdef POSTBASE_DEBUG
|
||||
std::cerr << "p3PostBase::background_requestUnprocessedGroup()";
|
||||
std::cerr << std::endl;
|
||||
#endif // POSTBASE_DEBUG
|
||||
|
||||
|
||||
RsGxsGroupId grpId;
|
||||
{
|
||||
RsStackMutex stack(mPostBaseMtx); /********** STACK LOCKED MTX ******/
|
||||
if (mBgProcessing)
|
||||
{
|
||||
std::cerr << "p3PostBase::background_requestUnprocessedGroup() Already Active";
|
||||
std::cerr << std::endl;
|
||||
return;
|
||||
}
|
||||
if (mBgGroupList.empty())
|
||||
{
|
||||
std::cerr << "p3PostBase::background_requestUnprocessedGroup() No Groups to Process";
|
||||
std::cerr << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
grpId = mBgGroupList.front();
|
||||
mBgGroupList.pop_front();
|
||||
mBgProcessing = true;
|
||||
}
|
||||
|
||||
background_requestGroupMsgs(grpId, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void p3PostBase::background_requestGroupMsgs(const RsGxsGroupId &grpId, bool unprocessedOnly)
|
||||
{
|
||||
std::cerr << "p3PostBase::background_requestGroupMsgs() id: " << grpId;
|
||||
std::cerr << std::endl;
|
||||
|
||||
uint32_t ansType = RS_TOKREQ_ANSTYPE_DATA;
|
||||
RsTokReqOptions opts;
|
||||
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
|
||||
|
||||
if (unprocessedOnly)
|
||||
{
|
||||
opts.mStatusFilter = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED;
|
||||
opts.mStatusMask = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED;
|
||||
}
|
||||
|
||||
std::list<RsGxsGroupId> grouplist;
|
||||
grouplist.push_back(grpId);
|
||||
|
||||
uint32_t token = 0;
|
||||
|
||||
RsGenExchange::getTokenService()->requestMsgInfo(token, ansType, opts, grouplist);
|
||||
|
||||
if (unprocessedOnly)
|
||||
{
|
||||
GxsTokenQueue::queueRequest(token, POSTBASE_UNPROCESSED_MSGS);
|
||||
}
|
||||
else
|
||||
{
|
||||
GxsTokenQueue::queueRequest(token, POSTBASE_ALL_MSGS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void p3PostBase::background_loadUnprocessedMsgs(const uint32_t &token)
|
||||
{
|
||||
background_loadMsgs(token, true);
|
||||
}
|
||||
|
||||
|
||||
void p3PostBase::background_loadAllMsgs(const uint32_t &token)
|
||||
{
|
||||
background_loadMsgs(token, false);
|
||||
}
|
||||
|
||||
|
||||
/* This function is generalised to support any collection of messages, across multiple groups */
|
||||
|
||||
void p3PostBase::background_loadMsgs(const uint32_t &token, bool unprocessed)
|
||||
{
|
||||
/* get messages */
|
||||
std::cerr << "p3PostBase::background_loadMsgs()";
|
||||
std::cerr << std::endl;
|
||||
|
||||
std::map<RsGxsGroupId, std::vector<RsGxsMsgItem*> > msgData;
|
||||
bool ok = RsGenExchange::getMsgData(token, msgData);
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
std::cerr << "p3PostBase::background_loadMsgs() Failed to getMsgData()";
|
||||
std::cerr << std::endl;
|
||||
|
||||
/* cleanup */
|
||||
background_cleanup();
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
RsStackMutex stack(mPostBaseMtx); /********** STACK LOCKED MTX ******/
|
||||
mBgStatsMap.clear();
|
||||
mBgIncremental = unprocessed;
|
||||
}
|
||||
|
||||
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> > postMap;
|
||||
|
||||
// generate vector of changes to push to the GUI.
|
||||
std::vector<RsGxsNotify *> changes;
|
||||
RsGxsMsgChange *msgChanges = new RsGxsMsgChange(RsGxsNotify::TYPE_PROCESSED);
|
||||
|
||||
|
||||
RsGxsGroupId groupId;
|
||||
std::map<RsGxsGroupId, std::vector<RsGxsMsgItem*> >::iterator mit;
|
||||
std::vector<RsGxsMsgItem*>::iterator vit;
|
||||
for (mit = msgData.begin(); mit != msgData.end(); mit++)
|
||||
{
|
||||
groupId = mit->first;
|
||||
for (vit = mit->second.begin(); vit != mit->second.end(); vit++)
|
||||
{
|
||||
RsGxsMessageId parentId = (*vit)->meta.mParentId;
|
||||
RsGxsMessageId threadId = (*vit)->meta.mThreadId;
|
||||
|
||||
|
||||
bool inc_counters = false;
|
||||
uint32_t vote_up_inc = 0;
|
||||
uint32_t vote_down_inc = 0;
|
||||
uint32_t comment_inc = 0;
|
||||
|
||||
bool add_voter = false;
|
||||
RsGxsId voterId;
|
||||
RsGxsCommentItem *commentItem;
|
||||
RsGxsVoteItem *voteItem;
|
||||
|
||||
/* THIS Should be handled by UNPROCESSED Filter - but isn't */
|
||||
if (!IS_MSG_UNPROCESSED((*vit)->meta.mMsgStatus))
|
||||
{
|
||||
RsStackMutex stack(mPostBaseMtx); /********** STACK LOCKED MTX ******/
|
||||
if (mBgIncremental)
|
||||
{
|
||||
std::cerr << "p3PostBase::background_loadMsgs() Msg already Processed - Skipping";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "p3PostBase::background_loadMsgs() ERROR This should not happen";
|
||||
std::cerr << std::endl;
|
||||
delete(*vit);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* 3 types expected: PostedPost, Comment and Vote */
|
||||
if (parentId.empty())
|
||||
{
|
||||
/* we don't care about top-level (Posts) */
|
||||
std::cerr << "\tIgnoring TopLevel Item";
|
||||
std::cerr << std::endl;
|
||||
|
||||
/* but we need to notify GUI about them */
|
||||
msgChanges->msgChangeMap[mit->first].push_back((*vit)->meta.mMsgId);
|
||||
}
|
||||
else if (NULL != (commentItem = dynamic_cast<RsGxsCommentItem *>(*vit)))
|
||||
{
|
||||
/* comment - want all */
|
||||
/* Comments are counted by Thread Id */
|
||||
std::cerr << "\tProcessing Comment: " << commentItem;
|
||||
std::cerr << std::endl;
|
||||
|
||||
inc_counters = true;
|
||||
comment_inc = 1;
|
||||
}
|
||||
else if (NULL != (voteItem = dynamic_cast<RsGxsVoteItem *>(*vit)))
|
||||
{
|
||||
/* vote - only care about direct children */
|
||||
if (parentId == threadId)
|
||||
{
|
||||
/* Votes are organised by Parent Id,
|
||||
* ie. you can vote for both Posts and Comments
|
||||
*/
|
||||
std::cerr << "\tProcessing Vote: " << voteItem;
|
||||
std::cerr << std::endl;
|
||||
|
||||
inc_counters = true;
|
||||
add_voter = true;
|
||||
voterId = voteItem->meta.mAuthorId;
|
||||
|
||||
if (voteItem->mMsg.mVoteType == GXS_VOTE_UP)
|
||||
{
|
||||
vote_up_inc = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
vote_down_inc = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* unknown! */
|
||||
std::cerr << "p3PostBase::background_processNewMessages() ERROR Strange NEW Message:";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "\t" << (*vit)->meta;
|
||||
std::cerr << std::endl;
|
||||
|
||||
}
|
||||
|
||||
if (inc_counters)
|
||||
{
|
||||
RsStackMutex stack(mPostBaseMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
std::map<RsGxsMessageId, PostStats>::iterator sit = mBgStatsMap.find(threadId);
|
||||
if (sit == mBgStatsMap.end())
|
||||
{
|
||||
// add to map of ones to update.
|
||||
postMap[groupId].push_back(threadId);
|
||||
|
||||
mBgStatsMap[threadId] = PostStats(0,0,0);
|
||||
sit = mBgStatsMap.find(threadId);
|
||||
}
|
||||
|
||||
sit->second.comments += comment_inc;
|
||||
sit->second.up_votes += vote_up_inc;
|
||||
sit->second.down_votes += vote_down_inc;
|
||||
|
||||
|
||||
if (add_voter)
|
||||
{
|
||||
sit->second.voters.push_back(voterId);
|
||||
}
|
||||
|
||||
std::cerr << "\tThreadId: " << threadId;
|
||||
std::cerr << " Comment Total: " << sit->second.comments;
|
||||
std::cerr << " UpVote Total: " << sit->second.up_votes;
|
||||
std::cerr << " DownVote Total: " << sit->second.down_votes;
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
|
||||
/* flag all messages as processed */
|
||||
if ((*vit)->meta.mMsgStatus & GXS_SERV::GXS_MSG_STATUS_UNPROCESSED)
|
||||
{
|
||||
uint32_t token_a;
|
||||
RsGxsGrpMsgIdPair msgId = std::make_pair(groupId, (*vit)->meta.mMsgId);
|
||||
RsGenExchange::setMsgStatusFlags(token_a, msgId, 0, GXS_SERV::GXS_MSG_STATUS_UNPROCESSED);
|
||||
}
|
||||
delete(*vit);
|
||||
}
|
||||
}
|
||||
|
||||
/* push updates of new Posts */
|
||||
if (msgChanges->msgChangeMap.size() > 0)
|
||||
{
|
||||
std::cerr << "p3PostBase::background_processNewMessages() -> receiveChanges()";
|
||||
std::cerr << std::endl;
|
||||
|
||||
changes.push_back(msgChanges);
|
||||
receiveHelperChanges(changes);
|
||||
}
|
||||
|
||||
/* request the summary info from the parents */
|
||||
uint32_t token_b;
|
||||
uint32_t anstype = RS_TOKREQ_ANSTYPE_SUMMARY;
|
||||
RsTokReqOptions opts;
|
||||
opts.mReqType = GXS_REQUEST_TYPE_MSG_META;
|
||||
RsGenExchange::getTokenService()->requestMsgInfo(token_b, anstype, opts, postMap);
|
||||
|
||||
GxsTokenQueue::queueRequest(token_b, POSTBASE_BG_POST_META);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#define RSGXS_MAX_SERVICE_STRING 1024
|
||||
bool encodePostCache(std::string &str, const PostStats &s)
|
||||
{
|
||||
char line[RSGXS_MAX_SERVICE_STRING];
|
||||
|
||||
snprintf(line, RSGXS_MAX_SERVICE_STRING, "%d %d %d", s.comments, s.up_votes, s.down_votes);
|
||||
|
||||
str = line;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool extractPostCache(const std::string &str, PostStats &s)
|
||||
{
|
||||
|
||||
uint32_t iupvotes, idownvotes, icomments;
|
||||
if (3 == sscanf(str.c_str(), "%d %d %d", &icomments, &iupvotes, &idownvotes))
|
||||
{
|
||||
s.comments = icomments;
|
||||
s.up_votes = iupvotes;
|
||||
s.down_votes = idownvotes;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void p3PostBase::background_updateVoteCounts(const uint32_t &token)
|
||||
{
|
||||
std::cerr << "p3PostBase::background_updateVoteCounts()";
|
||||
std::cerr << std::endl;
|
||||
|
||||
GxsMsgMetaMap parentMsgList;
|
||||
GxsMsgMetaMap::iterator mit;
|
||||
std::vector<RsMsgMetaData>::iterator vit;
|
||||
|
||||
bool ok = RsGenExchange::getMsgMeta(token, parentMsgList);
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
std::cerr << "p3PostBase::background_updateVoteCounts() ERROR";
|
||||
std::cerr << std::endl;
|
||||
background_cleanup();
|
||||
return;
|
||||
}
|
||||
|
||||
// generate vector of changes to push to the GUI.
|
||||
std::vector<RsGxsNotify *> changes;
|
||||
RsGxsMsgChange *msgChanges = new RsGxsMsgChange(RsGxsNotify::TYPE_PROCESSED);
|
||||
|
||||
for(mit = parentMsgList.begin(); mit != parentMsgList.end(); mit++)
|
||||
{
|
||||
for(vit = mit->second.begin(); vit != mit->second.end(); vit++)
|
||||
{
|
||||
std::cerr << "p3PostBase::background_updateVoteCounts() Processing Msg(" << mit->first;
|
||||
std::cerr << ", " << vit->mMsgId << ")";
|
||||
std::cerr << std::endl;
|
||||
|
||||
RsStackMutex stack(mPostBaseMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
/* extract current vote count */
|
||||
PostStats stats;
|
||||
if (mBgIncremental)
|
||||
{
|
||||
if (!extractPostCache(vit->mServiceString, stats))
|
||||
{
|
||||
if (!(vit->mServiceString.empty()))
|
||||
{
|
||||
std::cerr << "p3PostBase::background_updateVoteCounts() Failed to extract Votes";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "\tFrom String: " << vit->mServiceString;
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* get increment */
|
||||
std::map<RsGxsMessageId, PostStats>::iterator it;
|
||||
it = mBgStatsMap.find(vit->mMsgId);
|
||||
|
||||
if (it != mBgStatsMap.end())
|
||||
{
|
||||
std::cerr << "p3PostBase::background_updateVoteCounts() Adding to msgChangeMap: ";
|
||||
std::cerr << mit->first << " MsgId: " << vit->mMsgId;
|
||||
std::cerr << std::endl;
|
||||
|
||||
stats.increment(it->second);
|
||||
msgChanges->msgChangeMap[mit->first].push_back(vit->mMsgId);
|
||||
}
|
||||
else
|
||||
{
|
||||
// warning.
|
||||
std::cerr << "p3PostBase::background_updateVoteCounts() Warning No New Votes found.";
|
||||
std::cerr << " For MsgId: " << vit->mMsgId;
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
|
||||
std::string str;
|
||||
if (!encodePostCache(str, stats))
|
||||
{
|
||||
std::cerr << "p3PostBase::background_updateVoteCounts() Failed to encode Votes";
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "p3PostBase::background_updateVoteCounts() Encoded String: " << str;
|
||||
std::cerr << std::endl;
|
||||
/* store new result */
|
||||
uint32_t token_c;
|
||||
RsGxsGrpMsgIdPair msgId = std::make_pair(vit->mGroupId, vit->mMsgId);
|
||||
RsGenExchange::setMsgServiceString(token_c, msgId, str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (msgChanges->msgChangeMap.size() > 0)
|
||||
{
|
||||
std::cerr << "p3PostBase::background_updateVoteCounts() -> receiveChanges()";
|
||||
std::cerr << std::endl;
|
||||
|
||||
changes.push_back(msgChanges);
|
||||
receiveHelperChanges(changes);
|
||||
}
|
||||
|
||||
// DONE!.
|
||||
background_cleanup();
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool p3PostBase::background_cleanup()
|
||||
{
|
||||
std::cerr << "p3PostBase::background_cleanup()";
|
||||
std::cerr << std::endl;
|
||||
|
||||
RsStackMutex stack(mPostBaseMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
// Cleanup.
|
||||
mBgStatsMap.clear();
|
||||
mBgProcessing = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Overloaded from GxsTokenQueue for Request callbacks.
|
||||
void p3PostBase::handleResponse(uint32_t token, uint32_t req_type)
|
||||
{
|
||||
std::cerr << "p3PostBase::handleResponse(" << token << "," << req_type << ")";
|
||||
std::cerr << std::endl;
|
||||
|
||||
// stuff.
|
||||
switch(req_type)
|
||||
{
|
||||
case POSTBASE_ALL_GROUPS:
|
||||
background_loadGroups(token);
|
||||
break;
|
||||
case POSTBASE_UNPROCESSED_MSGS:
|
||||
background_loadUnprocessedMsgs(token);
|
||||
break;
|
||||
case POSTBASE_ALL_MSGS:
|
||||
background_loadAllMsgs(token);
|
||||
break;
|
||||
case POSTBASE_BG_POST_META:
|
||||
background_updateVoteCounts(token);
|
||||
break;
|
||||
default:
|
||||
/* error */
|
||||
std::cerr << "p3PostBase::handleResponse() Unknown Request Type: " << req_type;
|
||||
std::cerr << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
135
libretroshare/src/services/p3postbase.h
Normal file
135
libretroshare/src/services/p3postbase.h
Normal file
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* libretroshare/src/services: p3postbase.h
|
||||
*
|
||||
* GxsChannel interface for RetroShare.
|
||||
*
|
||||
* Copyright 2012-2013 by Robert Fernie.
|
||||
*
|
||||
* 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.1 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 "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef P3_POSTBASE_SERVICE_HEADER
|
||||
#define P3_POSTBASE_SERVICE_HEADER
|
||||
|
||||
|
||||
#include "services/p3gxscommon.h"
|
||||
#include "gxs/rsgenexchange.h"
|
||||
|
||||
#include "util/rstickevent.h"
|
||||
|
||||
#include <retroshare/rsidentity.h>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <list>
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
class PostStats
|
||||
{
|
||||
public:
|
||||
PostStats() :up_votes(0), down_votes(0), comments(0) { return; }
|
||||
PostStats(int up, int down, int c) :up_votes(up), down_votes(down), comments(c) { return; }
|
||||
|
||||
void increment(const PostStats &s)
|
||||
{
|
||||
up_votes += s.up_votes;
|
||||
down_votes += s.down_votes;
|
||||
comments += s.comments;
|
||||
return;
|
||||
}
|
||||
|
||||
int up_votes;
|
||||
int down_votes;
|
||||
int comments;
|
||||
std::list<RsGxsId> voters;
|
||||
};
|
||||
|
||||
bool encodePostCache(std::string &str, const PostStats &s);
|
||||
bool extractPostCache(const std::string &str, PostStats &s);
|
||||
|
||||
|
||||
class p3PostBase: public RsGenExchange, public GxsTokenQueue, public RsTickEvent
|
||||
{
|
||||
public:
|
||||
|
||||
p3PostBase(RsGeneralDataService *gds, RsNetworkExchangeService *nes, RsGixs* gixs,
|
||||
RsSerialType* serviceSerialiser, uint16_t serviceType);
|
||||
|
||||
virtual void service_tick();
|
||||
|
||||
// This should be overloaded to call RsGxsIfaceHelper::receiveChanges().
|
||||
virtual void receiveHelperChanges(std::vector<RsGxsNotify*>& changes) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
virtual void notifyChanges(std::vector<RsGxsNotify*>& changes);
|
||||
|
||||
// Overloaded from GxsTokenQueue for Request callbacks.
|
||||
virtual void handleResponse(uint32_t token, uint32_t req_type);
|
||||
|
||||
// Overloaded from RsTickEvent.
|
||||
virtual void handle_event(uint32_t event_type, const std::string &elabel);
|
||||
|
||||
public:
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
p3GxsCommentService *mCommentService;
|
||||
|
||||
private:
|
||||
|
||||
static uint32_t postBaseAuthenPolicy();
|
||||
|
||||
// Background processing.
|
||||
void background_tick();
|
||||
|
||||
bool background_requestAllGroups();
|
||||
void background_loadGroups(const uint32_t &token);
|
||||
|
||||
void addGroupForProcessing(RsGxsGroupId grpId);
|
||||
void background_requestUnprocessedGroup();
|
||||
|
||||
void background_requestGroupMsgs(const RsGxsGroupId &grpId, bool unprocessedOnly);
|
||||
void background_loadUnprocessedMsgs(const uint32_t &token);
|
||||
void background_loadAllMsgs(const uint32_t &token);
|
||||
void background_loadMsgs(const uint32_t &token, bool unprocessed);
|
||||
|
||||
|
||||
void background_updateVoteCounts(const uint32_t &token);
|
||||
bool background_cleanup();
|
||||
|
||||
|
||||
RsMutex mPostBaseMtx;
|
||||
|
||||
bool mBgProcessing;
|
||||
bool mBgIncremental;
|
||||
std::list<RsGxsGroupId> mBgGroupList;
|
||||
std::map<RsGxsMessageId, PostStats> mBgStatsMap;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load diff
|
@ -28,10 +28,7 @@
|
|||
|
||||
|
||||
#include "retroshare/rsposted.h"
|
||||
#include "services/p3gxscommon.h"
|
||||
#include "gxs/rsgenexchange.h"
|
||||
|
||||
#include "util/rstickevent.h"
|
||||
#include "services/p3postbase.h"
|
||||
|
||||
#include <retroshare/rsidentity.h>
|
||||
|
||||
|
@ -43,72 +40,41 @@
|
|||
*
|
||||
*/
|
||||
|
||||
|
||||
class PostStats
|
||||
{
|
||||
public:
|
||||
PostStats() :up_votes(0), down_votes(0), comments(0) { return; }
|
||||
PostStats(int up, int down, int c) :up_votes(up), down_votes(down), comments(c) { return; }
|
||||
|
||||
void increment(const PostStats &s)
|
||||
{
|
||||
up_votes += s.up_votes;
|
||||
down_votes += s.down_votes;
|
||||
comments += s.comments;
|
||||
return;
|
||||
}
|
||||
|
||||
int up_votes;
|
||||
int down_votes;
|
||||
int comments;
|
||||
std::list<RsGxsId> voters;
|
||||
};
|
||||
|
||||
bool encodePostedCache(std::string &str, const PostStats &s);
|
||||
bool extractPostedCache(const std::string &str, PostStats &s);
|
||||
|
||||
|
||||
class p3Posted: public RsGenExchange, public RsPosted,
|
||||
public GxsTokenQueue,
|
||||
public RsTickEvent /* only needed for testing - remove after */
|
||||
class p3Posted: public p3PostBase, public RsPosted
|
||||
{
|
||||
public:
|
||||
|
||||
p3Posted(RsGeneralDataService* gds, RsNetworkExchangeService* nes, RsGixs* gixs);
|
||||
|
||||
virtual void service_tick();
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
virtual void notifyChanges(std::vector<RsGxsNotify*>& changes);
|
||||
|
||||
// Overloaded from GxsTokenQueue for Request callbacks.
|
||||
virtual void handleResponse(uint32_t token, uint32_t req_type);
|
||||
|
||||
// Overloaded from RsTickEvent.
|
||||
virtual void handle_event(uint32_t event_type, const std::string &elabel);
|
||||
virtual void notifyChanges(std::vector<RsGxsNotify*>& changes)
|
||||
{
|
||||
return p3PostBase::notifyChanges(changes);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
virtual void receiveHelperChanges(std::vector<RsGxsNotify*>& changes)
|
||||
{
|
||||
return RsGxsIfaceHelper::receiveChanges(changes);
|
||||
}
|
||||
|
||||
// Posted Specific DataTypes.
|
||||
virtual bool getGroupData(const uint32_t &token, std::vector<RsPostedGroup> &groups);
|
||||
virtual bool getPostData(const uint32_t &token, std::vector<RsPostedPost> &posts);
|
||||
|
||||
virtual bool getRelatedPosts(const uint32_t &token, std::vector<RsPostedPost> &posts);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read);
|
||||
|
||||
//virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask);
|
||||
//virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask);
|
||||
|
||||
//virtual bool groupRestoreKeys(const std::string &groupId);
|
||||
//virtual bool groupShareKeys(const std::string &groupId, std::list<std::string>& peers);
|
||||
|
||||
virtual bool createGroup(uint32_t &token, RsPostedGroup &group);
|
||||
virtual bool createPost(uint32_t &token, RsPostedPost &post);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// WRAPPERS due to the separate Interface.
|
||||
|
||||
virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read)
|
||||
{
|
||||
return p3PostBase::setMessageReadStatus(token, msgId, read);
|
||||
}
|
||||
|
||||
|
||||
/* Comment service - Provide RsGxsCommentService - redirect to p3GxsCommentService */
|
||||
|
@ -145,82 +111,6 @@ virtual bool acknowledgeVote(const uint32_t& token, std::pair<RsGxsGroupId, RsGx
|
|||
}
|
||||
return acknowledgeMsg(token, msgId);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
static uint32_t postedAuthenPolicy();
|
||||
|
||||
bool calculateScores(RsPostedPost &post, time_t ref_time);
|
||||
|
||||
// Background processing.
|
||||
void background_tick();
|
||||
|
||||
bool background_requestAllGroups();
|
||||
void background_loadGroups(const uint32_t &token);
|
||||
|
||||
void addGroupForProcessing(RsGxsGroupId grpId);
|
||||
void background_requestUnprocessedGroup();
|
||||
|
||||
void background_requestGroupMsgs(const RsGxsGroupId &grpId, bool unprocessedOnly);
|
||||
void background_loadUnprocessedMsgs(const uint32_t &token);
|
||||
void background_loadAllMsgs(const uint32_t &token);
|
||||
void background_loadMsgs(const uint32_t &token, bool unprocessed);
|
||||
|
||||
|
||||
void background_updateVoteCounts(const uint32_t &token);
|
||||
bool background_cleanup();
|
||||
|
||||
|
||||
RsMutex mPostedMtx;
|
||||
|
||||
bool mBgProcessing;
|
||||
bool mBgIncremental;
|
||||
std::list<RsGxsGroupId> mBgGroupList;
|
||||
std::map<RsGxsMessageId, PostStats> mBgStatsMap;
|
||||
|
||||
|
||||
|
||||
|
||||
// DUMMY DATA,
|
||||
virtual bool generateDummyData();
|
||||
|
||||
std::string genRandomId();
|
||||
|
||||
void dummy_tick();
|
||||
|
||||
bool generatePost(uint32_t &token, const RsGxsGroupId &grpId);
|
||||
bool generateComment(uint32_t &token, const RsGxsGroupId &grpId,
|
||||
const RsGxsMessageId &parentId, const RsGxsMessageId &threadId);
|
||||
bool generateGroup(uint32_t &token, std::string groupName);
|
||||
|
||||
class PostedDummyRef
|
||||
{
|
||||
public:
|
||||
PostedDummyRef() { return; }
|
||||
PostedDummyRef(const RsGxsGroupId &grpId, const RsGxsMessageId &threadId, const RsGxsMessageId &msgId)
|
||||
:mGroupId(grpId), mThreadId(threadId), mMsgId(msgId) { return; }
|
||||
|
||||
RsGxsGroupId mGroupId;
|
||||
RsGxsMessageId mThreadId;
|
||||
RsGxsMessageId mMsgId;
|
||||
};
|
||||
|
||||
uint32_t mGenToken;
|
||||
bool mGenActive;
|
||||
int mGenCount;
|
||||
std::vector<PostedDummyRef> mGenRefs;
|
||||
RsGxsMessageId mGenThreadId;
|
||||
|
||||
p3GxsCommentService *mCommentService;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,190 +0,0 @@
|
|||
/*
|
||||
* libretroshare/src/services: p3posted.h
|
||||
*
|
||||
* 3P/PQI network interface for RetroShare.
|
||||
*
|
||||
* Copyright 2012-2012 by Robert Fernie.
|
||||
*
|
||||
* 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 "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef P3_POSTED_SERVICE_VEG_HEADER
|
||||
#define P3_POSTED_SERVICE_VEG_HEADER
|
||||
|
||||
#include "services/p3gxsserviceVEG.h"
|
||||
#include "retroshare/rspostedVEG.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
/*
|
||||
* Posted Service
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
class PostedDataProxy: public GxsDataProxyVEG
|
||||
{
|
||||
public:
|
||||
|
||||
bool addGroup(const RsPostedGroup &group);
|
||||
bool addPost(const RsPostedPost &post);
|
||||
bool addVote(const RsPostedVote &vote);
|
||||
bool addComment(const RsPostedComment &comment);
|
||||
|
||||
bool getGroup(const std::string &id, RsPostedGroup &group);
|
||||
bool getPost(const std::string &id, RsPostedPost &post);
|
||||
bool getVote(const std::string &id, RsPostedVote &vote);
|
||||
bool getComment(const std::string &id, RsPostedComment &comment);
|
||||
|
||||
/* These Functions must be overloaded to complete the service */
|
||||
virtual bool convertGroupToMetaData(void *groupData, RsGroupMetaData &meta);
|
||||
virtual bool convertMsgToMetaData(void *groupData, RsMsgMetaData &meta);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
class p3PostedServiceVEG: public p3GxsDataServiceVEG, public RsPostedVEG
|
||||
{
|
||||
public:
|
||||
|
||||
p3PostedServiceVEG(uint16_t type);
|
||||
|
||||
virtual int tick();
|
||||
|
||||
public:
|
||||
|
||||
// NEW INTERFACE.
|
||||
/************* Extern Interface *******/
|
||||
|
||||
virtual bool updated();
|
||||
|
||||
/* Data Requests */
|
||||
virtual bool requestGroupInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list<std::string> &groupIds);
|
||||
virtual bool requestMsgInfo( uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list<std::string> &groupIds);
|
||||
virtual bool requestMsgRelatedInfo(uint32_t &token, uint32_t ansType, const RsTokReqOptionsVEG &opts, const std::list<std::string> &msgIds);
|
||||
|
||||
/* Generic Lists */
|
||||
virtual bool getGroupList( const uint32_t &token, std::list<std::string> &groupIds);
|
||||
virtual bool getMsgList( const uint32_t &token, std::list<std::string> &msgIds);
|
||||
|
||||
/* Generic Summary */
|
||||
virtual bool getGroupSummary( const uint32_t &token, std::list<RsGroupMetaData> &groupInfo);
|
||||
virtual bool getMsgSummary( const uint32_t &token, std::list<RsMsgMetaData> &msgInfo);
|
||||
|
||||
/* Actual Data -> specific to Interface */
|
||||
/* Specific Service Data */
|
||||
virtual bool getGroup(const uint32_t &token, RsPostedGroup &group);
|
||||
virtual bool getPost(const uint32_t &token, RsPostedPost &post);
|
||||
virtual bool getComment(const uint32_t &token, RsPostedComment &comment);
|
||||
|
||||
|
||||
/* Poll */
|
||||
virtual uint32_t requestStatus(const uint32_t token);
|
||||
|
||||
/* Cancel Request */
|
||||
virtual bool cancelRequest(const uint32_t &token);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
virtual bool setMessageStatus(const std::string &msgId, const uint32_t status, const uint32_t statusMask);
|
||||
virtual bool setGroupStatus(const std::string &groupId, const uint32_t status, const uint32_t statusMask);
|
||||
virtual bool setGroupSubscribeFlags(const std::string &groupId, uint32_t subscribeFlags, uint32_t subscribeMask);
|
||||
virtual bool setMessageServiceString(const std::string &msgId, const std::string &str);
|
||||
virtual bool setGroupServiceString(const std::string &grpId, const std::string &str);
|
||||
|
||||
virtual bool groupRestoreKeys(const std::string &groupId);
|
||||
virtual bool groupShareKeys(const std::string &groupId, std::list<std::string>& peers);
|
||||
|
||||
virtual bool submitGroup(uint32_t &token, RsPostedGroup &group, bool isNew);
|
||||
virtual bool submitPost(uint32_t &token, RsPostedPost &post, bool isNew);
|
||||
virtual bool submitVote(uint32_t &token, RsPostedVote &vote, bool isNew);
|
||||
virtual bool submitComment(uint32_t &token, RsPostedComment &comment, bool isNew);
|
||||
|
||||
// Extended Interface for Collated Data View.
|
||||
virtual bool setViewMode(uint32_t mode);
|
||||
virtual bool setViewPeriod(uint32_t period);
|
||||
virtual bool setViewRange(uint32_t first, uint32_t count);
|
||||
|
||||
virtual bool requestRanking(uint32_t &token, std::string groupId);
|
||||
virtual bool getRankedPost(const uint32_t &token, RsPostedPost &post);
|
||||
|
||||
|
||||
// These are exposed for GUI usage.
|
||||
virtual bool encodePostedCache(std::string &str, uint32_t votes, uint32_t comments);
|
||||
virtual bool extractPostedCache(const std::string &str, uint32_t &votes, uint32_t &comments);
|
||||
virtual float calcPostScore(const RsMsgMetaData &meta);
|
||||
|
||||
private:
|
||||
|
||||
//
|
||||
bool checkRankingRequest();
|
||||
bool processPosts();
|
||||
|
||||
// background processing of Votes.
|
||||
// NB: These should probably be handled by a background thread.
|
||||
// At the moment they are run from the tick() thread.
|
||||
|
||||
bool background_checkTokenRequest();
|
||||
bool background_requestGroups();
|
||||
bool background_requestNewMessages();
|
||||
bool background_processNewMessages();
|
||||
|
||||
bool background_updateVoteCounts();
|
||||
bool background_cleanup();
|
||||
|
||||
|
||||
|
||||
std::string genRandomId();
|
||||
bool generateDummyData();
|
||||
bool addExtraDummyData();
|
||||
|
||||
PostedDataProxy *mPostedProxy;
|
||||
|
||||
RsMutex mPostedMtx;
|
||||
bool mUpdated;
|
||||
|
||||
// Ranking view mode, stored here.
|
||||
uint32_t mViewMode;
|
||||
uint32_t mViewPeriod;
|
||||
uint32_t mViewStart;
|
||||
uint32_t mViewCount;
|
||||
|
||||
// Processing Ranking stuff.
|
||||
bool mProcessingRanking;
|
||||
uint32_t mRankingState;
|
||||
uint32_t mRankingExternalToken;
|
||||
uint32_t mRankingInternalToken;
|
||||
|
||||
// background processing - Mutex protected.
|
||||
time_t mLastBgCheck;
|
||||
bool mBgProcessing;
|
||||
uint32_t mBgPhase;
|
||||
uint32_t mBgToken;
|
||||
|
||||
std::map<std::string, uint32_t> mBgVoteMap; // ParentId -> Vote Count.
|
||||
std::map<std::string, uint32_t> mBgCommentMap; // ThreadId -> Comment Count.
|
||||
|
||||
// extra dummy data.
|
||||
std::list<RsPostedVote> mDummyLaterVotes;
|
||||
std::list<RsPostedComment> mDummyLaterComments;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
432
libretroshare/src/services/p3rtt.cc
Normal file
432
libretroshare/src/services/p3rtt.cc
Normal file
|
@ -0,0 +1,432 @@
|
|||
/*
|
||||
* libretroshare/src/services p3rtt.cc
|
||||
*
|
||||
* Round Trip Time Measurement for RetroShare.
|
||||
*
|
||||
* Copyright 2011-2013 by Robert Fernie.
|
||||
*
|
||||
* 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.1 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 "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
#include "util/rsdir.h"
|
||||
#include "retroshare/rsiface.h"
|
||||
#include "pqi/pqibin.h"
|
||||
#include "pqi/pqistore.h"
|
||||
#include "pqi/p3linkmgr.h"
|
||||
|
||||
#include "services/p3rtt.h"
|
||||
#include "serialiser/rsrttitems.h"
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
/****
|
||||
* #define DEBUG_RTT 1
|
||||
****/
|
||||
|
||||
|
||||
/* DEFINE INTERFACE POINTER! */
|
||||
RsRtt *rsRtt = NULL;
|
||||
|
||||
|
||||
#define MAX_PONG_RESULTS 150
|
||||
#define RTT_PING_PERIOD 10
|
||||
|
||||
/************ IMPLEMENTATION NOTES *********************************
|
||||
*
|
||||
* Voice over Retroshare ;)
|
||||
*
|
||||
* This will be a simple test VoIP system aimed at testing out the possibilities.
|
||||
*
|
||||
* Important things to test:
|
||||
* 1) lag, and variability in data rate
|
||||
* - To do this we time tag every packet..., the destination can use this info to calculate the results.
|
||||
* - Like imixitup. Dt = clock_diff + lag.
|
||||
* we expect clock_diff to be relatively constant, but lag to vary.
|
||||
* lag cannot be negative, so minimal Dt is ~clock_diff, and delays on this are considered +lag.
|
||||
*
|
||||
* 2) we could directly measure lag. ping back and forth with Timestamps.
|
||||
*
|
||||
* 3) we also want to measure bandwidth...
|
||||
* - not sure the best method?
|
||||
* one way: send a ping, then a large amount of data (5 seconds worth), then another ping.
|
||||
* the delta in timestamps should be a decent indication of bandwidth.
|
||||
* say we have a 100kb/s connection... need 500kb.
|
||||
* actually the amount of data should be based on a reasonable maximum that we require.
|
||||
* what does decent video require?
|
||||
* Audio we can test for 64kb/s - which seems like a decent rate: e.g. mono, 16bit 22k = 1 x 2 x 22k = 44 kilobytes/sec
|
||||
* best to do this without a VoIP call going on ;)
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifdef WINDOWS_SYS
|
||||
#include <time.h>
|
||||
#include <sys/timeb.h>
|
||||
#endif
|
||||
|
||||
static double getCurrentTS()
|
||||
{
|
||||
|
||||
#ifndef WINDOWS_SYS
|
||||
struct timeval cts_tmp;
|
||||
gettimeofday(&cts_tmp, NULL);
|
||||
double cts = (cts_tmp.tv_sec) + ((double) cts_tmp.tv_usec) / 1000000.0;
|
||||
#else
|
||||
struct _timeb timebuf;
|
||||
_ftime( &timebuf);
|
||||
double cts = (timebuf.time) + ((double) timebuf.millitm) / 1000.0;
|
||||
#endif
|
||||
return cts;
|
||||
}
|
||||
|
||||
static uint64_t convertTsTo64bits(double ts)
|
||||
{
|
||||
uint32_t secs = (uint32_t) ts;
|
||||
uint32_t usecs = (uint32_t) ((ts - (double) secs) * 1000000);
|
||||
uint64_t bits = (((uint64_t) secs) << 32) + usecs;
|
||||
return bits;
|
||||
}
|
||||
|
||||
|
||||
static double convert64bitsToTs(uint64_t bits)
|
||||
{
|
||||
uint32_t usecs = (uint32_t) (bits & 0xffffffff);
|
||||
uint32_t secs = (uint32_t) ((bits >> 32) & 0xffffffff);
|
||||
double ts = (secs) + ((double) usecs) / 1000000.0;
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
p3rtt::p3rtt(p3LinkMgr *lm)
|
||||
:p3FastService(RS_SERVICE_TYPE_RTT), mRttMtx("p3rtt"), mLinkMgr(lm)
|
||||
{
|
||||
addSerialType(new RsRttSerialiser());
|
||||
|
||||
mSentPingTime = 0;
|
||||
mCounter = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int p3rtt::tick()
|
||||
{
|
||||
sendPackets();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int p3rtt::status()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int p3rtt::sendPackets()
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
time_t pt;
|
||||
{
|
||||
RsStackMutex stack(mRttMtx); /****** LOCKED MUTEX *******/
|
||||
pt = mSentPingTime;
|
||||
}
|
||||
|
||||
if (now - pt > RTT_PING_PERIOD)
|
||||
{
|
||||
sendPingMeasurements();
|
||||
|
||||
RsStackMutex stack(mRttMtx); /****** LOCKED MUTEX *******/
|
||||
mSentPingTime = now;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void p3rtt::sendPingMeasurements()
|
||||
{
|
||||
|
||||
|
||||
/* we ping our peers */
|
||||
/* who is online? */
|
||||
std::list<std::string> idList;
|
||||
|
||||
mLinkMgr->getOnlineList(idList);
|
||||
|
||||
double ts = getCurrentTS();
|
||||
|
||||
#ifdef DEBUG_RTT
|
||||
std::cerr << "p3rtt::sendPingMeasurements() @ts: " << ts;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
/* prepare packets */
|
||||
std::list<std::string>::iterator it;
|
||||
for(it = idList.begin(); it != idList.end(); it++)
|
||||
{
|
||||
#ifdef DEBUG_RTT
|
||||
std::cerr << "p3rtt::sendPingMeasurements() Pinging: " << *it;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
/* create the packet */
|
||||
RsRttPingItem *pingPkt = new RsRttPingItem();
|
||||
pingPkt->PeerId(*it);
|
||||
pingPkt->mSeqNo = mCounter;
|
||||
pingPkt->mPingTS = convertTsTo64bits(ts);
|
||||
|
||||
storePingAttempt(*it, ts, mCounter);
|
||||
|
||||
#ifdef DEBUG_RTT
|
||||
std::cerr << "p3rtt::sendPingMeasurements() With Packet:";
|
||||
std::cerr << std::endl;
|
||||
pingPkt->print(std::cerr, 10);
|
||||
#endif
|
||||
|
||||
sendItem(pingPkt);
|
||||
}
|
||||
|
||||
RsStackMutex stack(mRttMtx); /****** LOCKED MUTEX *******/
|
||||
mCounter++;
|
||||
}
|
||||
|
||||
|
||||
bool p3rtt::recvItem(RsItem *item)
|
||||
{
|
||||
switch(item->PacketSubType())
|
||||
{
|
||||
default:
|
||||
break;
|
||||
case RS_PKT_SUBTYPE_RTT_PING:
|
||||
{
|
||||
handlePing(item);
|
||||
}
|
||||
break;
|
||||
case RS_PKT_SUBTYPE_RTT_PONG:
|
||||
{
|
||||
handlePong(item);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* clean up */
|
||||
delete item;
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
int p3rtt::handlePing(RsItem *item)
|
||||
{
|
||||
/* cast to right type */
|
||||
RsRttPingItem *ping = (RsRttPingItem *) item;
|
||||
|
||||
#ifdef DEBUG_RTT
|
||||
std::cerr << "p3rtt::handlePing() Recvd Packet from: " << ping->PeerId();
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
/* with a ping, we just respond as quickly as possible - they do all the analysis */
|
||||
RsRttPongItem *pong = new RsRttPongItem();
|
||||
|
||||
|
||||
pong->PeerId(ping->PeerId());
|
||||
pong->mPingTS = ping->mPingTS;
|
||||
pong->mSeqNo = ping->mSeqNo;
|
||||
|
||||
// add our timestamp.
|
||||
double ts = getCurrentTS();
|
||||
pong->mPongTS = convertTsTo64bits(ts);
|
||||
|
||||
|
||||
#ifdef DEBUG_RTT
|
||||
std::cerr << "p3rtt::handlePing() With Packet:";
|
||||
std::cerr << std::endl;
|
||||
pong->print(std::cerr, 10);
|
||||
#endif
|
||||
|
||||
sendItem(pong);
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
int p3rtt::handlePong(RsItem *item)
|
||||
{
|
||||
/* cast to right type */
|
||||
RsRttPongItem *pong = (RsRttPongItem *) item;
|
||||
|
||||
#ifdef DEBUG_RTT
|
||||
std::cerr << "p3rtt::handlePong() Recvd Packet from: " << pong->PeerId();
|
||||
std::cerr << std::endl;
|
||||
pong->print(std::cerr, 10);
|
||||
#endif
|
||||
|
||||
/* with a pong, we do the maths! */
|
||||
double recvTS = getCurrentTS();
|
||||
double pingTS = convert64bitsToTs(pong->mPingTS);
|
||||
double pongTS = convert64bitsToTs(pong->mPongTS);
|
||||
|
||||
double rtt = recvTS - pingTS;
|
||||
double offset = pongTS - (recvTS - rtt / 2.0); // so to get to their time, we go ourTS + offset.
|
||||
|
||||
#ifdef DEBUG_RTT
|
||||
std::cerr << "p3rtt::handlePong() Timing:";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "\tpingTS: " << pingTS;
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "\tpongTS: " << pongTS;
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "\trecvTS: " << recvTS;
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "\t ==> rtt: " << rtt;
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "\t ==> offset: " << offset;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
storePongResult(pong->PeerId(), pong->mSeqNo, pingTS, rtt, offset);
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int p3rtt::storePingAttempt(std::string id, double ts, uint32_t seqno)
|
||||
{
|
||||
RsStackMutex stack(mRttMtx); /****** LOCKED MUTEX *******/
|
||||
|
||||
/* find corresponding local data */
|
||||
RttPeerInfo *peerInfo = locked_GetPeerInfo(id);
|
||||
|
||||
peerInfo->mCurrentPingTS = ts;
|
||||
peerInfo->mCurrentPingCounter = seqno;
|
||||
|
||||
peerInfo->mSentPings++;
|
||||
if (!peerInfo->mCurrentPongRecvd)
|
||||
{
|
||||
peerInfo->mLostPongs++;
|
||||
}
|
||||
|
||||
peerInfo->mCurrentPongRecvd = true;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int p3rtt::storePongResult(std::string id, uint32_t counter, double ts, double rtt, double offset)
|
||||
{
|
||||
RsStackMutex stack(mRttMtx); /****** LOCKED MUTEX *******/
|
||||
|
||||
/* find corresponding local data */
|
||||
RttPeerInfo *peerInfo = locked_GetPeerInfo(id);
|
||||
|
||||
if (peerInfo->mCurrentPingCounter != counter)
|
||||
{
|
||||
#ifdef DEBUG_RTT
|
||||
std::cerr << "p3rtt::storePongResult() ERROR Severly Delayed Measurements!" << std::endl;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
peerInfo->mCurrentPongRecvd = true;
|
||||
}
|
||||
|
||||
peerInfo->mPongResults.push_back(RsRttPongResult(ts, rtt, offset));
|
||||
|
||||
|
||||
while(peerInfo->mPongResults.size() > MAX_PONG_RESULTS)
|
||||
{
|
||||
peerInfo->mPongResults.pop_front();
|
||||
}
|
||||
|
||||
/* should do calculations */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
uint32_t p3rtt::getPongResults(std::string id, int n, std::list<RsRttPongResult> &results)
|
||||
{
|
||||
RsStackMutex stack(mRttMtx); /****** LOCKED MUTEX *******/
|
||||
|
||||
RttPeerInfo *peer = locked_GetPeerInfo(id);
|
||||
|
||||
std::list<RsRttPongResult>::reverse_iterator it;
|
||||
int i = 0;
|
||||
for(it = peer->mPongResults.rbegin(); (it != peer->mPongResults.rend()) && (i < n); it++, i++)
|
||||
{
|
||||
/* reversing order - so its easy to trim later */
|
||||
results.push_back(*it);
|
||||
}
|
||||
return i ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
RttPeerInfo *p3rtt::locked_GetPeerInfo(std::string id)
|
||||
{
|
||||
std::map<std::string, RttPeerInfo>::iterator it;
|
||||
it = mPeerInfo.find(id);
|
||||
if (it == mPeerInfo.end())
|
||||
{
|
||||
/* add it in */
|
||||
RttPeerInfo pinfo;
|
||||
|
||||
/* initialise entry */
|
||||
pinfo.initialisePeerInfo(id);
|
||||
|
||||
mPeerInfo[id] = pinfo;
|
||||
|
||||
it = mPeerInfo.find(id);
|
||||
|
||||
}
|
||||
|
||||
return &(it->second);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool RttPeerInfo::initialisePeerInfo(std::string id)
|
||||
{
|
||||
mId = id;
|
||||
|
||||
/* reset variables */
|
||||
mCurrentPingTS = 0;
|
||||
mCurrentPingCounter = 0;
|
||||
mCurrentPongRecvd = true;
|
||||
|
||||
mSentPings = 0;
|
||||
mLostPongs = 0;
|
||||
|
||||
mPongResults.clear();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
118
libretroshare/src/services/p3rtt.h
Normal file
118
libretroshare/src/services/p3rtt.h
Normal file
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* libretroshare/src/services/p3rtt.h
|
||||
*
|
||||
* Round Trip Time Measurement for RetroShare.
|
||||
*
|
||||
* Copyright 2011-2013 by Robert Fernie.
|
||||
*
|
||||
* 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.1 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 "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SERVICE_RSRTT_HEADER
|
||||
#define SERVICE_RSRTT_HEADER
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
#include "serialiser/rsrttitems.h"
|
||||
#include "services/p3service.h"
|
||||
#include "retroshare/rsrtt.h"
|
||||
|
||||
class p3LinkMgr;
|
||||
|
||||
class RttPeerInfo
|
||||
{
|
||||
public:
|
||||
|
||||
bool initialisePeerInfo(std::string id);
|
||||
|
||||
std::string mId;
|
||||
double mCurrentPingTS;
|
||||
double mCurrentPingCounter;
|
||||
bool mCurrentPongRecvd;
|
||||
|
||||
uint32_t mLostPongs;
|
||||
uint32_t mSentPings;
|
||||
|
||||
std::list<RsRttPongResult> mPongResults;
|
||||
};
|
||||
|
||||
|
||||
//!The RS Rtt Test service.
|
||||
/**
|
||||
*
|
||||
* Used to test Latency.
|
||||
*/
|
||||
|
||||
class p3rtt: public RsRtt, public p3FastService
|
||||
{
|
||||
public:
|
||||
p3rtt(p3LinkMgr *cm);
|
||||
|
||||
/***** overloaded from rsRtt *****/
|
||||
|
||||
virtual uint32_t getPongResults(std::string id, int n, std::list<RsRttPongResult> &results);
|
||||
|
||||
/***** overloaded from p3Service *****/
|
||||
|
||||
virtual int tick();
|
||||
virtual int status();
|
||||
|
||||
int sendPackets();
|
||||
void sendPingMeasurements();
|
||||
|
||||
virtual bool recvItem(RsItem *item); // Overloaded from p3FastService.
|
||||
|
||||
int handlePing(RsItem *item);
|
||||
int handlePong(RsItem *item);
|
||||
|
||||
int storePingAttempt(std::string id, double ts, uint32_t mCounter);
|
||||
int storePongResult(std::string id, uint32_t counter, double ts, double rtt, double offset);
|
||||
|
||||
|
||||
/*!
|
||||
* This retrieves all public chat msg items
|
||||
*/
|
||||
//bool getPublicChatQueue(std::list<ChatInfo> &chats);
|
||||
|
||||
/*************** pqiMonitor callback ***********************/
|
||||
//virtual void statusChange(const std::list<pqipeer> &plist);
|
||||
|
||||
|
||||
/************* from p3Config *******************/
|
||||
//virtual RsSerialiser *setupSerialiser() ;
|
||||
//virtual bool saveList(bool& cleanup, std::list<RsItem*>&) ;
|
||||
//virtual void saveDone();
|
||||
//virtual bool loadList(std::list<RsItem*>& load) ;
|
||||
|
||||
private:
|
||||
RsMutex mRttMtx;
|
||||
|
||||
RttPeerInfo *locked_GetPeerInfo(std::string id);
|
||||
|
||||
std::map<std::string, RttPeerInfo> mPeerInfo;
|
||||
time_t mSentPingTime;
|
||||
uint32_t mCounter;
|
||||
|
||||
p3LinkMgr *mLinkMgr;
|
||||
|
||||
};
|
||||
|
||||
#endif // SERVICE_RSRTT_HEADER
|
||||
|
|
@ -3,11 +3,11 @@
|
|||
*
|
||||
* 3P/PQI network interface for RetroShare.
|
||||
*
|
||||
* Copyright 2004-2008 by Robert Fernie.
|
||||
* Copyright 2004-2013 by Robert Fernie.
|
||||
*
|
||||
* 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.
|
||||
* License Version 2.1 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
|
||||
|
@ -36,18 +36,14 @@
|
|||
* #define SERV_DEBUG 1
|
||||
****/
|
||||
|
||||
void p3Service::addSerialType(RsSerialType *st)
|
||||
{
|
||||
rsSerialiser->addSerialType(st);
|
||||
}
|
||||
|
||||
|
||||
RsItem *p3Service::recvItem()
|
||||
{
|
||||
srvMtx.lock(); /***** LOCK MUTEX *****/
|
||||
RsStackMutex stack(srvMtx); /***** LOCK MUTEX *****/
|
||||
|
||||
if (recv_queue.size() == 0)
|
||||
{
|
||||
srvMtx.unlock(); /***** UNLOCK MUTEX *****/
|
||||
return NULL; /* nothing there! */
|
||||
}
|
||||
|
||||
|
@ -55,75 +51,82 @@ RsItem *p3Service::recvItem()
|
|||
RsItem *item = recv_queue.front();
|
||||
recv_queue.pop_front();
|
||||
|
||||
srvMtx.unlock(); /***** UNLOCK MUTEX *****/
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
bool p3Service::receivedItems()
|
||||
{
|
||||
srvMtx.lock(); /***** LOCK MUTEX *****/
|
||||
RsStackMutex stack(srvMtx); /***** LOCK MUTEX *****/
|
||||
|
||||
bool moreData = (recv_queue.size() != 0);
|
||||
|
||||
srvMtx.unlock(); /***** UNLOCK MUTEX *****/
|
||||
|
||||
return moreData;
|
||||
return (!recv_queue.empty());
|
||||
}
|
||||
|
||||
|
||||
int p3Service::sendItem(RsItem *item)
|
||||
bool p3Service::recvItem(RsItem *item)
|
||||
{
|
||||
srvMtx.lock(); /***** LOCK MUTEX *****/
|
||||
if (item)
|
||||
{
|
||||
RsStackMutex stack(srvMtx); /***** LOCK MUTEX *****/
|
||||
|
||||
send_queue.push_back(item);
|
||||
|
||||
srvMtx.unlock(); /***** UNLOCK MUTEX *****/
|
||||
|
||||
return 1;
|
||||
recv_queue.push_back(item);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void p3FastService::addSerialType(RsSerialType *st)
|
||||
{
|
||||
rsSerialiser->addSerialType(st);
|
||||
}
|
||||
|
||||
|
||||
// overloaded pqiService interface.
|
||||
int p3Service::receive(RsRawItem *raw)
|
||||
bool p3FastService::recv(RsRawItem *raw)
|
||||
{
|
||||
srvMtx.lock(); /***** LOCK MUTEX *****/
|
||||
|
||||
#ifdef SERV_DEBUG
|
||||
std::cerr << "p3Service::receive()";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
/* convert to RsServiceItem */
|
||||
uint32_t size = raw->getRawLength();
|
||||
RsItem *item = rsSerialiser->deserialise(raw->getRawData(), &size);
|
||||
if ((!item) || (size != raw->getRawLength()))
|
||||
RsItem *item = NULL;
|
||||
{
|
||||
/* error in conversion */
|
||||
#ifdef SERV_DEBUG
|
||||
std::cerr << "p3Service::receive() Error" << std::endl;
|
||||
std::cerr << "p3Service::receive() Size: " << size << std::endl;
|
||||
std::cerr << "p3Service::receive() RawLength: " << raw->getRawLength() << std::endl;
|
||||
#endif
|
||||
|
||||
if (item)
|
||||
RsStackMutex stack(srvMtx); /***** LOCK MUTEX *****/
|
||||
|
||||
#ifdef SERV_DEBUG
|
||||
std::cerr << "p3Service::recv()";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
/* convert to RsServiceItem */
|
||||
uint32_t size = raw->getRawLength();
|
||||
item = rsSerialiser->deserialise(raw->getRawData(), &size);
|
||||
if ((!item) || (size != raw->getRawLength()))
|
||||
{
|
||||
#ifdef SERV_DEBUG
|
||||
std::cerr << "p3Service::receive() Bad Item:";
|
||||
std::cerr << std::endl;
|
||||
item->print(std::cerr, 0);
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
delete item;
|
||||
item=NULL ;
|
||||
/* error in conversion */
|
||||
#ifdef SERV_DEBUG
|
||||
std::cerr << "p3Service::recv() Error" << std::endl;
|
||||
std::cerr << "p3Service::recv() Size: " << size << std::endl;
|
||||
std::cerr << "p3Service::recv() RawLength: " << raw->getRawLength() << std::endl;
|
||||
#endif
|
||||
|
||||
if (item)
|
||||
{
|
||||
#ifdef SERV_DEBUG
|
||||
std::cerr << "p3Service::recv() Bad Item:";
|
||||
std::cerr << std::endl;
|
||||
item->print(std::cerr, 0);
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
delete item;
|
||||
item=NULL ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* if we have something - pass it on */
|
||||
if (item)
|
||||
{
|
||||
#ifdef SERV_DEBUG
|
||||
std::cerr << "p3Service::receive() item:";
|
||||
std::cerr << "p3Service::recv() item:";
|
||||
std::cerr << std::endl;
|
||||
item->print(std::cerr, 0);
|
||||
std::cerr << std::endl;
|
||||
|
@ -131,33 +134,22 @@ int p3Service::receive(RsRawItem *raw)
|
|||
|
||||
/* ensure PeerId is transferred */
|
||||
item->PeerId(raw->PeerId());
|
||||
recv_queue.push_back(item);
|
||||
recvItem(item);
|
||||
}
|
||||
|
||||
/* cleanup input */
|
||||
delete raw;
|
||||
|
||||
srvMtx.unlock(); /***** UNLOCK MUTEX *****/
|
||||
|
||||
return (item != NULL);
|
||||
}
|
||||
|
||||
RsRawItem *p3Service::send()
|
||||
|
||||
|
||||
int p3FastService::sendItem(RsItem *si)
|
||||
{
|
||||
srvMtx.lock(); /***** LOCK MUTEX *****/
|
||||
|
||||
if (send_queue.size() == 0)
|
||||
{
|
||||
srvMtx.unlock(); /***** UNLOCK MUTEX *****/
|
||||
return NULL; /* nothing there! */
|
||||
}
|
||||
|
||||
/* get something off front */
|
||||
RsItem *si = send_queue.front();
|
||||
send_queue.pop_front();
|
||||
RsStackMutex stack(srvMtx); /***** LOCK MUTEX *****/
|
||||
|
||||
#ifdef SERV_DEBUG
|
||||
std::cerr << "p3Service::send() Sending item:";
|
||||
std::cerr << "p3Service::sendItem() Sending item:";
|
||||
std::cerr << std::endl;
|
||||
si->print(std::cerr, 0);
|
||||
std::cerr << std::endl;
|
||||
|
@ -167,34 +159,29 @@ RsRawItem *p3Service::send()
|
|||
uint32_t size = rsSerialiser->size(si);
|
||||
if (!size)
|
||||
{
|
||||
#ifdef SERV_DEBUG
|
||||
std::cerr << "p3Service::send() ERROR size == 0";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
/* can't convert! */
|
||||
delete si;
|
||||
srvMtx.unlock(); /***** UNLOCK MUTEX *****/
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
RsRawItem *raw = new RsRawItem(si->PacketId(), size);
|
||||
if (!rsSerialiser->serialise(si, raw->getRawData(), &size))
|
||||
{
|
||||
#ifdef SERV_DEBUG
|
||||
std::cerr << "p3Service::send() ERROR serialise failed";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
delete raw;
|
||||
raw = NULL;
|
||||
}
|
||||
|
||||
if ((raw) && (size != raw->getRawLength()))
|
||||
{
|
||||
#ifdef SERV_DEBUG
|
||||
std::cerr << "p3Service::send() ERROR serialise size mismatch";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
delete raw;
|
||||
raw = NULL;
|
||||
}
|
||||
|
@ -207,7 +194,7 @@ RsRawItem *p3Service::send()
|
|||
if(si->priority_level() == QOS_PRIORITY_UNKNOWN)
|
||||
{
|
||||
std::cerr << "************************************************************" << std::endl;
|
||||
std::cerr << "********** Warning: p3service::send() ********" << std::endl;
|
||||
std::cerr << "********** Warning: p3Service::send() ********" << std::endl;
|
||||
std::cerr << "********** Warning: caught a RsItem with undefined ********" << std::endl;
|
||||
std::cerr << "********** priority level. That should not ********" << std::endl;
|
||||
std::cerr << "********** happen. Please fix your items! ********" << std::endl;
|
||||
|
@ -219,38 +206,11 @@ RsRawItem *p3Service::send()
|
|||
/* cleanup */
|
||||
delete si;
|
||||
|
||||
srvMtx.unlock(); /***** UNLOCK MUTEX *****/
|
||||
#ifdef SERV_DEBUG
|
||||
std::cerr << "p3Service::send() returning RawItem.";
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "p3Service::send() returning RawItem.";
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
return raw;
|
||||
return pqiService::send(raw);
|
||||
}
|
||||
|
||||
|
||||
std::string generateRandomServiceId()
|
||||
{
|
||||
std::string out;
|
||||
|
||||
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
#ifndef WINDOWS_SYS
|
||||
/* 4 bytes per random number: 4 x 4 = 16 bytes */
|
||||
for(int i = 0; i < 4; i++)
|
||||
{
|
||||
uint32_t rint = random();
|
||||
rs_sprintf_append(out, "%08x", rint);
|
||||
}
|
||||
#else
|
||||
srand(time(NULL));
|
||||
/* 2 bytes per random number: 8 x 2 = 16 bytes */
|
||||
for(int i = 0; i < 8; i++)
|
||||
{
|
||||
uint16_t rint = rand(); /* only gives 16 bits */
|
||||
rs_sprintf_append(out, "%04x", rint);
|
||||
}
|
||||
#endif
|
||||
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -52,13 +52,14 @@ std::string generateRandomServiceId();
|
|||
|
||||
//TODO : encryption and upload / download rate implementation
|
||||
|
||||
class p3Service: public pqiService
|
||||
|
||||
class p3FastService: public pqiService
|
||||
{
|
||||
protected:
|
||||
|
||||
p3Service(uint16_t type)
|
||||
p3FastService(uint16_t type)
|
||||
:pqiService((((uint32_t) RS_PKT_VERSION_SERVICE) << 24) + (((uint32_t) type) << 8)),
|
||||
srvMtx("p3Service"), rsSerialiser(NULL)
|
||||
srvMtx("p3FastService"), rsSerialiser(NULL)
|
||||
{
|
||||
rsSerialiser = new RsSerialiser();
|
||||
return;
|
||||
|
@ -66,33 +67,59 @@ class p3Service: public pqiService
|
|||
|
||||
public:
|
||||
|
||||
virtual ~p3Service() { delete rsSerialiser; return; }
|
||||
virtual ~p3FastService() { delete rsSerialiser; return; }
|
||||
|
||||
/*************** INTERFACE ******************************/
|
||||
/* called from Thread/tick/GUI */
|
||||
int sendItem(RsItem *);
|
||||
RsItem * recvItem();
|
||||
bool receivedItems();
|
||||
|
||||
virtual int tick() { return 0; }
|
||||
/*************** INTERFACE ******************************/
|
||||
|
||||
|
||||
public:
|
||||
// overloaded pqiService interface.
|
||||
virtual int receive(RsRawItem *);
|
||||
virtual RsRawItem * send();
|
||||
virtual bool recv(RsRawItem *);
|
||||
|
||||
// called by recv().
|
||||
virtual bool recvItem(RsItem *item) = 0;
|
||||
|
||||
|
||||
protected:
|
||||
void addSerialType(RsSerialType *);
|
||||
|
||||
private:
|
||||
|
||||
RsMutex srvMtx;
|
||||
/* below locked by Mutex */
|
||||
RsMutex srvMtx; /* below locked by Mutex */
|
||||
|
||||
RsSerialiser *rsSerialiser;
|
||||
std::list<RsItem *> recv_queue, send_queue;
|
||||
};
|
||||
|
||||
|
||||
class p3Service: public p3FastService
|
||||
{
|
||||
protected:
|
||||
|
||||
p3Service(uint16_t type)
|
||||
:p3FastService(type)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/*************** INTERFACE ******************************/
|
||||
/* called from Thread/tick/GUI */
|
||||
//int sendItem(RsItem *);
|
||||
RsItem * recvItem();
|
||||
bool receivedItems();
|
||||
|
||||
//virtual int tick() { return 0; }
|
||||
/*************** INTERFACE ******************************/
|
||||
|
||||
public:
|
||||
// overloaded p3FastService interface.
|
||||
virtual bool recvItem(RsItem *item);
|
||||
|
||||
private:
|
||||
|
||||
/* below locked by srvMtx Mutex */
|
||||
std::list<RsItem *> recv_queue;
|
||||
};
|
||||
|
||||
|
||||
|
@ -110,16 +137,17 @@ class nullService: public pqiService
|
|||
|
||||
public:
|
||||
// overloaded NULL pqiService interface.
|
||||
virtual int receive(RsRawItem *item)
|
||||
virtual bool recv(RsRawItem *item)
|
||||
{
|
||||
/* drop any items */
|
||||
delete item;
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual RsRawItem * send()
|
||||
virtual bool send(RsRawItem *item)
|
||||
{
|
||||
return NULL;
|
||||
delete item;
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -504,7 +504,7 @@ std::string chooseRandomAuthorId()
|
|||
|
||||
uint32_t idx = (uint32_t) (ownIds.size() * RSRandom::random_f32());
|
||||
int i = 0;
|
||||
for(it = ownIds.begin(); (it != ownIds.end()) && (i < idx); it++, i++);
|
||||
for(it = ownIds.begin(); (it != ownIds.end()) && (i < idx); it++, i++) ;
|
||||
|
||||
std::string answer;
|
||||
if (it != ownIds.end())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue