Merge branch 'master' into webui

This commit is contained in:
zeners 2016-01-31 10:57:27 +01:00
commit 67475b30e7
33 changed files with 929 additions and 164 deletions

View File

@ -0,0 +1,486 @@
; Script generated with the Venis Install Wizard & modified by defnax
; Reworked by Thunder
# Needed defines
;!define BUILDADD ""
;!define SOURCEDIR ""
;!define RELEASEDIR ""
;!define QTDIR ""
;!define MINGWDIR ""
# Optional defines
;!define OUTDIR ""
# Check needed defines
!ifndef BUILDADD
!error "BUILDADD is not defined"
!endif
!ifndef SOURCEDIR
!error "SOURCEDIR is not defined"
!endif
!ifndef RELEASEDIR
!error "RELEASEDIR is not defined"
!endif
!ifndef QTDIR
!error "QTDIR is not defined"
!endif
!ifndef MINGWDIR
!error "MINGWDIR is not defined"
!endif
# Check optional defines
!ifdef OUTDIR
!define OUTDIR_ "${OUTDIR}\"
!else
!define OUTDIR ""
!define OUTDIR_ ""
!endif
# Get version from executable
!GetDllVersion "${RELEASEDIR}\retroshare-gui\src\release\RetroShare06.exe" VERSION_
!define VERSION ${VERSION_1}.${VERSION_2}.${VERSION_3}${BUILDADD}
;!define REVISION ${VERSION_4}
# Check version
!ifndef REVISION
!error "REVISION is not defined"
!endif
!ifndef REVISION
!error "REVISION is not defined"
!endif
# Date
!define /date Date "%Y%m%d"
# Application name and version
!define APPNAME "RetroShare"
!define APPNAMEANDVERSION "${APPNAME} ${VERSION}"
!define PUBLISHER "RetroShare Team"
# Install path
!define INSTDIR_NORMAL "$ProgramFiles\${APPNAME}"
!define INSTDIR_PORTABLE "$Desktop\${APPNAME}"
!define DATADIR_NORMAL "$APPDATA\${APPNAME}"
!define DATADIR_PORTABLE "$INSTDIR\Data"
# Main Install settings
Name "${APPNAMEANDVERSION}"
InstallDirRegKey HKLM "Software\${APPNAME}" ""
OutFile "${OUTDIR_}RetroShare-${VERSION}-${Date}-${REVISION}-setup.exe"
BrandingText "${APPNAMEANDVERSION}"
RequestExecutionlevel highest
# Use compression
SetCompressor /SOLID LZMA
# Global variables
Var PortableMode
Var InstDirNormal
Var InstDirPortable
Var DataDir
Var StyleSheetDir
# Modern interface settings
!include Sections.nsh
!include nsDialogs.nsh
!include "MUI.nsh"
# Interface Settings
!define MUI_ABORTWARNING
!define MUI_HEADERIMAGE
!define MUI_HEADERIMAGE_BITMAP "${SOURCEDIR}\build_scripts\Windows\HeaderImage.bmp"
;!define MUI_WELCOMEFINISHPAGE_BITMAP "...bmp"
# MUI defines
!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\orange-install.ico"
!define MUI_FINISHPAGE_NOAUTOCLOSE
!define MUI_LICENSEPAGE_RADIOBUTTONS
!define MUI_COMPONENTSPAGE_SMALLDESC
!define MUI_FINISHPAGE_LINK "Visit the RetroShare forum for the latest news and support"
!define MUI_FINISHPAGE_LINK_LOCATION "http://retroshare.sourceforge.net/forum/"
!define MUI_FINISHPAGE_RUN "$INSTDIR\RetroShare.exe"
!define MUI_FINISHPAGE_SHOWREADME $INSTDIR\changelog.txt
!define MUI_FINISHPAGE_SHOWREADME_TEXT changelog.txt
!define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED
!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\orange-uninstall.ico"
!define MUI_UNFINISHPAGE_NOAUTOCLOSE
;!define MUI_LANGDLL_REGISTRY_ROOT HKLM
;!define MUI_LANGDLL_REGISTRY_KEY ${REGKEY}
;!define MUI_LANGDLL_REGISTRY_VALUENAME InstallerLanguage
# Defines the un-/installer logo of RetroShare
!insertmacro MUI_DEFAULT MUI_WELCOMEFINISHPAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Wizard\orange.bmp"
!insertmacro MUI_DEFAULT MUI_UNWELCOMEFINISHPAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Wizard\orange-uninstall.bmp"
# Installer pages
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_LICENSE "$(myLicenseData)"
Page Custom PortableModePageCreate PortableModePageLeave
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE dir_leave
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
# Set languages (first is default language)
!insertmacro MUI_RESERVEFILE_LANGDLL
# Installer languages
!define MUI_LANGDLL_ALLLANGUAGES
# Translations
!macro LANG_LOAD LANGUAGE LANGCODE LANGID LICENCEFILE
!insertmacro MUI_LANGUAGE "${LANGUAGE}"
; !verbose off
!define LANG "${LANGUAGE}"
!include "lang\${LANGCODE}.nsh"
LangString LANGUAGEID "${LANG_${LANG}}" "1031"
LicenseLangString myLicenseData ${LANGCODE} ${LICENCEFILE}
; !verbose on
!undef LANG
!macroend
!macro LANG_STRING NAME VALUE
LangString "${NAME}" "${LANG_${LANG}}" "${VALUE}"
!macroend
!insertmacro LANG_LOAD "English" "en" "1033" "${SOURCEDIR}\retroshare-gui\src\license\license.txt"
!insertmacro LANG_LOAD "French" "fr" "1036" "${SOURCEDIR}\retroshare-gui\src\license\license-FR.txt"
!insertmacro LANG_LOAD "German" "de" "1031" "${SOURCEDIR}\retroshare-gui\src\license\license-GER.txt"
!insertmacro LANG_LOAD "Turkish" "tr" "1055" "${SOURCEDIR}\retroshare-gui\src\license\license-TR.txt"
!insertmacro LANG_LOAD "SimpChinese" "zh_CN" "2052" "${SOURCEDIR}\retroshare-gui\src\license\license.txt"
!insertmacro LANG_LOAD "Polish" "pl" "1045" "${SOURCEDIR}\retroshare-gui\src\license\license.txt"
!insertmacro LANG_LOAD "Spanish" "es" "1034" "${SOURCEDIR}\retroshare-gui\src\license\license.txt"
!insertmacro LANG_LOAD "Russian" "ru" "1049" "${SOURCEDIR}\retroshare-gui\src\license\license.txt"
!insertmacro LANG_LOAD "Catalan" "ca_ES" "1027" "${SOURCEDIR}\retroshare-gui\src\license\license.txt"
LicenseData $(myLicenseData)
# Main binaries
Section $(Section_Main) Section_Main
;Set Section required
SectionIn RO
; Set Section properties
SetOverwrite on
; Clears previous error logs
; Delete "$INSTDIR\*.log"
; Main binaries
SetOutPath "$INSTDIR"
File /oname=RetroShare.exe "${RELEASEDIR}\retroshare-gui\src\release\RetroShare06.exe"
File /oname=retroshare-nogui.exe "${RELEASEDIR}\retroshare-nogui\src\release\RetroShare06-nogui.exe"
; Qt binaries
File "${QTDIR}\bin\Qt5Core.dll"
File "${QTDIR}\bin\Qt5Gui.dll"
File "${QTDIR}\bin\Qt5Multimedia.dll"
File "${QTDIR}\bin\Qt5Network.dll"
File "${QTDIR}\bin\Qt5PrintSupport.dll"
File "${QTDIR}\bin\Qt5Svg.dll"
File "${QTDIR}\bin\Qt5Widgets.dll"
File "${QTDIR}\bin\Qt5Xml.dll"
; Qt audio
SetOutPath "$INSTDIR\audio"
File /r "${QTDIR}\plugins\audio\qtaudio_windows.dll"
; Qt platforms
SetOutPath "$INSTDIR\platforms"
File /r "${QTDIR}\plugins\platforms\qwindows.dll"
; MinGW binaries
SetOutPath "$INSTDIR"
File "${MINGWDIR}\bin\libstdc++-6.dll"
File "${MINGWDIR}\bin\libgcc_s_dw2-1.dll"
File "${MINGWDIR}\bin\libwinpthread-1.dll"
; External binaries
File "${SOURCEDIR}\..\libs\bin\miniupnpc.dll"
File "${SOURCEDIR}\..\libs\bin\libeay32.dll"
File "${SOURCEDIR}\..\libs\bin\ssleay32.dll"
; Other files
File "${SOURCEDIR}\retroshare-gui\src\changelog.txt"
File "${SOURCEDIR}\libbitdht\src\bitdht\bdboot.txt"
; Image formats
SetOutPath "$INSTDIR\imageformats"
File /r "${QTDIR}\plugins\imageformats\qgif.dll"
File /r "${QTDIR}\plugins\imageformats\qicns.dll"
File /r "${QTDIR}\plugins\imageformats\qico.dll"
File /r "${QTDIR}\plugins\imageformats\qjp2.dll"
File /r "${QTDIR}\plugins\imageformats\qjpeg.dll"
File /r "${QTDIR}\plugins\imageformats\qmng.dll"
File /r "${QTDIR}\plugins\imageformats\qsvg.dll"
File /r "${QTDIR}\plugins\imageformats\qtga.dll"
File /r "${QTDIR}\plugins\imageformats\qtiff.dll"
File /r "${QTDIR}\plugins\imageformats\qwbmp.dll"
File /r "${QTDIR}\plugins\imageformats\qwebp.dll"
; Sounds
SetOutPath "$INSTDIR\sounds"
File /r "${SOURCEDIR}\retroshare-gui\src\sounds\*.*"
; Translations
SetOutPath "$INSTDIR\translations"
File /r "${SOURCEDIR}\retroshare-gui\src\translations\*.qm"
File /r "${QTDIR}\translations\qt_*.qm"
File /r "${QTDIR}\translations\qtbase_*.qm"
File /r "${QTDIR}\translations\qtscript_*.qm"
File /r "${QTDIR}\translations\qtquick1_*.qm"
File /r "${QTDIR}\translations\qtmultimedia_*.qm"
File /r "${QTDIR}\translations\qtxmlpatterns_*.qm"
; WebUI
SetOutPath "$INSTDIR\webui"
File /r "${SOURCEDIR}\libresapi\src\webfiles\*.*"
; License
SetOutPath "$INSTDIR\license"
File /r "${SOURCEDIR}\retroshare-gui\src\license\*.*"
SectionEnd
# Plugins
SectionGroup $(Section_Plugins) Section_Plugins
Section $(Section_Plugin_FeedReader) Section_Plugin_FeedReader
SetOutPath "$DataDir\extensions6"
File "${RELEASEDIR}\plugins\FeedReader\release\FeedReader.dll"
SectionEnd
Section $(Section_Plugin_VOIP) Section_Plugin_VOIP
SetOutPath "$DataDir\extensions6"
File "${RELEASEDIR}\plugins\VOIP\release\VOIP.dll"
SectionEnd
SectionGroupEnd
# Data (Styles)
Section $(Section_Data) Section_Data
; Set Section properties
SetOverwrite on
; Chat style
SetOutPath "$StyleSheetDir\stylesheets\Bubble"
File /r "${SOURCEDIR}\retroshare-gui\src\gui\qss\chat\Bubble\*.*"
SetOutPath "$StyleSheetDir\stylesheets\Bubble_Compact"
File /r "${SOURCEDIR}\retroshare-gui\src\gui\qss\chat\Bubble_Compact\*.*"
; Stylesheets
SetOutPath "$INSTDIR\qss"
File /r "${SOURCEDIR}\retroshare-gui\src\qss\*.*"
SectionEnd
;Section $(Section_Link) Section_Link
; Delete any existing keys
; Write the file association
; WriteRegStr HKCR .pqi "" retroshare
; WriteRegStr HKCR retroshare "" "PQI File"
; WriteRegBin HKCR retroshare EditFlags 00000100
; WriteRegStr HKCR "retroshare\shell" "" open
; WriteRegStr HKCR "retroshare\shell\open\command" "" `"$INSTDIR\RetroShare.exe" "%1"`
;SectionEnd
# Shortcuts
SectionGroup $(Section_Shortcuts) Section_Shortcuts
Section $(Section_StartMenu) Section_StartMenu
SetOutPath "$INSTDIR"
CreateDirectory "$SMPROGRAMS\${APPNAME}"
CreateShortCut "$SMPROGRAMS\${APPNAME}\$(Link_Uninstall).lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0
CreateShortCut "$SMPROGRAMS\${APPNAME}\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0
SectionEnd
Section $(Section_Desktop) Section_Desktop
CreateShortCut "$DESKTOP\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0
SectionEnd
Section $(Section_QuickLaunch) Section_QuickLaunch
CreateShortCut "$QUICKLAUNCH\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe" 0
SectionEnd
SectionGroupEnd
Section $(Section_AutoStart) Section_AutoStart
WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "RetroShare" "$INSTDIR\${APPNAME}.exe -m"
SectionEnd
;Section $(Section_AutoStart) Section_AutoStart
; CreateShortCut "$SMSTARTUP\${APPNAME}.lnk" "$INSTDIR\RetroShare.exe" "" "$INSTDIR\RetroShare.exe -m" 0
;SectionEnd
Section -FinishSection
${If} $PortableMode = 0
WriteRegStr HKLM "Software\${APPNAME}" "" "$INSTDIR"
WriteRegStr HKLM "Software\${APPNAME}" "Version" "${VERSION}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "DisplayName" "${APPNAME}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "DisplayVersion" "${VERSION}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "DisplayIcon" "$INSTDIR\RetroShare.exe"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "Publisher" "${PUBLISHER}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "NoModify" "1"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "NoRepair" "1"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "UninstallString" "$INSTDIR\uninstall.exe"
WriteUninstaller "$INSTDIR\uninstall.exe"
${Else}
; Create the file the application uses to detect portable mode
FileOpen $0 "$INSTDIR\portable" w
FileClose $0
${EndIf}
SectionEnd
# Descriptions
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
!insertmacro MUI_DESCRIPTION_TEXT ${Section_Main} $(Section_Main_Desc)
!insertmacro MUI_DESCRIPTION_TEXT ${Section_Data} $(Section_Data_Desc)
!insertmacro MUI_DESCRIPTION_TEXT ${Section_Shortcuts} $(Section_Shortcuts_Desc)
!insertmacro MUI_DESCRIPTION_TEXT ${Section_StartMenu} $(Section_StartMenu_Desc)
!insertmacro MUI_DESCRIPTION_TEXT ${Section_Desktop} $(Section_Desktop_Desc)
!insertmacro MUI_DESCRIPTION_TEXT ${Section_QuickLaunch} $(Section_QuickLaunch_Desc)
!insertmacro MUI_DESCRIPTION_TEXT ${Section_Plugins} $(Section_Plugins_Desc)
!insertmacro MUI_DESCRIPTION_TEXT ${Section_Plugin_FeedReader} $(Section_Plugin_FeedReader_Desc)
!insertmacro MUI_DESCRIPTION_TEXT ${Section_Plugin_VOIP} $(Section_Plugin_VOIP_Desc)
; !insertmacro MUI_DESCRIPTION_TEXT ${Section_Link} $(Section_Link_Desc)
!insertmacro MUI_DESCRIPTION_TEXT ${Section_AutoStart} $(Section_AutoStart_Desc)
!insertmacro MUI_FUNCTION_DESCRIPTION_END
# Uninstall
Section "Uninstall"
; Remove file association registry keys
; DeleteRegKey HKCR .pqi
DeleteRegKey HKCR RetroShare
; Remove program/uninstall regsitry keys
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}"
DeleteRegKey HKLM SOFTWARE\${APPNAME}
DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "RetroShare"
; Remove shortcuts, if any
Delete "$SMPROGRAMS\${APPNAME}\*.*"
; Remove desktop shortcut
Delete "$DESKTOP\${APPNAME}.lnk"
; Remove Quicklaunch shortcut
Delete "$QUICKLAUNCH\${APPNAME}.lnk"
; Remove Autstart
Delete "$SMSTARTUP\${APPNAME}.lnk"
; Remove directories used
RMDir "$SMPROGRAMS\${APPNAME}"
RMDir /r "$INSTDIR"
; Don't remove the directory, otherwise
; we lose the XPGP keys.
; Should make this an option though...
RMDir /r "${DATADIR_NORMAL}\extensions6"
RMDir /r "${DATADIR_NORMAL}\stylesheets"
SectionEnd
Function .onInit
StrCpy $InstDirNormal "${INSTDIR_NORMAL}"
StrCpy $InstDirPortable "${INSTDIR_PORTABLE}"
StrCpy $PortableMode 0
StrCpy $INSTDIR "$InstDirNormal"
StrCpy $DataDir "${DATADIR_NORMAL}"
InitPluginsDir
Push $R1
File /oname=$PLUGINSDIR\spltmp.bmp "${SOURCEDIR}\retroshare-gui\src\gui\images\logo\logo_splash.png"
advsplash::show 1200 1000 1000 -1 $PLUGINSDIR\spltmp
Pop $R1
Pop $R1
!insertmacro MUI_LANGDLL_DISPLAY
FunctionEnd
# Installation mode
Function RequireAdmin
UserInfo::GetAccountType
Pop $8
${If} $8 != "admin"
MessageBox MB_ICONSTOP "You need administrator rights to install ${APPNAME}"
SetErrorLevel 740 ;ERROR_ELEVATION_REQUIRED
Abort
${EndIf}
FunctionEnd
Function SetModeDestinationFromInstdir
${If} $PortableMode = 0
StrCpy $InstDirNormal $INSTDIR
${Else}
StrCpy $InstDirPortable $INSTDIR
${EndIf}
FunctionEnd
Function PortableModePageCreate
Call SetModeDestinationFromInstdir ; If the user clicks BACK on the directory page we will remember their mode specific directory
!insertmacro MUI_HEADER_TEXT $(Page_InstallMode) $(Page_InstallMode_Desc)
nsDialogs::Create 1018
Pop $0
${NSD_CreateRadioButton} 5u 25u -10u 8u $(Page_InstallMode_Standard)
Pop $1
${NSD_CreateLabel} 18u 40u -10u 24u $(Page_InstallMode_Standard_Desc)
Pop $0
${NSD_CreateRadioButton} 5u 75u -10u 8u $(Page_InstallMode_Portable)
Pop $2
${NSD_CreateLabel} 18u 90u -10u 24u $(Page_InstallMode_Portable_Desc)
Pop $0
${If} $PortableMode = 0
SendMessage $1 ${BM_SETCHECK} ${BST_CHECKED} 0
${Else}
SendMessage $2 ${BM_SETCHECK} ${BST_CHECKED} 0
${EndIf}
nsDialogs::Show
FunctionEnd
Function PortableModePageLeave
${NSD_GetState} $1 $0
${If} $0 <> ${BST_UNCHECKED}
StrCpy $PortableMode 0
StrCpy $INSTDIR $InstDirNormal
Call RequireAdmin
; Enable sections
SectionSetText ${Section_Shortcuts} $(Section_Shortcuts)
SectionSetText ${Section_StartMenu} $(Section_StartMenu)
SectionSetText ${Section_Desktop} $(Section_Desktop)
SectionSetText ${Section_QuickLaunch} $(Section_QuickLaunch)
SectionSetText ${Section_AutoStart} $(Section_AutoStart)
!insertmacro SelectSection ${Section_Shortcuts}
!insertmacro SelectSection ${Section_AutoStart}
!insertmacro SelectSection ${Section_StartMenu}
!insertmacro SelectSection ${Section_Desktop}
!insertmacro SelectSection ${Section_QuickLaunch}
${Else}
StrCpy $PortableMode 1
StrCpy $INSTDIR $InstDirPortable
; Disable sections
!insertmacro UnselectSection ${Section_Shortcuts}
!insertmacro UnselectSection ${Section_AutoStart}
!insertmacro UnselectSection ${Section_StartMenu}
!insertmacro UnselectSection ${Section_Desktop}
!insertmacro UnselectSection ${Section_QuickLaunch}
SectionSetText ${Section_Shortcuts} ""
SectionSetText ${Section_StartMenu} ""
SectionSetText ${Section_Desktop} ""
SectionSetText ${Section_QuickLaunch} ""
SectionSetText ${Section_AutoStart} ""
${EndIf}
FunctionEnd
Function dir_leave
${If} $PortableMode = 0
StrCpy $DataDir "${DATADIR_NORMAL}"
StrCpy $StyleSheetDir $DataDir
${Else}
StrCpy $DataDir "${DATADIR_PORTABLE}"
StrCpy $StyleSheetDir $INSTDIR
${EndIf}
FunctionEnd

