/// <summary> /// Invokes the Parsers. /// </summary> /// <param name="s">The server object.</param> /// <param name="c">The channel triggered on.</param> /// <param name="u">The user triggered from.</param> /// <param name="cu">The channeluser triggered from.</param> /// <param name="text">The offending text.</param> /// <param name="pt">The Parse Types to invoke on.</param> private static void InvokeParsers(Server s, Channel c, User u, ChannelUser cu, string text, IRCEvents.ParseTypes pt) { bool pcount = s.EventObject.Parses.Count > 0; bool wcount = s.EventObject.WildcardParses.Count > 0; if ( pcount || wcount ) { IRCEvents.ParseReturns pr = CreateParseReturns( s.ServerID, c, u, cu, text ); if ( pcount ) s.QueueData( ParseInvocation( pr.Text, s.EventObject, pr, pt, false ) ); if ( wcount ) s.QueueData( ParseInvocation( pr.Text, s.EventObject, pr, pt, true ) ); } }
/// <summary> /// Invokes the parses (if match exists) with a specific ParseReturns struct. /// </summary> /// <param name="toParse">The string to parse.</param> /// <param name="irce">The IRCEvents object to retrieve parses from.</param> /// <param name="pr">The parse returns struct.</param> /// <param name="pt">The parse type of the firing event.</param> /// <param name="doWildcards">True if we are doing the wildcard parses. False if not.</param> /// <returns>The raw data to queue into the server.</returns> private static string[][] ParseInvocation(string toParse, IRCEvents irce, IRCEvents.ParseReturns pr, IRCEvents.ParseTypes pt, bool doWildCards) { List<IRCEvents.Parse> parses = doWildCards ? irce.WildcardParses : irce.Parses; int n = parses.Count; string[][] returns = new string[n][]; string[] splits = doWildCards ? null : toParse.Split( ' ' ); /*if ( splits.Length > 1 ) TODO: Evaluate if this is a good feature. pr.Text = toParse.Substring( toParse.IndexOf( ' ' ) + 1 );*/ //TODO: You set it up so that parses could be bsearched then you linearly search them. for ( int i = 0; i < n; i++ ) { if ( ( pt & parses[i].ParseTypes ) == 0 ) continue; bool continueWithCall = true; //True right now. if ( doWildCards ) continueWithCall = IRCHost.WildcardCompare( parses[0].ParseString, toParse ) == 0; else continueWithCall = splits[0].Equals( parses[i].ParseString ); if ( !continueWithCall ) //True if the parse went through correctly. continue; PrivelegeContainer pc = pr.User.UserAttributes != null ? pr.User.UserAttributes.Privegeles : null; if ( pc == null || !pc.HasPrivelege( Priveleges.SuperUser ) ) { object[] privreq = parses[i].Function.Method.GetCustomAttributes( false ); for ( int j = 0; continueWithCall && j < privreq.Length; j++ ) { if ( privreq[j].GetType().Equals( typeof( PrivelegeRequiredAttribute ) ) ) { PrivelegeRequiredAttribute pra = (PrivelegeRequiredAttribute)privreq[j]; continueWithCall = pc != null && pc.HasPrivelege( pra.Required ); } if ( continueWithCall && privreq[j].GetType().Equals( typeof( UserLevelRequiredAttribute ) ) ) { UserLevelRequiredAttribute ura = (UserLevelRequiredAttribute)privreq[j]; continueWithCall = pc != null && pc.NumericalLevel >= ura.Required; } } } if ( !continueWithCall ) continue; parses[i].FieldInfo.SetValue( parses[i].InstanceOf, pr ); parses[i].Function.Invoke(); FieldInfo fi = parses[i].InstanceOf.GetType().GetField( "returns", BindingFlags.GetField | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static ); returns[i] = (string[])fi.GetValue( parses[i].InstanceOf ); } return returns; }
/// <summary> /// Creates a server from a ServerConfig with a parameter /// to provide an interface for logging. /// </summary> /// <param name="config">The configuration to build the Server from.</param> /// <param name="logFunction">The function to call to log text for the application.</param> public Server(Configuration.ServerConfig config, Project2QService.WriteLogFunction logFunction) { //Instantiate and load databases uc = new UserCollection(); cc = new ChannelCollection(); uc.LoadRegisteredUsers( "userdb\\" + config.Name + ".udb" ); //Rip up this little guy to help us out :D currentHost = new IRCHost(); currentIP = null; this.authmode = !File.Exists( "userdb\\" + config.Name + ".udb" ); this.writeLogFunction = logFunction; //Assign a Server ID this.serverId = Server.NextServerId; if ( this.serverId == -1 ) throw new OverflowException( "Too many servers created." ); servers[serverId] = this; //Save the configuration. this.config = config; //Tie default static handlers together for this instance of IRCEvents. irce = new IRCEvents(); //Initialize the socket pipe before the modules. Modules are scary. state = State.Disconnected; socketPipe = new SocketPipe( this.serverId, config.RetryTimeout, config.OperationTimeout, config.SendInhibit, config.SocketBufferSize ); //Default values for now, get them from config later plz. socketPipe.OnDisconnect += new SocketPipe.NoParams( this.OnDisconnect ); socketPipe.OnReceive += new SocketPipe.ReceiveData( this.OnReceive ); }