1 //////////////////////////////////////////////////////////////////////
2 //
3 // BeeBEEP Copyright (C) 2010-2021 Marco Mastroddi
4 //
5 // BeeBEEP is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published
7 // by the Free Software Foundation, either version 3 of the License,
8 // or (at your option) any later version.
9 //
10 // BeeBEEP is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with BeeBEEP. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // Author: Marco Mastroddi <marco.mastroddi(AT)gmail.com>
19 //
20 // $Id: CoreParser.cpp 1462 2021-01-02 12:54:56Z mastroddi $
21 //
22 //////////////////////////////////////////////////////////////////////
23 
24 #include "BeeUtils.h"
25 #include "Broadcaster.h"
26 #include "ChatManager.h"
27 #include "Connection.h"
28 #include "Core.h"
29 #include "FileInfo.h"
30 #include "FileShare.h"
31 #include "Hive.h"
32 #include "IconManager.h"
33 #include "Protocol.h"
34 #include "Settings.h"
35 #include "UserManager.h"
36 
37 
parseMessage(VNumber user_id,const Message & m)38 void Core::parseMessage( VNumber user_id, const Message& m )
39 {
40   User u = UserManager::instance().findUser( user_id );
41   if( !u.isValid() )
42   {
43     qWarning() << "Invalid user" << user_id << "found while parsing message";
44     return;
45   }
46   parseMessage( u, m );
47 }
48 
parseMessage(const User & u,const Message & m)49 void Core::parseMessage( const User& u, const Message& m )
50 {
51   switch( m.type() )
52   {
53   case Message::User:
54     parseUserMessage( u, m );
55     break;
56   case Message::Chat:
57     parseChatMessage( u, m );
58     break;
59   case Message::Read:
60     parseChatReadMessage( u, m );
61     break;
62   case Message::Group:
63     parseGroupMessage( u, m );
64     break;
65   case Message::File:
66     parseFileMessage( u, m );
67     break;
68   case Message::Folder:
69     parseFolderMessage( u, m );
70     break;
71   case Message::Share:
72     parseFileShareMessage( u, m );
73     break;
74   case Message::Hive:
75     parseHiveMessage( u, m );
76     break;
77   case Message::ShareBox:
78     parseShareBoxMessage( u, m );
79     break;
80   case Message::Buzz:
81     parseBuzzMessage( u, m );
82     break;
83   case Message::ShareDesktop:
84 #ifdef BEEBEEP_USE_SHAREDESKTOP
85     parseShareDesktopMessage( u, m );
86 #endif
87     break;
88   default:
89     qWarning() << "Core cannot parse the message with type" << m.type();
90     break;
91   }
92 }
93 
parseUserMessage(const User & u,const Message & m)94 void Core::parseUserMessage( const User& u, const Message& m )
95 {
96   if( m.hasFlag( Message::UserWriting ) )
97   {
98 #ifdef BEEBEEP_DEBUG
99     qDebug() << "User" << qPrintable( u.path() ) << "is writing";
100 #endif
101     Chat c = ChatManager::instance().findChatByPrivateId( m.data(), false, u.id() );
102     if( c.hasUser( u.id() ) )
103       emit userIsWriting( u, c.id() );
104     return;
105   }
106   else if( m.hasFlag( Message::UserStatus ) )
107   {
108     User user_with_new_status = u;
109     if( Protocol::instance().changeUserStatusFromMessage( &user_with_new_status, m ) )
110     {
111 #ifdef BEEBEEP_DEBUG
112       qDebug() << "User" << qPrintable( user_with_new_status.path() ) << "changes status to" << user_with_new_status.status() << user_with_new_status.statusDescription();
113 #endif
114       UserManager::instance().setUser( user_with_new_status );
115       emit userChanged( user_with_new_status );
116     }
117   }
118   else if( m.hasFlag( Message::UserVCard ) )
119   {
120     User user_with_new_vcard = u;
121 
122     if( Protocol::instance().changeVCardFromMessage( &user_with_new_vcard, m ) )
123     {
124       bool color_changed = user_with_new_vcard.color() != u.color();
125       bool vcard_changed = !(user_with_new_vcard.vCard() == u.vCard() );
126       VCard vc_tmp = user_with_new_vcard.vCard();
127       vc_tmp.setNickName( u.vCard().nickName() );
128       bool only_user_name_changed = vc_tmp == u.vCard();
129 
130       if( vcard_changed || color_changed )
131       {
132         UserManager::instance().setUser( user_with_new_vcard );
133         if( user_with_new_vcard.name() != u.name() )
134         {
135           ChatManager::instance().changePrivateChatNameAfterUserNameChanged( u.id(), user_with_new_vcard.name() );
136           showUserNameChanged( user_with_new_vcard, u.name() );
137         }
138         if( vcard_changed && !only_user_name_changed )
139           showUserVCardChanged( user_with_new_vcard, u.vCard() );
140         emit userChanged( user_with_new_vcard );
141       }
142     }
143     else
144       qWarning() << "Unable to read vCard from" << qPrintable( u.path() );
145   }
146   else
147     qWarning() << "Invalid flag" << m.flags() << "found in user message from" << qPrintable( u.name() );
148 }
149 
parseFileMessage(const User & u,const Message & m)150 void Core::parseFileMessage( const User& u, const Message& m )
151 {
152   FileInfo fi = Protocol::instance().fileInfoFromMessage( m, u.protocolVersion() );
153   if( !fi.isValid() )
154   {
155     qWarning() << "Invalid FileInfo received from user" << u.id() << ": [" << qPrintable( m.data() ) << "]:" << qPrintable( m.text() );
156     return;
157   }
158 
159   Chat chat_to_show_message = ChatManager::instance().findChatByPrivateId( fi.chatPrivateId(), false, u.id() );
160 
161   if( m.hasFlag( Message::Refused ) )
162   {
163     dispatchSystemMessage( chat_to_show_message.id(), u.id(), tr( "%1 %2 has refused to download the file: %3" )
164                            .arg( IconManager::instance().toHtml( "red-ball.png", "*F*" ), Bee::userNameToShow( u, true ), fi.name() ),
165                            chat_to_show_message.isValid() ? DispatchToChat : DispatchToAllChatsWithUser, ChatMessage::FileTransfer, false );
166     return;
167   }
168 
169   if( !Settings::instance().enableFileTransfer() )
170   {
171     refuseToDownloadFile( u.id(), fi );
172     return;
173   }
174 
175   if( !fi.name().endsWith( fi.suffix(), Qt::CaseInsensitive ) )
176   {
177     qWarning() << "Invalid file transfer request received from user" << qPrintable( u.path() ) << ": file extension is" << fi.suffix() << "but the file name is" << fi.name();
178     return;
179   }
180 
181   if( fi.isInShareBox() )
182   {
183     if( !Settings::instance().useShareBox() || Settings::instance().disableFileSharing() )
184     {
185       refuseToDownloadFile( u.id(), fi );
186       return;
187     }
188   }
189 
190   QString sys_msg;
191   if( m.hasFlag( Message::VoiceMessage ) )
192     sys_msg = tr( "%1 %2 is sending to you the voice message: %3" ).arg( IconManager::instance().toHtml( "download.png", "*F*" ), Bee::userNameToShow( u, true ), fi.name() );
193   else
194     sys_msg = tr( "%1 %2 is sending to you the file: %3" ).arg( IconManager::instance().toHtml( "download.png", "*F*" ), Bee::userNameToShow( u, true ), fi.name() );
195   dispatchSystemMessage( chat_to_show_message.id(), u.id(), sys_msg, chat_to_show_message.isValid() ? DispatchToChat : DispatchToAllChatsWithUser, ChatMessage::FileTransfer, false );
196 
197   if( !Settings::instance().isFileExtensionAllowedInFileTransfer( fi.suffix() ) )
198   {
199     qWarning() << "User" << qPrintable( u.path() ) << "is sending to you the file" << fi.name() << "but you are not allowed to download this file extension";
200     refuseToDownloadFile( u.id(), fi );
201     return;
202   }
203 
204   fi.setHostAddress( u.networkAddress().hostAddress() );
205   if( fi.isInShareBox() )
206   {
207     QString to_path;
208     if( !fi.shareFolder().isEmpty() )
209       to_path = Bee::convertToNativeFolderSeparator( QString( "%1/%2/%3" ).arg( Settings::instance().shareBoxPath() )
210                                                                           .arg( fi.shareFolder() )
211                                                                           .arg( fi.name() ) );
212     else
213       to_path = Bee::convertToNativeFolderSeparator( QString( "%1/%2" ).arg( Settings::instance().shareBoxPath() )
214                                                                        .arg( fi.name() ) );
215 
216     QFileInfo file_info( to_path );
217     if( file_info.exists() && file_info.isDir() && Settings::instance().onExistingFileAction() == Settings::GenerateNewFileName )
218       to_path = Bee::uniqueFilePath( to_path, false );
219 
220     qDebug() << "BeeBOX downloads from user" << qPrintable( u.path() ) << "the file" << qPrintable( fi.name() ) << "in path" << qPrintable( to_path );
221     fi.setPath( to_path );
222 
223     mp_fileTransfer->downloadFile( u.id(), fi );
224   }
225   else if( fi.isVoiceMessage() )
226   {
227     QString file_path = Bee::uniqueFilePath( QString( "%1/%2" ).arg( Settings::instance().cacheFolder(), fi.name() ), false );
228     fi.setPath( file_path );
229     mp_fileTransfer->downloadFile( u.id(), fi );
230   }
231   else
232     emit fileDownloadRequest( u, fi );
233 }
234 
parseChatMessage(const User & u,const Message & m)235 void Core::parseChatMessage( const User& u, const Message& m )
236 {
237   if( m.hasFlag( Message::Private ) || m.flags() == 0 || m.hasFlag( Message::GroupChat ) )
238     dispatchChatMessageReceived( u.id(), m );
239   else
240     qWarning() << "Invalid flag found in chat message from" << qPrintable( u.path() );
241 }
242 
parseGroupMessage(const User & u,const Message & m)243 void Core::parseGroupMessage( const User& u, const Message& m )
244 {
245   ChatMessageData cmd = Protocol::instance().dataFromChatMessage( m );
246 
247   if( m.hasFlag( Message::Request ) )
248   {
249  #ifdef BEEBEEP_DEBUG
250     qDebug() << "Group chat request from" << qPrintable( u.path() );
251  #endif
252     if( ChatManager::instance().isChatRefused( cmd.groupId() ) )
253     {
254       qWarning() << "Group chat request from" << qPrintable( u.name() ) << "is refused because the chat"
255                  << qPrintable( cmd.groupName() ) << "is blocked on id" << qPrintable( cmd.groupId() );
256       sendMessageToLocalNetwork( u, Protocol::instance().groupChatRefuseMessage( cmd ) );
257       return;
258     }
259 
260     Chat group_chat = ChatManager::instance().findChatByPrivateId( cmd.groupId(), true, ID_INVALID );
261     if( group_chat.isValid() )
262     {
263       if( cmd.groupLastModified().isValid() && group_chat.lastModified().isValid() )
264       {
265         if( cmd.groupLastModified() <= group_chat.lastModified() )
266         {
267 #ifdef BEEBEEP_DEBUG
268           qDebug() << "Group chat request for" << qPrintable( cmd.groupName() ) << "from" << qPrintable( u.name() ) << "is skipped because it has old timestamp:" << qPrintable( cmd.groupLastModified().toString( Qt::ISODate ) );
269 #endif
270           return;
271         }
272 #ifdef BEEBEEP_DEBUG
273         else
274           qDebug() << "Group chat request from" << qPrintable( u.path() ) << "is newer" << qPrintable( cmd.groupLastModified().toString( Qt::ISODate ) )
275                    << "than your" << qPrintable( group_chat.lastModified().toString( Qt::ISODate ) ) ;
276 #endif
277       }
278       else if( !cmd.groupLastModified().isValid() )
279       {
280         if( group_chat.lastModified().isValid() )
281         {
282 #ifdef BEEBEEP_DEBUG
283           qDebug() << "Group chat request for" << qPrintable( cmd.groupName() ) << "from" << qPrintable( u.name() ) << "is skipped because it has not last modified date";
284 #endif
285           return;
286         }
287 #ifdef BEEBEEP_DEBUG
288         else
289           qDebug() << "Group chat request from" << qPrintable( u.path() ) << "has not last modified date as your chat";
290 #endif
291       }
292 #ifdef BEEBEEP_DEBUG
293       else
294         qDebug() << "Group chat request from" << qPrintable( u.path() ) << "has last modified date" << qPrintable( cmd.groupLastModified().toString( Qt::ISODate ) );
295 #endif
296 
297       if( !group_chat.usersId().contains( ID_LOCAL_USER ) )
298       {
299         ChatManager::instance().addToRefusedChat( ChatRecord( group_chat.name(), group_chat.privateId() ) );
300         qWarning() << "Group chat request from" << qPrintable( u.name() ) << "is refused because you have left the chat" << qPrintable( group_chat.name() );
301         sendMessageToLocalNetwork( u, Protocol::instance().groupChatRefuseMessage( cmd ) );
302         return;
303       }
304     }
305 
306     UserList ul;
307     ul.set( u ); // User from request
308     ul.set( Settings::instance().localUser() );
309 
310     if( u.protocolVersion() < NEW_GROUP_PROTO_VERSION )
311     {
312       QStringList user_paths = Protocol::instance().userPathsFromGroupRequestMessage_obsolete( m );
313       if( user_paths.isEmpty() )
314       {
315         qWarning() << "(obsolete) Group chat request for" << qPrintable( cmd.groupName() ) << "from" << qPrintable( u.name() ) << "has not members";
316         return;
317       }
318       else
319         qDebug() << "(obsolete) Group chat request for" << qPrintable( cmd.groupName() ) << "from" << qPrintable( u.name() ) << "has" << user_paths.size() << "members";
320 
321       foreach( QString user_path, user_paths )
322       {
323         if( user_path.isEmpty() )
324         {
325           qWarning() << "(obsolete) Group chat request for" << qPrintable( cmd.groupName() ) << "from" << qPrintable( u.name() ) << "has a NULL member";
326           continue;
327         }
328 
329         User user_tmp = UserManager::instance().findUserByNickname( User::nameFromPath( user_path ) );
330         if( user_tmp.isValid() )
331         {
332           if( !user_tmp.isLocal() )
333           {
334 #ifdef BEEBEEP_DEBUG
335             qDebug() << "(obsolete) Group chat request for" << qPrintable( cmd.groupName() ) << "from" << qPrintable( u.name() ) << "has found member" << qPrintable( user_tmp.name() );
336 #endif
337             ul.set( user_tmp );
338           }
339         }
340         else
341         {
342           UserRecord ur( User::nameFromPath( user_path ), "", "", "" );
343           ur.setNetworkAddress( NetworkAddress::fromString( User::hostAddressAndPortFromPath( user_path ) ) );
344           if( !ur.networkAddressIsValid() )
345             qWarning() << "(obsolete) Invalid network address found in user" << qPrintable( user_path ) << "from group request of" << qPrintable( u.name() );
346           user_tmp = Protocol::instance().createTemporaryUser( ur );
347           qDebug() << "(obsolete) Group chat request for" << qPrintable( cmd.groupName() ) << "from" << qPrintable( u.name() ) << "has created temporary user" << user_tmp.id() << qPrintable( user_tmp.name() );
348           UserManager::instance().setUser( user_tmp );
349           createPrivateChat( user_tmp );
350           emit userChanged( user_tmp );
351           ul.set( user_tmp );
352         }
353       }
354     }
355     else
356     {
357       QList<UserRecord> user_records = Protocol::instance().userRecordsFromGroupRequestMessage( m );
358       if( !user_records.isEmpty() )
359       {
360         qDebug() << "Group chat request for" << qPrintable( cmd.groupName() ) << "from" << qPrintable( u.name() ) << "has" << user_records.size() << "members";
361         foreach( UserRecord ur, user_records )
362         {
363           User group_member = Protocol::instance().recognizeUser( ur, Settings::instance().userRecognitionMethod() );
364           if( group_member.isLocal() )
365             continue;
366 
367           if( !group_member.isValid() )
368           {
369             group_member = Protocol::instance().createTemporaryUser( ur );
370             UserManager::instance().setUser( group_member );
371             qDebug() << "Temporary user" << group_member.id() << qPrintable( group_member.name() ) << "is created after request of" << qPrintable( u.name() ) << "for group" << qPrintable( cmd.groupName() );
372             createPrivateChat( group_member );
373             emit userChanged( group_member );
374           }
375 
376           ul.set( group_member );
377         }
378       }
379       else
380         qDebug() << "Group chat request for" << qPrintable( cmd.groupName() ) << "from" << qPrintable( u.name() ) << "makes this group private";
381     }
382 
383     if( group_chat.isValid() )
384     {
385       qDebug() << "Group chat request for" << qPrintable( cmd.groupName() ) << "from" << qPrintable( u.name() ) << "is accepted with timestamp" << qPrintable( cmd.groupLastModified().toString( Qt::ISODate ) );
386       Group g = group_chat.group();
387       g.setName( cmd.groupName() );
388       g.setUsers( ul.toUsersId() );
389       if( cmd.groupLastModified().isValid() )
390         g.setLastModified( cmd.groupLastModified() );
391       changeGroupChat( u, g );
392     }
393     else
394     {
395       if( ul.toList().size() > 1 )
396       {
397         Group g;
398         g.setName( cmd.groupName() );
399         g.setPrivateId( cmd.groupId() );
400         g.setUsers( ul.toUsersId() );
401         g.setChatType( Group::GroupChat );
402         if( cmd.groupLastModified().isValid() )
403           g.setLastModified( cmd.groupLastModified() );
404 
405         createGroupChat( u, g, false );
406       }
407       else
408         qWarning() << "Unable to create group chat" << qPrintable( cmd.groupName() ) << "from user" << qPrintable( u.name() ) << "because members are minus than 2";
409     }
410   }
411   else if( m.hasFlag( Message::Refused ) )
412   {
413     removeUserFromGroupChat( u, cmd.groupId() );
414   }
415   else if( m.hasFlag( Message::Delete ) )
416   {
417     removeLocalUserFromGroupChatByOther( u, cmd.groupId() );
418   }
419   else
420     qWarning() << "Invalid flag found in group message from" << qPrintable( u.path() );
421 }
422 
parseFileShareMessage(const User & u,const Message & m)423 void Core::parseFileShareMessage( const User& u, const Message& m )
424 {
425   if( m.hasFlag( Message::List ) )
426   {
427     QList<FileInfo> file_info_list = Protocol::instance().messageToFileShare( m, u.networkAddress().hostAddress() );
428     int prev_files = FileShare::instance().network().count( u.id() );
429     int new_files = FileShare::instance().addToNetwork( u.id(), file_info_list );
430 
431     QString share_status;
432     if( prev_files > 0 && new_files == 0 )
433       share_status = tr( "%1 has removed shared files" ).arg( Bee::userNameToShow( u, true ) );
434     else if( new_files > 0 )
435       share_status = tr( "%1 has shared %2 files" ).arg( Bee::userNameToShow( u, true ) ).arg( new_files );
436     else
437       share_status = "";
438 
439     if( !share_status.isEmpty() )
440       dispatchSystemMessage( ID_DEFAULT_CHAT, ID_LOCAL_USER, QString( "%1 %2." ).arg( IconManager::instance().toHtml( "download.png", "*F*" ), share_status ),
441                              DispatchToChat, ChatMessage::System, false );
442 
443     emit fileShareAvailable( u );
444   }
445   else if( m.hasFlag( Message::Request ) )
446   {
447     if( !Settings::instance().enableFileTransfer() )
448       return;
449 
450     if( !Settings::instance().enableFileSharing() )
451       return;
452 
453     sendFileShareListTo( u.id() );
454   }
455   else
456     qWarning() << "Invalid flag found in file share message from" << qPrintable( u.path() );
457 }
458 
parseFolderMessage(const User & u,const Message & m)459 void Core::parseFolderMessage( const User& u, const Message& m )
460 {
461   Chat chat_to_show_message;
462   if( m.hasFlag( Message::Refused ) )
463   {
464     chat_to_show_message = ChatManager::instance().findChatByPrivateId( m.data(), false, u.id() );
465     dispatchSystemMessage( chat_to_show_message.id(), u.id(), tr( "%1 %2 has refused to download folder %3." )
466                              .arg( IconManager::instance().toHtml( "red-ball.png", "*F*" ), Bee::userNameToShow( u, true ), m.text() ),
467                              chat_to_show_message.isValid() ? DispatchToChat : DispatchToDefaultAndPrivateChat, ChatMessage::FileTransfer, false );
468     return;
469   }
470   else if( m.hasFlag( Message::Request ) )
471   {
472     if( !Settings::instance().enableFileTransfer() )
473       return;
474 
475     QString folder_name = tr( "unknown folder" );
476     QList<FileInfo> file_info_list = Protocol::instance().messageFolderToInfoList( m, u.networkAddress().hostAddress(), &folder_name );
477     if( file_info_list.isEmpty() )
478     {
479       qWarning() << "Invalid file info list found in folder message from" << qPrintable( u.path() );
480       return;
481     }
482 
483     QString chat_private_id = file_info_list.first().chatPrivateId();
484     chat_to_show_message = ChatManager::instance().findChatByPrivateId( chat_private_id, false, u.id() );
485     QString sys_msg = tr( "%1 %2 is sending to you the folder: %3." ).arg( IconManager::instance().toHtml( "download.png", "*F*" ), Bee::userNameToShow( u, true ), folder_name );
486     dispatchSystemMessage( chat_to_show_message.id(), u.id(), sys_msg, chat_to_show_message.isValid() ? DispatchToChat : DispatchToAllChatsWithUser, ChatMessage::FileTransfer, false );
487 
488     QList<FileInfo> file_info_list_allowed;
489     foreach( FileInfo fi, file_info_list )
490     {
491       if( !Settings::instance().isFileExtensionAllowedInFileTransfer( fi.suffix() ) )
492       {
493         qWarning() << "User" << qPrintable( u.path() ) << "is sending to you the file" << fi.name() << "in folder" << folder_name << "but you are not allowed to download this file extension";
494         refuseToDownloadFile( u.id(), fi );
495       }
496       else
497         file_info_list_allowed.append( fi );
498     }
499 
500     if( file_info_list_allowed.isEmpty() )
501     {
502       qWarning() << "User" << qPrintable( u.path() ) << "sent you the folder" << folder_name << "but all the files contained are not allowed";
503       refuseToDownloadFolder( u.id(), folder_name, chat_private_id );
504     }
505     else
506       emit folderDownloadRequest( u, folder_name, file_info_list_allowed );
507   }
508   else
509     qWarning() << "Invalid flag found in folder message from user" << qPrintable( u.path() );
510 }
511 
parseChatReadMessage(const User & u,const Message & m)512 void Core::parseChatReadMessage( const User& u, const Message& m )
513 {
514   Chat c = findChatFromMessageData( u.id(), m );
515   if( !c.isValid() )
516   {
517     qWarning() << "Invalid chat message read received from" << qPrintable( u.path() );
518     return;
519   }
520 
521 #ifdef BEEBEEP_DEBUG
522   qDebug() << "User" << qPrintable( u.path() ) << "has read messages in chat" << c.name();
523 #endif
524 
525   c.setReadMessagesByUser( u.id() );
526   ChatManager::instance().setChat( c );
527   emit chatReadByUser( c, u );
528 }
529 
parseHiveMessage(const User & u,const Message & m)530 void Core::parseHiveMessage( const User& u, const Message& m )
531 {
532   if( !Settings::instance().useHive() )
533   {
534 #ifdef BEEBEEP_DEBUG
535     qDebug() << "Skips hive message arrived from" << qPrintable( u.path() ) << "(option disabled)";
536 #endif
537     return;
538   }
539 
540   if( m.hasFlag( Message::List ) )
541   {
542     QList<UserRecord> user_record_list = Protocol::instance().hiveMessageToUserRecordList( m );
543     if( user_record_list.isEmpty() )
544       return;
545 #ifdef BEEBEEP_DEBUG
546     qDebug() << "Hive message arrived with" << user_record_list.size() << "user(s) from" << qPrintable( u.path() );
547 #endif
548     int hive_users_added = 0;
549     foreach( UserRecord ur, user_record_list )
550     {
551       if( !isUserConnected( ur.networkAddress() ) )
552       {
553         if( Hive::instance().addNetworkAddress( ur.networkAddress() ) )
554         {
555           hive_users_added++;
556           qDebug() << "New user added from Hive with address" << qPrintable( ur.networkAddress().toString() );
557         }
558       }
559     }
560     if( hive_users_added > 0 )
561       mp_broadcaster->updateUsersFromHive();
562   }
563   else
564     qWarning() << "Invalid flag found in hive message from user" << qPrintable( u.path() );
565 }
566 
parseShareBoxMessage(const User & u,const Message & m)567 void Core::parseShareBoxMessage( const User& u, const Message& m )
568 {
569   QString folder_name = Protocol::instance().folderNameFromShareBoxMessage( m );
570 
571 #ifdef BEEBEEP_DEBUG
572   if( !Settings::instance().enableFileTransfer() )
573     qDebug() << "Skips share box message arrived from" << qPrintable( u.path() ) << "(file transfer disabled)";
574   else if( !Settings::instance().enableFileSharing() )
575     qDebug() << "Skips share box message arrived from" << qPrintable( u.path() ) << "(file sharing disabled)";
576   else if( !Settings::instance().useShareBox() )
577     qDebug() << "Skips share box message arrived from" << qPrintable( u.path() ) << "(share box disabled)";
578   else
579     qDebug() << "Parsing share box message from" << qPrintable( u.path() ) << "for folder" << folder_name;
580 #endif
581 
582   bool sharebox_is_active = Settings::instance().enableFileTransfer() && Settings::instance().enableFileSharing() && Settings::instance().useShareBox();
583 
584   if( !sharebox_is_active )
585   {
586     if( !m.hasFlag( Message::Refused ) )
587       sendMessageToLocalNetwork( u, Protocol::instance().refuseToShareBoxPath( folder_name, m.hasFlag( Message::Create ) ) );
588   }
589   else if( m.hasFlag( Message::List ) )
590   {
591     QList<FileInfo> file_info_list = Protocol::instance().messageToShareBoxFileList( m, u.networkAddress().hostAddress() );
592     emit shareBoxAvailable( u, folder_name, file_info_list );
593   }
594   else if( m.hasFlag( Message::Request ) )
595   {
596     if( m.hasFlag( Message::Refused ) )
597       emit shareBoxUnavailable( u, folder_name );
598     else
599       buildShareBoxFileList( u, folder_name, false );
600   }
601   else if( m.hasFlag( Message::Create ) )
602   {
603     if( m.hasFlag( Message::Refused ) )
604       emit shareBoxUnavailable( u, folder_name );
605     else
606       buildShareBoxFileList( u, folder_name, true );
607   }
608   else
609     qWarning() << "Invalid flag found in share box message from user" << qPrintable( u.path() );
610 }
611 
parseBuzzMessage(const User & u,const Message &)612 void Core::parseBuzzMessage( const User& u, const Message& )
613 {
614   QString sys_msg = tr( "%1 %2 is buzzing you." ).arg( IconManager::instance().toHtml( "bell.png", "*Z*" ), Bee::userNameToShow( u, true ) );
615   Chat c = ChatManager::instance().privateChatForUser( u.id() );
616   if( !c.isValid() )
617     c = ChatManager::instance().defaultChat();
618   c.addUnreadMessage();
619   ChatManager::instance().setChat( c );
620   dispatchSystemMessage( c.id(), u.id(), sys_msg, DispatchToChat, ChatMessage::Other, false );
621   emit localUserIsBuzzedBy( u );
622 }
623