Eigene Dateien/Visual Studio 2005/Projects/DCPlusPlus/DCPlusPlus/Hub.cs

Go to the documentation of this file.
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   TODO 
00013  * add OnCommandHandler which apps can overwrite and if they dont want to act on a certain command
00014  * it calls DefaultCommandHandler
00015  * add support for user infos beside his name ;-)
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                 //check if port is included in adress
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         //TODO if nick differs and already loggedin send validatenick again to change nickname
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         //TODO change to a userinfo holding class list instead of just the username
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         //TODO create a thread safe enumerator for this
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,// = "28.8Kbps",
00768             kbps_33_6,//  = "33.6Kbps",
00773             kbps_56,//  = "56Kbps",
00778             satellite,//  = "Satellite",
00783             isdn,//  = "ISDN",
00788             dsl,//  = "DSL",
00793             cable,//  = "Cable",
00798             lan_t1,//  = "LAN(T1)",
00803             lan_t3,//  = "LAN(T3)",
00808             modem,//  = "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             //,Socks5
00840         }
00841         //Socks5 is not implemented atm
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             //Disconnect();
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                         //if(receive_operation!=null) socket //socket.EndReceive(receive_operation);
00894                         socket.Shutdown(SocketShutdown.Both);
00895                         //Thread.Sleep(10);
00896                         socket.Close();
00897                         socket = null;
00898                         //receive_operation = null;
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             {//better handling of fast user retries
00928                 error_code = ErrorCodes.UserDisconnect;
00929                 Disconnect();
00930             }
00931             if (!is_connected)
00932             {
00933                 //Console.WriteLine("Connecting to Hub: "+name);
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                     //IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse(address),port);
00942                     //IPHostEntry ip = Dns.GetHostEntry(address);
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(); // correct the ip string
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) //TODO i know , or correctly i dont know ...
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                     //Console.WriteLine("Successfully connected to Hub: " + name);
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;//TODO change to disconnect();
01053             try
01054             {
01055                 int received_bytes = receive_socket.EndReceive(result);
01056                 if (received_bytes > 0)
01057                 {
01058                     //string received_string = Encoding.ASCII.GetString(receive_buffer, 0, received_bytes);
01059                     string received_string = System.Text.Encoding.Default.GetString(receive_buffer, 0, received_bytes);
01060                     //Console.WriteLine("Received a string: "+received_string);
01061                     //interpret string and act accordingly
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                 //socket.Send(Encoding.UTF8.GetBytes(send_string), SocketFlags.None);
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             //"Search Hub:[DE]Test F?F?0?1?extras"
01201             //string send_string = "<" + nick + "> " + message + "|";
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         {//TODO finish this 
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             //check if info changed and a myinfo command is actually needed
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             //else if (my_connection_mode == Hub.ConnectionMode.Socks5) temp_connection_mode = "5";
01314             //SendCommand("MyINFO", "$ALL " + parameters[0] + " <" + my_name + " V:" + my_tag_version + ",M:" + temp_connection_mode + ",H:0/0/0,S:2>$ $Cable1$" + my_email + "$" + my_share_size.ToString() + "$");
01315             //TODO add user flag support and hubs accounting
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             //                                                                                                                                             ,O:0           
01318         }
01327         private void AddChatToHistory(string username, string message)
01328         {
01329             if (chat_history_max_length != 0)
01330             {//using max history -> delete first line added to list
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             // possible strings
01404             //$command|
01405             //<chat>
01406             //| 
01407             received_string_buffer += received_string;
01408             //if (received_string_buffer.IndexOf("|") == -1) return;//incomplete command
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                 //received_string_buffer = received_string_buffer.Substring(last_command_marker);
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                         //Console.WriteLine("chat message on hub: " + name + " - " + received_strings[i]);
01432                     }
01433                     else
01434                     {
01435                         if (received_strings[i].StartsWith("$")) InterpretCommand(received_strings[i]);
01436                         //else Console.WriteLine("Received a non command line: " + received_strings[i]);
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                     //Console.WriteLine("Command: '" + command + "' ,Parameter(" + parameters.Length + "): '" + parameter + "'");
01462                 }
01463                 switch (command)
01464                 {
01465                     case "HubName" :
01466                         //Console.WriteLine("Hubname Command received: " + parameter);
01467                         name = parameter;
01468                         //fire nameChange event
01469                         break;
01470 
01471                     case "Hello" :
01472                         //Console.WriteLine("Hello Command received: " + parameters[0]);
01473                         if (!is_logged_in)
01474                         {
01475                             is_logged_in = true;
01476                             SendCommand("Version", my_version);
01477                             SendCommand("GetNickList");
01478                             SendMyInfo();
01479                             //Console.WriteLine("Logged in Hub: "+name);
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                         {//new user announced by server
01492                             //Console.WriteLine("User "+parameters[0]+" has joined Hub: "+name);
01493                             UserListAdd(parameters[0]);
01494                         }
01495                         break;
01496 
01497                     case "Quit":
01498                         //Console.WriteLine("User "+parameters[0]+" has left Hub: "+name);
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); //add username also, to counter possible network attacks 
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                         //topic = parameters[0];
01550                         topic = parameter;
01551                         break;
01552 
01553                     case "UserCommand":
01554                         //Console.WriteLine("User Command received: "+parameter);
01555                         //TODO support user context menu entries
01556                         break;
01557 
01558                     case "Search":
01559                         //Console.WriteLine("Search Command received: "+parameter);
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); //to skip the leading $
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                         //Console.WriteLine("Private Message received: " + parameter);
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                         //Console.WriteLine("Search result received: " + parameter);
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                         //what the hell is this and who forgot to take some english lessons ?
01662                         break;
01663                     case "MyINFO":
01664                         //Console.WriteLine("MyINFO Message received: " + parameter);
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                         //Console.WriteLine("FORCE MOVE NOT IMPLEMENTED");
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                         //Console.WriteLine("Lock Command received: "+parameter);
01696                         //int key_end = parameter.IndexOf(" ");
01697                         //if (key_end != -1)
01698                         //{
01699                             //string key = parameter.Substring(0, key_end);
01700                         if (parameters.Length > 1)
01701                         {
01702                             string key = parameters[0];
01703                             //Console.WriteLine("Key: " + key);
01704                             if (key.StartsWith("EXTENDEDPROTOCOL"))
01705                             {
01706                                 is_extended_protocol = true;
01707                                 //Console.WriteLine("Hub is using the dc++ protocol enhancements.");
01708                                 //SendCommand("Supports", "UserCommand NoGetINFO NoHello UserIP2 TTHSearch ZPipe0 GetZBlock ");
01709                                 SendCommand("Supports", "UserCommand TTHSearch NoGetINFO NoHello ");
01710                             }
01711 
01712                             //string decoded_key = MyLockToKey(key);
01713                             string decoded_key = L2K(key);
01714                             //Console.WriteLine("Decoded key: " + decoded_key);
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                 //Assert.IsTrue(!string.IsNullOrEmpty(external_ip), "no ip address fetched");
01809                 //wait = false;
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 }

Generated on Wed Mar 7 19:09:20 2007 for DCPlusPlus by  doxygen 1.5.1-p1