View File

@ -299,10 +299,10 @@ bool p3BitDht::loadList(std::list<RsItem *>& load)
return false; return false;
} }
std::cerr << "BITDHT Load Item:"; //std::cerr << "BITDHT Load Item:";
std::cerr << std::endl; //std::cerr << std::endl;
config->print(std::cerr, 0); //config->print(std::cerr, 0);
std::list<std::string> servers; std::list<std::string> servers;
int peers[RSDHT_RELAY_NUM_CLASS] = {0}; int peers[RSDHT_RELAY_NUM_CLASS] = {0};
@ -320,16 +320,16 @@ bool p3BitDht::loadList(std::list<RsItem *>& load)
{ {
/* add to RELAY_SERVER List */ /* add to RELAY_SERVER List */
servers.push_back(value); servers.push_back(value);
std::cerr << "p3BitDht::loadList() Found Server: " << value; //std::cerr << "p3BitDht::loadList() Found Server: " << value;
std::cerr << std::endl; //std::cerr << std::endl;
} }
else if (0 == strncmp(key.c_str(), "RELAY_MODE", 10)) else if (0 == strncmp(key.c_str(), "RELAY_MODE", 10))
{ {
mode = atoi(value.c_str()); mode = atoi(value.c_str());
haveMode = true; haveMode = true;
std::cerr << "p3BitDht::loadList() Found Mode: " << mode; //std::cerr << "p3BitDht::loadList() Found Mode: " << mode;
std::cerr << std::endl; //std::cerr << std::endl;
} }
else if (0 == strncmp(key.c_str(), "RELAY_CLASS", 11)) else if (0 == strncmp(key.c_str(), "RELAY_CLASS", 11))
{ {
@ -358,24 +358,24 @@ bool p3BitDht::loadList(std::list<RsItem *>& load)
if (key[13] == 'C') if (key[13] == 'C')
{ {
std::cerr << "p3BitDht::loadList() Found Count(" << idx << "): "; //std::cerr << "p3BitDht::loadList() Found Count(" << idx << "): ";
std::cerr << val; //std::cerr << val;
std::cerr << std::endl; //std::cerr << std::endl;
peers[idx] = val; peers[idx] = val;
} }
else else
{ {
std::cerr << "p3BitDht::loadList() Found Bandwidth(" << idx << "): "; //std::cerr << "p3BitDht::loadList() Found Bandwidth(" << idx << "): ";
std::cerr << val; //std::cerr << val;
std::cerr << std::endl; //std::cerr << std::endl;
bandwidth[idx] = val; bandwidth[idx] = val;
} }
} }
else else
{ {
std::cerr << "p3BitDht::loadList() Unknown Key:value: " << key; //std::cerr << "p3BitDht::loadList() Unknown Key:value: " << key;
std::cerr << ":" << value; //std::cerr << ":" << value;
std::cerr << std::endl; //std::cerr << std::endl;
} }
} }

