00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "StdAfx.h"
00023 #include "Shareaza.h"
00024 #include "Settings.h"
00025 #include "GProfile.h"
00026 #include "G2Packet.h"
00027 #include "XML.h"
00028
00029 #ifdef _DEBUG
00030 #undef THIS_FILE
00031 static char THIS_FILE[]=__FILE__;
00032 #define new DEBUG_NEW
00033 #endif
00034
00035 LPCTSTR CGProfile::xmlns = _T("http://www.shareaza.com/schemas/GProfile.xsd");
00036
00037 BEGIN_INTERFACE_MAP(CGProfile, CComObject)
00038 END_INTERFACE_MAP()
00039
00040 CGProfile MyProfile;
00041
00042
00044
00045
00046 CGProfile::CGProfile()
00047 {
00048 m_pXML = NULL;
00049 }
00050
00051 CGProfile::~CGProfile()
00052 {
00053 Clear();
00054 }
00055
00057
00058
00059 BOOL CGProfile::IsValid() const
00060 {
00061 if ( this == NULL ) return FALSE;
00062 if ( m_pXML == NULL ) return FALSE;
00063 CXMLElement* pIdentity = m_pXML->GetElementByName( _T("identity") );
00064 CXMLElement* pLocation = m_pXML->GetElementByName( _T("location") );
00065 return pIdentity != NULL || pLocation != NULL;
00066 }
00067
00068 CXMLElement* CGProfile::GetXML(LPCTSTR pszElement, BOOL bCreate)
00069 {
00070 if ( m_pXML == NULL )
00071 {
00072 if ( ! bCreate ) return NULL;
00073 Create();
00074 }
00075
00076 if ( pszElement == NULL ) return m_pXML;
00077
00078 return m_pXML->GetElementByName( pszElement, bCreate );
00079 }
00080
00082
00083
00084 void CGProfile::Create()
00085 {
00086 Clear();
00087
00088 GGUID tmp( GUID );
00089 CoCreateGuid( (::GUID*)&tmp );
00090 srand( GetTickCount() );
00091
00092 for ( int nByte = 0 ; nByte < 16 ; nByte++ ) tmp.n[ nByte ] += rand();
00093
00094 wchar_t szGUID[39];
00095 szGUID[ StringFromGUID2( *(::GUID*)&tmp, szGUID, 39 ) - 2 ] = 0;
00096
00097 GUID = tmp;
00098
00099 m_pXML = new CXMLElement( NULL, _T("gProfile") );
00100 m_pXML->AddAttribute( _T("xmlns"), xmlns );
00101
00102 CXMLElement* pGnutella = m_pXML->AddElement( _T("gnutella") );
00103 pGnutella->AddAttribute( _T("guid"), (CString)&szGUID[1] );
00104 }
00105
00106 void CGProfile::Clear()
00107 {
00108 if ( m_pXML ) delete m_pXML;
00109 m_pXML = NULL;
00110 }
00111
00113
00114
00115 BOOL CGProfile::Load(LPCTSTR pszFile)
00116 {
00117 CString strFile;
00118
00119 if ( pszFile != NULL )
00120 strFile = pszFile;
00121 else
00122 strFile = Settings.General.UserPath + _T("\\Data\\Profile.xml");
00123
00124 CXMLElement* pXML = CXMLElement::FromFile( strFile, TRUE );
00125
00126 if ( pXML == NULL )
00127 {
00128 if ( pszFile == NULL ) Create();
00129 return FALSE;
00130 }
00131
00132 if ( FromXML( pXML ) ) return TRUE;
00133 delete pXML;
00134
00135 return FALSE;
00136 }
00137
00138 BOOL CGProfile::Save(LPCTSTR pszFile)
00139 {
00140 CString strXML;
00141 CFile pFile;
00142
00143 if ( pszFile != NULL )
00144 strXML = pszFile;
00145 else
00146 strXML = Settings.General.UserPath + _T("\\Data\\Profile.xml");
00147
00148 if ( ! pFile.Open( strXML, CFile::modeWrite|CFile::modeCreate ) ) return FALSE;
00149
00150 if ( m_pXML != NULL )
00151 strXML = m_pXML->ToString( TRUE, TRUE );
00152 else
00153 strXML.Empty();
00154
00155 int nASCII = WideCharToMultiByte( CP_UTF8, 0, strXML, strXML.GetLength(), NULL, 0, NULL, NULL );
00156 LPSTR pszASCII = new CHAR[ nASCII ];
00157 WideCharToMultiByte( CP_UTF8, 0, strXML, strXML.GetLength(), pszASCII, nASCII, NULL, NULL );
00158 pFile.Write( pszASCII, nASCII );
00159 delete [] pszASCII;
00160
00161 pFile.Close();
00162
00163 return TRUE;
00164 }
00165
00167
00168
00169 BOOL CGProfile::FromXML(CXMLElement* pXML)
00170 {
00171 Clear();
00172
00173 if ( pXML == NULL ) return FALSE;
00174 if ( pXML->GetAttributeValue( _T("xmlns") ).CompareNoCase( xmlns ) ) return FALSE;
00175 if ( pXML->IsNamed( _T("gProfile") ) == FALSE ) return FALSE;
00176
00177 CXMLElement* pGnutella = pXML->GetElementByName( _T("gnutella") );
00178 if ( pGnutella == NULL ) return FALSE;
00179
00180 CString strGUID = pGnutella->GetAttributeValue( _T("guid") );
00181
00182 GGUID tmp;
00183 if ( ! GUIDX::Decode( strGUID, &tmp ) ) return FALSE;
00184 GUID = tmp;
00185
00186 m_pXML = pXML;
00187
00188 return TRUE;
00189 }
00190
00192
00193
00194 CString CGProfile::GetNick() const
00195 {
00196 CString str;
00197 if ( m_pXML == NULL ) return str;
00198 CXMLElement* pIdentity = m_pXML->GetElementByName( _T("identity") );
00199 if ( pIdentity == NULL ) return str;
00200 CXMLElement* pHandle = pIdentity->GetElementByName( _T("handle") );
00201 if ( pHandle == NULL ) return str;
00202 str = pHandle->GetAttributeValue( _T("primary") );
00203 return str;
00204 }
00205
00206 CString CGProfile::GetLocation() const
00207 {
00208 CString str;
00209 if ( m_pXML == NULL ) return str;
00210 CXMLElement* pLocation = m_pXML->GetElementByName( _T("location") );
00211 if ( pLocation == NULL ) return str;
00212 CXMLElement* pPolitical = pLocation->GetElementByName( _T("political") );
00213 if ( pPolitical == NULL ) return str;
00214
00215 CString strCity = pPolitical->GetAttributeValue( _T("city") );
00216 CString strState = pPolitical->GetAttributeValue( _T("state") );
00217 CString strCountry = pPolitical->GetAttributeValue( _T("country") );
00218
00219 str = strCity;
00220 if ( strState.GetLength() )
00221 {
00222 if ( str.GetLength() ) str += _T(", ");
00223 str += strState;
00224 }
00225 if ( strCountry.GetLength() )
00226 {
00227 if ( str.GetLength() ) str += _T(", ");
00228 str += strCountry;
00229 }
00230
00231 return str;
00232 }
00233
00234 CString CGProfile::GetContact(LPCTSTR pszType) const
00235 {
00236 CString str;
00237
00238 if ( m_pXML == NULL ) return str;
00239 CXMLElement* pContacts = m_pXML->GetElementByName( _T("contacts") );
00240 if ( pContacts == NULL ) return str;
00241
00242 for ( POSITION pos = pContacts->GetElementIterator() ; pos ; )
00243 {
00244 CXMLElement* pGroup = pContacts->GetNextElement( pos );
00245
00246 if ( pGroup->IsNamed( _T("group") ) &&
00247 pGroup->GetAttributeValue( _T("class") ).CompareNoCase( pszType ) == 0 )
00248 {
00249 if ( CXMLElement* pAddress = pGroup->GetElementByName( _T("address") ) )
00250 {
00251 str = pAddress->GetAttributeValue( _T("content") );
00252 break;
00253 }
00254 }
00255 }
00256
00257 return str;
00258 }
00259
00260 DWORD CGProfile::GetPackedGPS() const
00261 {
00262 if ( m_pXML == NULL ) return 0;
00263 CXMLElement* pLocation = m_pXML->GetElementByName( _T("location") );
00264 if ( pLocation == NULL ) return 0;
00265 CXMLElement* pCoordinates = pLocation->GetElementByName( _T("coordinates") );
00266 if ( pCoordinates == NULL ) return 0;
00267
00268 float nLatitude = 0, nLongitude = 0;
00269 _stscanf( pCoordinates->GetAttributeValue( _T("latitude") ), _T("%f"), &nLatitude );
00270 _stscanf( pCoordinates->GetAttributeValue( _T("longitude") ), _T("%f"), &nLongitude );
00271 if ( nLatitude == 0 || nLongitude == 0 ) return 0;
00272
00273 #define WORDLIM(x) (WORD)( (x) < 0 ? 0 : ( (x) > 65535 ? 65535 : (x) ) )
00274 WORD nLat = WORDLIM( ( nLatitude + 90.0f ) * 65535.0f / 180.0f );
00275 WORD nLon = WORDLIM( ( nLongitude + 180.0f ) * 65535.0f / 360.0f );
00276 #undef WORDLIM
00277
00278 return (DWORD)nLon + ( (DWORD)nLat << 16 );
00279 }
00280
00282
00283
00284 CG2Packet* CGProfile::CreateAvatar()
00285 {
00286 if ( m_pXML == NULL ) return NULL;
00287
00288 CXMLElement* pAvatar = m_pXML->GetElementByName( _T("avatar") );
00289 if ( pAvatar == NULL ) return NULL;
00290 CString strPath = pAvatar->GetAttributeValue( _T("path") );
00291 if ( strPath.IsEmpty() ) return NULL;
00292
00293 CFile pFile;
00294 if ( ! pFile.Open( strPath, CFile::modeRead ) ) return NULL;
00295
00296 int nPos = strPath.ReverseFind( '\\' );
00297 if ( nPos >= 0 ) strPath = strPath.Mid( nPos + 1 );
00298
00299 CG2Packet* pPacket = CG2Packet::New( G2_PACKET_PROFILE_AVATAR );
00300
00301 pPacket->WritePacket( "NAME", pPacket->GetStringLen( strPath ) );
00302 pPacket->WriteString( strPath, FALSE );
00303
00304 pPacket->WritePacket( "BODY", (DWORD)pFile.GetLength() );
00305 LPBYTE pBody = pPacket->WriteGetPointer( (DWORD)pFile.GetLength() );
00306
00307 pFile.Read( pBody, (DWORD)pFile.GetLength() );
00308 pFile.Close();
00309
00310 return pPacket;
00311 }