unit koala_main; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, IdTCPConnection, IdTCPClient, IdIRC, IdBaseComponent, IdComponent, IdUDPBase, IdUDPServer, TBXStatusBars, StdCtrls, ExtCtrls, ImgList, TBX, TBXExtItems, TB2ExtItems, TB2Item, TB2Dock, TB2Toolbar, SynEditHighlighter, SynHighlighterPas, SynEdit,koala_types, ComCtrls,udp_rcon, JvExStdCtrls, JvEdit, IdAntiFreezeBase, IdAntiFreeze,IdSocketHandle,parser_css; type Tform_main = class(TForm) logdisplay: TSynEdit; SynPasSyn1: TSynPasSyn; dock_top: TTBXDock; toolbar_main: TTBXToolbar; tb_main_menu_file: TTBXSubmenuItem; tb_main_edit_irc_server: TTBXEditItem; tb_main_label_ircserver: TTBXLabelItem; tb_main_label_ircport: TTBXLabelItem; tb_main_edit_irc_port: TTBXEditItem; tb_main_label_ircroom: TTBXLabelItem; tb_main_edit_irc_room: TTBXEditItem; tb_main_file_exit: TTBXItem; tb_main_connect: TTBXItem; serverlistimages: TImageList; label_serverlog: TLabel; label_ircchat: TLabel; Splitter: TSplitter; memo_irc: TMemo; Label1: TLabel; statusbar: TTBXStatusBar; IRC1: TIdIRC; status_memo: TRichEdit; Splitter1: TSplitter; panel_irc: TPanel; edit_ircinput: TJvEdit; Bevel1: TBevel; dock_mid: TTBXDock; toolbar_log: TTBXToolbar; tb_logging_start: TTBXItem; smallimages: TImageList; IdAntiFreeze: TIdAntiFreeze; Image1: TImage; procedure FormCreate(Sender: TObject); procedure tb_main_connectClick(Sender: TObject); procedure status_memoChange(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure IRC1Connected(Sender: TObject); procedure IRC1Message(Sender: TObject; AUser: TIdIRCUser; AChannel: TIdIRCChannel; Content: String); procedure IRC1Joined(Sender: TObject; AChannel: TIdIRCChannel); procedure IRC1System(Sender: TObject; AUser: TIdIRCUser; ACmdCode: Integer; ACommand, AContent: String); procedure IRC1Join(Sender: TObject; AUser: TIdIRCUser; AChannel: TIdIRCChannel); procedure IRC1Error(Sender: TObject; AUser: TIdIRCUser; ANumeric, AError: String); procedure edit_ircinputKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure IRC1Disconnected(Sender: TObject); procedure tb_logging_startClick(Sender: TObject); procedure UDP1UDPRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle); private { Private declarations } procedure QuickDebug(thestatus:integer;thetext:string); procedure DoStartup(firsttime:boolean); procedure DoShutdown; public { Public declarations } // messages setion, info sent from other programs or from other parts of the program procedure UpdateDebugInfo(var message: TMessage); message WM_UPDATEDEBUG; procedure UpdatePacketData(var message: TMessage); message WM_PACKETDATA; end; type Tkirc = class // helper class for performing server data related functions owner:Tform_main; private gotMOTD :boolean; public function Connected:boolean; constructor Create(theowner:Tform_main); destructor Destroy;override; procedure Connect(host:string;port:integer); procedure Disconnect; procedure JoinChannel(channelname:string); procedure EchoLocalMessage(content:string); procedure EchoLocalSystemMessage(content:string); procedure EchoMessage(AUser: TIdIRCUser; AChannel: TIdIRCChannel; Content: String); procedure EchoSystemMessage(AUser: TIdIRCUser; ACmdCode: Integer; ACommand, AContent: String); procedure CheckSystemMessage(AUser: TIdIRCUser; ACmdCode: Integer; ACommand, AContent: String); procedure Say(channel,text:string); end; type TGUI = class // helper class for GUI functions owner:Tform_main; public constructor Create(theowner:Tform_main); destructor Destroy;override; procedure IRC_connectbutton(connected:boolean); procedure LOG_sendtoirc(sendtoirc:boolean); procedure LOG_updatelog(text:string); end; type TLogParser = class owner:Tform_main; irc:Tkirc; gui:TGUI; parser_css:Tparser_css; public sendtoirc :boolean; logtype :string; // choices : css,hl2dm constructor Create(theowner:Tform_main;theirc:Tkirc;thegui:Tgui); destructor Destroy;override; procedure start; procedure stop; procedure parsetext(text:string); end; var form_main: Tform_main; irc:Tkirc; UDP_rcon:Tudp_rcon; log:Tlogparser; GUI:TGUI; implementation {$R *.dfm} { Tkirc } constructor Tkirc.Create(theowner: Tform_main); begin owner:=theowner; gotMOTD:=false; end; destructor Tkirc.Destroy; begin try if owner.IRC1.Connected then begin Disconnect; end; owner.IRC1.Free; except end; inherited; end; procedure Tkirc.Connect(host: string; port: integer); begin if owner.IRC1.Connected then begin owner.QuickDebug(1,'IRC - Unable to connect - Already Connected'); end else begin owner.QuickDebug(2,'IRC - Attempting to conenct to IRC server '+host+':'+inttostr(port)); owner.IRC1.Host:=host; owner.IRC1.Port:=port; randomize; owner.IRC1.nick:='KoalaBot'; owner.IRC1.AltNick:=owner.IRC1.Nick+inttostr(random(65535)); try owner.IRC1.Connect(5000); except if owner.IRC1.connected=false then owner.QuickDebug(1,'IRC - Unable to connect to server (connection attempt timed out)'); end; end; end; procedure Tkirc.JoinChannel(channelname: string); begin if owner.irc1.connected then try while self.gotMOTD=false do begin sleep(100); application.processmessages; application.processmessages; end; {if owner.irc1.IsChannel(channelname) then }owner.IRC1.Join(channelname); except end; end; procedure Tkirc.EchoLocalMessage(content: string); begin if owner.memo_irc.lines.count>SCROLLBACK then owner.memo_irc.lines.Delete(0); if content<>'' then owner.memo_irc.lines.add('<'+owner.IRC1.nick+'> '+Content); end; procedure Tkirc.EchoLocalSystemMessage(content: string); begin if owner.memo_irc.lines.count>SCROLLBACK then owner.memo_irc.lines.Delete(0); owner.memo_irc.lines.add(Content); end; procedure Tkirc.EchoMessage(AUser: TIdIRCUser; AChannel: TIdIRCChannel; Content: String); begin if owner.memo_irc.lines.count>SCROLLBACK then owner.memo_irc.lines.Delete(0); owner.memo_irc.lines.add('<'+Auser.Nick+'> '+Content); end; procedure Tkirc.EchoSystemMessage(AUser: TIdIRCUser; ACmdCode: Integer; ACommand, AContent: String); begin if owner.memo_irc.lines.count>SCROLLBACK then owner.memo_irc.lines.Delete(0); owner.memo_irc.lines.Add('- ['+inttostr(ACmdCode)+'] '+ACommand+' '+AContent); end; procedure Tkirc.CheckSystemMessage(AUser: TIdIRCUser; ACmdCode: Integer; ACommand, AContent: String); begin if ACmdCode=376 then gotMOTD:=true; if ACmdCode=433 then owner.IRC1.Nick:=owner.IRC1.AltNick; end; procedure Tkirc.Say(channel,text: string); begin if text<>'' then owner.IRC1.Say(channel,text); end; procedure Tkirc.Disconnect; begin owner.QuickDebug(2,'IRC - Disconnecting from IRC server '+owner.IRC1.host+':'+inttostr(owner.IRC1.port)); owner.IRC1.Quit('KoalaBot Terminated'); owner.IRC1.Disconnect(true); end; function Tkirc.Connected: boolean; begin result:=owner.IRC1.Connected; end; // -------------------------------------------------------------------- { TGUI } constructor TGUI.Create(theowner: Tform_main); begin owner:=theowner; end; destructor TGUI.Destroy; begin inherited; end; procedure TGUI.IRC_connectbutton(connected: boolean); begin if connected then begin owner.tb_main_connect.Tag:=1; owner.tb_main_connect.Caption:='Disconnect'; owner.tb_main_connect.ImageIndex:=144; end else begin owner.tb_main_connect.Tag:=0; owner.tb_main_connect.Caption:='Connect'; owner.tb_main_connect.ImageIndex:=140; end; end; procedure TGUI.LOG_sendtoirc(sendtoirc: boolean); begin if sendtoirc then begin owner.tb_logging_start.Tag:=1; owner.tb_logging_start.Caption:='Stop sending info to IRC'; owner.tb_logging_start.ImageIndex:=1; end else begin owner.tb_logging_start.Tag:=0; owner.tb_logging_start.Caption:='Send game information to IRC'; owner.tb_logging_start.ImageIndex:=3; end; end; procedure TGUI.LOG_updatelog(text: string); begin owner.logdisplay.lines.add(text); owner.logdisplay.GotoLineAndCenter(owner.logdisplay.Lines.count); if owner.logdisplay.Lines.count>SCROLLBACK then owner.logdisplay.lines.Delete(0); end; // -------------------------------------------------------------------- { TLogParser } constructor TLogParser.Create(theowner: Tform_main;theirc:Tkirc;thegui:Tgui); begin owner:=theowner; irc:=theirc; gui:=thegui; logtype:='css'; parser_css:=Tparser_css.Create(owner.WindowHandle); end; destructor TLogParser.Destroy; begin parser_css.free; inherited; end; procedure TLogParser.parsetext(text:string); var echotext:string; irctext1:string; irctext2:string; begin // strip header echotext:=copy(text,8,length(text)-7); gui.LOG_updatelog(echotext); // irctext:=copy(text,21,length(text)-20); if self.logtype='css' then begin irctext1:=parser_css.parse(text,true); irctext2:=parser_css.parse(text,false); end; if irc.Connected and self.sendtoirc then begin irc.EchoLocalMessage(irctext2); irc.Say(owner.tb_main_edit_irc_room.text,irctext1); end; end; procedure TLogParser.start; begin owner.quickdebug(0,'Starting to relay information to IRC'); self.sendtoirc:=true; end; procedure TLogParser.stop; begin owner.quickdebug(0,'Stopping relay of information to IRC'); self.sendtoirc:=false; end; // -------------------------------------------------------------------- // -------------------------------------------------------------------- procedure Tform_main.QuickDebug(thestatus: integer; thetext: string); var debug:Pdebugmessage; begin try debug:=new(Pdebugmessage); debug^.category:=thestatus; debug^.text:=thetext; SendMessage(self.handle, WM_UPDATEDEBUG, wparam(debug), lparam(-1)); except end; end; procedure TForm_main.UpdateDebugInfo(var message: TMessage); var debug:Tdebugmessage; begin try debug:=Pdebugmessage(message.wparam)^; status_memo.selAttributes.Color:=clBlack; case debug.category of 0 : status_memo.selAttributes.Color:=clBlack; 1 : status_memo.selAttributes.Color:=clRed; 2 : status_memo.selAttributes.Color:=clGreen; 3 : status_memo.selAttributes.Color:=clOlive; 10 : status_memo.selAttributes.Color:=clOlive; 11 : status_memo.selAttributes.Color:=clOlive; 21 : begin status_memo.selAttributes.Color:=clRed; status_memo.selAttributes.Style:=[fsBold]; end; end; status_memo.lines.add(TimeToStr(Time) +' '+debug.text); finally dispose(Pdebugmessage(message.wparam)); end; end; procedure Tform_main.FormCreate(Sender: TObject); begin dostartup(true); end; procedure Tform_main.tb_main_connectClick(Sender: TObject); begin if tb_main_connect.tag=0 then begin irc.Connect(tb_main_edit_irc_server.Text,strtoint(tb_main_edit_irc_port.text)); irc.JoinChannel(tb_main_edit_irc_room.text); end else begin irc.disconnect; end; end; procedure Tform_main.DoStartup(firsttime: boolean); var var_interface,var_rootport,var_debuglevel,count:integer; tempstring:String; begin quickdebug(0,'---'); quickdebug(2,'KoalaBot 1.0 initialised'); logdisplay.Lines.clear; // init vars irc:=tkirc.Create(self); gui:=TGUI.create(self); log:=Tlogparser.create(self,irc,gui); var_interface:=-1; var_rootport:=10045; var_debuglevel:=-1; quickdebug(0,'Checking Commandline Parameters [first pass]'); for count := 1 to ParamCount do try tempstring:=(ParamStr(count)); if tempstring='-network_interface' then var_interface:=strtoint(paramstr(count+1)); if tempstring='-root_port' then var_rootport:=strtoint(paramstr(count+1)); if tempstring='-debug_level' then var_debuglevel:=strtoint(paramstr(count+1)); except end; debug_level:=var_debuglevel; QuickDebug(2,'Loading UDP components...'); // create UDP components try UDP_rcon:=Tudp_rcon.create(self.WindowHandle,var_interface,var_rootport); except end; end; procedure Tform_main.status_memoChange(Sender: TObject); begin status_memo.Perform(EM_SCROLLCARET, 0, 0); end; procedure Tform_main.FormClose(Sender: TObject; var Action: TCloseAction); begin DoShutdown; end; procedure Tform_main.DoShutdown; begin UDP_rcon.Free; irc.Free; gui.free; log.free; end; procedure Tform_main.IRC1Connected(Sender: TObject); begin quickdebug(0,'IRC - Connection Established'); GUI.IRC_connectbutton(true); end; procedure Tform_main.IRC1Message(Sender: TObject; AUser: TIdIRCUser; AChannel: TIdIRCChannel; Content: String); begin IRC.EchoMessage(Auser,Achannel,Content); end; procedure Tform_main.IRC1Joined(Sender: TObject; AChannel: TIdIRCChannel); begin quickdebug(0,'IRC - Joined Channel '+AChannel.name); IRC.EchoLocalSystemMessage('* Now Talking in #'+AChannel.name); end; procedure Tform_main.IRC1System(Sender: TObject; AUser: TIdIRCUser; ACmdCode: Integer; ACommand, AContent: String); begin IRC.CheckSystemMessage(AUser,ACmdCode,ACommand, AContent); IRC.EchoSystemMessage(AUser,ACmdCode,ACommand, AContent); end; procedure Tform_main.IRC1Join(Sender: TObject; AUser: TIdIRCUser; AChannel: TIdIRCChannel); begin quickdebug(0,'IRC - Atempting to join Channel '+AChannel.name); end; procedure Tform_main.IRC1Error(Sender: TObject; AUser: TIdIRCUser; ANumeric, AError: String); begin quickdebug(0,'IRC - An error occured - ['+ANumeric+'] '+AError); end; procedure Tform_main.edit_ircinputKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin if key=vk_return then begin IRC.say(tb_main_edit_irc_room.text,edit_ircinput.text); IRC.EchoLocalMessage(edit_ircinput.text); edit_ircinput.Clear; end; end; procedure Tform_main.IRC1Disconnected(Sender: TObject); begin quickdebug(0,'IRC - Disconnected'); GUI.IRC_connectbutton(false); end; procedure Tform_main.tb_logging_startClick(Sender: TObject); begin if tb_logging_start.tag=0 then begin IRC.Say(tb_main_edit_irc_room.text,'Game reporting activated'); GUI.LOG_sendtoirc(true); log.start; end else begin IRC.Say(tb_main_edit_irc_room.text,'Game reporting disabled'); GUI.LOG_sendtoirc(false); log.stop; end; end; procedure Tform_main.UDP1UDPRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle); //var //datastring:String; begin //setLength(datastring,Adata.size); //Adata.readBuffer(datastring[1],Adata.size); //log.parsetext(datastring); end; procedure TForm_main.UpdatePacketData(var message: TMessage); var packet:Ppacket; begin try packet:=ppacket(message.lparam); // send packet to control unit for parsing log.parsetext(packet.data); except end; dispose(packet); end; end.