View File

@ -142,25 +142,44 @@ RsGRouterGenericDataItem *RsGRouterSerialiser::deserialise_RsGRouterGenericDataI
ok &= getRawUInt32(data, pktsize, &offset, &item->service_id); ok &= getRawUInt32(data, pktsize, &offset, &item->service_id);
ok &= getRawUInt32(data, pktsize, &offset, &item->data_size); ok &= getRawUInt32(data, pktsize, &offset, &item->data_size);
if(item->data_size > rssize || offset > rssize - item->data_size) // better than if(item->data_size + offset > rssize) if(item->data_size > 0) // This happens when the item data has been deleted from the cache
{ {
std::cerr << __PRETTY_FUNCTION__ << ": Cannot read beyond item size. Serialisation error!" << std::endl; if(item->data_size > rssize || offset > rssize - item->data_size) // better than if(item->data_size + offset > rssize)
delete item; {
return NULL ; std::cerr << __PRETTY_FUNCTION__ << ": Cannot read beyond item size. Serialisation error!" << std::endl;
} delete item;
return NULL ;
}
if( NULL == (item->data_bytes = (uint8_t*)rs_malloc(item->data_size))) if( NULL == (item->data_bytes = (uint8_t*)rs_malloc(item->data_size)))
{ {
delete item; delete item;
return NULL ; return NULL ;
} }
memcpy(item->data_bytes,&((uint8_t*)data)[offset],item->data_size) ; memcpy(item->data_bytes,&((uint8_t*)data)[offset],item->data_size) ;
offset += item->data_size ; offset += item->data_size ;
}
else
item->data_bytes = NULL ;
ok &= item->signature.GetTlv(data, pktsize, &offset) ; ok &= item->signature.GetTlv(data, pktsize, &offset) ;
ok &= getRawUInt32(data, pktsize, &offset, &item->randomized_distance); ok &= getRawUInt32(data, pktsize, &offset, &item->duplication_factor);
// make sure the duplication factor is not altered by friends. In the worst case, the item will duplicate a bit more.
if(item->duplication_factor < 1)
{
item->duplication_factor = 1 ;
std::cerr << "(II) correcting GRouter item duplication factor from 0 to 1, to ensure backward compat." << std::endl;
}
if(item->duplication_factor > GROUTER_MAX_DUPLICATION_FACTOR)
{
std::cerr << "(WW) correcting GRouter item duplication factor of " << item->duplication_factor << ". This is very unexpected." << std::endl;
item->duplication_factor = GROUTER_MAX_DUPLICATION_FACTOR ;
}
ok &= getRawUInt32(data, pktsize, &offset, &item->flags); ok &= getRawUInt32(data, pktsize, &offset, &item->flags);
if (offset != rssize || !ok) if (offset != rssize || !ok)
@ -382,7 +401,7 @@ uint32_t RsGRouterGenericDataItem::serial_size() const
s += 4 ; // service id s += 4 ; // service id
s += data_size ; // data s += data_size ; // data
s += signature.TlvSize() ; // signature s += signature.TlvSize() ; // signature
s += 4 ; // randomized distance s += 4 ; // duplication_factor
s += 4 ; // flags s += 4 ; // flags
return s ; return s ;
@ -483,7 +502,7 @@ bool RsGRouterGenericDataItem::serialise(void *data,uint32_t& size) const
ok &= signature.SetTlv(data, tlvsize, &offset) ; ok &= signature.SetTlv(data, tlvsize, &offset) ;
ok &= setRawUInt32(data, tlvsize, &offset, randomized_distance) ; ok &= setRawUInt32(data, tlvsize, &offset, duplication_factor) ;
ok &= setRawUInt32(data, tlvsize, &offset, flags) ; ok &= setRawUInt32(data, tlvsize, &offset, flags) ;
if (offset != tlvsize) if (offset != tlvsize)
@ -796,7 +815,7 @@ std::ostream& RsGRouterGenericDataItem::print(std::ostream& o, uint16_t)
o << " Data size: " << data_size << std::endl ; o << " Data size: " << data_size << std::endl ;
o << " Data hash: " << RsDirUtil::sha1sum(data_bytes,data_size) << std::endl ; o << " Data hash: " << RsDirUtil::sha1sum(data_bytes,data_size) << std::endl ;
o << " signature key: " << signature.keyId << std::endl; o << " signature key: " << signature.keyId << std::endl;
o << " randomized dist:" << randomized_distance << std::endl; o << " duplication fac:" << duplication_factor << std::endl;
o << " flags: " << flags << std::endl; o << " flags: " << flags << std::endl;
return o ; return o ;

View File

@ -133,7 +133,7 @@ class RsGRouterGenericDataItem: public RsGRouterAbstractMsgItem, public RsGRoute
uint32_t data_size ; uint32_t data_size ;
uint8_t *data_bytes; uint8_t *data_bytes;
uint32_t randomized_distance ; // number of hops (tunnel wise. Does not preclude of the real distance) uint32_t duplication_factor ; // number of duplicates allowed. Should be capped at each de-serialise operation!
// utility methods for signing data // utility methods for signing data
virtual uint32_t signed_data_size() const ; virtual uint32_t signed_data_size() const ;

View File

