Advertisement
Guest User

Untitled

a guest
Jan 14th, 2018
300
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pascal 40.37 KB | None | 0 0
  1. unit EvilIrc;
  2.  
  3. interface
  4.  
  5. uses
  6.     Windows, Classes, SysUtils,
  7.     EvilStrings, EvilWinUtils, EvilClasses, EvilTCPSocket;
  8.  
  9. const
  10.     CWHO: string     = 'WHO';
  11.     CTIME: string    = 'TIME';
  12.     CPASS: string    = 'PASS';
  13.     CNICK: string    = 'NICK';
  14.     CUSER: string    = 'USER';
  15.     CPING: string    = 'PING';
  16.     CPONG: string    = 'PONG';
  17.     CJOIN: string    = 'JOIN';
  18.     CPART: string    = 'PART';
  19.     CKICK: string    = 'KICK';
  20.     CMODE: string    = 'MODE';
  21.     CQUIT: string    = 'QUIT';
  22.     CKILL: string    = 'KILL';
  23.     CTOPIC: string   = 'TOPIC';
  24.     CNAMES: string   = 'NAMES';
  25.     CERROR: string   = 'ERROR';
  26.     CINVITE: string  = 'INVITE';
  27.     CNOTICE: string  = 'NOTICE';
  28.     CACTION: string  = 'ACTION';
  29.     CFINGER: string  = 'FINGER';
  30.     CVERSION: string = 'VERSION';
  31.     CWALLOPS: string = 'WALLOPS';
  32.     CPRIVMSG: string = 'PRIVMSG';
  33.  
  34.     CBold: char      = #$02;
  35.     CColor: char     = #$03;
  36.     COrdinary: char  = #$0F;
  37.     CReverse: char   = #$16;
  38.     CItalic: char    = #$1D;
  39.     CUnderline: char = #$1F;
  40.  
  41. type
  42.     { Forward declarations }
  43.     TIrc = class;
  44.  
  45.     { TIrcMsgParser }
  46.     TIrcMsgParser = class
  47.     strict private
  48.     type
  49.         TSourceType = (stServer, stUser, stNotPresent);
  50.  
  51.         TWordMarker = record
  52.             Start: word;
  53.             Length: word;
  54.         end;
  55.     strict private
  56.         FRaw           : string; { Parsed IRC command }
  57.         FSourceType    : TSourceType;
  58.         FSource        : TWordMarker;
  59.         FSourceNickName: TWordMarker;
  60.         FSourceUserName: TWordMarker;
  61.         FSourceHostName: TWordMarker;
  62.         FCommand       : TWordMarker;
  63.         FParams        : TWordMarker;
  64.         FParamsArray   : array of TWordMarker;
  65.         FParamCount    : integer;
  66.         FTrailings     : TWordMarker;
  67.         FTrailingsArray: array of TWordMarker;
  68.         FTrailingCount : integer;
  69.         function GetParam(aIndex: integer): string;
  70.         function GetTrailing(aIndex: integer): string;
  71.     private
  72.         procedure AddParam(const aStart, aLength: integer);
  73.         procedure AddTrailing(const aStart, aLength: integer);
  74.         procedure Clear;
  75.     public
  76.         constructor Create;
  77.         destructor Destroy; override;
  78.  
  79.         function Parse(const aRaw: string): boolean; { Parses a RAW IRC message }
  80.         property Raw: string read FRaw;              { Returns the last RAW passed to Parse(); }
  81.  
  82.         property SourceType: TSourceType read FSourceType; { Type of message source prefix. }
  83.         function Source: string;                           { Returns the message source, if present; Client or server that sent the message. }
  84.         function SourceNickName: string;                   { Returns NickName from Source if Source is a Client, full source string otherwise }
  85.         function SourceUserName: string;                   { Returns UserName from Source if Source is a Client, full source string otherwise }
  86.         function SourceHostName: string;                   { Returns HostName from Source if Source is a Client, full source string otherwise }
  87.  
  88.         function Command: string; { Returns IRC Command that was parsed from RAW }
  89.  
  90.         property Param[aIndex: integer]: string read GetParam; { Array of parsed Parameters. This excludes trailing Parameters }
  91.         property ParamCount: integer read FParamCount;         { Number of parsed Parameters. }
  92.         function Params: string;                               { Returns all Parameters as a single string }
  93.         function ParamsFrom(const aIndex: integer): string;    { Returns parameters from and including token at aIndex. }
  94.  
  95.         property Trailing[aIndex: integer]: string read GetTrailing; { Array of parsed trailing Parameters. }
  96.         property TrailingCount: integer read FTrailingCount;         { Number of parsed trailing Parameters. }
  97.         function Trailings: string;                                  { Returns all trailing Parameters as a single string }
  98.         function TrailingsFrom(const aIndex: integer): string;       { Returns trailing parameters from and including token at aIndex. }
  99.  
  100.         function AllParams: string; { Returns all middle and trailing params as a single string. }
  101.     end;
  102.  
  103.     { TIrcChannel }
  104.     TIrcChannel = class(TPersistent)
  105.  
  106.     end;
  107.  
  108.     { TIrcNickname }
  109.     TIrcNickname = class(TPersistent)
  110.     private
  111.         FNickname: string;
  112.         FUsername: string;
  113.         FRealname: string;
  114.         FHostname: string;
  115.         procedure SetNickname(const Value: string);
  116.         procedure SetRealName(const Value: string);
  117.         procedure SetUsername(const Value: string);
  118.         procedure SetHostname(const Value: string);
  119.     public
  120.         function GetHostMask: string; overload;
  121.         function GetHostMask(const aType: byte): string; overload;
  122.     published
  123.         property Nickname: string read FNickname write SetNickname;
  124.         property Username: string read FUsername write SetUsername;
  125.         property Realname: string read FRealname write SetRealName;
  126.         property Hostname: string read FHostname write SetHostname;
  127.     end;
  128.  
  129.     { TInternalAddressList }
  130.     TInternalAddressList = class(TPersistent)
  131.     private
  132.         FOwner  : TIrc;
  133.         FEnabled: boolean;
  134.         procedure SetEnabled(const Value: boolean);
  135.         function GetIrcChannel(const aIndex: integer): TIrcChannel;
  136.         function GetChannelCount: integer;
  137.         function GetNickname(const aIndex: integer): TIrcNickname;
  138.         function GetNicknameCount: integer;
  139.         procedure SetIrcChannel(const aIndex: integer; const Value: TIrcChannel);
  140.         procedure SetNickname(const aIndex: integer; const Value: TIrcNickname);
  141.     protected
  142.  
  143.     public
  144.         constructor Create(aIrc: TIrc);
  145.         destructor Destroy; override;
  146.     public
  147.         property Channels[const aIndex: integer]: TIrcChannel read GetIrcChannel write SetIrcChannel;
  148.         property ChannelCount                   : integer read GetChannelCount;
  149.  
  150.         property Nicknames[const aIndex: integer]: TIrcNickname read GetNickname write SetNickname;
  151.         property NicknameCount                   : integer read GetNicknameCount;
  152.     published
  153.         property Enabled: boolean read FEnabled write SetEnabled default True;
  154.     end;
  155.  
  156.     { Events }
  157.     TOnIrcEvent        = procedure(aClient: TIrc) of object;
  158.     TOnIrcTextEvent    = procedure(aClient: TIrc; const aText: string) of object;
  159.     TOnIrcRaw          = procedure(aClient: TIrc; const aCmd: string; aIn: boolean; var aBlockIt: boolean) of object;
  160.     TOnIrcJoin         = procedure(aClient: TIrc; const aNick, aHost, aChannel: string) of object;
  161.     TOnIrcPart         = procedure(aClient: TIrc; const aNick, aHost, aChannel, aReason: string) of object;
  162.     TOnIrcKick         = procedure(aClient: TIrc; const aKicker, aKicked, aChannel, aReason: string) of object;
  163.     TOnIrcKill         = procedure(aClient: TIrc; const aKiller, aKilled, aReason: string) of object;
  164.     TOnIrcQuit         = procedure(aClient: TIrc; const aNick, aHost, aReason: string) of object;
  165.     TOnIrcPrivMsg      = procedure(aClient: TIrc; const aFromNick, aFromHost, aTarget, aText: string) of object;
  166.     TOnIrcServerNotice = procedure(aClient: TIrc; const aSource, aText: string) of object;
  167.     TOnIrcCTCP         = procedure(aClient: TIrc; const aFromNick, aFromHost, aTarget, aCommand, aParameters: string) of object;
  168.     TOnNick            = procedure(aClient: TIrc; const aOldNick, aNewNick, aHost: string) of object;
  169.     TOnMode            = procedure(aClient: TIrc; const aSource, aTarget, aMode: string) of object;
  170.     TOnIrcStatus       = procedure(aClient: TIrc; const aStatus: string) of object;
  171.     TOnIrcError        = procedure(aClient: TIrc; const aError: string) of object;
  172.  
  173.     { TIrc }
  174.     TIrc = class(TCustomTCPSocket)
  175.     private
  176.         FNickname           : string;
  177.         FRealname           : string;
  178.         FUsername           : string;
  179.         FPassword           : string;
  180.         FAltNicknames       : TStrings;
  181.         FUserMode           : string;
  182.         FRejoinWhenKicked   : boolean;
  183.         FReconnectWhenKilled: boolean;
  184.     private
  185.         FIAL: TInternalAddressList;
  186.     private
  187.         FOnRaw          : TOnIrcRaw;
  188.         FOnServerWelcome: TOnIrcEvent;
  189.         FOnCTCP         : TOnIrcCTCP;
  190.         FOnJoin         : TOnIrcJoin;
  191.         FOnPrivMsg      : TOnIrcPrivMsg;
  192.         FOnNotice       : TOnIrcPrivMsg;
  193.         FOnQuit         : TOnIrcQuit;
  194.         FOnPart         : TOnIrcPart;
  195.         FOnKick         : TOnIrcKick;
  196.         FOnNick         : TOnNick;
  197.         FOnKill         : TOnIrcKill;
  198.         FOnServerNotice : TOnIrcServerNotice;
  199.         FOnMode         : TOnMode;
  200.         procedure SetNickname(const Value: string);
  201.         procedure SetRealname(const Value: string);
  202.         procedure SetUsername(const Value: string);
  203.         procedure SetPassword(const Value: string);
  204.         procedure SetAltNicknames(const Value: TStrings);
  205.         procedure SetUserMode(const Value: string);
  206.         procedure SetRejoinWhenKicked(const Value: boolean);
  207.         procedure SetReconnectWhenKilled(const Value: boolean);
  208.     protected
  209.         FTokenizer    : TTokenizer;
  210.         FParser       : TIrcMsgParser;
  211.         FIncompleteCmd: string; { Stores an incomplete command text in case of incomplete socket receive. }
  212.         procedure EventConnect(const aError: word); override;
  213.         procedure EventClose(const aError: word; const aClosedByRemote: boolean); override;
  214.         procedure EventRead(const aError: word); override;
  215.  
  216.         procedure ParseCommand(const aLine: string);
  217.  
  218.         procedure Handle_PING;
  219.         procedure Handle_JOIN;
  220.         procedure Handle_PART;
  221.         procedure Handle_KICK;
  222.         procedure Handle_QUIT;
  223.         procedure Handle_KILL;
  224.         procedure Handle_NICK;
  225.         procedure Handle_MODE;
  226.         procedure Handle_PRIVMSG;
  227.         procedure Handle_NOTICE;
  228.         procedure Handle_INVITE;
  229.         procedure Handle_WALLOPS;
  230.         procedure Handle_ERROR;
  231.         procedure Handle_319_RPL_WHOISCHANNELS;
  232.         procedure Handle_322_RPL_LIST;
  233.         procedure Handle_352_RPL_WHOREPLY;
  234.         procedure Handle_353_RPL_NAMEREPLY;
  235.         procedure Handle_333;
  236.         procedure Handle_Numeric(const aCode: integer);
  237.     public
  238.         constructor Create(aOwner: TComponent); override;
  239.         destructor Destroy; override;
  240.         procedure Assign(aSource: TPersistent); override;
  241.  
  242.         procedure Raw(const aText: string); { Sends raw text, terminates with CRLF. }
  243.  
  244.         procedure Cmd_Join(const aChannel: string; const aKey: string = CEmpty);
  245.         procedure Cmd_Part(const aChannel: string; const aPartMsg: string = CEmpty);
  246.         procedure Cmd_Msg(const aTarget, aMessage: string);
  247.         procedure Cmd_Nick(const aNewNickname: string);
  248.     published
  249.         property AddressFamily;
  250.         property SocketState;
  251.         property ReceiveBufferSize;
  252.  
  253.         property BindHost;
  254.         property BindPort;
  255.         property RemoteHost;
  256.         property RemotePort;
  257.  
  258.         property ProxyHost;
  259.         property ProxyPort;
  260.         property ProxyType;
  261.  
  262.         property SSLType;
  263.         property SSLPrivateKeyFile;
  264.         property SSLCertificateChainFile;
  265.         property SSLTrustedAuthoritiesFile;
  266.         property SSLVerifyCertificate;
  267.  
  268.         property ConnectTimeout;
  269.         property ConnectRetryDelay;
  270.         property ConnectRetryCount;
  271.  
  272.         property ReconnectOnError;
  273.         property ReconnectOnClose;
  274.  
  275.         property Nickname    : string read FNickname write SetNickname;
  276.         property Username    : string read FUsername write SetUsername;
  277.         property Realname    : string read FRealname write SetRealname;
  278.         property Password    : string read FPassword write SetPassword;
  279.         property UserMode    : string read FUserMode write SetUserMode;
  280.         property AltNicknames: TStrings read FAltNicknames write SetAltNicknames;
  281.  
  282.         property IAL: TInternalAddressList read FIAL;
  283.  
  284.         property RejoinWhenKicked   : boolean read FRejoinWhenKicked write SetRejoinWhenKicked default True;
  285.         property ReconnectWhenKilled: boolean read FReconnectWhenKilled write SetReconnectWhenKilled default True;
  286.  
  287.         property OnResolving;
  288.         property OnResolved;
  289.         property OnConnecting;
  290.         property OnConnectTimeout;
  291.         property OnConnected;
  292.         property OnDisconnected;
  293.         property OnError;
  294.  
  295.         property OnRaw: TOnIrcRaw read FOnRaw write FOnRaw;
  296.  
  297.         property OnServerWelcome: TOnIrcEvent read FOnServerWelcome write FOnServerWelcome;
  298.         property OnJoin         : TOnIrcJoin read FOnJoin write FOnJoin;
  299.         property OnPart         : TOnIrcPart read FOnPart write FOnPart;
  300.         property OnKick         : TOnIrcKick read FOnKick write FOnKick;
  301.         property OnQuit         : TOnIrcQuit read FOnQuit write FOnQuit;
  302.         property OnKill         : TOnIrcKill read FOnKill write FOnKill;
  303.         property OnPrivMsg      : TOnIrcPrivMsg read FOnPrivMsg write FOnPrivMsg;
  304.         property OnNotice       : TOnIrcPrivMsg read FOnNotice write FOnNotice;
  305.         property OnServerNotice : TOnIrcServerNotice read FOnServerNotice write FOnServerNotice;
  306.         property OnCTCP         : TOnIrcCTCP read FOnCTCP write FOnCTCP;
  307.         property OnNick         : TOnNick read FOnNick write FOnNick;
  308.         property OnMode         : TOnMode read FOnMode write FOnMode;
  309.     end;
  310.  
  311. implementation
  312.  
  313. { TELIrc.TELIrcMsgParser }
  314.  
  315. constructor TIrcMsgParser.Create;
  316. begin
  317.     Clear;
  318. end;
  319.  
  320. destructor TIrcMsgParser.Destroy;
  321. begin
  322.     Clear;
  323.     inherited;
  324. end;
  325.  
  326. procedure TIrcMsgParser.AddParam(const aStart, aLength: integer);
  327. begin
  328.     Inc(FParamCount);
  329.     SetLength(FParamsArray, FParamCount);
  330.     FParamsArray[FParamCount - 1].Start  := aStart;
  331.     FParamsArray[FParamCount - 1].Length := aLength;
  332. end;
  333.  
  334. procedure TIrcMsgParser.AddTrailing(const aStart, aLength: integer);
  335. begin
  336.     Inc(FTrailingCount);
  337.     SetLength(FTrailingsArray, FTrailingCount);
  338.     FTrailingsArray[FTrailingCount - 1].Start  := aStart;
  339.     FTrailingsArray[FTrailingCount - 1].Length := aLength;
  340. end;
  341.  
  342. procedure TIrcMsgParser.Clear;
  343. begin
  344.     FRaw := CEmpty;
  345.  
  346.     FSourceType    := stNotPresent;
  347.     FSource.Start  := 0;
  348.     FSource.Length := 0;
  349.  
  350.     FSourceNickName.Start  := 0;
  351.     FSourceNickName.Length := 0;
  352.     FSourceUserName.Start  := 0;
  353.     FSourceUserName.Length := 0;
  354.     FSourceHostName.Start  := 0;
  355.     FSourceHostName.Length := 0;
  356.  
  357.     FCommand.Start  := 0;
  358.     FCommand.Length := 0;
  359.  
  360.     FParams.Start  := 0;
  361.     FParams.Length := 0;
  362.     SetLength(FParamsArray, 0);
  363.     FParamCount := 0;
  364.  
  365.     FTrailings.Start  := 0;
  366.     FTrailings.Length := 0;
  367.     SetLength(FTrailingsArray, 0);
  368.     FTrailingCount := 0;
  369. end;
  370.  
  371. function TIrcMsgParser.Parse(const aRaw: string): boolean;
  372. var
  373.     a: integer; // Copy start/Last Copy end position.
  374.     b: integer; // Parse cursor.
  375.     t: integer; // Temp cursor.
  376.     l: integer; // Length of input string.
  377.  
  378.     function DoTrim: boolean;
  379.     begin
  380.         Result := False;
  381.         while (b <= l) do
  382.         begin
  383.             if (b > l) then
  384.                 Exit(False);
  385.             if (FRaw[b] <= CSpace) then
  386.                 Inc(b)
  387.             else
  388.             begin
  389.                 a := b;
  390.                 Exit(True);
  391.             end;
  392.         end;
  393.     end;
  394.  
  395.     function FindSpace: boolean;
  396.     begin
  397.         b      := TextPos(FRaw, CSpace, True, b);
  398.         Result := (b <> 0);
  399.     end;
  400.  
  401. begin
  402.     // <message> ::=
  403.     //
  404.     // [':' <prefix> <SPACE> ] <command> <Trailing> <crlf>
  405.     //
  406.     // <prefix> ::=
  407.     // <servername> | <nick> [ '!' <user> ] [ '@' <host> ]
  408.     //
  409.     // <command> ::=
  410.     // <letter> { <letter> } | <number> <number> <number>
  411.     //
  412.     // <SPACE> ::=
  413.     // ' ' { ' ' }
  414.     //
  415.     // <Trailing> ::=
  416.     // <SPACE> [ ':' <Trailings> | <middle> <Trailing> ]
  417.     //
  418.     // <middle> ::=
  419.     // <Any *non-empty* sequence of octets not including SPACE or NUL or CR or LF, the first of which may not be ':'>
  420.     //
  421.     // <Trailings> ::=
  422.     // <Any, possibly *empty*, sequence of octets not including NUL or CR or LF>
  423.     //
  424.     // <crlf> ::=
  425.     // CR LF
  426.  
  427.     { Check and initialize }
  428.     Result := False;
  429.     l      := Length(aRaw);
  430.     if (l = 0) then
  431.         Exit;
  432.  
  433.     Clear;
  434.     FRaw := aRaw;
  435.     a    := 1;
  436.     b    := 1;
  437.  
  438.     if (DoTrim = False) then
  439.         Exit;
  440.  
  441.     { Optional Message Source Prefix. }
  442.     if (FRaw[b] = CColon) then
  443.     begin
  444.         if (FindSpace = False) then
  445.             Exit;
  446.  
  447.         Inc(a);
  448.         FSource.Start  := a;
  449.         FSource.Length := (b - a);
  450.  
  451.         { If msg source is an user, split it to <nick>!<user>@<host>. }
  452.         t := TextPos(FRaw, CExclam, True, a);
  453.         if (t > 0) and (t < b) then
  454.         begin
  455.             FSourceNickName.Start  := a;
  456.             FSourceNickName.Length := (t - a);
  457.  
  458.             a := t;
  459.             Inc(a);
  460.             t := TextPos(FRaw, CMonkey, True, a);
  461.             if (t > 0) and (t < b) then
  462.             begin
  463.                 FSourceUserName.Start  := a;
  464.                 FSourceUserName.Length := (t - a);
  465.  
  466.                 a := t;
  467.                 Inc(a);
  468.                 t := TextPos(FRaw, CSpace, True, a);
  469.                 if (t = b) then
  470.                 begin
  471.                     FSourceHostName.Start  := a;
  472.                     FSourceHostName.Length := (t - a);
  473.  
  474.                     FSourceType := stUser;
  475.                 end;
  476.             end;
  477.         end
  478.         else
  479.             FSourceType := stServer;
  480.  
  481.         a := b;
  482.  
  483.         { Trim }
  484.         if (DoTrim = False) then
  485.             Exit;
  486.     end;
  487.  
  488.     { Parse out command }
  489.     if (FindSpace) then
  490.     begin
  491.         FCommand.Start  := a;
  492.         FCommand.Length := (b - a);
  493.  
  494.         a := b;
  495.         { If no params, exit. }
  496.         if (DoTrim = False) then
  497.             Exit(True);
  498.     end
  499.     else
  500.     begin
  501.         { If no params, exit }
  502.         FCommand.Start  := a;
  503.         FCommand.Length := (l - a);
  504.         Exit(True);
  505.     end;
  506.  
  507.     { Parse parameters }
  508.  
  509.     { If there are trailing params, parse middle first }
  510.     t := TextPos(FRaw, CColon, True, a);
  511.     if (t <> 0) then
  512.     begin
  513.         FParams.Start  := a;
  514.         FParams.Length := (t - a);
  515.         // Get the pre-Trailings params.
  516.         while (b < t) and (FindSpace) do
  517.         begin
  518.             AddParam(a, b - a);
  519.             Inc(b);
  520.             a := b;
  521.         end;
  522.  
  523.         // If no space before Trailings colon..
  524.         if (a < t) then
  525.             AddParam(a, t - a);
  526.  
  527.         // Move cursor to start of Trailings.
  528.         a := t + 1;
  529.         b := a;
  530.     end
  531.     else
  532.     begin
  533.         FParams.Start  := a;
  534.         FParams.Length := (l + 1 - a);
  535.     end;
  536.  
  537.     if (t <> 0) then
  538.     begin
  539.         FTrailings.Start  := t + 1;
  540.         FTrailings.Length := (l + 1 - a);
  541.     end;
  542.  
  543.     while (FindSpace) do
  544.     begin
  545.         if (t <> 0) then
  546.             AddTrailing(a, b - a)
  547.         else
  548.             AddParam(a, b - a);
  549.         Inc(b);
  550.         a := b;
  551.     end;
  552.  
  553.     // Last chunk.
  554.     if (b < l) then
  555.     begin
  556.         if (t <> 0) then
  557.             AddTrailing(a, MaxInt)
  558.         else
  559.             AddParam(a, MaxInt);
  560.     end;
  561.  
  562.     // Done.
  563.     Result := True;
  564. end;
  565.  
  566. function TIrcMsgParser.Source: string;
  567. begin
  568.     if (FSource.Length = 0) then
  569.         Result := CEmpty
  570.     else
  571.         Result := TextCopy(FRaw, FSource.Start, FSource.Length);
  572. end;
  573.  
  574. function TIrcMsgParser.SourceNickName: string;
  575. begin
  576.     if (FSourceNickName.Length = 0) then
  577.         Result := CEmpty
  578.     else
  579.         Result := TextCopy(FRaw, FSourceNickName.Start, FSourceNickName.Length);
  580. end;
  581.  
  582. function TIrcMsgParser.SourceUserName: string;
  583. begin
  584.     if (FSourceUserName.Length = 0) then
  585.         Result := CEmpty
  586.     else
  587.         Result := TextCopy(FRaw, FSourceUserName.Start, FSourceUserName.Length);
  588. end;
  589.  
  590. function TIrcMsgParser.SourceHostName: string;
  591. begin
  592.     if (FSourceHostName.Length = 0) then
  593.         Result := CEmpty
  594.     else
  595.         Result := TextCopy(FRaw, FSourceHostName.Start, FSourceHostName.Length);
  596. end;
  597.  
  598. function TIrcMsgParser.Command: string;
  599. begin
  600.     if (FCommand.Length = 0) then
  601.         Result := CEmpty
  602.     else
  603.         Result := TextCopy(FRaw, FCommand.Start, FCommand.Length);
  604. end;
  605.  
  606. function TIrcMsgParser.Params: string;
  607. begin
  608.     if (FParams.Length = 0) then
  609.         Result := CEmpty
  610.     else
  611.         Result := Trim(TextCopy(FRaw, FParams.Start, FParams.Length));
  612. end;
  613.  
  614. function TIrcMsgParser.ParamsFrom(const aIndex: integer): string;
  615. begin
  616.     if (aIndex < 0) or (aIndex >= FParamCount) then
  617.         Result := CEmpty
  618.     else
  619.         Result := TextCopy(FRaw, FParamsArray[aIndex].Start, MaxInt);
  620. end;
  621.  
  622. function TIrcMsgParser.Trailings: string;
  623. begin
  624.     if (FTrailings.Length = 0) then
  625.         Result := CEmpty
  626.     else
  627.         Result := TextCopy(FRaw, FTrailings.Start, FTrailings.Length);
  628. end;
  629.  
  630. function TIrcMsgParser.TrailingsFrom(const aIndex: integer): string;
  631. begin
  632.     if (aIndex < 0) or (aIndex >= FTrailingCount) then
  633.         Result := CEmpty
  634.     else
  635.         Result := TextCopy(FRaw, FTrailingsArray[aIndex].Start, MaxInt);
  636. end;
  637.  
  638. function TIrcMsgParser.AllParams: string;
  639. begin
  640.     if (FParams.Length > 0) then
  641.         Result := Params
  642.     else
  643.         Result := CEmpty;
  644.  
  645.     if (FParams.Length > 0) then
  646.     begin
  647.         if (FTrailings.Length > 0) then
  648.             Result := Result + CSpace + Trailings;
  649.     end
  650.     else
  651.     begin
  652.         if (FTrailings.Length > 0) then
  653.             Result := Trailings;
  654.     end;
  655. end;
  656.  
  657. function TIrcMsgParser.GetParam(aIndex: integer): string;
  658. begin
  659.     if (aIndex < 0) or (aIndex >= FParamCount) then
  660.         Result := CEmpty
  661.     else
  662.         Result := TextCopy(FRaw, FParamsArray[aIndex].Start, FParamsArray[aIndex].Length);
  663. end;
  664.  
  665. function TIrcMsgParser.GetTrailing(aIndex: integer): string;
  666. begin
  667.     if (aIndex < 0) or (aIndex >= FTrailingCount) then
  668.         Result := CEmpty
  669.     else
  670.         Result := TextCopy(FRaw, FTrailingsArray[aIndex].Start, FTrailingsArray[aIndex].Length);
  671. end;
  672.  
  673. { TIrcNickname }
  674.  
  675. function TIrcNickname.GetHostMask: string;
  676. begin
  677.     if (FNickname = CEmpty) or (FUsername = CEmpty) or (FHostname = CEmpty) then
  678.         Exit(CEmpty);
  679.  
  680.     Result := FNickname + CExclam + FUsername + CMonkey + FHostname;
  681. end;
  682.  
  683. function TIrcNickname.GetHostMask(const aType: byte): string;
  684. begin
  685.     if (FNickname = CEmpty) or (FUsername = CEmpty) or (FHostname = CEmpty) then
  686.         Exit(CEmpty);
  687.  
  688.     case aType of
  689.         0:
  690.         Result := FNickname + CExclam + CAsterisk + CMonkey + CAsterisk; // nick!*@*
  691.         1:
  692.         Result := CAsterisk + CExclam + FUsername + CMonkey + CAsterisk; // *!user@*
  693.         2:
  694.         Result := CAsterisk + CExclam + CAsterisk + CMonkey + FHostname; // *!*@host
  695.         3:
  696.         Result := FNickname + CExclam + FUsername + CMonkey + CAsterisk; // nick!user@*
  697.         4:
  698.         Result := CAsterisk + CExclam + FUsername + CMonkey + FHostname; // *!user@host
  699.         5:
  700.         Result := FNickname + CExclam + CAsterisk + CMonkey + FHostname; // nick!*@host
  701.         else
  702.         Result := FNickname + CExclam + FUsername + CMonkey + FHostname; // nick!user@host
  703.     end;
  704. end;
  705.  
  706. procedure TIrcNickname.SetHostname(const Value: string);
  707. begin
  708.     FHostname := Value;
  709. end;
  710.  
  711. procedure TIrcNickname.SetNickname(const Value: string);
  712. begin
  713.     FNickname := Value;
  714. end;
  715.  
  716. procedure TIrcNickname.SetRealName(const Value: string);
  717. begin
  718.     FRealName := Value;
  719. end;
  720.  
  721. procedure TIrcNickname.SetUsername(const Value: string);
  722. begin
  723.     FUsername := Value;
  724. end;
  725.  
  726. { TELInternalAddressList }
  727.  
  728. constructor TInternalAddressList.Create(aIrc: TIrc);
  729. begin
  730.     FOwner := aIrc;
  731.  
  732.     FEnabled := True;
  733. end;
  734.  
  735. destructor TInternalAddressList.Destroy;
  736. begin
  737.  
  738. end;
  739.  
  740. function TInternalAddressList.GetChannelCount: integer;
  741. begin
  742.     Result := 0;
  743. end;
  744.  
  745. function TInternalAddressList.GetIrcChannel(const aIndex: integer): TIrcChannel;
  746. begin
  747.     Result := nil;
  748. end;
  749.  
  750. function TInternalAddressList.GetNickname(const aIndex: integer): TIrcNickname;
  751. begin
  752.     Result := nil;
  753. end;
  754.  
  755. function TInternalAddressList.GetNicknameCount: integer;
  756. begin
  757.     Result := 0;
  758. end;
  759.  
  760. procedure TInternalAddressList.SetEnabled(const Value: boolean);
  761. begin
  762.     if (FEnabled = Value) then
  763.         Exit;
  764.     FEnabled := Value;
  765. end;
  766.  
  767. procedure TInternalAddressList.SetIrcChannel(const aIndex: integer; const Value: TIrcChannel);
  768. begin
  769.  
  770. end;
  771.  
  772. procedure TInternalAddressList.SetNickname(const aIndex: integer; const Value: TIrcNickname);
  773. begin
  774.  
  775. end;
  776.  
  777. { TELIrc }
  778.  
  779. constructor TIrc.Create(aOwner: TComponent);
  780. begin
  781.     inherited Create(aOwner);
  782.     FAltNicknames := TStringList.Create;
  783.     FTokenizer    := TTokenizer.Create;
  784.     FParser       := TIrcMsgParser.Create;
  785.     FUserMode     := '+ix';
  786.  
  787.     FIAL := TInternalAddressList.Create(Self);
  788.  
  789.     FRejoinWhenKicked    := True;
  790.     FReconnectWhenKilled := True;
  791. end;
  792.  
  793. destructor TIrc.Destroy;
  794. begin
  795.     FIAL.Free;
  796.     FAltNicknames.Free;
  797.     FParser.Free;
  798.     FTokenizer.Free;
  799.     inherited;
  800. end;
  801.  
  802. procedure TIrc.Assign(aSource: TPersistent);
  803. begin
  804.     if (aSource is TIrc) then
  805.     begin
  806.         Nickname            := TIrc(aSource).Nickname;
  807.         Username            := TIrc(aSource).Username;
  808.         RealName            := TIrc(aSource).RealName;
  809.         Password            := TIrc(aSource).Password;
  810.         UserMode            := TIrc(aSource).UserMode;
  811.         RejoinWhenKicked    := TIrc(aSource).RejoinWhenKicked;
  812.         ReconnectWhenKilled := TIrc(aSource).ReconnectWhenKilled;
  813.         AltNicknames.Assign(TIrc(aSource).AltNicknames);
  814.     end
  815.     else
  816.         inherited;
  817. end;
  818.  
  819. procedure TIrc.EventClose(const aError: word; const aClosedByRemote: boolean);
  820. begin
  821.     inherited;
  822.  
  823. end;
  824.  
  825. procedure TIrc.EventConnect(const aError: word);
  826. begin
  827.     inherited;
  828.  
  829.     { Login }
  830.     if (FPassword <> CEmpty) then
  831.         Raw('PASS' + CSpace + FPassword);
  832.     Raw('NICK' + CSpace + FNickname);
  833.     Raw('USER' + CSpace + FUsername + CSpace + FUserMode + CSpace + CAsterisk + CSpace + CColon + FRealname);
  834. end;
  835.  
  836. procedure TIrc.EventRead(const aError: word);
  837. var
  838.     s: string;
  839.     i: integer;
  840. begin
  841.     inherited;
  842.  
  843.     while (RecvString(s)) do
  844.     begin
  845.         { Split on CRLF }
  846.         if (FIncompleteCmd <> CEmpty) then
  847.         begin
  848.             { If there was incomplete command present in last parse prepend that to received data. }
  849.             FTokenizer.Split(FIncompleteCmd + s, CCrLf, [esoCSQot, esoCSSep]);
  850.             FIncompleteCmd := CEmpty;
  851.         end
  852.         else
  853.             { Otherwise split the incoming data. }
  854.             FTokenizer.Split(s, CCrLf, [esoCSQot, esoCSSep]);
  855.  
  856.         if (TextRight(s, 2) = CCrLf) then
  857.         begin
  858.             { If received data was CRLF terminated parse all commands now. }
  859.             for i := 0 to FTokenizer.Count - 1 do
  860.                 ParseCommand(FTokenizer[i]);
  861.         end
  862.         else
  863.         begin
  864.             { Otherwise add last token as incomplete command if not CRLF terminated }
  865.             if (FTokenizer.Count = 1) then
  866.                 FIncompleteCmd := FTokenizer[0]
  867.             else
  868.             begin
  869.                 for i := 0 to FTokenizer.Count - 2 do
  870.                     ParseCommand(FTokenizer[i]);
  871.                 FIncompleteCmd := FTokenizer[FTokenizer.Count - 1];
  872.             end;
  873.         end;
  874.     end;
  875. end;
  876.  
  877. procedure TIrc.ParseCommand(const aLine: string);
  878. var
  879.     Code : integer;
  880.     Block: boolean;
  881. begin
  882.     { Fire event }
  883.     if (Assigned(FOnRaw)) then
  884.     begin
  885.         Block := False;
  886.         FOnRaw(Self, aLine, True, Block);
  887.         if (Block) then
  888.             Exit;
  889.     end;
  890.  
  891.     FParser.Parse(aLine);
  892.  
  893.     if (SameText(FParser.Command, CPING)) then
  894.     begin
  895.         Handle_PING;
  896.         Exit;
  897.     end;
  898.  
  899.     if (SameText(FParser.Command, CJOIN)) then
  900.     begin
  901.         Handle_JOIN;
  902.         Exit;
  903.     end;
  904.  
  905.     if (SameText(FParser.Command, CPART)) then
  906.     begin
  907.         Handle_PART;
  908.         Exit;
  909.     end;
  910.  
  911.     if (SameText(FParser.Command, CKICK)) then
  912.     begin
  913.         Handle_KICK;
  914.         Exit;
  915.     end;
  916.  
  917.     if (SameText(FParser.Command, CQUIT)) then
  918.     begin
  919.         Handle_QUIT;
  920.         Exit;
  921.     end;
  922.  
  923.     if (SameText(FParser.Command, CKILL)) then
  924.     begin
  925.         Handle_KILL;
  926.         Exit;
  927.     end;
  928.  
  929.     if (SameText(FParser.Command, CNICK)) then
  930.     begin
  931.         Handle_NICK;
  932.         Exit;
  933.     end;
  934.  
  935.     if (SameText(FParser.Command, CMODE)) then
  936.     begin
  937.         Handle_MODE;
  938.         Exit;
  939.     end;
  940.  
  941.     if (SameText(FParser.Command, CPRIVMSG)) then
  942.     begin
  943.         Handle_PRIVMSG;
  944.         Exit;
  945.     end;
  946.  
  947.     if (SameText(FParser.Command, CNOTICE)) then
  948.     begin
  949.         Handle_NOTICE;
  950.         Exit;
  951.     end;
  952.  
  953.     if (SameText(FParser.Command, CERROR)) then
  954.     begin
  955.         Handle_ERROR;
  956.         Exit;
  957.     end;
  958.  
  959.     if (SameText(FParser.Command, CINVITE)) then
  960.     begin
  961.         Handle_INVITE;
  962.         Exit;
  963.     end;
  964.  
  965.     if (SameText(FParser.Command, CWALLOPS)) then
  966.     begin
  967.         Handle_WALLOPS;
  968.         Exit;
  969.     end;
  970.  
  971.     Code := StrToIntDef(FParser.Command, -1);
  972.     if (Code <> -1) then
  973.         Handle_Numeric(Code);
  974. end;
  975.  
  976. procedure TIrc.Handle_PING;
  977. begin
  978.     if (FParser.TrailingCount > 0) then
  979.         Raw(CPONG + CSpace + CColon + FParser.Trailings)
  980.     else
  981.         Raw(CPONG);
  982. end;
  983.  
  984. procedure TIrc.Handle_JOIN;
  985. begin
  986.     { Fire event }
  987.     if (Assigned(FOnJoin)) then
  988.         FOnJoin(Self, FParser.SourceNickName, FParser.Source, FParser.AllParams);
  989. end;
  990.  
  991. procedure TIrc.Handle_PART;
  992. begin
  993.     { Fire event }
  994.     if (Assigned(FOnPart)) then
  995.         FOnPart(Self, FParser.SourceNickName, FParser.Source, FParser.Param[0], FParser.Trailings);
  996. end;
  997.  
  998. procedure TIrc.Handle_KICK;
  999. begin
  1000.     { Fire event }
  1001.     if (Assigned(FOnKick)) then
  1002.         FOnKick(Self, FParser.SourceNickName, FParser.Param[1], FParser.Param[0], FParser.Trailings);
  1003.  
  1004.     { Auto rejoin }
  1005.     if (SameText(FParser.Param[1], FNickname)) then
  1006.         if (FRejoinWhenKicked) then
  1007.             Cmd_Join(FParser.Param[0]);
  1008. end;
  1009.  
  1010. procedure TIrc.Handle_QUIT;
  1011. begin
  1012.     { Fire event }
  1013.     if (Assigned(FOnQuit)) then
  1014.         FOnQuit(Self, FParser.SourceNickName, FParser.Source, FParser.Trailings);
  1015. end;
  1016.  
  1017. procedure TIrc.Handle_KILL;
  1018. begin
  1019.     { Fire event }
  1020.     if (Assigned(FOnKill)) then
  1021.         FOnKill(Self, FParser.Source, FParser.Param[0], FParser.Trailings);
  1022. end;
  1023.  
  1024. procedure TIrc.Handle_NICK;
  1025. begin
  1026.     { Fire event }
  1027.     if (Assigned(FOnNick)) then
  1028.         FOnNick(Self, FParser.SourceNickName, FParser.Param[0], FParser.Source);
  1029. end;
  1030.  
  1031. procedure TIrc.Handle_MODE;
  1032. begin
  1033.     //    -> :evilworks!evilworks@staff.anonops.li MODE #evilden +i
  1034.     //    -> :evilworks!evilworks@staff.anonops.li MODE #evilden -i
  1035.     //    -> :evilworks!evilworks@staff.anonops.li MODE #evilden +i
  1036.     //    -> :evilworks!evilworks@staff.anonops.li MODE #evilden +DM-i+o win32
  1037.     //    -> :evilworks!evilworks@staff.anonops.li MODE #evilden -DM+i-o win32
  1038.     //    -> :evilworks!evilworks@staff.anonops.li MODE #evilden +DM-i+o win32
  1039.     //    -> :evilworks!evilworks@staff.anonops.li MODE #evilden -DM+i-o win32
  1040.     //    -> :evilworks!evilworks@staff.anonops.li MODE #evilden +DM-i+ov win32 evilworks
  1041.     //
  1042.     //    <- :evilworks!evilworks@evil.machine MODE #anonops +i-i
  1043.     //
  1044.     //    -> shitstorm.anonops.in MODE evilworks -i
  1045.     //    <- :evilworks!evilworks@evil.machine MODE evilworks -i
  1046.  
  1047.     //    -> shitstorm.anonops.in SAMODE p0ke -i
  1048.     //    <- :shitstorm.anonops.in NOTICE evilworks :*** ANNOUNCEMENT: evilworks used SAMODE: p0ke -i
  1049.     if (Assigned(FOnMode)) then
  1050.         FOnMode(Self, FParser.Source, FParser.Param[0], FParser.ParamsFrom(1));
  1051. end;
  1052.  
  1053. procedure TIrc.Handle_PRIVMSG;
  1054. var
  1055.     cmd   : string;
  1056.     params: string;
  1057. begin
  1058.     if (TextEnclosed(FParser.Trailings, #01, True)) then
  1059.     begin
  1060.         if (Assigned(FOnCTCP)) then
  1061.         begin
  1062.             params := TextUnEnclose(FParser.Trailings, #01, True);
  1063.             cmd    := TextGet(params, CSpace, True, True);
  1064.             FOnCTCP(Self, FParser.SourceNickName, FParser.Source, FParser.Param[0], cmd, params);
  1065.         end;
  1066.     end
  1067.     else
  1068.     begin
  1069.         if (Assigned(FOnPrivMsg)) then
  1070.             FOnPrivMsg(Self, FParser.SourceNickName, FParser.Source, FParser.Param[0], FParser.Trailings);
  1071.     end;
  1072. end;
  1073.  
  1074. procedure TIrc.Handle_NOTICE;
  1075. var
  1076.     cmd   : string;
  1077.     params: string;
  1078. begin
  1079.     if (TextEnclosed(FParser.Trailings, #01, True)) then
  1080.     begin
  1081.         if (Assigned(FOnCTCP)) then
  1082.         begin
  1083.             cmd    := TextRight(FParser.Trailing[0], Length(FParser.Trailing[0]) - 1);
  1084.             params := TextLeft(FParser.TrailingsFrom(1), Length(FParser.TrailingsFrom(1)) - 1);
  1085.             FOnCTCP(Self, FParser.SourceNickName, FParser.Source, FParser.Param[0], cmd, params);
  1086.         end;
  1087.     end
  1088.     else
  1089.     begin
  1090.         if (FParser.SourceType = stServer) then
  1091.         begin
  1092.             if (Assigned(FOnServerNotice)) then
  1093.                 FOnServerNotice(Self, FParser.Source, FParser.Trailings);
  1094.         end
  1095.         else
  1096.         begin
  1097.             if (Assigned(FOnNotice)) then
  1098.                 FOnNotice(Self, FParser.SourceNickName, FParser.Source, FParser.Param[0], FParser.Trailings);
  1099.         end;
  1100.     end;
  1101. end;
  1102.  
  1103. procedure TIrc.Handle_INVITE;
  1104. begin
  1105.     // -> :evilworks!evilworks@evil.machine INVITE win32 :#evilden
  1106. end;
  1107.  
  1108. procedure TIrc.Handle_WALLOPS;
  1109. begin
  1110.  
  1111. end;
  1112.  
  1113. procedure TIrc.Handle_ERROR;
  1114. begin
  1115.  
  1116. end;
  1117.  
  1118. procedure TIrc.Handle_319_RPL_WHOISCHANNELS;
  1119. begin
  1120.  
  1121. end;
  1122.  
  1123. procedure TIrc.Handle_322_RPL_LIST;
  1124. begin
  1125.  
  1126. end;
  1127.  
  1128. procedure TIrc.Handle_352_RPL_WHOREPLY;
  1129. begin
  1130.  
  1131. end;
  1132.  
  1133. procedure TIrc.Handle_353_RPL_NAMEREPLY;
  1134. begin
  1135.  
  1136. end;
  1137.  
  1138. procedure TIrc.Handle_333;
  1139. begin
  1140.  
  1141. end;
  1142.  
  1143. procedure TIrc.Handle_Numeric(const aCode: integer);
  1144. begin
  1145.     case aCode of
  1146.  
  1147.         001:
  1148.         begin
  1149.             if (Assigned(FOnServerWelcome)) then
  1150.                 FOnServerWelcome(Self);
  1151.             { :corey.anonops.in 001 win32 :Welcome to the AnonOps IRC Network win32!win32@188.129.57.61 }
  1152.         end;
  1153.  
  1154.         002:
  1155.         begin
  1156.             { :corey.anonops.in 002 win32 :Your host is corey.anonops.in, running version InspIRCd-2.0 }
  1157.         end;
  1158.  
  1159.         003:
  1160.         begin
  1161.             { :corey.anonops.in 003 win32 :This server was created 00:58:35 Sep  6 2011 }
  1162.         end;
  1163.  
  1164.         004:
  1165.         begin
  1166.             { :corey.anonops.in 004 win32 corey.anonops.in InspIRCd-2.0 BHIRSWghiorswx ACDFIKLMNOQRSTYabcfhijklmnopqrstuvz FILYabfhjkloqv }
  1167.         end;
  1168.  
  1169.         005:
  1170.         begin
  1171.             { :corey.anonops.in 005 win32 AWAYLEN=31 CALLERID=g CASEMAPPING=rfc1459 CHANMODES=IYb,k,FLfjl,ACDKMNOQRSTcimnprstuz CHANTYPES=# CHARSET=ascii ELIST=MU EXTBAN=,ACNOQRSTcmz FNC INVEX=I KICKLEN=151 MAP MAXBANS=60 :are supported by this server }
  1172.             { :corey.anonops.in 005 win32 MAXCHANNELS=50 MAXPARA=32 MAXTARGETS=20 MODES=20 NETWORK=AnonOps NICKLEN=32 OVERRIDE PREFIX=(qaohv)~&@%+ SECURELIST SSL=93.114.44.112:6697 STARTTLS STATUSMSG=~&@%+ TOPICLEN=308 :are supported by this server }
  1173.             { :corey.anonops.in 005 win32 VBANLIST WALLCHOPS WALLVOICES WATCH=32 :are supported by this server }
  1174.         end;
  1175.  
  1176.         042:
  1177.         begin
  1178.             { :corey.anonops.in 042 win32 750AACQH7 :your unique ID }
  1179.         end;
  1180.  
  1181.         251:
  1182.         begin
  1183.             { :corey.anonops.in 251 win32 :There are 52 users and 469 invisible on 8 servers }
  1184.         end;
  1185.  
  1186.         252:
  1187.         begin
  1188.             { :corey.anonops.in 252 win32 8 :operator(s) online }
  1189.         end;
  1190.  
  1191.         253:
  1192.         begin
  1193.             { :corey.anonops.in 253 win32 1 :unknown connections }
  1194.         end;
  1195.  
  1196.         254:
  1197.         begin
  1198.             { :corey.anonops.in 254 win32 195 :channels formed }
  1199.         end;
  1200.  
  1201.         255:
  1202.         begin
  1203.             { :corey.anonops.in 255 win32 :I have 411 clients and 1 servers }
  1204.         end;
  1205.  
  1206.         265:
  1207.         begin
  1208.             { :corey.anonops.in 265 win32 :Current Local Users: 411  Max: 541 }
  1209.         end;
  1210.  
  1211.         266:
  1212.         begin
  1213.             { :corey.anonops.in 266 win32 :Current Global Users: 521  Max: 679 }
  1214.         end;
  1215.  
  1216.         319:
  1217.         begin
  1218.             Handle_319_RPL_WHOISCHANNELS;
  1219.             { RPL_WHOISCHANNELS }
  1220.         end;
  1221.  
  1222.         321:
  1223.         begin
  1224.             { RPL_LISTSTART - :src 321 tgt chan :usrs nam }
  1225.         end;
  1226.  
  1227.         322:
  1228.         begin
  1229.             Handle_322_RPL_LIST;
  1230.             { RPL_LIST }
  1231.         end;
  1232.  
  1233.         331:
  1234.         begin
  1235.             { RPL_NOTOPIC }
  1236.         end;
  1237.  
  1238.         332:
  1239.         begin
  1240.             { RPL_TOPIC }
  1241.             { :corey.anonops.in 332 win32 #anonops :Some topic text here }
  1242.         end;
  1243.  
  1244.         333:
  1245.         begin
  1246.             Handle_333;
  1247.             { :corey.anonops.in 333 win32 #anonops Jupiler 1317771878 }
  1248.         end;
  1249.  
  1250.         341:
  1251.         begin
  1252.             { RPL_INVITING }
  1253.         end;
  1254.  
  1255.         352:
  1256.         begin
  1257.             Handle_352_RPL_WHOREPLY;
  1258.             { RPL_WHOREPLY }
  1259.         end;
  1260.  
  1261.         353:
  1262.         begin
  1263.             Handle_353_RPL_NAMEREPLY;
  1264.             { RPL_NAMEREPLY }
  1265.             { Replies to /names }
  1266.             { :corey.anonops.in 353 win32 = #anonops :SpecialBit Thought_Criminal mnx }
  1267.         end;
  1268.  
  1269.         366:
  1270.         begin
  1271.             { END OF NAMES LIST }
  1272.             { :corey.anonops.in 366 win32 #anonops :End of /NAMES list. }
  1273.         end;
  1274.  
  1275.         372:
  1276.         begin
  1277.             { MOTD line }
  1278.         end;
  1279.  
  1280.         375:
  1281.         begin
  1282.             { MOTD start }
  1283.             { :corey.anonops.in 375 win32 :corey.anonops.in message of the day }
  1284.         end;
  1285.  
  1286.         376:
  1287.         begin
  1288.             { MOTD end }
  1289.             { :corey.anonops.in 376 win32 :End of message of the day. }
  1290.         end;
  1291.  
  1292.         396:
  1293.         begin
  1294.             { :corey.anonops.in 396 win32 AN-0jb.13v.2j3fss.IP :is now your displayed host }
  1295.         end;
  1296.  
  1297.         482:
  1298.         begin
  1299.             { :corey.anonops.in 482 win32 #evilden :You must have a registered nickname to create a new channel }
  1300.         end;
  1301.  
  1302.     end; { case }
  1303. end;
  1304.  
  1305. procedure TIrc.Raw(const aText: string);
  1306. var
  1307.     Block: boolean;
  1308. begin
  1309.     if (SocketState <> ssConnected) then
  1310.         Exit;
  1311.  
  1312.     { Fire event }
  1313.     if (Assigned(FOnRaw)) then
  1314.     begin
  1315.         Block := False;
  1316.         FOnRaw(Self, aText, False, Block);
  1317.         if (Block) then
  1318.             Exit;
  1319.     end;
  1320.  
  1321.     SendLine(aText);
  1322. end;
  1323.  
  1324. procedure TIrc.Cmd_Join(const aChannel, aKey: string);
  1325. begin
  1326.     if (aKey <> CEmpty) then
  1327.         Raw(CJOIN + CSpace + aChannel + CSpace + aKey)
  1328.     else
  1329.         Raw(CJOIN + CSpace + aChannel);
  1330. end;
  1331.  
  1332. procedure TIrc.Cmd_Part(const aChannel, aPartMsg: string);
  1333. begin
  1334.     if (aPartMsg <> CEmpty) then
  1335.         Raw(CPART + CSpace + aChannel + CSpace + CColon + aPartMsg)
  1336.     else
  1337.         Raw(CPART + CSpace + aChannel);
  1338. end;
  1339.  
  1340. procedure TIrc.Cmd_Msg(const aTarget, aMessage: string);
  1341. begin
  1342.     Raw(CPRIVMSG + CSpace + aTarget + CSpace + CColon + aMessage);
  1343. end;
  1344.  
  1345. procedure TIrc.Cmd_Nick(const aNewNickname: string);
  1346. begin
  1347.     Raw(CNICK + CSpace + aNewNickname);
  1348. end;
  1349.  
  1350. procedure TIrc.SetPassword(const Value: string);
  1351. begin
  1352.     if (FPassword = Value) then
  1353.         Exit;
  1354.     FPassword := Value;
  1355. end;
  1356.  
  1357. procedure TIrc.SetAltNicknames(const Value: TStrings);
  1358. begin
  1359.     FAltNicknames.Assign(Value);
  1360. end;
  1361.  
  1362. procedure TIrc.SetNickname(const Value: string);
  1363. begin
  1364.     if (FNickname = Value) then
  1365.         Exit;
  1366.     FNickname := Value;
  1367.     Cmd_Nick(FNickname);
  1368. end;
  1369.  
  1370. procedure TIrc.SetRealname(const Value: string);
  1371. begin
  1372.     if (SocketState <> ssDisconnected) then
  1373.         Exit;
  1374.     if (FRealname = Value) then
  1375.         Exit;
  1376.     FRealname := Value;
  1377. end;
  1378.  
  1379. procedure TIrc.SetReconnectWhenKilled(const Value: boolean);
  1380. begin
  1381.     if (FReconnectWhenKilled = Value) then
  1382.         Exit;
  1383.     FReconnectWhenKilled := Value;
  1384. end;
  1385.  
  1386. procedure TIrc.SetRejoinWhenKicked(const Value: boolean);
  1387. begin
  1388.     if (FRejoinWhenKicked = Value) then
  1389.         Exit;
  1390.     FRejoinWhenKicked := Value;
  1391. end;
  1392.  
  1393. procedure TIrc.SetUserMode(const Value: string);
  1394. begin
  1395.     if (FUserMode = Value) then
  1396.         Exit;
  1397.     FUserMode := Value;
  1398.     if (TextLeft(FUserMode, 1) <> CPlus) then
  1399.         FUserMode := CPlus + FUserMode;
  1400. end;
  1401.  
  1402. procedure TIrc.SetUsername(const Value: string);
  1403. begin
  1404.     if (SocketState <> ssDisconnected) then
  1405.         Exit;
  1406.     if (FUsername = Value) then
  1407.         Exit;
  1408.     FUsername := Value;
  1409. end;
  1410.  
  1411. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement