/// <summary> /// Constructor of a DCC Chat for a Incoming DCC Chat Request /// </summary> /// <param name="irc">IrcFeature Class</param> /// <param name="externalIpAdress">Our externally reachable IP Adress</param> /// <param name="e">The Ctcp Event which initiated this constructor</param> internal DccChat(IrcFeatures irc, IPAddress externalIpAdress, CtcpEventArgs e) { Irc = irc; ExternalIPAdress = externalIpAdress; User = e.Data.Nick; if (e.Data.MessageArray.Length > 4) { bool okIP = Int64.TryParse(e.Data.MessageArray[3], out long ip); bool okPo = Int32.TryParse(FilterMarker(e.Data.MessageArray[4]), out int port); // port 0 = passive if ((e.Data.MessageArray[2] == "chat") && okIP && okPo) { RemoteEndPoint = new IPEndPoint(IPAddress.Parse(DccIntToHost(ip)), port); if (e.Data.MessageArray.Length > 5 && e.Data.MessageArray[5] != "T") { AcceptRequest(); // Since we initated the Request, we accept DCC return; // No OnDccChatRequestEvent Event! (we know that we want a connection) } DccChatRequestEvent(new DccEventArgs(this)); return; } else { irc.SendMessage(SendType.CtcpReply, e.Data.Nick, "ERRMSG DCC Chat Parameter Error"); } } else { irc.SendMessage(SendType.CtcpReply, e.Data.Nick, "ERRMSG DCC Chat not enough parameters"); } isValid = false; }
internal DccSend(IrcFeatures irc, IPAddress externalIpAdress, CtcpEventArgs e) { /* Remote Request */ Irc = irc; _DirectionUp = false; User = e.Data.Nick; if (e.Data.MessageArray.Length > 4) { long filesize = 0; if (e.Data.MessageArray.Length > 5) { bool okFs = Int64.TryParse(FilterMarker(e.Data.MessageArray[5]), out filesize); _Filesize = filesize; _Filename = e.Data.MessageArray[2].Trim('"'); } if (Int64.TryParse(e.Data.MessageArray[3], out long ip) && Int32.TryParse(e.Data.MessageArray[4], out int port)) // port 0 = passive { RemoteEndPoint = new IPEndPoint(IPAddress.Parse(DccIntToHost(ip)), port); DccSendRequestEvent(new DccSendRequestEventArgs(this, e.Data.MessageArray[2], filesize)); return; } irc.SendMessage(SendType.CtcpReply, e.Data.Nick, "ERRMSG DCC Send Parameter Error"); } else { irc.SendMessage(SendType.CtcpReply, e.Data.Nick, "ERRMSG DCC Send not enough parameters"); } }
private async Task CtcpClientInfoDelegate(CtcpEventArgs e) { string clientInfo = "CLIENTINFO"; foreach (KeyValuePair <string, CtcpDelegate> kvp in CtcpDelegates) { clientInfo = clientInfo + " " + kvp.Key.ToUpper(); } await SendMessage(SendType.CtcpReply, e.Data.Nick, clientInfo); }
internal bool SetRemote(CtcpEventArgs e) { // port 0 = passive if (Int64.TryParse(e.Data.MessageArray[3], out long ip) && Int32.TryParse(e.Data.MessageArray[4], out int port)) { RemoteEndPoint = new IPEndPoint(IPAddress.Parse(DccIntToHost(ip)), port); return(true); } return(false); }
/// <summary> /// This is the correct Rfc Ping Delegate, which is not used because all other clients do not use the PING According to RfC /// </summary> /// <param name="e"></param> private async Task CtcpRfcPingDelegate(CtcpEventArgs e) { if (e.Data.Message.Length > 7) { await SendMessage(SendType.CtcpReply, e.Data.Nick, "PONG " + e.Data.Message.Substring(6, (e.Data.Message.Length - 7))); } else { await SendMessage(SendType.CtcpReply, e.Data.Nick, "PONG"); } }
private async Task CtcpPingDelegate(CtcpEventArgs e) { if (e.Data.Message.Length > 7) { await SendMessage(SendType.CtcpReply, e.Data.Nick, "PING " + e.Data.Message.Substring(6, (e.Data.Message.Length - 7))); } else { await SendMessage(SendType.CtcpReply, e.Data.Nick, "PING"); //according to RFC, it should be PONG! } }
private async Task CtcpRequestsHandler(object sender, CtcpEventArgs e) { if (CtcpDelegates.ContainsKey(e.CtcpCommand)) { await CtcpDelegates[e.CtcpCommand].Invoke(e); } else { /* No CTCP Handler for this Command */ } RemoveInvalidDccConnections(); }
internal bool TryResume(CtcpEventArgs e) { if (User == e.Data.Nick && e.Data.MessageArray.Length > 4 && _Filename == e.Data.MessageArray[2].Trim('"')) { Int64.TryParse(FilterMarker(e.Data.MessageArray[4]), out long offset); if (_File.CanSeek) { if (e.Data.MessageArray.Length > 5) { Irc.SendMessage(SendType.CtcpRequest, e.Data.Nick, "DCC ACCEPT " + e.Data.MessageArray[2] + " " + e.Data.MessageArray[3] + " " + e.Data.MessageArray[4] + " " + FilterMarker(e.Data.MessageArray[5])); } else { Irc.SendMessage(SendType.CtcpRequest, e.Data.Nick, "DCC ACCEPT " + e.Data.MessageArray[2] + " " + e.Data.MessageArray[3] + " " + FilterMarker(e.Data.MessageArray[4])); } _File.Seek(offset, SeekOrigin.Begin); SentBytes = offset; return(true); } Irc.SendMessage(SendType.CtcpRequest, e.Data.Nick, "ERRMSG DCC File not seekable"); } return(false); }
private async Task CtcpFingerDelegate(CtcpEventArgs e) => await SendMessage(SendType.CtcpReply, e.Data.Nick, "FINGER Don't touch little Helga there! ");//SendMessage(SendType.CtcpReply, e.Data.Nick, "FINGER " + this.Realname + " (" + this.Email + ") Idle " + this.Idle + " seconds (" + ((string.IsNullOrEmpty(this.Reason))?this.Reason:"-") + ") " ); private async Task CtcpDccDelegate(CtcpEventArgs e) { if (e.Data.MessageArray.Length < 2) { await SendMessage(SendType.CtcpReply, e.Data.Nick, "ERRMSG DCC missing parameters"); } else { switch (e.Data.MessageArray[1]) { case "CHAT": var chat = new DccChat(this, ExternalIpAdress, e); _DccConnections.Add(chat); ThreadPool.QueueUserWorkItem(new WaitCallback(chat.InitWork)); break; case "SEND": if (e.Data.MessageArray.Length > 6 && (FilterMarker(e.Data.MessageArray[6]) != "T")) { if (!Int64.TryParse(FilterMarker(e.Data.MessageArray[6]), out long session)) { break; } foreach (DccConnection dc in _DccConnections) { if (dc.SessionId == session) { ((DccSend)dc).SetRemote(e); ((DccSend)dc).AcceptRequest(null, 0); return; } } await SendMessage(SendType.CtcpReply, e.Data.Nick, "ERRMSG Invalid passive DCC"); } else { var send = new DccSend(this, ExternalIpAdress, e); _DccConnections.Add(send); ThreadPool.QueueUserWorkItem(new WaitCallback(send.InitWork)); } break; case "RESUME": foreach (DccConnection dc in _DccConnections) { if (dc is DccSend dcs && dcs.TryResume(e)) { return; } } await SendMessage(SendType.CtcpReply, e.Data.Nick, "ERRMSG Invalid DCC RESUME"); break; case "ACCEPT": foreach (DccConnection dc in _DccConnections) { if (dc is DccSend dcs && dcs.TryAccept(e)) { return; } } await SendMessage(SendType.CtcpReply, e.Data.Nick, "ERRMSG Invalid DCC ACCEPT"); break; case "XMIT": await SendMessage(SendType.CtcpReply, e.Data.Nick, "ERRMSG DCC XMIT not implemented"); break; default: await SendMessage(SendType.CtcpReply, e.Data.Nick, "ERRMSG DCC " + e.CtcpParameter + " unavailable"); break; } } }
private async Task CtcpFingerDelegate(CtcpEventArgs e) => await SendMessage(SendType.CtcpReply, e.Data.Nick, "FINGER Don't touch little Helga there! ");//SendMessage(SendType.CtcpReply, e.Data.Nick, "FINGER " + this.Realname + " (" + this.Email + ") Idle " + this.Idle + " seconds (" + ((string.IsNullOrEmpty(this.Reason))?this.Reason:"-") + ") " );
private async Task CtcpSourceDelegate(CtcpEventArgs e) => await SendMessage(SendType.CtcpReply, e.Data.Nick, "SOURCE " + (CtcpSource ?? "http://smartirc4net.meebey.net"));
private async Task CtcpUrlDelegate(CtcpEventArgs e) => await SendMessage(SendType.CtcpReply, e.Data.Nick, "URL " + (CtcpUrl ?? "http://www.google.com"));
private async Task CtcpUserInfoDelegate(CtcpEventArgs e) => await SendMessage(SendType.CtcpReply, e.Data.Nick, "USERINFO " + (CtcpUserInfo ?? "No user info given."));
private async Task CtcpTimeDelegate(CtcpEventArgs e) => await SendMessage(SendType.CtcpReply, e.Data.Nick, "TIME " + DateTime.Now.ToString("r"));
private async Task CtcpVersionDelegate(CtcpEventArgs e) => await SendMessage(SendType.CtcpReply, e.Data.Nick, "VERSION " + (CtcpVersion ?? VersionString));
internal bool TryAccept(CtcpEventArgs e) => User == e.Data.Nick && e.Data.MessageArray.Length > 4 && _Filename == e.Data.MessageArray[2].Trim('"') && AcceptRequest(null, 0);