@ -203,7 +203,7 @@ void GRouterMatrix::debugDump() const
std::cerr << " " << it->first << ": from " << it->second.friend_id << " " << now - it->second.time_stamp << " secs ago." << std::endl; std::cerr << " " << it->first << ": from " << it->second.friend_id << " " << now - it->second.time_stamp << " secs ago." << std::endl;
} }
bool GRouterMatrix::computeRoutingProbabilities(const GRouterKeyId& key_id, const std::vector<RsPeerId>& friends, std::vector<float>& probas) const bool GRouterMatrix::computeRoutingProbabilities(const GRouterKeyId& key_id, const std::vector<RsPeerId>& friends, std::vector<float>& probas, float& maximum) const
{ {
// Routing probabilities are computed according to routing clues // Routing probabilities are computed according to routing clues
// //
@ -239,6 +239,7 @@ bool GRouterMatrix::computeRoutingProbabilities(const GRouterKeyId& key_id, cons
return false ; return false ;
} }
const std::vector<float>& w(it2->second) ; const std::vector<float>& w(it2->second) ;
maximum = 0.0f ;
for(uint32_t i=0;i<friends.size();++i) for(uint32_t i=0;i<friends.size();++i)
{ {
@ -250,6 +251,9 @@ bool GRouterMatrix::computeRoutingProbabilities(const GRouterKeyId& key_id, cons
{ {
probas[i] = w[findex] ; probas[i] = w[findex] ;
total += w[findex] ; total += w[findex] ;
if(maximum < w[findex])
maximum = w[findex] ;
} }
} }

View File

@ -57,7 +57,7 @@ class GRouterMatrix
// the computation accounts for the time at which the info was received and the // the computation accounts for the time at which the info was received and the
// weight of each routing hit record. // weight of each routing hit record.
// //
bool computeRoutingProbabilities(const GRouterKeyId& id, const std::vector<RsPeerId>& friends, std::vector<float>& probas) const ; bool computeRoutingProbabilities(const GRouterKeyId& id, const std::vector<RsPeerId>& friends, std::vector<float>& probas, float &maximum) const ;
// Update routing probabilities for each key, accounting for all received events, but without // Update routing probabilities for each key, accounting for all received events, but without
// activity information // activity information

View File

@ -44,6 +44,8 @@ static const uint32_t RS_GROUTER_MAX_KEEP_TRACKING_CLUES = 86400*10 ; // m
static const float RS_GROUTER_BASE_WEIGHT_ROUTED_MSG = 1.0f ; // base contribution of routed message clue to routing matrix static const float RS_GROUTER_BASE_WEIGHT_ROUTED_MSG = 1.0f ; // base contribution of routed message clue to routing matrix
static const float RS_GROUTER_BASE_WEIGHT_GXS_PACKET = 0.1f ; // base contribution of GXS message to routing matrix static const float RS_GROUTER_BASE_WEIGHT_GXS_PACKET = 0.1f ; // base contribution of GXS message to routing matrix
static const float RS_GROUTER_PROBABILITY_THRESHOLD_FOR_RANDOM_ROUTING = 0.01f ; // routing probability under which the routage is performed randomly
static const float RS_GROUTER_PROBABILITY_THRESHOLD_BEST_PEERS_SELECT = 0.5f ; // min ratio of forward proba with respect to best peer.
static const uint32_t MAX_TUNNEL_WAIT_TIME = 60 ; // wait for 60 seconds at most for a tunnel response. static const uint32_t MAX_TUNNEL_WAIT_TIME = 60 ; // wait for 60 seconds at most for a tunnel response.
static const uint32_t MAX_TUNNEL_UNMANAGED_TIME = 600 ; // min time before retry tunnels for that msg. static const uint32_t MAX_TUNNEL_UNMANAGED_TIME = 600 ; // min time before retry tunnels for that msg.
@ -54,6 +56,8 @@ static const uint32_t MAX_GROUTER_DATA_SIZE = 2*1024*1024 ; // 2M
static const uint32_t MAX_TRANSACTION_ACK_WAITING_TIME = 60 ; // wait for at most 60 secs for a ACK. If not restart the transaction. static const uint32_t MAX_TRANSACTION_ACK_WAITING_TIME = 60 ; // wait for at most 60 secs for a ACK. If not restart the transaction.
static const uint32_t DIRECT_FRIEND_TRY_DELAY = 20 ; // wait for 20 secs if no friends available, then try tunnels. static const uint32_t DIRECT_FRIEND_TRY_DELAY = 20 ; // wait for 20 secs if no friends available, then try tunnels.
static const uint32_t MAX_INACTIVE_DATA_PIPE_DELAY = 300 ; // clean inactive data pipes for more than 5 mins static const uint32_t MAX_INACTIVE_DATA_PIPE_DELAY = 300 ; // clean inactive data pipes for more than 5 mins
static const uint32_t GROUTER_MAX_DUPLICATION_FACTOR = 10 ; // max number of duplicates for a given message to keep in the network
static const uint32_t GROUTER_MAX_BRANCHING_FACTOR = 3 ; // max number of branches, for locally forwarding items
static const time_t RS_GROUTER_DEBUG_OUTPUT_PERIOD = 10 ; // Output everything static const time_t RS_GROUTER_DEBUG_OUTPUT_PERIOD = 10 ; // Output everything
static const time_t RS_GROUTER_AUTOWASH_PERIOD = 10 ; // Autowash every minute. Not a costly operation. static const time_t RS_GROUTER_AUTOWASH_PERIOD = 10 ; // Autowash every minute. Not a costly operation.

View File

@ -190,6 +190,7 @@
#include "services/p3idservice.h" #include "services/p3idservice.h"
#include "turtle/p3turtle.h" #include "turtle/p3turtle.h"
#include "gxs/rsgixs.h" #include "gxs/rsgixs.h"
#include "retroshare/rspeers.h"
#include "p3grouter.h" #include "p3grouter.h"
#include "grouteritems.h" #include "grouteritems.h"
@ -855,6 +856,34 @@ void p3GRouter::handleTunnels()
} }
} }
void p3GRouter::locked_sendToPeers(RsGRouterGenericDataItem *data_item,const std::map<RsPeerId,uint32_t>& peers_and_duplication_factors)
{
// slice the data appropriately and send.
uint32_t saved_duplication_factor = data_item->duplication_factor ; // this little trick avoids copying the item for each peer before slicing it up
for(std::map<RsPeerId,uint32_t>::const_iterator itpid(peers_and_duplication_factors.begin());itpid!=peers_and_duplication_factors.end();++itpid)
{
std::list<RsGRouterTransactionChunkItem*> chunks ;
data_item->duplication_factor = itpid->second;
sliceDataItem(data_item,chunks) ;
for(std::list<RsGRouterTransactionChunkItem*>::const_iterator it2(chunks.begin());it2!=chunks.end();++it2)
locked_sendTransactionData(itpid->first,*(*it2) ) ;
#ifdef GROUTER_DEBUG
std::cerr << " sending " << chunks.size() << " slices to peer " << itpid->first << " with duplication factor = " << itpid->second << std::endl;
#endif
// delete temporary items
for(std::list<RsGRouterTransactionChunkItem*>::const_iterator cit=chunks.begin();cit!=chunks.end();++cit)
delete *cit;
}
data_item->duplication_factor = saved_duplication_factor ;
}
void p3GRouter::routePendingObjects() void p3GRouter::routePendingObjects()
{ {
// Go throught he list of pending messages. For those with a peer ready, send the message to that peer. // Go throught he list of pending messages. For those with a peer ready, send the message to that peer.
@ -885,17 +914,45 @@ void p3GRouter::routePendingObjects()
{ {
// Look for tunnels and friends where to send the data. Send to both. // Look for tunnels and friends where to send the data. Send to both.
std::list<RsPeerId> peers ; std::map<RsPeerId,uint32_t> peers_and_duplication_factors ;
if(it->second.routing_flags & GRouterRoutingInfo::ROUTING_FLAGS_ALLOW_TUNNELS) if(it->second.routing_flags & GRouterRoutingInfo::ROUTING_FLAGS_ALLOW_TUNNELS)
locked_collectAvailableTunnels(it->second.tunnel_hash,peers); locked_collectAvailableTunnels(it->second.tunnel_hash,it->second.data_item->duplication_factor,peers_and_duplication_factors);
// For now, disable friends. We'll first check that the good old tunnel system works as before. if(!peers_and_duplication_factors.empty())
{
#ifdef GROUTER_DEBUG
std::cerr << " tunnels available! sending!" << std::endl;
#endif
locked_sendToPeers(it->second.data_item,peers_and_duplication_factors) ;
// change item state in waiting list
it->second.data_status = RS_GROUTER_DATA_STATUS_ONGOING ;
it->second.data_transaction_TS = now ;
pending_messages_changed = true ;
continue ; // no need to seek for friend asynced routes since tunnels directly go to the final destination!
}
if(it->second.routing_flags & GRouterRoutingInfo::ROUTING_FLAGS_ALLOW_FRIENDS) if(it->second.routing_flags & GRouterRoutingInfo::ROUTING_FLAGS_ALLOW_FRIENDS)
locked_collectAvailableFriends(it->second.data_item->destination_key,peers, it->second.incoming_routes.ids, it->second.routing_flags & GRouterRoutingInfo::ROUTING_FLAGS_IS_ORIGIN); locked_collectAvailableFriends(it->second.data_item->destination_key,it->second.incoming_routes.ids,it->second.data_item->duplication_factor,peers_and_duplication_factors);
if(peers.empty()) if(!peers_and_duplication_factors.empty())
{
#ifdef GROUTER_DEBUG
std::cerr << " friends available! sending!" << std::endl;
#endif
locked_sendToPeers(it->second.data_item,peers_and_duplication_factors) ;
// change item state in waiting list
it->second.data_status = RS_GROUTER_DATA_STATUS_ONGOING ;
it->second.data_transaction_TS = now ;
pending_messages_changed = true ;
}
else
{ {
#ifdef GROUTER_DEBUG #ifdef GROUTER_DEBUG
std::cerr << " no direct friends available" << std::endl; std::cerr << " no direct friends available" << std::endl;
@ -908,33 +965,8 @@ void p3GRouter::routePendingObjects()
#endif #endif
it->second.routing_flags |= GRouterRoutingInfo::ROUTING_FLAGS_ALLOW_TUNNELS ; it->second.routing_flags |= GRouterRoutingInfo::ROUTING_FLAGS_ALLOW_TUNNELS ;
} }
continue ;
} }
// slice the data appropriately and send.
std::list<RsGRouterTransactionChunkItem*> chunks ;
sliceDataItem(it->second.data_item,chunks) ;
#ifdef GROUTER_DEBUG
if(!peers.empty())
std::cerr << " sending to peers:" << std::endl;
#endif
for(std::list<RsPeerId>::const_iterator itpid(peers.begin());itpid!=peers.end();++itpid)
for(std::list<RsGRouterTransactionChunkItem*>::const_iterator it2(chunks.begin());it2!=chunks.end();++it2)
locked_sendTransactionData(*itpid,*(*it2) ) ;
// delete temporary items
for(std::list<RsGRouterTransactionChunkItem*>::const_iterator cit=chunks.begin();cit!=chunks.end();++cit)
delete *cit;
// change item state in waiting list
it->second.data_status = RS_GROUTER_DATA_STATUS_ONGOING ;
it->second.data_transaction_TS = now ;
pending_messages_changed = true ;
} }
else if(it->second.data_status == RS_GROUTER_DATA_STATUS_ONGOING && now > MAX_TRANSACTION_ACK_WAITING_TIME + it->second.data_transaction_TS) else if(it->second.data_status == RS_GROUTER_DATA_STATUS_ONGOING && now > MAX_TRANSACTION_ACK_WAITING_TIME + it->second.data_transaction_TS)
{ {
@ -1014,70 +1046,161 @@ void p3GRouter::routePendingObjects()
IndicateConfigChanged() ; IndicateConfigChanged() ;
} }
void p3GRouter::locked_collectAvailableFriends(const GRouterKeyId& gxs_id,std::list<RsPeerId>& friend_peers,const std::set<RsPeerId>& incoming_routes,bool is_origin) void p3GRouter::locked_collectAvailableFriends(const GRouterKeyId& gxs_id,const std::set<RsPeerId>& incoming_routes,uint32_t duplication_factor, std::map<RsPeerId,uint32_t>& friend_peers_and_duplication_factors)
{ {
// The strategy is the following: // Old strategy was the following:
// if origin // if origin
// send to multiple neighbors : best and random // send to multiple neighbors : best and random
// else // else
// send to a single "best" neighbor (determined by threshold over routing probability), // send to a single "best" neighbor (determined by threshold over routing probability),
std::set<RsPeerId> ids ; // New strategy is:
mServiceControl->getPeersConnected(getServiceInfo().mServiceType,ids) ; //
// Characteristics of the distribution to look at:
std::vector<float> probas; // * who's online, who's not
std::vector<RsPeerId> tmp_peers; // * all values quite equal
// * single value well above others
// remove previous peers // * largest value is small
// Algorithm:
for(std::set<RsPeerId>::const_iterator it(ids.begin());it!=ids.end();++it) //
if(incoming_routes.find(*it) == incoming_routes.end()) // 0 - encode duplicate factor in routed item and allow at most N duplicates
tmp_peers.push_back(*it) ; // - when forwarding to N peers, split the duplication factor into N bins, each being proportional to the forwarding probability.
// Example for N=3 and D=10:
if(tmp_peers.empty()) //
return ; // p Calculation Final bin
//
_routing_matrix.computeRoutingProbabilities(gxs_id, tmp_peers, probas) ; // +-0.21--> 0.21*10=2.1 --> 2 0.1 below
// |
// 10 ----+-0.45--> 0.45*10=4.5 --> 4.6-> 5 0.4 above
// |
// +-0.34--> 0.34*10=3.4 --> 3.0-> 3 0
//
//
// 1 - get routing probabilities p_i for all peers as well as the maximum proba p before normalization.
//
// Set N = min(3,item->duplication_factor) // max number of friends to route to
//
// if p < threshold // That means the routage info is too old => Fallback to random routing.
// Select N random online friends and forward to them.
// else
// Let p_i be the probabilities of all peers
// Select all online peers for which p_i >= 0.5*p.
// if !empty
// Update duplication factors according to probabilities and number of peers
// Route to these peers
// else
// Keep the item
//
#ifdef GROUTER_DEBUG #ifdef GROUTER_DEBUG
std::cerr << "locked_getAvailableFriends()" << std::endl; std::cerr << "locked_getAvailableFriends()" << std::endl;
std::cerr << " getting connected friends, computing routing probabilities" << std::endl; std::cerr << " looking for friends for item to ID " << gxs_id << " duplication factor = " << duplication_factor << std::endl;
std::cerr << " retrieving online friends and all friends lists." << std::endl;
#endif
std::set<RsPeerId> online_ids ;
std::list<RsPeerId> all_ids ;
rsPeers->getFriendList(all_ids) ;
mServiceControl->getPeersConnected(getServiceInfo().mServiceType,online_ids) ;
std::vector<RsPeerId> tmp_peers;
for(std::list<RsPeerId>::const_iterator it(all_ids.begin());it!=all_ids.end();++it)
tmp_peers.push_back(*it) ;
std::vector<float> probas;
float maximum = 1.0;
float max_probability = 0.0;
_routing_matrix.computeRoutingProbabilities(gxs_id, tmp_peers, probas, maximum) ;
#ifdef GROUTER_DEBUG
std::cerr << " initial routing probabilities (maximum=" << maximum << ")" << std::endl;
for(uint32_t i=0;i<tmp_peers.size();++i)
std::cerr << " " << tmp_peers[i] << " " << probas[i] << std::endl;
#endif
if(maximum < RS_GROUTER_PROBABILITY_THRESHOLD_FOR_RANDOM_ROUTING)
{
max_probability = 0.0f ;
#ifdef GROUTER_DEBUG
std::cerr << " max proba: " << maximum << " is below random threshold => using uniform random routing." << std::endl;
#endif
}
else
{
for(uint32_t i=0;i<tmp_peers.size();++i)
max_probability = std::max(max_probability,probas[i]) ;
}
#ifdef GROUTER_DEBUG
std::cerr << " maxi probability=" << max_probability << std::endl;
#endif
// remove incoming peers and peers for which the proba is less than half the maximum proba
float total_probas = 0.0f ;
uint32_t count=0;
for(uint32_t i=0;i<tmp_peers.size();++i)
if(incoming_routes.find(tmp_peers[i]) != incoming_routes.end())
std::cerr << " removing " << tmp_peers[i] << " which is an incoming route" << std::endl;
else if(probas[i] < RS_GROUTER_PROBABILITY_THRESHOLD_BEST_PEERS_SELECT*max_probability)
std::cerr << " removing " << tmp_peers[i] << " because probability is below best peers threshold" << std::endl;
else
{
tmp_peers[count] = tmp_peers[i] ;
probas[count] = (max_probability==0.0)? (0.5+0.001*RSRandom::random_f32()) : probas[i] ;
++count ;
total_probas+=probas[i] ;
}
tmp_peers.resize(count) ;
probas.resize(count) ;
if(tmp_peers.empty())
{
#ifdef GROUTER_DEBUG
std::cerr << " online - available peers empty => giving up." << std::endl;
#endif
return ;
}
// now select the N best peers
#ifdef GROUTER_DEBUG
std::cerr << " Remaining peers and routing probabilities:" << std::endl;
for(uint32_t i=0;i<tmp_peers.size();++i) for(uint32_t i=0;i<tmp_peers.size();++i)
std::cerr << " " << tmp_peers[i] << ", probability: " << probas[i] << std::endl; std::cerr << " " << tmp_peers[i] << ", probability: " << probas[i] << std::endl;
#endif #endif
uint32_t max_count = is_origin?3:1 ; float probability_threshold = RS_GROUTER_PROBABILITY_THRESHOLD_FOR_RANDOM_ROUTING ;
float probability_threshold = is_origin?0.0:0.5 ;
#ifdef GROUTER_DEBUG
std::cerr << " position at origin: " << is_origin << " => mac_count=" << max_count << ", proba threshold=" << probability_threshold << std::endl;
#endif
std::vector<std::pair<float,RsPeerId> > mypairs ; std::vector<std::pair<float,RsPeerId> > mypairs ;
for(uint32_t i=0;i<tmp_peers.size();++i) for(uint32_t i=0;i<tmp_peers.size();++i)
mypairs.push_back(std::make_pair(probas[i],tmp_peers[i])) ; mypairs.push_back(std::make_pair(probas[i]/total_probas,tmp_peers[i])) ;
// now sort them up // now sort them up
std::sort(mypairs.begin(),mypairs.end(),item_comparator_001()) ; std::sort(mypairs.begin(),mypairs.end(),item_comparator_001()) ;
// take the max_count peers that are still above min_probability uint32_t max_count = std::min(std::min((uint32_t)mypairs.size(),(uint32_t)GROUTER_MAX_BRANCHING_FACTOR),duplication_factor);
uint32_t n=0 ; uint32_t n=0 ;
float duplication_factor_delta =0.0;
uint32_t duplication_factor_buff =duplication_factor ;
for(std::vector<std::pair<float,RsPeerId> >::const_reverse_iterator it = mypairs.rbegin();it!=mypairs.rend() && n<max_count;++it) for(int i=mypairs.size()-1;i>=0 && n<max_count;--i)
if( (*it).first >= probability_threshold )
{ {
friend_peers.push_back( (*it).second ), ++n ; float ideal_dupl = duplication_factor*mypairs[i].first - duplication_factor_delta ; // correct what was taken in advance
#ifdef GROUTER_DEBUG
std::cerr << " keeping " << (*it).second << std::endl; uint32_t real_dupl = std::min( duplication_factor - max_count+1,std::max(1u,uint32_t(rint(ideal_dupl)))) ;
#endif duplication_factor_delta = real_dupl - ideal_dupl ;
if(!is_origin) // only collect one peer if we're not at origin. std::cerr << " Peer " << mypairs[i].second << " prob=" << mypairs[i].first << ", ideal_dupl=" << ideal_dupl << ", real=" << real_dupl << ". Delta = " << duplication_factor_delta << std::endl;
break ;
friend_peers_and_duplication_factors[ mypairs[i].second ] = real_dupl ; // should be updated correctly
++n ;
} }
} }
void p3GRouter::locked_collectAvailableTunnels(const TurtleFileHash& hash,std::list<RsPeerId>& tunnel_peers) void p3GRouter::locked_collectAvailableTunnels(const TurtleFileHash& hash,uint32_t total_duplication,std::map<RsPeerId,uint32_t>& tunnel_peers_and_duplication_factors)
{ {
time_t now = time(NULL) ; time_t now = time(NULL) ;
@ -1110,7 +1233,7 @@ void p3GRouter::locked_collectAvailableTunnels(const TurtleFileHash& hash,std::l
#endif #endif
TurtleVirtualPeerId vpid = *(vpit->second.virtual_peers.begin()) ; TurtleVirtualPeerId vpid = *(vpit->second.virtual_peers.begin()) ;
tunnel_peers.push_back(vpid) ; tunnel_peers_and_duplication_factors[vpid] = total_duplication ;
} }
bool p3GRouter::locked_sendTransactionData(const RsPeerId& pid,const RsGRouterTransactionItem& trans_item) bool p3GRouter::locked_sendTransactionData(const RsPeerId& pid,const RsGRouterTransactionItem& trans_item)
@ -1927,7 +2050,7 @@ bool p3GRouter::sendData(const RsGxsId& destination,const GRouterServiceId& clie
data_item->data_size = data_size ; data_item->data_size = data_size ;
data_item->routing_id = propagation_id ; data_item->routing_id = propagation_id ;
data_item->randomized_distance = 0 ; data_item->duplication_factor = GROUTER_MAX_DUPLICATION_FACTOR ;
data_item->service_id = client_id ; data_item->service_id = client_id ;
data_item->destination_key = destination ; data_item->destination_key = destination ;
data_item->flags = 0 ; // this is unused for now. data_item->flags = 0 ; // this is unused for now.
@ -1987,7 +2110,7 @@ bool p3GRouter::sendData(const RsGxsId& destination,const GRouterServiceId& clie
grouter_debug() << " data status = " << info.data_status << std::endl; grouter_debug() << " data status = " << info.data_status << std::endl;
grouter_debug() << " tunnel status = " << info.tunnel_status << std::endl; grouter_debug() << " tunnel status = " << info.tunnel_status << std::endl;
grouter_debug() << " sending attempt= " << info.sending_attempts << std::endl; grouter_debug() << " sending attempt= " << info.sending_attempts << std::endl;
grouter_debug() << " distance = " << info.data_item->randomized_distance << std::endl; grouter_debug() << " duplicate fact = " << info.data_item->duplication_factor << std::endl;
grouter_debug() << " recv time = " << info.received_time_TS << std::endl; grouter_debug() << " recv time = " << info.received_time_TS << std::endl;
grouter_debug() << " client id = " << std::hex << data_item->service_id << std::dec << std::endl; grouter_debug() << " client id = " << std::hex << data_item->service_id << std::dec << std::endl;
grouter_debug() << " tunnel hash = " << info.tunnel_hash << std::endl; grouter_debug() << " tunnel hash = " << info.tunnel_hash << std::endl;
@ -2134,21 +2257,23 @@ bool p3GRouter::getRoutingMatrixInfo(RsGRouter::GRouterRoutingMatrixInfo& info)
info.friend_ids.clear() ; info.friend_ids.clear() ;
info.published_keys.clear() ; info.published_keys.clear() ;
std::set<RsPeerId> ids ; std::list<RsPeerId> ids ;
mServiceControl->getPeersConnected(getServiceInfo().mServiceType,ids) ; //mServiceControl->getPeersConnected(getServiceInfo().mServiceType,ids) ;
rsPeers->getFriendList(ids) ;
info.published_keys = _owned_key_ids ; info.published_keys = _owned_key_ids ;
for(std::set<RsPeerId>::const_iterator it(ids.begin());it!=ids.end();++it) for(std::list<RsPeerId>::const_iterator it(ids.begin());it!=ids.end();++it)
info.friend_ids.push_back(*it) ; info.friend_ids.push_back(*it) ;
std::vector<GRouterKeyId> known_keys ; std::vector<GRouterKeyId> known_keys ;
std::vector<float> probas ; std::vector<float> probas ;
float maximum= 0.0f;
_routing_matrix.getListOfKnownKeys(known_keys) ; _routing_matrix.getListOfKnownKeys(known_keys) ;
for(uint32_t i=0;i<known_keys.size();++i) for(uint32_t i=0;i<known_keys.size();++i)
{ {
_routing_matrix.computeRoutingProbabilities(known_keys[i],info.friend_ids,probas) ; _routing_matrix.computeRoutingProbabilities(known_keys[i],info.friend_ids,probas,maximum) ;
info.per_friend_probabilities[known_keys[i]] = probas ; info.per_friend_probabilities[known_keys[i]] = probas ;
} }
@ -2167,6 +2292,7 @@ bool p3GRouter::getRoutingCacheInfo(std::vector<GRouterRoutingCacheInfo>& infos)
cinfo.mid = it->first ; cinfo.mid = it->first ;
cinfo.local_origin = it->second.incoming_routes.ids ; cinfo.local_origin = it->second.incoming_routes.ids ;
cinfo.destination = it->second.data_item->destination_key ; cinfo.destination = it->second.data_item->destination_key ;
cinfo.duplication_factor = it->second.data_item->duplication_factor ;
cinfo.routing_time = it->second.received_time_TS ; cinfo.routing_time = it->second.received_time_TS ;
cinfo.last_tunnel_attempt_time = it->second.last_tunnel_request_TS ; cinfo.last_tunnel_attempt_time = it->second.last_tunnel_request_TS ;
cinfo.last_sent_time = it->second.last_sent_TS ; cinfo.last_sent_time = it->second.last_sent_TS ;
@ -2220,15 +2346,16 @@ void p3GRouter::debugDump()
{ {
grouter_debug() << " Msg id: " << std::hex << it->first << std::dec ; grouter_debug() << " Msg id: " << std::hex << it->first << std::dec ;
grouter_debug() << " data hash: " << it->second.item_hash ; grouter_debug() << " data hash: " << it->second.item_hash ;
grouter_debug() << " client id: " << std::hex << it->second.client_id << std::dec; grouter_debug() << " client: " << std::hex << it->second.client_id << std::dec;
grouter_debug() << " Flags: " << std::hex << it->second.routing_flags << std::dec; grouter_debug() << " Flags: " << std::hex << it->second.routing_flags << std::dec;
grouter_debug() << " Destination: " << it->second.data_item->destination_key ; grouter_debug() << " Dest: " << it->second.data_item->destination_key ;
grouter_debug() << " Received: " << now - it->second.received_time_TS << " secs ago."; grouter_debug() << " Recd: " << now - it->second.received_time_TS << " secs ago.";
grouter_debug() << " Last sent: " << now - it->second.last_sent_TS << " secs ago."; grouter_debug() << " Sent: " << now - it->second.last_sent_TS << " secs ago.";
grouter_debug() << " Transaction TS: " << now - it->second.data_transaction_TS << " secs ago."; grouter_debug() << " Trans. TS: " << now - it->second.data_transaction_TS << " secs ago." ;
grouter_debug() << " Data Status: " << statusString[it->second.data_status] << std::endl; grouter_debug() << " Data Status: " << statusString[it->second.data_status] ;
grouter_debug() << " Tunl Status: " << statusString[it->second.tunnel_status] << std::endl; grouter_debug() << " Tunl Status: " << statusString[it->second.tunnel_status] ;
grouter_debug() << " Receipt ok: " << (it->second.receipt_item != NULL) << std::endl; grouter_debug() << " Receipt ok: " << (it->second.receipt_item != NULL) ;
grouter_debug() << " Dup: " << it->second.data_item->duplication_factor << std::endl;
} }
grouter_debug() << " Tunnels: " << std::endl; grouter_debug() << " Tunnels: " << std::endl;
@ -2251,8 +2378,8 @@ void p3GRouter::debugDump()
grouter_debug() << " Routing matrix: " << std::endl; grouter_debug() << " Routing matrix: " << std::endl;
if(_debug_enabled) // if(_debug_enabled)
_routing_matrix.debugDump() ; // _routing_matrix.debugDump() ;
} }

View File

@ -272,8 +272,9 @@ private:
//bool locked_getGxsIdAndClientId(const TurtleFileHash &sum,RsGxsId& gxs_id,GRouterServiceId& client_id); //bool locked_getGxsIdAndClientId(const TurtleFileHash &sum,RsGxsId& gxs_id,GRouterServiceId& client_id);
bool locked_sendTransactionData(const RsPeerId& pid,const RsGRouterTransactionItem& item); bool locked_sendTransactionData(const RsPeerId& pid,const RsGRouterTransactionItem& item);
void locked_collectAvailableFriends(const GRouterKeyId &gxs_id,std::list<RsPeerId>& friend_peers, const std::set<RsPeerId>& incoming_routes,bool is_origin); void locked_collectAvailableFriends(const GRouterKeyId &gxs_id, const std::set<RsPeerId>& incoming_routes,uint32_t duplication_factor, std::map<RsPeerId, uint32_t> &friend_peers_and_duplication_factors);
void locked_collectAvailableTunnels(const TurtleFileHash& hash,std::list<RsPeerId>& tunnel_peers); void locked_collectAvailableTunnels(const TurtleFileHash& hash, uint32_t total_duplication, std::map<RsPeerId, uint32_t> &tunnel_peers_and_duplication_factors);
void locked_sendToPeers(RsGRouterGenericDataItem *data_item, const std::map<RsPeerId, uint32_t> &peers_and_duplication_factors);
//===================================================// //===================================================//
// p3Config methods // // p3Config methods //

View File

@ -591,7 +591,7 @@ void RsGxsNetService::syncWithPeers()
grp->PeerId(*sit); grp->PeerId(*sit);
grp->updateTS = updateTS; grp->updateTS = updateTS;
NxsBandwidthRecorder::recordEvent(mServType,grp) ; //NxsBandwidthRecorder::recordEvent(mServType,grp) ;
#ifdef NXS_NET_DEBUG_5 #ifdef NXS_NET_DEBUG_5
GXSNETDEBUG_P_(*sit) << "Service "<< std::hex << ((mServiceInfo.mServiceType >> 8)& 0xffff) << std::dec << " sending global group TS of peer id: " << *sit << " ts=" << nice_time_stamp(time(NULL),updateTS) << " (secs ago) to himself" << std::endl; GXSNETDEBUG_P_(*sit) << "Service "<< std::hex << ((mServiceInfo.mServiceType >> 8)& 0xffff) << std::dec << " sending global group TS of peer id: " << *sit << " ts=" << nice_time_stamp(time(NULL),updateTS) << " (secs ago) to himself" << std::endl;
@ -626,7 +626,11 @@ void RsGxsNetService::syncWithPeers()
sit = peers.begin(); sit = peers.begin();
float sending_probability = NxsBandwidthRecorder::computeCurrentSendingProbability() ; // Jan. 26, 2016. This has been disabled, since GXS has been fixed, groups will not re-ask for data. So even if outqueues are filled up by multiple
// attempts of the same request, the transfer will eventually end up. The code for NxsBandwidthRecorder should be kept for a while,
// just in case.
// float sending_probability = NxsBandwidthRecorder::computeCurrentSendingProbability() ;
#ifdef NXS_NET_DEBUG_2 #ifdef NXS_NET_DEBUG_2
std::cerr << " syncWithPeers(): Sending probability = " << sending_probability << std::endl; std::cerr << " syncWithPeers(): Sending probability = " << sending_probability << std::endl;
#endif #endif
@ -682,22 +686,24 @@ void RsGxsNetService::syncWithPeers()
msg->grpId = grpId; msg->grpId = grpId;
msg->updateTS = updateTS; msg->updateTS = updateTS;
NxsBandwidthRecorder::recordEvent(mServType,msg) ; //NxsBandwidthRecorder::recordEvent(mServType,msg) ;
if(RSRandom::random_f32() < sending_probability) //if(RSRandom::random_f32() < sending_probability)
{ //{
sendItem(msg);
sendItem(msg);
#ifdef NXS_NET_DEBUG_5 #ifdef NXS_NET_DEBUG_5
GXSNETDEBUG_PG(*sit,grpId) << "Service "<< std::hex << ((mServiceInfo.mServiceType >> 8)& 0xffff) << std::dec << " sending global message TS of peer id: " << *sit << " ts=" << nice_time_stamp(time(NULL),updateTS) << " (secs ago) for group " << grpId << " to himself" << std::endl; GXSNETDEBUG_PG(*sit,grpId) << "Service "<< std::hex << ((mServiceInfo.mServiceType >> 8)& 0xffff) << std::dec << " sending global message TS of peer id: " << *sit << " ts=" << nice_time_stamp(time(NULL),updateTS) << " (secs ago) for group " << grpId << " to himself" << std::endl;
#endif #endif
} //}
else //else
{ //{
delete msg ; // delete msg ;
#ifdef NXS_NET_DEBUG_0 //#ifdef NXS_NET_DEBUG_0
GXSNETDEBUG_PG(*sit,grpId) << " cancel RsNxsSyncMsg req (last local update TS for group+peer) for grpId=" << grpId << " to peer " << *sit << ": not enough bandwidth." << std::endl; // GXSNETDEBUG_PG(*sit,grpId) << " cancel RsNxsSyncMsg req (last local update TS for group+peer) for grpId=" << grpId << " to peer " << *sit << ": not enough bandwidth." << std::endl;
#endif //#endif
} //}
} }
} }
@ -2308,7 +2314,6 @@ void RsGxsNetService::locked_processCompletedIncomingTrans(NxsTransaction* tr)
GXSNETDEBUG_P_(tr->mTransaction->PeerId()) << " and updating mClientGrpUpdateMap for peer " << peerFrom << " of new time stamp " << nice_time_stamp(time(NULL),updateTS) << std::endl; GXSNETDEBUG_P_(tr->mTransaction->PeerId()) << " and updating mClientGrpUpdateMap for peer " << peerFrom << " of new time stamp " << nice_time_stamp(time(NULL),updateTS) << std::endl;
#endif #endif
#warning should not we conservatively use the most recent one, in case the peer has reset its mServerGrpUpdate time?? What happens if the peer unsubscribed a recent group?
item->grpUpdateTS = updateTS; item->grpUpdateTS = updateTS;
item->peerId = peerFrom; item->peerId = peerFrom;
@ -2591,7 +2596,12 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr)
mDataStore->retrieveGxsGrpMetaData(grpMetaMap); mDataStore->retrieveGxsGrpMetaData(grpMetaMap);
RsGxsGrpMetaData* grpMeta = grpMetaMap[grpId]; RsGxsGrpMetaData* grpMeta = grpMetaMap[grpId];
#warning TODO: what if grpMeta is NULL? if(grpMeta == NULL) // this should not happen, but just in case...
{
std::cerr << "(EE) grpMeta is NULL in " << __PRETTY_FUNCTION__ << " line " << __LINE__ << ". This is very unexpected." << std::endl;
return ;
}
if(! (grpMeta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED )) if(! (grpMeta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED ))
{ {
// For unsubscribed groups, we update the timestamp something more recent, so that the group content will not be asked to the same // For unsubscribed groups, we update the timestamp something more recent, so that the group content will not be asked to the same

View File

@ -101,7 +101,6 @@ bool p3GxsTunnelService::registerClientService(uint32_t service_id,RsGxsTunnelSe
int p3GxsTunnelService::tick() int p3GxsTunnelService::tick()
{ {
static time_t last_dump = 0 ;
#ifdef DEBUG_GXS_TUNNEL #ifdef DEBUG_GXS_TUNNEL
time_t now = time(NULL); time_t now = time(NULL);

View File

@ -434,9 +434,9 @@ int pqipersongrp::removePeer(const RsPeerId& id)
std::map<RsPeerId, SearchModule *>::iterator it; std::map<RsPeerId, SearchModule *>::iterator it;
#ifdef PGRP_DEBUG #ifdef PGRP_DEBUG
#endif
std::cerr << "pqipersongrp::removePeer() id: " << id; std::cerr << "pqipersongrp::removePeer() id: " << id;
std::cerr << std::endl; std::cerr << std::endl;
#endif
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/ RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/

View File

@ -50,6 +50,7 @@ public:
time_t last_tunnel_attempt_time; time_t last_tunnel_attempt_time;
time_t last_sent_time; time_t last_sent_time;
bool receipt_available ; bool receipt_available ;
uint32_t duplication_factor ;
uint32_t data_status ; uint32_t data_status ;
uint32_t tunnel_status ; uint32_t tunnel_status ;
uint32_t data_size ; uint32_t data_size ;

View File

@ -296,8 +296,17 @@ bool p3Peers::getPeerDetails(const RsPeerId& id, RsPeerDetails &d)
d.hiddenNodeAddress = ps.hiddenDomain; d.hiddenNodeAddress = ps.hiddenDomain;
d.hiddenNodePort = ps.hiddenPort; d.hiddenNodePort = ps.hiddenPort;
d.hiddenType = ps.hiddenType; d.hiddenType = ps.hiddenType;
d.localAddr = sockaddr_storage_iptostring(ps.localaddr);
d.localPort = sockaddr_storage_port(ps.localaddr); if(sockaddr_storage_isnull(ps.localaddr)) // that happens if the address is not initialised.
{
d.localAddr = "INVALID_IP";
d.localPort = 0 ;
}
else
{
d.localAddr = sockaddr_storage_iptostring(ps.localaddr);
d.localPort = sockaddr_storage_port(ps.localaddr);
}
d.extAddr = "hidden"; d.extAddr = "hidden";
d.extPort = 0; d.extPort = 0;
d.dyndns = ""; d.dyndns = "";

View File

@ -354,7 +354,6 @@ int p3MsgService::checkOutgoingMessages()
* if online, send * if online, send
*/ */
time_t now = time(NULL);
bool changed = false ; bool changed = false ;
std::list<RsMsgItem*> output_queue ; std::list<RsMsgItem*> output_queue ;

View File

@ -1872,6 +1872,7 @@ void p3turtle::monitorTunnels(const RsFileHash& hash,RsTurtleClientService *clie
// No tunnels at start, but this triggers digging new tunnels. // No tunnels at start, but this triggers digging new tunnels.
// //
_incoming_file_hashes[hash].tunnels.clear(); _incoming_file_hashes[hash].tunnels.clear();
_incoming_file_hashes[hash].use_aggressive_mode = allow_multi_tunnels ;
// also should send associated request to the file transfer module. // also should send associated request to the file transfer module.
_incoming_file_hashes[hash].last_digg_time = RSRandom::random_u32()%10 ; _incoming_file_hashes[hash].last_digg_time = RSRandom::random_u32()%10 ;

View File

@ -28,6 +28,14 @@ win32 {
QMAKE_CFLAGS += -Wextra QMAKE_CFLAGS += -Wextra
QMAKE_CXXFLAGS += -Wextra QMAKE_CXXFLAGS += -Wextra
CONFIG(debug, debug|release) {
} else {
# Tell linker to use ASLR protection
QMAKE_LFLAGS += -Wl,-dynamicbase
# Tell linker to use DEP protection
QMAKE_LFLAGS += -Wl,-nxcompat
}
# solve linker warnings because of the order of the libraries # solve linker warnings because of the order of the libraries
QMAKE_LFLAGS += -Wl,--start-group QMAKE_LFLAGS += -Wl,--start-group

View File

@ -85,6 +85,7 @@ void SoundManager::soundEvents(SoundEvents &events)
events.addEvent(tr("Chatmessage"), tr("New Msg"), SOUND_NEW_CHAT_MESSAGE, QFileInfo(baseDir, "incomingchat.wav").absoluteFilePath()); events.addEvent(tr("Chatmessage"), tr("New Msg"), SOUND_NEW_CHAT_MESSAGE, QFileInfo(baseDir, "incomingchat.wav").absoluteFilePath());
events.addEvent(tr("Message"), tr("Message arrived"), SOUND_MESSAGE_ARRIVED, QFileInfo(baseDir, "receive.wav").absoluteFilePath()); events.addEvent(tr("Message"), tr("Message arrived"), SOUND_MESSAGE_ARRIVED, QFileInfo(baseDir, "receive.wav").absoluteFilePath());
events.addEvent(tr("Download"), tr("Download complete"), SOUND_DOWNLOAD_COMPLETE, QFileInfo(baseDir, "ft_complete.wav").absoluteFilePath()); events.addEvent(tr("Download"), tr("Download complete"), SOUND_DOWNLOAD_COMPLETE, QFileInfo(baseDir, "ft_complete.wav").absoluteFilePath());
events.addEvent(tr("Lobby"), tr("Message arrived"), SOUND_NEW_LOBBY_MESSAGE, QFileInfo(baseDir, "incomingchat.wav").absoluteFilePath());
/* add plugin events */ /* add plugin events */
int pluginCount = rsPlugins->nbPlugins(); int pluginCount = rsPlugins->nbPlugins();
@ -243,9 +244,9 @@ void SoundManager::playFile(const QString &filename)
bool played = false ; bool played = false ;
#if QT_VERSION >= QT_VERSION_CHECK (5, 0, 0) #if QT_VERSION >= QT_VERSION_CHECK (5, 0, 0)
if (!QAudioDeviceInfo::availableDevices(QAudio::AudioOutput).isEmpty()) if (!QAudioDeviceInfo::availableDevices(QAudio::AudioOutput).isEmpty())
#else #else
if (QSound::isAvailable()) if (QSound::isAvailable())
#endif #endif
{ {
QSound::play(playFilename); QSound::play(playFilename);

View File

@ -29,6 +29,7 @@
#define SOUND_USER_ONLINE "User_go_Online" #define SOUND_USER_ONLINE "User_go_Online"
#define SOUND_MESSAGE_ARRIVED "MessageArrived" #define SOUND_MESSAGE_ARRIVED "MessageArrived"
#define SOUND_DOWNLOAD_COMPLETE "DownloadComplete" #define SOUND_DOWNLOAD_COMPLETE "DownloadComplete"
#define SOUND_NEW_LOBBY_MESSAGE "NewLobbyMessage"
class SoundEvents class SoundEvents
{ {

View File

@ -18,6 +18,11 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, * Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA. * Boston, MA 02110-1301, USA.
*
* ccr . 2016 Jan 26
*
* Play sound on incoming messages.
*
****************************************************************/ ****************************************************************/
#include <unistd.h> #include <unistd.h>
@ -42,6 +47,7 @@
#include "gui/gxs/GxsIdChooser.h" #include "gui/gxs/GxsIdChooser.h"
#include "gui/gxs/GxsIdDetails.h" #include "gui/gxs/GxsIdDetails.h"
#include "util/HandleRichText.h" #include "util/HandleRichText.h"
#include "gui/SoundManager.h"
#include <retroshare/rsnotify.h> #include <retroshare/rsnotify.h>
@ -400,7 +406,8 @@ void ChatLobbyDialog::addChatMsg(const ChatMessage& msg)
name = QString::fromUtf8(msg.peer_alternate_nickname.c_str()) + " (" + QString::fromStdString(gxs_id.toStdString()) + ")" ; name = QString::fromUtf8(msg.peer_alternate_nickname.c_str()) + " (" + QString::fromStdString(gxs_id.toStdString()) + ")" ;
ui.chatWidget->addChatMsg(msg.incoming, name, gxs_id, sendTime, recvTime, message, ChatWidget::MSGTYPE_NORMAL); ui.chatWidget->addChatMsg(msg.incoming, name, gxs_id, sendTime, recvTime, message, ChatWidget::MSGTYPE_NORMAL);
emit messageReceived(msg.incoming, id(), sendTime, name, message) ; emit messageReceived(msg.incoming, id(), sendTime, name, message) ;
SoundManager::play(SOUND_NEW_LOBBY_MESSAGE);
// This is a trick to translate HTML into text. // This is a trick to translate HTML into text.
QTextEdit editor; QTextEdit editor;

View File

@ -127,6 +127,7 @@ ChatWidget::ChatWidget(QWidget *parent) :
connect(ui->actionChooseColor, SIGNAL(triggered()), this, SLOT(chooseColor())); connect(ui->actionChooseColor, SIGNAL(triggered()), this, SLOT(chooseColor()));
connect(ui->actionResetFont, SIGNAL(triggered()), this, SLOT(resetFont())); connect(ui->actionResetFont, SIGNAL(triggered()), this, SLOT(resetFont()));
connect(ui->actionQuote, SIGNAL(triggered()), this, SLOT(quote())); connect(ui->actionQuote, SIGNAL(triggered()), this, SLOT(quote()));
connect(ui->actionDropPlacemark, SIGNAL(triggered()), this, SLOT(dropPlacemark()));
connect(ui->actionSave_image, SIGNAL(triggered()), this, SLOT(saveImage())); connect(ui->actionSave_image, SIGNAL(triggered()), this, SLOT(saveImage()));
connect(ui->hashBox, SIGNAL(fileHashingFinished(QList<HashedFile>)), this, SLOT(fileHashingFinished(QList<HashedFile>))); connect(ui->hashBox, SIGNAL(fileHashingFinished(QList<HashedFile>)), this, SLOT(fileHashingFinished(QList<HashedFile>)));
@ -923,7 +924,7 @@ void ChatWidget::addChatMsg(bool incoming, const QString &name, const RsGxsId gx
QString strGxsId = ""; QString strGxsId = "";
if (!gxsId.isNull()) if (!gxsId.isNull())
strGxsId = QString::fromStdString(gxsId.toStdString()); strGxsId = QString::fromStdString(gxsId.toStdString());
formatMsg.replace(QString("<a name=\"name\">"),QString("<a name=\"%1\">").arg(strGxsId)); formatMsg.replace(QString("<a name=\"name\">"),QString("<a name=\"Person Id: %1\">").arg(strGxsId));
QTextCursor textCursor = QTextCursor(ui->textBrowser->textCursor()); QTextCursor textCursor = QTextCursor(ui->textBrowser->textCursor());
textCursor.movePosition(QTextCursor::End); textCursor.movePosition(QTextCursor::End);
@ -979,6 +980,7 @@ void ChatWidget::contextMenuTextBrowser(QPoint point)
contextMnu->addSeparator(); contextMnu->addSeparator();
contextMnu->addAction(ui->actionClearChatHistory); contextMnu->addAction(ui->actionClearChatHistory);
contextMnu->addAction(ui->actionQuote); contextMnu->addAction(ui->actionQuote);
contextMnu->addAction(ui->actionDropPlacemark);
QTextCursor cursor = ui->textBrowser->cursorForPosition(point); QTextCursor cursor = ui->textBrowser->cursorForPosition(point);
if(ImageUtil::checkImage(cursor)) if(ImageUtil::checkImage(cursor))
@ -1698,6 +1700,11 @@ void ChatWidget::quote()
} }
} }
void ChatWidget::dropPlacemark()
{
ui->textBrowser->append("----------");
}
void ChatWidget::saveImage() void ChatWidget::saveImage()
{ {
QPoint point = ui->actionSave_image->data().toPoint(); QPoint point = ui->actionSave_image->data().toPoint();

View File

@ -186,6 +186,7 @@ private slots:
bool fileSaveAs(); bool fileSaveAs();
void quote(); void quote();
void dropPlacemark();
void saveImage(); void saveImage();
private: private:

View File

@ -1052,6 +1052,14 @@ border-image: url(:/images/closepressed.png)
<string>Quotes the selected text</string> <string>Quotes the selected text</string>
</property> </property>
</action> </action>
<action name="actionDropPlacemark">
<property name="text">
<string>Drop Placemark</string>
</property>
<property name="toolTip">
<string>Insert horizontal rule</string>
</property>
</action>
<action name="actionSave_image"> <action name="actionSave_image">
<property name="icon"> <property name="icon">
<iconset resource="../images.qrc"> <iconset resource="../images.qrc">

View File

@ -254,10 +254,10 @@ void FriendSelectionWidget::loadRequest(const TokenQueue */*queue*/, const Token
for(uint32_t i=0;i<datavector.size();++i) for(uint32_t i=0;i<datavector.size();++i)
{ {
gxsIds.push_back(datavector[i].mMeta.mGroupId) ; gxsIds.push_back(datavector[i].mMeta.mGroupId) ;
std::cerr << " got ID = " << datavector[i].mMeta.mGroupId << std::endl; //std::cerr << " got ID = " << datavector[i].mMeta.mGroupId << std::endl;
} }
std::cerr << "Got all " << datavector.size() << " ids from rsIdentity. Calling update of list." << std::endl; //std::cerr << "Got all " << datavector.size() << " ids from rsIdentity. Calling update of list." << std::endl;
fillList() ; fillList() ;
} }

View File

@ -160,11 +160,11 @@ static void loadPrivateIdsCallback(GxsIdDetailsType type, const RsIdentityDetail
chooser->setItemData(index, (type == GXS_ID_DETAILS_TYPE_DONE) ? TYPE_FOUND_ID : TYPE_UNKNOWN_ID, ROLE_TYPE); chooser->setItemData(index, (type == GXS_ID_DETAILS_TYPE_DONE) ? TYPE_FOUND_ID : TYPE_UNKNOWN_ID, ROLE_TYPE);
chooser->setItemIcon(index, icons.empty() ? QIcon() : icons[0]); chooser->setItemIcon(index, icons.empty() ? QIcon() : icons[0]);
std::cerr << "ID=" << details.mId << ", chooser->flags()=" << chooser->flags() << ", flags=" << details.mFlags ; //std::cerr << "ID=" << details.mId << ", chooser->flags()=" << chooser->flags() << ", flags=" << details.mFlags ;
if((chooser->flags() & IDCHOOSER_NON_ANONYMOUS) && !(details.mFlags & RS_IDENTITY_FLAGS_PGP_LINKED)) if((chooser->flags() & IDCHOOSER_NON_ANONYMOUS) && !(details.mFlags & RS_IDENTITY_FLAGS_PGP_LINKED))
{ {
std::cerr << " - disabling ID - entry = " << index << std::endl; //std::cerr << " - disabling ID - entry = " << index << std::endl;
chooser->setEntryEnabled(index,false) ; chooser->setEntryEnabled(index,false) ;
} }
std::cerr << std::endl; std::cerr << std::endl;

View File

@ -20,6 +20,26 @@
* Boston, MA 02110-1301, USA. * Boston, MA 02110-1301, USA.
****************************************************************/ ****************************************************************/
/* ccr . 2015 Aug 01 . Resize Main page and Main window.
*
* On very small legacy CRTs of about 15" (38 cm) RetroShare pages are
* initially too deep (too tall) to fit the screen at 1024x768
* resolution. Some can be shrunk down manually from their initial
* size. Others cannot. This patch tries to allow each page to be
* shrunk somewhat. Then code that runs elsewhere to fit the logical
* Main window into the physical screen will have a better chance of
* success. Notably, on Linux -- Gnome3 -- X11 systems, only when the
* Main window first fits entirely into the physical screen, can it
* then be maximized.
*
* This code is borrowed from a Stack Overflow post:
*
* o Darkgaze. "Resize QStackedWidget to the Page Which Is Opened." 23
* Jan. 2013. Online posting. Stack Overflow. 1 Aug. 2015
* <https://stackoverflow.com/questions/14480696/resize-qstackedwidget-to-the-page-which-is-opened>.
*
*/
#include <QAction> #include <QAction>
#include "mainpagestack.h" #include "mainpagestack.h"
@ -34,6 +54,7 @@ void
MainPageStack::add(MainPage *page, QAction *action) MainPageStack::add(MainPage *page, QAction *action)
{ {
_pages.insert(action, page); _pages.insert(action, page);
page->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); /* 2015 Aug 01 */
insertWidget(count(), page); insertWidget(count(), page);
} }
@ -61,3 +82,14 @@ MainPageStack::showPage(QAction *pageAction)
setCurrentWidget(_pages.value(pageAction)); setCurrentWidget(_pages.value(pageAction));
} }
/** Adjusts the size of the Main page and the Main window. */
void
MainPageStack::onCurrentChanged(int index) /* 2015 Aug 01 */
{
QWidget* pWidget = widget(index);
Q_ASSERT(pWidget);
pWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
pWidget->adjustSize();
adjustSize();
}

View File

@ -50,6 +50,8 @@ public:
public slots: public slots:
/** Displays the page associated with the activated action. */ /** Displays the page associated with the activated action. */
void showPage(QAction *pageAction); void showPage(QAction *pageAction);
/** Adjusts the size of the Main page and the Main window. */
void onCurrentChanged(int index);
private: private:
/** Maps an action to a Main page. */ /** Maps an action to a Main page. */

View File

@ -420,6 +420,10 @@ void MessageComposer::processSettings(bool bLoad)
int index = Settings->value("ShowType", 0).toInt(); int index = Settings->value("ShowType", 0).toInt();
ui.filterComboBox->setCurrentIndex(index); ui.filterComboBox->setCurrentIndex(index);
RsGxsId resp_to_id ( Settings->value("LastRespondTo").toString().toStdString());
if(!resp_to_id.isNull())
ui.respond_to_CB->setDefaultId(resp_to_id);
} else { } else {
// save settings // save settings
@ -433,6 +437,7 @@ void MessageComposer::processSettings(bool bLoad)
// state of filter combobox // state of filter combobox
Settings->setValue("ShowType", ui.filterComboBox->currentIndex()); Settings->setValue("ShowType", ui.filterComboBox->currentIndex());
Settings->setValue("LastRespondTo",ui.respond_to_CB->itemData(ui.respond_to_CB->currentIndex()).toString());
} }
Settings->endGroup(); Settings->endGroup();
@ -1280,7 +1285,7 @@ bool MessageComposer::sendMessage_internal(bool bDraftbox)
mi.rsgxsid_srcId = RsGxsId(ui.respond_to_CB->itemData(ui.respond_to_CB->currentIndex()).toString().toStdString()) ; mi.rsgxsid_srcId = RsGxsId(ui.respond_to_CB->itemData(ui.respond_to_CB->currentIndex()).toString().toStdString()) ;
std::cerr << "MessageSend: setting 'from' field to GXS id = " << mi.rsgxsid_srcId << std::endl; //std::cerr << "MessageSend: setting 'from' field to GXS id = " << mi.rsgxsid_srcId << std::endl;
mi.title = misc::removeNewLine(ui.titleEdit->text()).toUtf8().constData(); mi.title = misc::removeNewLine(ui.titleEdit->text()).toUtf8().constData();
// needed to send system flags with reply // needed to send system flags with reply

View File

@ -43,15 +43,16 @@
#include "util/QtVersion.h" #include "util/QtVersion.h"
#include "util/misc.h" #include "util/misc.h"
#define COL_ID 0 #define COL_ID 0
#define COL_NICKNAME 1 #define COL_NICKNAME 1
#define COL_DESTINATION 2 #define COL_DESTINATION 2
#define COL_DATASTATUS 3 #define COL_DATASTATUS 3
#define COL_TUNNELSTATUS 4 #define COL_TUNNELSTATUS 4
#define COL_DATASIZE 5 #define COL_DATASIZE 5
#define COL_DATAHASH 6 #define COL_DATAHASH 6
#define COL_RECEIVED 7 #define COL_RECEIVED 7
#define COL_SEND 8 #define COL_SEND 8
#define COL_DUPLICATION_FACTOR 9
static const int PARTIAL_VIEW_SIZE = 5 ; static const int PARTIAL_VIEW_SIZE = 5 ;
static const int MAX_TUNNEL_REQUESTS_DISPLAY = 10 ; static const int MAX_TUNNEL_REQUESTS_DISPLAY = 10 ;
@ -187,6 +188,7 @@ void GlobalRouterStatistics::updateContent()
item -> setData(COL_DATAHASH, Qt::DisplayRole, QString::fromStdString(cache_infos[i].item_hash.toStdString())); item -> setData(COL_DATAHASH, Qt::DisplayRole, QString::fromStdString(cache_infos[i].item_hash.toStdString()));
item -> setData(COL_RECEIVED, Qt::DisplayRole, QString::number(now - cache_infos[i].routing_time)); item -> setData(COL_RECEIVED, Qt::DisplayRole, QString::number(now - cache_infos[i].routing_time));
item -> setData(COL_SEND, Qt::DisplayRole, QString::number(now - cache_infos[i].last_sent_time)); item -> setData(COL_SEND, Qt::DisplayRole, QString::number(now - cache_infos[i].last_sent_time));
item -> setData(COL_DUPLICATION_FACTOR, Qt::DisplayRole, QString::number(cache_infos[i].duplication_factor));
} }
} }
@ -333,6 +335,9 @@ void GlobalRouterStatisticsWidget::updateContent()
mMinWheelZoneX = ox+2*cellx ; mMinWheelZoneX = ox+2*cellx ;
mMinWheelZoneY = oy ; mMinWheelZoneY = oy ;
RsGxsId current_id ;
float current_width=0 ;
for(std::map<GRouterKeyId,std::vector<float> >::const_iterator it(matrix_info.per_friend_probabilities.begin());it!=matrix_info.per_friend_probabilities.end();++it,++n) for(std::map<GRouterKeyId,std::vector<float> >::const_iterator it(matrix_info.per_friend_probabilities.begin());it!=matrix_info.per_friend_probabilities.end();++it,++n)
if(n >= mCurrentN-PARTIAL_VIEW_SIZE/2 && n <= mCurrentN+PARTIAL_VIEW_SIZE/2) if(n >= mCurrentN-PARTIAL_VIEW_SIZE/2 && n <= mCurrentN+PARTIAL_VIEW_SIZE/2)
{ {
@ -355,12 +360,19 @@ void GlobalRouterStatisticsWidget::updateContent()
{ {
current_probs = it->second ; current_probs = it->second ;
current_oy = oy ; current_oy = oy ;
current_id = it->first ;
current_width = ox+matrix_info.friend_ids.size()*cellx+fm_monospace.width(ids);
} }
oy += celly ; oy += celly ;
//} //}
} }
RsIdentityDetails iddetails ;
if(rsIdentity->getIdDetails(current_id,iddetails))
painter.drawText(current_width+cellx, current_oy+celly, QString::fromUtf8(iddetails.mNickname.c_str())) ;
mMaxWheelZoneY = oy+celly ; mMaxWheelZoneY = oy+celly ;
painter.setPen(QColor::fromRgb(0,0,0)) ; painter.setPen(QColor::fromRgb(0,0,0)) ;
@ -382,7 +394,7 @@ void GlobalRouterStatisticsWidget::updateContent()
painter.drawLine(x1,y1,x1,y2); painter.drawLine(x1,y1,x1,y2);
painter.drawLine(x1,y2,x1 + total_length - i*cellx,y2) ; painter.drawLine(x1,y2,x1 + total_length - i*cellx,y2) ;
painter.drawText(cellx+ x1 + total_length - i*cellx,y2+(0.35)*celly, QString::fromUtf8(peer_ssl_details.name.c_str()) + " ("+QString::number(current_probs[i])+")"); painter.drawText(cellx+ x1 + total_length - i*cellx,y2+(0.35)*celly, QString::fromUtf8(peer_ssl_details.name.c_str()) + " - " + QString::fromUtf8(peer_ssl_details.location.c_str()) + " ("+QString::number(current_probs[i])+")");
} }
oy += celly * (2+matrix_info.friend_ids.size()); oy += celly * (2+matrix_info.friend_ids.size());

