00001 using System;
00002 using System.Collections.Generic;
00003 using System.Text;
00004 using System.IO;
00005 using System.Reflection;
00006
00007 namespace DCPlusPlus
00008 {
00015 public class Client
00016 {
00017
00018
00019 protected Object peers_lock = new Object();
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 protected List<Peer> peers = new List<Peer>();
00035 public List<Peer> Peers
00036 {
00037 get
00038 {
00039 return (peers);
00040 }
00041 }
00042
00043 protected Queue download_queue = new Queue();
00047 public Queue DownloadQueue
00048 {
00049 get
00050 {
00051 return (download_queue);
00052 }
00053 }
00054 protected SearchResults search_results = new SearchResults();
00058 public SearchResults SearchResults
00059 {
00060 get
00061 {
00062 return (search_results);
00063 }
00064 }
00065 protected ListeningSockets local_peer = new ListeningSockets();
00069 public ListeningSockets LocalPeer
00070 {
00071 get
00072 {
00073 return (local_peer);
00074 }
00075 }
00076 protected Sharing shares = new Sharing();
00080 public Sharing Shares
00081 {
00082 get
00083 {
00084 return (shares);
00085 }
00086 }
00087 protected Object connected_hubs_lock = new Object();
00092 public Object ConnectedHubsLock
00093 {
00094 get
00095 {
00096 return (connected_hubs_lock);
00097 }
00098 set
00099 {
00100 connected_hubs_lock = value;
00101 }
00102 }
00103 protected List<Hub> connected_hubs = new List<Hub>();
00108 public List<Hub> ConnectedHubs
00109 {
00110 get
00111 {
00112 return (connected_hubs);
00113 }
00114 }
00115 protected string nick = "unknown";
00119 public string Nick
00120 {
00121 get
00122 {
00123 return (nick);
00124 }
00125 set
00126 {
00127 nick = value;
00128 }
00129 }
00130 protected string connection_speed = "unknown";
00134 public string ConnectionSpeed
00135 {
00136 get
00137 {
00138 return (connection_speed);
00139 }
00140 set
00141 {
00142 connection_speed = value;
00143 }
00144
00145 }
00146 protected Hub.ConnectionMode connection_mode = Hub.ConnectionMode.Passive;
00153 public Hub.ConnectionMode ConnectionMode
00154 {
00155 get
00156 {
00157 return (connection_mode);
00158 }
00159 set
00160 {
00161 connection_mode = value;
00162 }
00163
00164 }
00165 protected string version = "1,0091";
00169 public string Version
00170 {
00171 get
00172 {
00173 return (version);
00174 }
00175 set
00176 {
00177 version = value;
00178 }
00179 }
00180 protected string tag_version = "0.698";
00184 public string TagVersion
00185 {
00186 get
00187 {
00188 return (tag_version);
00189 }
00190 set
00191 {
00192 tag_version = value;
00193 }
00194 }
00195 protected string name = "c#++";
00199 public string Name
00200 {
00201 get
00202 {
00203 return (name);
00204 }
00205 set
00206 {
00207 name = value;
00208 }
00209 }
00210 protected string email = "unknown@unknown.net";
00214 public string Email
00215 {
00216 get
00217 {
00218 return (email);
00219 }
00220 set
00221 {
00222 email = value;
00223 }
00224 }
00225 protected string description = "";
00229 public string Description
00230 {
00231 get
00232 {
00233 return (description);
00234 }
00235 set
00236 {
00237 description = value;
00238 }
00239 }
00240 protected long share_size = 0;
00245 public long ShareSize
00246 {
00247 get
00248 {
00249 return (share_size);
00250 }
00251 set
00252 {
00253 share_size = value;
00254 }
00255 }
00262 public void Search(string search_string)
00263 {
00264 search_results.SearchTerm = search_string;
00265 lock (connected_hubs_lock)
00266 {
00267 foreach (Hub hub in connected_hubs)
00268 {
00269
00270 hub.Search(search_string);
00271 }
00272 }
00273 }
00284 public void Search(string search_string, bool size_restricted, bool is_max_size, int size, Hub.SearchFileType file_type)
00285 {
00286 search_results.SearchTerm = search_string;
00287 lock (connected_hubs_lock)
00288 {
00289 foreach (Hub hub in connected_hubs)
00290 {
00291
00292 hub.Search(search_string, size_restricted, is_max_size, size, file_type);
00293 }
00294 }
00295 }
00302 public void Search(Hub.SearchParameters sp)
00303 {
00304 search_results.SearchTerm = sp.search_string;
00305 lock (connected_hubs_lock)
00306 {
00307 foreach (Hub hub in connected_hubs)
00308 {
00309
00310 hub.Search(sp);
00311 }
00312 }
00313 }
00321 public void Search(string search_tth, bool is_tth)
00322 {
00323 if (!is_tth)
00324 Search(search_tth);
00325 else
00326 {
00327 lock (connected_hubs_lock)
00328 {
00329 foreach (Hub hub in connected_hubs)
00330 {
00331
00332 hub.Search(search_tth, true);
00333 }
00334 }
00335 }
00336 }
00342 public void FindAlternateSources(Queue.QueueEntry me)
00343 {
00344
00345 if (me != null && me.HasTTH)
00346 Search(me.TTH, true);
00347 }
00356 private void InterpretReceivedSearchResult(SearchResults.SearchResult result)
00357 {
00358
00359 result.Hub = ResolveHub(result.HubAddress);
00360 if (result.Hub != null)
00361 {
00362 if (result.HasTTH)
00363 {
00364 Queue.QueueEntry entry = download_queue.FindQueueEntryByTTH(result.TTH);
00365 if (entry != null)
00366 {
00367
00368 entry.AddSource(new Queue.QueueEntry.Source(result.UserName, result.Filename, result.Hub));
00369
00370 }
00371 else search_results.AddResult(result);
00372 }
00373 else search_results.AddResult(result);
00374 }
00375
00376
00377
00378
00379
00380
00381 }
00387 public void GetFileList(Hub hub, string username)
00388 {
00389 download_queue.AddFileList(hub, username);
00390 hub.SendConnectToMe(username);
00391 }
00396 public void GetTTHL(Queue.QueueEntry me)
00397 {
00398
00399 me.WantTTHL = true;
00400 me.StartDownload();
00401 }
00410 public void StopDownload(Queue.QueueEntry me)
00411 {
00412 lock (peers_lock)
00413 {
00414 foreach (Peer peer in peers)
00415 {
00416 if (peer.QueueEntry == me && peer.IsDownloading )
00417 {
00418 peers.Remove(peer);
00419 peer.Disconnect();
00420 break;
00421 }
00422 }
00423 }
00424 }
00430 public void StartDownload(SearchResults.SearchResult result)
00431 {
00432 if (result.IsHubResolved)
00433 {
00434 download_queue.AddSearchResult(result);
00435 result.Hub.SendConnectToMe(result.UserName);
00436 }
00437 else Console.WriteLine("Hub was not resolved from result hub address: " + result.HubAddress);
00438 }
00445 public void StartDownload(Queue.QueueEntry.Source source)
00446 {
00447 if (source == null) return;
00448
00449 if (source.HasHub && source.IsOnline && !CheckForUserInPeers(source.UserName))
00450 {
00451 source.Hub.SendConnectToMe(source.UserName);
00452 }
00453 }
00460 public void StartDownload(Queue.QueueEntry me)
00461 {
00462
00463
00464 if (me == null) return;
00465 me.StartDownload();
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485 }
00491 public void UpdateConnectionSettings()
00492 {
00493 local_peer.UpdateConnectionSettings();
00494 lock (connected_hubs_lock)
00495 {
00496 foreach (Hub hub in connected_hubs)
00497 {
00498 if (!string.IsNullOrEmpty(local_peer.ExternalIP)) hub.MyIP = local_peer.ExternalIP;
00499 else hub.MyIP = local_peer.IP;
00500 hub.MyTcpPort = local_peer.TcpPort;
00501 hub.MyUdpPort = local_peer.UdpPort;
00502 hub.MyConnectionSpeed = connection_speed;
00503 hub.MyConnectionMode = connection_mode;
00504 }
00505 }
00506 }
00507
00516 private Hub ResolveHub(string hub_address)
00517 {
00518 int port = 411;
00519 string address = "";
00520 try
00521 {
00522 int port_start = hub_address.IndexOf(":");
00523 if (port_start != -1)
00524 {
00525 address = hub_address.Substring(0, port_start);
00526 port = int.Parse(hub_address.Substring(port_start + 1));
00527 }
00528 else address = hub_address;
00529
00530 }
00531 catch (Exception ex)
00532 {
00533 Console.WriteLine("Exception occured during resolving of hub for address: " + hub_address + " - " + ex.Message);
00534 return (null);
00535 }
00536
00537
00538 lock (connected_hubs_lock)
00539 {
00540 foreach (Hub hub in connected_hubs)
00541 {
00542 if (hub.IP == address && hub.Port == port)
00543 {
00544 return (hub);
00545 }
00546 }
00547 }
00548 return (null);
00549 }
00556 public Hub FindUserHub(string username)
00557 {
00558 return (null);
00559 }
00560
00561
00562
00563
00572 private void UpdateSourcesByUsername(string username, Hub source_hub, bool is_online)
00573 {
00574 download_queue.UpdateSourcesByUsername(username, source_hub, is_online);
00575 }
00583 private void UpdateSourcesByHub(Hub me, bool is_online)
00584 {
00585 foreach (string username in me.UserList)
00586 UpdateSourcesByUsername(username, me, is_online);
00587 }
00593 private bool CheckForUserInPeers(string username)
00594 {
00595 bool ret = false;
00596 lock (peers_lock)
00597 {
00598 foreach (Peer peer in peers)
00599 {
00600 if (peer.PeerNick == username)
00601 {
00602 ret = true;
00603 break;
00604 }
00605 }
00606 }
00607 return (ret);
00608 }
00616 private void ContinueWithQueueForUser(string username)
00617 {
00618
00619
00620 if (string.IsNullOrEmpty(username)) return;
00621 Queue.QueueEntry entry = download_queue.FindFirstUnusedQueueEntryBySourceUser(username);
00622 if (entry != null)
00623 {
00624 StartDownload(entry.FindFirstSourceByUser(username));
00625 }
00626 }
00631 public string GetClientDirectory()
00632 {
00633 return (Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetModules()[0].FullyQualifiedName));
00634 }
00639 public event Peer.ConnectedEventHandler PeerConnected;
00644 public event Peer.DisconnectedEventHandler PeerDisconnected;
00650 public event Peer.HandShakeCompletedEventHandler PeerHandShakeCompleted;
00655 public event Peer.CompletedEventHandler PeerCompleted;
00660 public event Peer.DataReceivedEventHandler PeerDataReceived;
00665 public event Hub.UserQuitEventHandler HubUserQuit;
00670 public event Hub.UserJoinedEventHandler HubUserJoined;
00677 public event Hub.UnableToConnectEventHandler HubUnableToConnect;
00682 public event Hub.LoggedInEventHandler HubLoggedIn;
00687 public event Hub.DisconnectedEventHandler HubDisconnected;
00692 public event Hub.ConnectedEventHandler HubConnected;
00697 public event Hub.MoveForcedEventHandler HubMoveForced;
00703 public event Hub.MainChatLineReceivedEventHandler HubMainChatReceived;
00709 public event Hub.PrivateChatLineReceivedEventHandler HubPrivateChatReceived;
00714 public event Hub.PasswordRequestedEventHandler HubPasswordRequested;
00719 private void SetupPeerEventHandler(Peer client)
00720 {
00721 client.Nick = nick;
00722 client.DataReceived += delegate(Peer data_received_client)
00723 {
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745 if (PeerDataReceived != null)
00746 PeerDataReceived(data_received_client);
00747 };
00748
00749 client.FileListRequestReceived += delegate(Peer file_list_request_client)
00750 {
00751 if (file_list_request_client.UploadRequestFilename == "files.xml.bz2")
00752 file_list_request_client.UploadFilename = file_list_request_client.UploadRequestFilename;
00753 file_list_request_client.UploadFileListData = shares.GetFileListXmlBZ2();
00754 return (Peer.FileRequestAnswer.LetsGo);
00755 };
00756
00757 client.FileRequestReceived += delegate(Peer file_request_client)
00758 {
00759 Sharing.SharingEntry entry = shares.GetShareByFileRequest(file_request_client.UploadRequestFilename);
00760 if(entry!=null)
00761 {
00762 file_request_client.UploadFilename = entry.Filename;
00763 return (Peer.FileRequestAnswer.LetsGo);
00764 }
00765 else return (Peer.FileRequestAnswer.FileNotAvailable);
00766 };
00767
00768 client.HandShakeCompleted += delegate(Peer handshake_client)
00769 {
00770 if (PeerHandShakeCompleted != null)
00771 PeerHandShakeCompleted(handshake_client);
00772 Queue.QueueEntry entry = download_queue.FindFirstUnusedQueueEntryBySourceUser(handshake_client.PeerNick);
00773 if (entry != null)
00774 {
00775 Queue.QueueEntry.Source source = entry.FindFirstSourceByUser(handshake_client.PeerNick);
00776 if (source != null)
00777 {
00778
00779 if (entry.Type == Queue.QueueEntry.EntryType.File && entry.WantTTHL)
00780 handshake_client.GetTTHL(entry);
00781 else if (entry.Type == Queue.QueueEntry.EntryType.File )
00782 handshake_client.StartDownload(source, entry);
00783 else if (entry.Type == Queue.QueueEntry.EntryType.FileList)
00784 handshake_client.GetFileList(entry);
00785 }
00786 else
00787 {
00788 Console.WriteLine("no correct source found in queue entry for user: " + handshake_client.PeerNick);
00789 }
00790 }
00791 else
00792 {
00793 if (handshake_client.Direction == Peer.ConnectionDirection.Download)
00794 {
00795 Console.WriteLine("nothing found in queue for user: " + handshake_client.PeerNick);
00796 handshake_client.Disconnect();
00797 }
00798 }
00799 };
00800
00801
00802 client.Completed += delegate(Peer completed_client)
00803 {
00804
00805 download_queue.Remove(completed_client.QueueEntry);
00806 ContinueWithQueueForUser(completed_client.PeerNick);
00807 if (PeerCompleted != null)
00808 PeerCompleted(completed_client);
00809 };
00810
00811 client.Disconnected += delegate(Peer disconnected_client)
00812 {
00813 lock (peers_lock)
00814 {
00815 if(peers.Contains(disconnected_client))
00816 peers.Remove(disconnected_client);
00817 }
00818
00819
00820
00821
00822
00823 if (PeerDisconnected != null)
00824 PeerDisconnected(disconnected_client);
00825 };
00826 }
00832 public Client()
00833 {
00834
00835 search_results.DiscardOldResults = true;
00836
00837 download_queue.EntrySourceStatusChanged += delegate(Queue.QueueEntry entry_changed,Queue.QueueEntry.Source source)
00838 {
00839 StartDownload(source);
00840 };
00841
00842 local_peer.SearchResultReceived += delegate(SearchResults.SearchResult result)
00843 {
00844 InterpretReceivedSearchResult(result);
00845 };
00846
00847 local_peer.PeerConnected += delegate(Peer client)
00848 {
00849 SetupPeerEventHandler(client);
00850 if (PeerConnected != null)
00851 PeerConnected(client);
00852 client.StartHandShake();
00853 lock (peers_lock)
00854 {
00855 peers.Add(client);
00856 }
00857 };
00858
00859 download_queue.FileListsDirectory = GetClientDirectory() + "\\filelists";
00860 download_queue.DownloadDirectory = GetClientDirectory() + "\\downloads";
00861 share_size = 901 * 1024 * 1024;
00862 share_size = share_size * 1024+523;
00863 }
00868 ~Client()
00869 {
00870
00871
00872 }
00881 public void ConnectHub(Hub me)
00882 {
00883 me.Nick = nick;
00884 if (!string.IsNullOrEmpty(local_peer.ExternalIP)) me.MyIP = local_peer.ExternalIP;
00885 else me.MyIP = local_peer.IP;
00886 me.MyTcpPort = local_peer.TcpPort;
00887 me.MyUdpPort = local_peer.UdpPort;
00888 me.MyEmail = email;
00889 me.MyDescription = description;
00890 me.MyVersion = version;
00891 me.MyTagVersion = tag_version;
00892 me.MyShareSize = share_size;
00893 me.MyConnectionMode = connection_mode;
00894 me.MyConnectionSpeed = connection_speed;
00895 me.MyName = name;
00896
00897 if (!me.IsGrabbedByClient)
00898 {
00899 me.SearchReceived += delegate(Hub search_hub, Hub.SearchParameters search)
00900 {
00901 if (search.HasTTH)
00902 {
00903 Sharing.SharingEntry entry = shares.GetShareByTTH(search.tth);
00904 if (entry != null)
00905 {
00906 if (search.mode == Hub.ConnectionMode.Passive)
00907 search_hub.SearchReply(entry.Filename,entry.Filesize, search);
00908 else local_peer.SearchReply(entry.Filename,entry.Filesize,search_hub, search);
00909 }
00910 }
00911 else
00912 {
00913
00914 }
00915
00916 };
00917 me.SearchResultReceived += delegate(Hub search_result_hub, SearchResults.SearchResult result)
00918 {
00919 InterpretReceivedSearchResult(result);
00920 };
00921 me.PasswordRequested += delegate(Hub password_requested)
00922 {
00923
00924
00925
00926 if (HubPasswordRequested != null)
00927 return(HubPasswordRequested(password_requested));
00928 return (null);
00929 };
00930 me.MainChatLineReceived += delegate(Hub main_chat_hub, Hub.ChatLine main_chat_line)
00931 {
00932 if (HubMainChatReceived != null)
00933 HubMainChatReceived(main_chat_hub, main_chat_line);
00934 };
00935 me.PrivateChatLineReceived += delegate(Hub private_chat_hub, Hub.ChatLine private_chat_line)
00936 {
00937 if (HubPrivateChatReceived != null)
00938 HubPrivateChatReceived(private_chat_hub, private_chat_line);
00939 };
00940 me.MoveForced += delegate(Hub src_hub, Hub dst_hub)
00941 {
00942 if (HubMoveForced != null)
00943 HubMoveForced(src_hub, dst_hub);
00944 };
00945 me.ConnectToMeReceived += delegate(Hub hub, Peer connect_to_me_client)
00946 {
00947
00948 SetupPeerEventHandler(connect_to_me_client);
00949 connect_to_me_client.Connected += delegate(Peer connect_to_me_connected_client)
00950 {
00951 if (PeerConnected != null)
00952 PeerConnected(connect_to_me_connected_client);
00953 connect_to_me_connected_client.StartHandShake();
00954 lock (peers_lock)
00955 {
00956 peers.Add(connect_to_me_connected_client);
00957 }
00958 };
00959 connect_to_me_client.Connect();
00960
00961 };
00962 me.Disconnected += delegate(Hub hub)
00963 {
00964 UpdateSourcesByHub(hub, false);
00965 lock (connected_hubs_lock)
00966 {
00967 if (connected_hubs.Contains(hub))
00968 connected_hubs.Remove(hub);
00969 }
00970 if (HubDisconnected != null)
00971 HubDisconnected(hub);
00972 };
00973 me.Connected += delegate(Hub hub)
00974 {
00975 lock (connected_hubs_lock)
00976 {
00977 if (!connected_hubs.Contains(hub))
00978 connected_hubs.Add(hub);
00979 }
00980 if (HubConnected != null)
00981 HubConnected(hub);
00982 };
00983 me.UnableToConnect += delegate(Hub hub)
00984 {
00985 UpdateSourcesByHub(hub, false);
00986
00987
00988
00989
00990
00991 if (HubUnableToConnect != null)
00992 HubUnableToConnect(hub);
00993 };
00994 me.LoggedIn += delegate(Hub hub)
00995 {
00996 if (HubLoggedIn != null)
00997 HubLoggedIn(hub);
00998 };
00999 me.UserJoined += delegate(Hub hub, string username)
01000 {
01001 UpdateSourcesByUsername(username, hub, true);
01002 if (HubUserJoined != null)
01003 HubUserJoined(hub, username);
01004 };
01005 me.UserQuit += delegate(Hub hub, string username)
01006 {
01007 UpdateSourcesByUsername(username, hub, false);
01008 if (HubUserQuit != null)
01009 HubUserQuit(hub, username);
01010 };
01011
01012 me.IsGrabbedByClient = true;
01013 }
01014 me.Connect();
01015 }
01022 public void DisconnectHub(Hub me)
01023 {
01024 lock (connected_hubs_lock)
01025 {
01026 connected_hubs.Remove(me);
01027 }
01028 me.Disconnect();
01029 me.Ungrab();
01030 }
01031 }
01032 }