/// <summary> /// Creates a new instance of <see cref="InvitationEventArgs"/>. /// </summary> /// <param name="sender">The sender of the invitation.</param> /// <param name="recipient">The recipient of the invitation.</param> /// <param name="channel">The channel the invitation is for.</param> public InvitationEventArgs(IrcIdentity sender, IrcString recipient, IrcString channel) : base(sender, recipient) { Throw.If.Null(channel, "channel"); Channel = channel; }
/// <summary> /// Creates an instance of <see cref="ChatMessageEventArgs"/>. /// </summary> /// <param name="sender">The sender, or <c>null</c> if the message has no sender.</param> /// <param name="recipient">The recipient.</param> /// <param name="message">The chat message.</param> public ChatMessageEventArgs(IrcIdentity sender, IrcString recipient, IrcString message) : base(sender, recipient) { Throw.If.Null(message, "message"); Message = message; }
/// <summary> /// Creates a new instance of <see cref="KickEventArgs"/>. /// </summary> /// <param name="sender">The user doing the kicking.</param> /// <param name="recipient">The user being kicked out of the channel.</param> /// <param name="channel">The channel the user is being kicked from.</param> /// <param name="reason">The reason the user is being kicked, or <c>null</c> if none is given.</param> public KickEventArgs(IrcIdentity sender, IrcString recipient, IrcString channel, IrcString reason) : base(sender, recipient) { Throw.If.Null(channel, "channel"); Channel = channel; Reason = reason; }
/// <summary> /// Creates a new instance of <see cref="ModeEventArgs"/>. /// </summary> /// <param name="sender">The user changing the mode.</param> /// <param name="recipient">The target of the mode change. This may be a channel or a user.</param> /// <param name="command">The mode change, for example +o or +v.</param> /// <param name="parameters">The mode change parameters.</param> public ModeEventArgs(IrcIdentity sender, IrcString recipient, IrcString command, IrcString[] parameters) : base(sender, recipient) { Throw.If.Null(command, "command").NullElements(parameters, "parameters"); Command = command; _parameters = (IrcString[])parameters.Clone(); }
/// <summary> /// Checks if the nickname is valid. The definition used by this test is somewhat loose. /// /// Nicknames may not contain spaces, commas, NULL, BELL, CR, LF, #, &, @, or +. /// </summary> /// <param name="nickname">The nickname to test.</param> /// <returns><c>true</c> if the name is valid.</returns> public static bool IsNickname(IrcString nickname) { if (nickname == null) { return(false); } string errorMessage; return(ValidateNickname(nickname, out errorMessage)); }
/// <summary> /// Checks if the channel name is valid. The definition used by this test is somewhat loose. /// /// Channel names may not contain spaces, commas, NULL, BELL, CR, or LF, and must start with # or &. /// </summary> /// <param name="channel">The channel name to test.</param> /// <returns><c>true</c> if the name is valid.</returns> public static bool IsChannelName(IrcString channel) { if (channel == null) { return(false); } string errorMessage; return(ValidateChannel(channel, out errorMessage)); }
internal static bool ValidateIdentityPart(IrcString identityPart, out string errorMessage) { if (!ValidateParameter(identityPart, false, out errorMessage)) { return(false); } if (identityPart.Contains((byte)'@') || identityPart.Contains((byte)'!')) { errorMessage = "Identity parts may not contain @ or !."; return(false); } return(true); }
internal static bool ValidateChannel(IrcString channel, out string errorMessage) { if (!ValidateTarget(channel, out errorMessage)) { return(false); } if (channel[0] != (byte)'#' && channel[0] != (byte)'&') { errorMessage = "Channel names must begin with # or &."; return(false); } return(true); }
internal static bool ValidateParameter(IrcString parameter, bool trailing, out string errorMessage) { errorMessage = null; if (!trailing && (parameter.Contains((byte)' ') || parameter.StartsWith(":"))) { errorMessage = "Only the trailing parameter may contain spaces or start with a colon."; return(false); } if (parameter.Contains(0) || parameter.Contains(13) || parameter.Contains(10)) { errorMessage = "IRC does not allow embedded NULL, CR, or LF."; return(false); } return(true); }
internal static bool ValidateNickname(IrcString nickname, out string errorMessage) { if (!ValidateTarget(nickname, out errorMessage)) { return(false); } if (nickname.Contains((byte)'#') || nickname.Contains((byte)'&') || nickname.Contains((byte)'@') || nickname.Contains((byte)'+')) { errorMessage = "Nicknames may not contain #, &, @, or +."; return(false); } return(true); }
internal static bool ValidateTarget(IrcString target, out string errorMessage) { if (!ValidateParameter(target, false, out errorMessage)) { return(false); } if (target.Length == 0) { errorMessage = "Targets may not be zero-byte."; return(false); } if (target.Contains(7) || target.Contains((byte)',')) { errorMessage = "Targets may not contain BELL or a comma."; return(false); } return(true); }
/// <summary> /// Creates a new instance of <see cref="SimpleMessageEventArgs"/>. /// </summary> /// <param name="message">The message.</param> public SimpleMessageEventArgs(IrcString message) { Throw.If.Null(message, "message"); Message = message; }
/// <summary> /// Creates a new instance of <see cref="NameListEndEventArgs"/>. /// </summary> /// <param name="channel">The channel the name list has been sent for.</param> public NameListEndEventArgs(IrcString channel) { Throw.If.Null(channel, "channel"); Channel = channel; }
/// <summary> /// Creates a new instance of <see cref="NameListReplyEventArgs"/>. /// </summary> /// <param name="channel">The channel this list pertains to.</param> /// <param name="names">The names of users in the channel.</param> public NameListReplyEventArgs(IrcString channel, IrcString[] names) { Throw.If.Null(channel, "channel").NullElements(names, "names"); Channel = channel; _names = (IrcString[])names.Clone(); }
/// <summary> /// Creates a new instance of <see cref="ChannelTopicChangeEventArgs"/>. /// </summary> /// <param name="channel">The channel name.</param> /// <param name="newTopic">The new channel topic.</param> public ChannelTopicChangeEventArgs(IrcString channel, IrcString newTopic) { Throw.If.Null(channel, "channel").Null(newTopic, "newTopic"); Channel = channel; NewTopic = newTopic; }
/// <summary> /// Creates a new instance of <see cref="ChannelListEntryEventArgs"/>. /// </summary> /// <param name="channel">The channel name.</param> /// <param name="userCount">The number of users in the channel.</param> /// <param name="topic">The channel topic.</param> public ChannelListEntryEventArgs(IrcString channel, int userCount, IrcString topic) { Throw.If.Null(channel, "channel").Negative(userCount, "userCount").Null(topic, "topic"); Channel = channel; UserCount = userCount; Topic = topic; }
/// <summary> /// The on name list. /// </summary> /// <param name="ircString"> /// The irc string. /// </param> internal void OnNameList(IrcString[] ircString) { foreach (IrcString name in ircString) { this.EvaluateUserName(name); } }
/// <summary> /// Tries to read a buffer and parse out an IRC statement. /// Additionally, on failure, the reason for failure is returned. /// </summary> /// <param name="buffer">The buffer to read from.</param> /// <param name="offset">The offset to begin reading. The parser may advance this, even if parsing fails.</param> /// <param name="count">The maximum number of bytes to read.</param> /// <param name="statement">The statement, if parsing succeeds, or <c>null</c>.</param> /// <param name="parseResult">The result of parsing. On failure, this is the reason for the failure.</param> /// <returns><c>true</c> if parsing succeeded.</returns> public static bool TryParse(byte[] buffer, ref int offset, int count, out IrcStatement statement, out IrcStatementParseResult parseResult) { Throw.If.Null(buffer, "buffer"); string errorMessage = null; IrcString[] parts; statement = null; parseResult = IrcStatementParseResult.NothingToParse; // First, skip all initial CR/LF. SkipCrlf(buffer, ref offset, ref count); // See if we've got a CR or LF anywhere. int crlfIndex = IrcString.IndexOf(buffer, @byte => @byte == 13 || @byte == 10, offset, count); if (crlfIndex == -1) { if (count >= IrcConstants.MaxStatementLength) { parseResult = IrcStatementParseResult.StatementTooLong; } return(false); } // OK, let's get our string. var @string = new IrcString(buffer, offset, crlfIndex - offset); #if DEBUG var debugString = @string; #endif offset += @string.Length + 1; count -= @string.Length + 1; SkipCrlf(buffer, ref offset, ref count); if (crlfIndex >= IrcConstants.MaxStatementLength) { parseResult = IrcStatementParseResult.StatementTooLong; return(false); } // Do we have a prefix? statement = new IrcStatement(); if (@string.Length >= 1 && @string[0] == (byte)':') { parts = @string.Split((byte)' ', 2); var sourceString = parts[0].Substring(1); IrcIdentity source; if (!IrcIdentity.TryParse(sourceString, out source)) { goto invalid; } statement.Source = source; @string = parts.Length >= 2 ? parts[1] : IrcString.Empty; } // Now get the command. parts = @string.Split((byte)' ', 2); statement.Command = parts[0]; @string = parts.Length >= 2 ? parts[1] : IrcString.Empty; // Parameters, now... while (@string.Length > 0) { if (@string[0] == (byte)':') { statement.Parameters.Add(@string.Substring(1)); break; } else { parts = @string.Split((byte)' ', 2); statement.Parameters.Add(parts[0]); if (parts.Length == 1) { break; } @string = parts[1]; } } // We're done. If everything's kosher, we'll return true. if (!IrcValidation.ValidateStatement(statement, out errorMessage)) { goto invalid; } parseResult = IrcStatementParseResult.OK; return(true); invalid: #if DEBUG Console.WriteLine("Invalid statement '{0}' (error '{1}').", debugString, errorMessage); #endif statement = null; parseResult = IrcStatementParseResult.InvalidStatement; return(false); }
/// <summary> /// Creates a new instance of <see cref="NameChangeEventArgs"/>. /// </summary> /// <param name="identity">The user who is changing their nickname.</param> /// <param name="newName">The new nickname.</param> public NameChangeEventArgs(IrcIdentity identity, IrcString newName) { Throw.If.Null(identity, "identity").Null(newName, "newName"); Identity = identity; NewName = newName; }
/// <summary> /// Creates a new instance of <see cref="TargetedMessageEventArgs"/>. /// </summary> /// <param name="sender">The sender, or <c>null</c> if the message has no sender.</param> /// <param name="recipient">The recipient.</param> public TargetedMessageEventArgs(IrcIdentity sender, IrcString recipient) { Throw.If.Null(recipient, "recipient"); Sender = sender; Recipient = recipient; }
/// <summary> /// Creates a new instance of <see cref="QuitEventArgs"/>. /// </summary> /// <param name="identity">The user who disconnected.</param> /// <param name="quitMessage">The quit message, or <c>null</c> if none was given.</param> public QuitEventArgs(IrcIdentity identity, IrcString quitMessage) { Throw.If.Null(identity, "identity"); Identity = identity; QuitMessage = quitMessage; }
/// <summary> /// Creates an IRC statement. /// </summary> /// <param name="source">The source of the statement, if any. This is called the prefix in the IRC specification.</param> /// <param name="command">The command or three-digit reply code.</param> /// <param name="parameters">The parameters of the command.</param> public IrcStatement(IrcIdentity source, IrcString command, params IrcString[] parameters) { Source = source; Command = command; Parameters = new List <IrcString>(parameters); }