View File

@ -35,7 +35,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>593</width> <width>593</width>
<height>159</height> <height>156</height>
</rect> </rect>
</property> </property>
</widget> </widget>
@ -101,6 +101,11 @@
<string>Send</string> <string>Send</string>
</property> </property>
</column> </column>
<column>
<property name="text">
<string>Branching factor</string>
</property>
</column>
</widget> </widget>
</item> </item>
</layout> </layout>

View File

@ -157,6 +157,14 @@ win32 {
QMAKE_CFLAGS += -Wextra QMAKE_CFLAGS += -Wextra
QMAKE_CXXFLAGS += -Wextra QMAKE_CXXFLAGS += -Wextra
CONFIG(debug, debug|release) {
} else {
# Tell linker to use ASLR protection
QMAKE_LFLAGS += -Wl,-dynamicbase
# Tell linker to use DEP protection
QMAKE_LFLAGS += -Wl,-nxcompat
}
# solve linker warnings because of the order of the libraries # solve linker warnings because of the order of the libraries
QMAKE_LFLAGS += -Wl,--start-group QMAKE_LFLAGS += -Wl,--start-group

View File

@ -72,6 +72,14 @@ win32 {
# solve linker warnings because of the order of the libraries # solve linker warnings because of the order of the libraries
QMAKE_LFLAGS += -Wl,--start-group QMAKE_LFLAGS += -Wl,--start-group
CONFIG(debug, debug|release) {
} else {
# Tell linker to use ASLR protection
QMAKE_LFLAGS += -Wl,-dynamicbase
# Tell linker to use DEP protection
QMAKE_LFLAGS += -Wl,-nxcompat
}
for(lib, LIB_DIR):LIBS += -L"$$lib" for(lib, LIB_DIR):LIBS += -L"$$lib"
LIBS += -lssl -lcrypto -lpthread -lminiupnpc -lz LIBS += -lssl -lcrypto -lpthread -lminiupnpc -lz
LIBS += -lcrypto -lws2_32 -lgdi32 LIBS += -lcrypto -lws2_32 -lgdi32