00001 using System;
00002 using System.Collections.Generic;
00003 using System.Text;
00004 using System.Threading;
00005 using System.Net;
00006 using System.Net.Sockets;
00007 using System.IO;
00008 using NUnit.Framework;
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 namespace DCPlusPlus
00019 {
00024 [TestFixture]
00025 public class Hub : Connection
00026 {
00032 public delegate void SearchResultReceivedEventHandler(Hub hub, SearchResults.SearchResult result);
00037 public event SearchResultReceivedEventHandler SearchResultReceived;
00043 public delegate void SearchReceivedEventHandler(Hub hub, SearchParameters search);
00049 public event SearchReceivedEventHandler SearchReceived;
00055 public delegate void MainChatLineReceivedEventHandler(Hub hub, ChatLine line);
00060 public event MainChatLineReceivedEventHandler MainChatLineReceived;
00066 public delegate void PrivateChatLineReceivedEventHandler(Hub hub, ChatLine line);
00071 public event PrivateChatLineReceivedEventHandler PrivateChatLineReceived;
00077 public delegate void UserQuitEventHandler(Hub hub, string username);
00082 public event UserQuitEventHandler UserQuit;
00088 public delegate void UserJoinedEventHandler(Hub hub, string username);
00093 public event UserJoinedEventHandler UserJoined;
00098 public delegate void LoggedInEventHandler(Hub hub);
00103 public event LoggedInEventHandler LoggedIn;
00108 public delegate string PasswordRequestedEventHandler(Hub hub);
00115 public event PasswordRequestedEventHandler PasswordRequested;
00121 public delegate void MoveForcedEventHandler(Hub src_hub, Hub dst_hub);
00126 public event MoveForcedEventHandler MoveForced;
00132 public delegate void ConnectToMeEventHandler(Hub hub, Peer connection);
00137 public event ConnectToMeEventHandler ConnectToMeReceived;
00142 public delegate void DisconnectedEventHandler(Hub hub);
00147 public event DisconnectedEventHandler Disconnected;
00152 public delegate void ConnectedEventHandler(Hub hub);
00157 public event ConnectedEventHandler Connected;
00162 public delegate void UnableToConnectEventHandler(Hub hub);
00167 public event UnableToConnectEventHandler UnableToConnect;
00171 public class FileParameters
00172 {
00176 public string filename;
00180 public long filesize;
00181 }
00185 public class SearchParameters
00186 {
00190 public ConnectionMode mode;
00194 public string search_string;
00198 public bool size_restricted;
00202 public bool is_max_size;
00206 public long size;
00210 public SearchFileType file_type;
00214 public string ip;
00218 public int port;
00222 public string username;
00226 public bool HasTTH
00227 {
00228 get
00229 {
00230 return (!string.IsNullOrEmpty(tth));
00231 }
00232 }
00236 public string tth = "";
00240 public SearchParameters()
00241 {
00242 }
00255 public SearchParameters(ConnectionMode mode, string search_string, bool size_restricted, bool is_max_size, int size, SearchFileType file_type,string tth, string ip, int port)
00256 {
00257 this.mode = ConnectionMode.Active;
00258 this.search_string = search_string;
00259 this.size_restricted = size_restricted;
00260 this.is_max_size = is_max_size;
00261 this.size = size;
00262 this.file_type = file_type;
00263 this.ip = ip;
00264 this.port = port;
00265 this.username = "";
00266 this.tth = tth;
00267 }
00278 public SearchParameters(string search_string, bool size_restricted, bool is_max_size, int size, SearchFileType file_type, string tth,string username)
00279 {
00280 this.mode = ConnectionMode.Passive;
00281 this.search_string = search_string;
00282 this.size_restricted = size_restricted;
00283 this.is_max_size = is_max_size;
00284 this.size = size;
00285 this.file_type = file_type;
00286 this.ip = "";
00287 this.port = 0;
00288 this.tth = tth;
00289 this.username = username;
00290 }
00291 }
00292 protected string name = "";
00296 public string Name
00297 {
00298 get
00299 {
00300 return (name);
00301 }
00302 set
00303 {
00304 name = value;
00305 }
00306 }
00307 protected string address = "";
00311 public string Address
00312 {
00313 get
00314 {
00315 return (address);
00316 }
00317 set
00318 {
00319
00320
00321 string tmp = value;
00322 int port_start = tmp.IndexOf(":");
00323 if (port_start != -1)
00324 {
00325 int tmp_port = 411;
00326 string tmp_port_string = tmp.Substring(port_start+1);
00327 try
00328 {
00329 tmp_port = int.Parse(tmp_port_string);
00330 }
00331 catch (Exception)
00332 {
00333 Console.WriteLine("error parsing port : "+tmp_port_string);
00334 }
00335
00336 tmp = tmp.Substring(0, port_start);
00337 port = tmp_port;
00338 }
00339
00340 address = tmp;
00341 }
00342 }
00343 protected string description = "";
00347 public string Description
00348 {
00349 get
00350 {
00351 return (description);
00352 }
00353 set
00354 {
00355 description = value;
00356 }
00357 }
00358 protected string country = "";
00362 public string Country
00363 {
00364 get
00365 {
00366 return (country);
00367 }
00368 set
00369 {
00370 country = value;
00371 }
00372 }
00373 protected long users = 0;
00379 public long Users
00380 {
00381 get
00382 {
00383 return (users);
00384 }
00385 set
00386 {
00387 users = value;
00388 }
00389 }
00390 protected long shared = 0;
00394 public long Shared
00395 {
00396 get
00397 {
00398 return (shared);
00399 }
00400 set
00401 {
00402 shared = value;
00403 }
00404 }
00405 protected long min_share = 0;
00409 public long MinShare
00410 {
00411 get
00412 {
00413 return (min_share);
00414 }
00415 set
00416 {
00417 min_share = value;
00418 }
00419 }
00420 protected int min_slots = 0;
00424 public int MinSlots
00425 {
00426 get
00427 {
00428 return (min_slots);
00429 }
00430 set
00431 {
00432 min_slots = value;
00433 }
00434 }
00435 protected int max_hubs = 0;
00439 public int MaxHubs
00440 {
00441 get
00442 {
00443 return (max_hubs);
00444 }
00445 set
00446 {
00447 max_hubs = value;
00448 }
00449 }
00450 protected long max_users = 0;
00454 public long MaxUsers
00455 {
00456 get
00457 {
00458 return (max_users);
00459 }
00460 set
00461 {
00462 max_users = value;
00463 }
00464 }
00465
00466 protected string topic = "";
00470 public string Topic
00471 {
00472 get
00473 {
00474 return (topic);
00475 }
00476
00477 }
00478 protected bool is_grabbed = false;
00482 public bool IsGrabbedByClient
00483 {
00484 get
00485 {
00486 return (is_grabbed);
00487 }
00488 set
00489 {
00490 is_grabbed = value;
00491 }
00492 }
00493 protected bool is_logged_in= false;
00497 public bool IsLoggedIn
00498 {
00499 get
00500 {
00501 return (is_logged_in);
00502 }
00503
00504 }
00505 protected bool auto_reconnect = false;
00510 public bool AutoReconnect
00511 {
00512 get
00513 {
00514 return (auto_reconnect);
00515 }
00516 set
00517 {
00518 auto_reconnect = value;
00519 }
00520 }
00521
00522 protected int chat_history_max_length = 0;
00527 public int ChatHistoryMaxLength
00528 {
00529 get
00530 {
00531 return (chat_history_max_length);
00532 }
00533 set
00534 {
00535 chat_history_max_length = value;
00536 }
00537 }
00541 public class ChatLine
00542 {
00546 public string username = "unknown";
00550 public string message = "";
00556 public ChatLine(string username, string message)
00557 {
00558 this.username = username;
00559 this.message = message;
00560 }
00561 }
00562 protected List<ChatLine> chat_history = new List<ChatLine>();
00568 public List<ChatLine> ChatHistory
00569 {
00570 get
00571 {
00572 return (chat_history);
00573 }
00574 set
00575 {
00576 chat_history = value;
00577 }
00578 }
00579 protected List<string> user_list = new List<string>();
00580
00586 public List<string> UserList
00587 {
00588 get
00589 {
00590 return (user_list);
00591 }
00592 set
00593 {
00594 user_list = value;
00595 }
00596 }
00597 protected List<string> op_list = new List<string>();
00604 public List<string> OperatorList
00605 {
00606 get
00607 {
00608 return (op_list);
00609 }
00610 set
00611 {
00612 op_list = value;
00613 }
00614 }
00615 protected string my_ip = "";
00620 public string MyIP
00621 {
00622 get
00623 {
00624 return (my_ip);
00625 }
00626 set
00627 {
00628 my_ip = value;
00629 }
00630 }
00631 protected string my_version = "1,0091";
00635 public string MyVersion
00636 {
00637 get
00638 {
00639 return (my_version);
00640 }
00641 set
00642 {
00643 my_version = value;
00644 }
00645 }
00646 protected string my_tag_version = "0.698";
00650 public string MyTagVersion
00651 {
00652 get
00653 {
00654 return (my_tag_version);
00655 }
00656 set
00657 {
00658 my_tag_version = value;
00659 }
00660 }
00661 protected string my_name = "c#++";
00665 public string MyName
00666 {
00667 get
00668 {
00669 return (my_name);
00670 }
00671 set
00672 {
00673 my_name = value;
00674 }
00675 }
00676 protected string my_email = "unknown@unknown.net";
00680 public string MyEmail
00681 {
00682 get
00683 {
00684 return (my_email);
00685 }
00686 set
00687 {
00688 my_email = value;
00689 }
00690 }
00691 protected string my_description = "";
00695 public string MyDescription
00696 {
00697 get
00698 {
00699 return (my_description);
00700 }
00701 set
00702 {
00703 my_description = value;
00704 }
00705 }
00706 protected long my_share_size = 0;
00710 public long MyShareSize
00711 {
00712 get
00713 {
00714 return (my_share_size);
00715 }
00716 set
00717 {
00718 my_share_size = value;
00719 }
00720 }
00721 protected int my_tcp_port = 0;
00726 public int MyTcpPort
00727 {
00728 get
00729 {
00730 return (my_tcp_port);
00731 }
00732 set
00733 {
00734 my_tcp_port = value;
00735 }
00736 }
00737 protected int my_udp_port = 0;
00742 public int MyUdpPort
00743 {
00744 get
00745 {
00746 return (my_udp_port);
00747 }
00748 set
00749 {
00750 my_udp_port = value;
00751 }
00752
00753 }
00757 public enum ConnectionSpeed
00758 {
00763 kbps_28_8,
00768 kbps_33_6,
00773 kbps_56,
00778 satellite,
00783 isdn,
00788 dsl,
00793 cable,
00798 lan_t1,
00803 lan_t3,
00808 modem,
00809 }
00810 protected string my_connection_speed = "0.02";
00814 public string MyConnectionSpeed
00815 {
00816 get
00817 {
00818 return (my_connection_speed);
00819 }
00820 set
00821 {
00822 my_connection_speed = value;
00823 }
00824
00825 }
00829 public enum ConnectionMode
00830 {
00834 Active,
00838 Passive
00839
00840 }
00841
00842 protected ConnectionMode my_connection_mode = ConnectionMode.Passive;
00848 public ConnectionMode MyConnectionMode
00849 {
00850 get
00851 {
00852 return (my_connection_mode);
00853 }
00854 set
00855 {
00856 my_connection_mode = value;
00857 }
00858
00859 }
00864 public Hub()
00865 {
00866 is_connecting = false;
00867 is_connected = false;
00868 is_extended_protocol = false;
00869 is_logged_in = false;
00870 socket = null;
00871 port = 411;
00872
00873 }
00877 public void Reconnect()
00878 {
00879 Disconnect();
00880 Connect();
00881 }
00885 public override void Disconnect()
00886 {
00887 if (is_connected || is_connecting)
00888 {
00889 try
00890 {
00891 if (socket != null && socket.Connected)
00892 {
00893
00894 socket.Shutdown(SocketShutdown.Both);
00895
00896 socket.Close();
00897 socket = null;
00898
00899 }
00900 if (is_connected)
00901 {
00902 if (Disconnected != null)
00903 Disconnected(this);
00904 }else if (is_connecting)
00905 {
00906 if (UnableToConnect != null)
00907 UnableToConnect(this);
00908 }
00909 is_connecting = false;
00910 is_connected = false;
00911 is_extended_protocol = false;
00912 is_logged_in = false;
00913 }
00914 catch (Exception ex)
00915 {
00916 Console.WriteLine("Error disconnecting Hub: " + name + "(exception:" + ex.Message + ")");
00917 error_code = ErrorCodes.Exception;
00918 }
00919 }
00920 }
00924 public void Connect()
00925 {
00926 if (is_connecting)
00927 {
00928 error_code = ErrorCodes.UserDisconnect;
00929 Disconnect();
00930 }
00931 if (!is_connected)
00932 {
00933
00934 try
00935 {
00936 is_connecting = true;
00937 socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
00938 socket.Blocking = false;
00939 AsyncCallback event_host_resolved = new AsyncCallback(OnHostResolve);
00940 Dns.BeginGetHostEntry(address, event_host_resolved, socket);
00941
00942
00943 }
00944 catch (Exception ex)
00945 {
00946 error_code = ErrorCodes.Exception;
00947 Console.WriteLine("Error connecting to Hub: " + name + "(exception:" + ex.Message + ")");
00948 Disconnect();
00949 }
00950 }
00951 }
00956 private void OnHostResolve(IAsyncResult result)
00957 {
00958 Socket resolve_socket = (Socket)result.AsyncState;
00959 try
00960 {
00961 IPHostEntry ip_entry = Dns.EndGetHostEntry(result);
00962 if (ip_entry != null && ip_entry.AddressList.Length > 0)
00963 {
00964 ip = ip_entry.AddressList[0].ToString();
00965 IPEndPoint endpoint = new IPEndPoint(ip_entry.AddressList[0], port);
00966 AsyncCallback event_connect = new AsyncCallback(OnConnect);
00967 socket.BeginConnect(endpoint, event_connect, socket);
00968 }
00969 else
00970 {
00971 Console.WriteLine("Unable to connect to server: " + name + "(address:" + address + ")");
00972 error_code = ErrorCodes.UnableToConnect;
00973 Disconnect();
00974 }
00975
00976 }
00977
00978 catch (SocketException sex)
00979 {
00980 if (sex.ErrorCode == 11001)
00981 {
00982 error_code = ErrorCodes.UnableToConnect;
00983 Console.WriteLine("Error during Address resolve of Hub: " + name + "(address:" + address + ")");
00984 Disconnect();
00985 }
00986 else
00987 {
00988 error_code = ErrorCodes.UnableToConnect;
00989 Console.WriteLine("Error during Address resolve of Hub: " + name + "(address:" + address + ")");
00990 Disconnect();
00991 }
00992
00993 }
00994 catch (Exception ex)
00995 {
00996 error_code = ErrorCodes.Exception;
00997 Console.WriteLine("Error during Address resolve of Hub: " + name + "(address:" + address +",exception:"+ex.Message+")");
00998 Disconnect();
00999 }
01000 }
01005 private void OnConnect(IAsyncResult result)
01006 {
01007 Socket connect_socket = (Socket)result.AsyncState;
01008 try
01009 {
01010 if (connect_socket.Connected)
01011 {
01012 AsyncCallback event_receive = new AsyncCallback(OnReceive);
01013 receive_buffer = new byte[32768];
01014 connect_socket.BeginReceive(receive_buffer, 0, receive_buffer.Length, SocketFlags.None, event_receive, connect_socket);
01015
01016 try
01017 {
01018 if (Connected != null)
01019 Connected(this);
01020 }
01021 catch (Exception ex)
01022 {
01023 error_code = ErrorCodes.Exception;
01024 Console.WriteLine("Exception in Connected event: " + ex.Message);
01025 Disconnect();
01026 }
01027 is_connecting = false;
01028 is_connected = true;
01029 }
01030 else
01031 {
01032 error_code = ErrorCodes.UnableToConnect;
01033 Console.WriteLine("Unable to connect to server: " + name);
01034 Disconnect();
01035 }
01036
01037 }
01038 catch (Exception ex)
01039 {
01040 error_code = ErrorCodes.Exception;
01041 Console.WriteLine("Error during connect to Hub: " + name + "(exception:" + ex.Message + ")");
01042 Disconnect();
01043 }
01044 }
01049 private void OnReceive(IAsyncResult result)
01050 {
01051 Socket receive_socket = (Socket)result.AsyncState;
01052 if (!receive_socket.Connected) return;
01053 try
01054 {
01055 int received_bytes = receive_socket.EndReceive(result);
01056 if (received_bytes > 0)
01057 {
01058
01059 string received_string = System.Text.Encoding.Default.GetString(receive_buffer, 0, received_bytes);
01060
01061
01062 InterpretReceivedString(received_string);
01063 AsyncCallback event_receive = new AsyncCallback(OnReceive);
01064 receive_socket.BeginReceive(receive_buffer, 0, receive_buffer.Length, SocketFlags.None, event_receive, receive_socket);
01065 }
01066 else
01067 {
01068 Disconnect();
01069 }
01070
01071 }
01072 catch (Exception ex)
01073 {
01074 error_code = ErrorCodes.Exception;
01075 Console.WriteLine("Error receiving data from Hub: " + name + "(exception:" + ex.Message + ")");
01076 Disconnect();
01077 }
01078
01079 }
01084 public void SendChatMessage(string message)
01085 {
01086 string send_string = "<" + nick + "> " + message + "|";
01087 try
01088 {
01089
01090 byte[] send_bytes = System.Text.Encoding.Default.GetBytes(send_string);
01091 socket.BeginSend(send_bytes, 0, send_bytes.Length, SocketFlags.None, new AsyncCallback(SendChatMessageCallback), socket);
01092 }
01093 catch (Exception e)
01094 {
01095 error_code = ErrorCodes.Exception;
01096 Console.WriteLine("Error sending chat message to Hub: " + name + "(exception:" + e.Message + ")");
01097 Disconnect();
01098 }
01099 }
01104 private void SendChatMessageCallback(IAsyncResult ar)
01105 {
01106 Socket send_chat_message_socket = (Socket)ar.AsyncState;
01107 try
01108 {
01109 int bytes = send_chat_message_socket.EndSend(ar);
01110 }
01111 catch (Exception ex)
01112 {
01113 error_code = ErrorCodes.Exception;
01114 Console.WriteLine("Error during sending chat message to Hub: " + name + "(exception:" + ex.Message + ")");
01115 Disconnect();
01116 }
01117 }
01123 public void SendChatMessage(string message, string username)
01124 {
01125 SendCommand("To: " + username + " From: " + nick + " $<" + nick + "> " + message);
01126 }
01134 public void SendChatMessage(string message, string username,bool show_in_main_chat)
01135 {
01136 if (show_in_main_chat)
01137 SendCommand("MCTo: " + username + " $" + nick + " " + message);
01138 else SendChatMessage(message, username);
01139 }
01143 public enum SearchFileType
01144 {
01148 any = 1,
01152 audio = 2,
01156 compressed = 3,
01160 documents = 4,
01164 executables = 5,
01168 pictures = 6,
01172 video = 7,
01176 folders = 8,
01180 tth = 9
01181 }
01186 public void Search(string search_string)
01187 {
01188 Search(search_string,false,false,0,SearchFileType.any);
01189 }
01198 public void Search(string search_string, bool size_restricted, bool is_max_size, long size, SearchFileType file_type)
01199 {
01200
01201
01202 string parameter = "";
01203 if (my_connection_mode == ConnectionMode.Active)
01204 {
01205 parameter = my_ip + ":" + my_udp_port.ToString() + " ";
01206 }
01207 else if (my_connection_mode == ConnectionMode.Passive)
01208 {
01209 parameter = "Hub:" + nick + " ";
01210 }
01211 if (size_restricted)
01212 parameter += "T?";
01213 else parameter += "F?";
01214 if (is_max_size)
01215 parameter += "T?";
01216 else parameter += "F?";
01217
01218 parameter += size.ToString()+"?";
01219 parameter += ((int)file_type).ToString()+"?";
01220 parameter += search_string.Replace(' ','$');
01221 SendCommand("Search",parameter);
01222 }
01227 public void Search(SearchParameters sp)
01228 {
01229 Search(sp.search_string, sp.size_restricted, sp.is_max_size, sp.size, sp.file_type);
01230 }
01236 public void Search(string search_tth, bool is_tth)
01237 {
01238 if (!is_tth)
01239 Search(search_tth);
01240 else
01241 {
01242 Search("TTH:" + search_tth,false,false,0,SearchFileType.tth);
01243 }
01244 }
01252 public void SearchReply(string result_name, long filesize, SearchParameters search)
01253 {
01254 if (search.mode == ConnectionMode.Passive)
01255 {
01256 string temp_hub = name;
01257 if (search.HasTTH) temp_hub = "TTH:" + search.tth;
01258 string reply_parameter = nick + " " + result_name + (char)0x05 + filesize + " 1/1" + (char)0x05 + temp_hub + " (" + ip + ":" + port + ")" + (char)0x05 + search.username;
01259 Console.WriteLine("Replying to passive search: " + reply_parameter);
01260 SendCommand("SR", reply_parameter);
01261 }
01262 }
01267 public void SendPassword(string password)
01268 {
01269 if (string.IsNullOrEmpty(password)) return;
01270 SendCommand("MyPass", password);
01271 }
01278 public void GetUserInfo(string username)
01279 {
01280
01281 SendCommand("GetInfo",username+" "+nick);
01282 }
01289 public void SendConnectToMe(string username)
01290 {
01291 if (my_connection_mode == ConnectionMode.Active)
01292 SendCommand("ConnectToMe", username + " " + my_ip + ":" + my_tcp_port);
01293 else SendCommand("RevConnectToMe",nick + " " + username);
01294 }
01300 public void SendConnectToMeV2(string username)
01301 {
01302 SendCommand("ConnectToMe", nick + " " + username + " " + my_ip + ":" + my_tcp_port);
01303 }
01307 public void SendMyInfo()
01308 {
01309 string temp_connection_mode = "";
01310
01311 if (my_connection_mode == Hub.ConnectionMode.Active) temp_connection_mode = "A";
01312 else if (my_connection_mode == Hub.ConnectionMode.Passive) temp_connection_mode = "P";
01313
01314
01315
01316 SendCommand("MyINFO", "$ALL " + nick + " "+my_description+"<" + my_name + " V:" + my_tag_version + ",M:" + temp_connection_mode + ",H:1/2/2,S:2>$ $"+my_connection_speed+(char)0x01+"$" + my_email + "$" + my_share_size.ToString() + "$");
01317
01318 }
01327 private void AddChatToHistory(string username, string message)
01328 {
01329 if (chat_history_max_length != 0)
01330 {
01331 if (chat_history.Count > chat_history_max_length)
01332 chat_history.RemoveAt(0);
01333 }
01334 ChatLine cline = new ChatLine(username, message);
01335 chat_history.Add(cline);
01336 if (MainChatLineReceived != null)
01337 MainChatLineReceived(this,cline);
01338
01339 }
01345 private void UserListAdd(string username)
01346 {
01347 user_list.Add(username);
01348 try
01349 {
01350 if (UserJoined != null)
01351 UserJoined(this, username);
01352 }
01353 catch (Exception ex)
01354 {
01355 Console.WriteLine("Exception in UserJoined: " + ex.Message);
01356 }
01357 }
01363 private void UserListRemove(string username)
01364 {
01365 user_list.Remove(username);
01366 try
01367 {
01368 if (UserQuit != null)
01369 UserQuit(this, username);
01370 }
01371 catch (Exception ex)
01372 {
01373 Console.WriteLine("Exception in UserJoined: " + ex.Message);
01374 }
01375 }
01381 private void UserListClear()
01382 {
01383 if(user_list.Count>0)
01384 foreach (string temp_user in user_list)
01385 {
01386 UserListRemove(temp_user);
01387 }
01388 user_list.Clear();
01389 }
01394 private string received_string_buffer = "";
01401 private void InterpretReceivedString(string received_string)
01402 {
01403
01404
01405
01406
01407 received_string_buffer += received_string;
01408
01409 int last_command_marker = received_string_buffer.LastIndexOf("|");
01410 if (last_command_marker != -1)
01411 {
01412 string command_strings = received_string_buffer.Substring(0, last_command_marker);
01413
01414
01415 received_string_buffer = received_string_buffer.Remove(0, last_command_marker);
01416 string[] received_strings = command_strings.Split("|".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
01417 for (int i = 0; i < received_strings.Length; i++)
01418 {
01419 if (received_strings[i].StartsWith("<"))
01420 {
01421 int user_end_marker = received_strings[i].IndexOf(">");
01422 if (user_end_marker != -1)
01423 {
01424 string user = received_strings[i].Substring(1, user_end_marker - 1);
01425 string message = "";
01426 if ((user_end_marker + 1) < received_strings[i].Length)
01427 message = received_strings[i].Substring(user_end_marker+1);
01428 AddChatToHistory(user, message);
01429 }
01430 else Console.WriteLine("Received a wrong chat line: " + received_strings[i]);
01431
01432 }
01433 else
01434 {
01435 if (received_strings[i].StartsWith("$")) InterpretCommand(received_strings[i]);
01436
01437 }
01438 }
01439 }
01440
01441 }
01446 private void InterpretCommand(string received_command)
01447 {
01448 int command_end = received_command.IndexOf(" ");
01449 if (command_end == -1) command_end = received_command.Length;
01450
01451 if (command_end != -1)
01452 {
01453 string parameter = "";
01454 string[] parameters ={ };
01455 string command = received_command.Substring(1);
01456 if (command_end != received_command.Length)
01457 {
01458 command = received_command.Substring(1, command_end - 1);
01459 parameter = received_command.Substring(command_end + 1);
01460 parameters = parameter.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
01461
01462 }
01463 switch (command)
01464 {
01465 case "HubName" :
01466
01467 name = parameter;
01468
01469 break;
01470
01471 case "Hello" :
01472
01473 if (!is_logged_in)
01474 {
01475 is_logged_in = true;
01476 SendCommand("Version", my_version);
01477 SendCommand("GetNickList");
01478 SendMyInfo();
01479
01480 try
01481 {
01482 if (LoggedIn != null)
01483 LoggedIn(this);
01484 }
01485 catch (Exception ex)
01486 {
01487 Console.WriteLine("Exception in LoggedIn: " + ex.Message);
01488 }
01489 }
01490 else
01491 {
01492
01493 UserListAdd(parameters[0]);
01494 }
01495 break;
01496
01497 case "Quit":
01498
01499 UserListRemove(parameters[0]);
01500 break;
01501
01502 case "NickList":
01503 Console.WriteLine("NickList Message received.");
01504 UserListClear();
01505 string[] temp_users = parameters[0].Split("$$".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
01506 foreach (string temp_user in temp_users)
01507 {
01508 UserListAdd(temp_user);
01509 }
01510 break;
01511
01512 case "OpList":
01513 op_list.Clear();
01514 string[] temp_ops = parameters[0].Split("$$".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
01515 foreach (string temp_op in temp_ops)
01516 {
01517 op_list.Add(temp_op);
01518 }
01519 break;
01520
01521 case "ConnectToMe":
01522 try
01523 {
01524 string peer_address = "";
01525 if (parameters.Length == 2)
01526 {
01527 peer_address = parameters[1];
01528 }
01529 else if (parameters.Length == 3)
01530 {
01531 peer_address = parameters[2];
01532 }
01533 else break;
01534 Peer peer = new Peer(peer_address);
01535 if (ConnectToMeReceived != null)
01536 ConnectToMeReceived(this, peer);
01537 }
01538 catch (Exception ex)
01539 {
01540 Console.WriteLine("Exception in ConnectToMe EventHandler: " + ex.Message);
01541 }
01542 break;
01543
01544 case "RevConnectToMe":
01545 SendConnectToMe(parameters[0]);
01546 break;
01547
01548 case "HubTopic":
01549
01550 topic = parameter;
01551 break;
01552
01553 case "UserCommand":
01554
01555
01556 break;
01557
01558 case "Search":
01559
01560 SearchParameters search = new SearchParameters();
01561 if(parameters[0].StartsWith("Hub:"))
01562 {
01563 search.mode = ConnectionMode.Passive;
01564 int username_start = parameters[0].IndexOf(":");
01565 if (username_start == -1 || username_start + 1 > parameters[0].Length) break;
01566 search.username = parameters[0].Substring(username_start + 1);
01567 }
01568 else
01569 {
01570 search.mode = ConnectionMode.Active;
01571 int port_start = parameters[0].IndexOf(":");
01572 if (port_start == -1 || port_start + 1 > parameters[0].Length) break;
01573 search.ip = parameters[0].Substring(0,port_start);
01574 try
01575 {
01576 search.port = int.Parse(parameters[0].Substring(port_start + 1));
01577 }
01578 catch (Exception ex)
01579 {
01580 Console.WriteLine("error parsing port in search: " + ex.Message);
01581 break;
01582 }
01583 }
01584
01585 char[] seps ={ '?' };
01586 string[] search_parameters = parameters[1].Split(seps,StringSplitOptions.RemoveEmptyEntries);
01587 if (search_parameters.Length < 4) break;
01588 if (search_parameters[0] == "F")
01589 search.size_restricted = false;
01590 else search.size_restricted = true;
01591 if (search_parameters[1] == "F")
01592 search.is_max_size = false;
01593 else search.is_max_size = true;
01594 try
01595 {
01596 search.size = long.Parse(search_parameters[2]);
01597 search.file_type = (SearchFileType)int.Parse(search_parameters[3]);
01598 }
01599 catch (Exception ex)
01600 {
01601 Console.WriteLine("error parsing ints in search: " + ex.Message);
01602 break;
01603 }
01604 if (search_parameters[4].StartsWith("TTH:") && search.file_type == SearchFileType.tth)
01605 search.tth = search_parameters[4].Substring(4);
01606 else search.search_string = search_parameters[4];
01607
01608 if (SearchReceived != null)
01609 SearchReceived(this,search);
01610 break;
01611
01612 case "Supports":
01613 supports = (string[])parameters.Clone();
01614 break;
01615
01616 case "UserIP":
01617 Console.WriteLine("UserIP Message received: " + parameter);
01618 break;
01619
01620 case "MCTo:":
01621 string mcto_username = parameters[1].Substring(1);
01622 int mcto_message_start = parameters[0].Length + parameters[1].Length + 2;
01623 if (mcto_message_start < parameter.Length)
01624 {
01625 string mcto_message = parameter.Substring(mcto_message_start);
01626 AddChatToHistory(mcto_username, mcto_message);
01627 }
01628 break;
01629
01630 case "To:":
01631
01632 string to_username = parameters[2];
01633 int to_message_start = parameters[0].Length + parameters[1].Length + parameters[2].Length + parameters[3].Length + 4;
01634 if (to_message_start < parameter.Length )
01635 {
01636 string to_message = parameter.Substring(to_message_start);
01637 ChatLine to_message_line = new ChatLine(to_username, to_message);
01638 if (PrivateChatLineReceived != null)
01639 PrivateChatLineReceived(this, to_message_line);
01640 }
01641 break;
01642
01643 case "SR":
01644
01645 SearchResults.SearchResult result = new SearchResults.SearchResult();
01646 result.ResultLine = parameter;
01647 try
01648 {
01649 if (SearchResultReceived != null)
01650 SearchResultReceived(this, result);
01651 }
01652 catch (Exception ex)
01653 {
01654 Console.WriteLine("Exception in event handler: " + ex.Message);
01655 }
01656
01657 break;
01658
01659 case "LogedIn":
01660 Console.WriteLine("LogedIn Message received: " + parameter);
01661
01662 break;
01663 case "MyINFO":
01664
01665 UserListAdd(parameters[1]);
01666 break;
01667 case "GetPass":
01668 Console.WriteLine("GetPass Message received: " + parameter);
01669 if (PasswordRequested != null)
01670 {
01671 string password = PasswordRequested(this);
01672 SendPassword(password);
01673 }
01674 break;
01675
01676 case "ForceMove":
01677
01678 if (MoveForced != null)
01679 {
01680 Hub dst_hub = this.Copy();
01681 MoveForced(this, dst_hub);
01682 }
01683 break;
01684
01685 case "ValidateDenide":
01686 Console.WriteLine("Nick: "+parameters[0]+" on Hub: " + name + " is already in use.");
01687 break;
01688
01689 case "HubIsFull":
01690 Console.WriteLine("Hub: " + name + " is full.");
01691 Disconnect();
01692 break;
01693
01694 case "Lock" :
01695
01696
01697
01698
01699
01700 if (parameters.Length > 1)
01701 {
01702 string key = parameters[0];
01703
01704 if (key.StartsWith("EXTENDEDPROTOCOL"))
01705 {
01706 is_extended_protocol = true;
01707
01708
01709 SendCommand("Supports", "UserCommand TTHSearch NoGetINFO NoHello ");
01710 }
01711
01712
01713 string decoded_key = L2K(key);
01714
01715 SendCommand("Key" , decoded_key);
01716 SendCommand("ValidateNick", nick);
01717
01718
01719 }
01720 break;
01721 default:
01722 Console.WriteLine("Unknown Command received: " + command + ", Parameter: " + parameter);
01723 break;
01724 }
01725 }
01726 else Console.WriteLine("Error interpreting command: " + received_command);
01727 }
01733 public Hub Copy()
01734 {
01735 Hub ret = new Hub();
01736 ret.address = this.address;
01737 ret.auto_reconnect = this.auto_reconnect;
01738 ret.country = this.country;
01739 ret.description = this.description;
01740 ret.ip = this.ip;
01741 ret.is_connecting = false;
01742 ret.is_connected = false;
01743 ret.is_extended_protocol = false;
01744 ret.is_grabbed = this.is_grabbed;
01745 ret.is_logged_in = false;
01746 ret.Connected = this.Connected;
01747 ret.Disconnected = this.Disconnected;
01748 ret.UnableToConnect = this.UnableToConnect;
01749 ret.LoggedIn = this.LoggedIn;
01750 ret.SearchResultReceived = this.SearchResultReceived;
01751 ret.UserJoined = this.UserJoined;
01752 ret.UserQuit = this.UserQuit;
01753 ret.MoveForced = this.MoveForced;
01754 ret.max_hubs = 0;
01755 ret.max_users = 0;
01756 ret.min_share = 0;
01757 ret.min_slots = 0;
01758 ret.my_connection_mode = this.my_connection_mode;
01759 ret.my_connection_speed = this.my_connection_speed;
01760 ret.my_email = this.my_email;
01761 ret.my_ip = this.my_ip;
01762 ret.my_name = this.my_name;
01763 ret.my_share_size = this.my_share_size;
01764 ret.my_tag_version = this.my_tag_version;
01765 ret.my_tcp_port = this.my_tcp_port;
01766 ret.my_udp_port = this.my_udp_port;
01767 ret.my_version = this.my_version;
01768 ret.name = this.name;
01769 ret.nick = this.nick;
01770 ret.op_list = new List<string>();
01771 ret.port = this.port;
01772 ret.shared = 0;
01773 ret.topic = this.topic;
01774 ret.user_list = new List<string>();
01775 ret.UserList = new List<string>();
01776 ret.users = 0;
01777 return (ret);
01778 }
01782 public void Ungrab()
01783 {
01784 Connected = null;
01785 Disconnected = null;
01786 UnableToConnect = null;
01787 LoggedIn = null;
01788 SearchResultReceived = null;
01789 UserJoined = null;
01790 UserQuit = null;
01791 MoveForced = null;
01792 is_grabbed = false;
01793 }
01794 #region Unit Testing
01798 [Test]
01799 public void TestLocalHubConnect()
01800 {
01801 Console.WriteLine("Test to connect to a local hub (remember to start some hub before).");
01802 bool wait = true;
01803 Hub hub = new Hub();
01804 hub.Address = "localhost";
01805 hub.Connected += delegate(Hub connected)
01806 {
01807 Console.WriteLine("Hub Connected");
01808
01809
01810 };
01811 hub.LoggedIn += delegate(Hub logged_in)
01812 {
01813 Console.WriteLine("Hub Logged in");
01814 wait = false;
01815 };
01816 hub.Disconnected += delegate(Hub disconnected)
01817 {
01818 if (wait)
01819 {
01820 Console.WriteLine("Test failed : Hub disconnected.");
01821 Assert.Fail("Test failed : Hub disconnected.");
01822 }
01823 };
01824 hub.UnableToConnect += delegate(Hub error)
01825 {
01826 Console.WriteLine("Test failed : Unable to connect to");
01827 };
01828 hub.IsGrabbedByClient = true;
01829 hub.Connect();
01830 Console.WriteLine("Waiting for hub events.");
01831 DateTime start = DateTime.Now;
01832 while (wait)
01833 {
01834 if (DateTime.Now - start > new TimeSpan(0, 0, 10))
01835 {
01836 Console.WriteLine("");
01837 Console.WriteLine("Operation took too long");
01838 wait = false;
01839 Assert.Fail("Operation took too long");
01840 }
01841 Console.Write(".");
01842 Thread.Sleep(250);
01843 }
01844 hub.Disconnect();
01845 Console.WriteLine("Local Hub Connect Test successful.");
01846 }
01847 #endregion
01848 }
01849 }