DECLARE SUB FancyFade () DECLARE SUB HandleMessage () DECLARE SUB DoWsaDestruct () DECLARE SUB CheckNetEvent () DECLARE SUB vgaPalette (a%, r%, g%, b%) DECLARE SUB ReadConfig (CFile$, Me$, ident$, host$, realname$, LaunchIRC$) DECLARE SUB SBeep () DECLARE SUB RestoreCodeKey (kind%) DECLARE FUNCTION WhatKind% (Orig$) DECLARE FUNCTION GenKey$ (kind%) DECLARE FUNCTION translate$ (dir%, kind%, Orig$) DECLARE FUNCTION ToMorse$ (a$) DECLARE FUNCTION FromMorse$ (a$) DECLARE FUNCTION IsOp% (NICK$, Chan$) DECLARE FUNCTION RandWord$ (length%) DECLARE FUNCTION mLimit% (inmode$) DECLARE FUNCTION mKey$ (inmode$) DECLARE SUB rest (seconds!) DECLARE FUNCTION undot$ (Orig$) DECLARE SUB lPrivMsg (To$, msg$) DECLARE SUB QueryUserInfo (Me$, ident$, host$, realname$) DECLARE FUNCTION LyxQuery$ (row%, col%, textcolor%, fillcolor%, max%, tmp$) DECLARE SUB ColorPrint (ltp$) DECLARE SUB ToServer (ToSend$) DECLARE FUNCTION GetNick$ (ltp$) DECLARE FUNCTION IsVocal% (in$) DECLARE SUB CapsOn () DECLARE SUB CapsOff () DECLARE SUB Leave (Source$, Target$) DECLARE FUNCTION StripOp$ (Orig$) DECLARE FUNCTION UnTrail$ (Orig$) DECLARE FUNCTION ScanLine$ (row%) DECLARE FUNCTION IsCMode% (Cnum%, ModeChar$) DECLARE SUB split (Orig$) DECLARE SUB Inc (i%) DECLARE FUNCTION Quot$ (in$) DECLARE FUNCTION GetChan% (in$) DECLARE SUB mSplit (Orig$) DECLARE SUB ListChans () DECLARE SUB IRCParse (ltp$) DECLARE SUB NickChange (Oldnick$, Newnick$) DECLARE SUB Signoff (NICK$) DECLARE SUB Dec (v%) DECLARE SUB UpdStatus () DECLARE SUB Clreol () DECLARE FUNCTION CommandParse$ (ltp$) DECLARE FUNCTION StripFirst$ (in$) DECLARE FUNCTION StripBoth$ (in$) DECLARE FUNCTION GetLine$ () DECLARE FUNCTION Stderr$ (SMessage$) DECLARE SUB PAst (typ%) 'DECLARE FUNCTION Spritinfo& 'DECLARE FUNCTION SpritinfoWidth% 'DECLARE FUNCTION SpritinfoDepth% 'DECLARE FUNCTION SpritinfoLength% ' SPRIT, String-Parser for Raw IRC Translation ' ' (fw) 1997, Rasmus Sten ' $INCLUDE: 'sprshare.bas' DIM Out$(1 TO 100) DIM Channel$(1 TO 20) DIM People%(1 TO 100) DIM Names$(1 TO 100) DIM Cmodes$(1 TO 20) DIM mOut$(1 TO 100) CONST TRUE = -1, FALSE = NOT TRUE ' Attention strings CONST INFO = 0, INTERR = 1, CTOPIC = 2, JOIN = 3, PART = 4, mode = 5 CONST CNICK = 6, WHOIS = 7 ' Text style ASCII values (bold, underlined, etc) CONST IRCBOLD = 2, IRCULINE = 31, IRCREV = 22, mIRCSHIT = 3 ' Channel modes CONST Invite = "i", Secret = "s", OpTopic = "t", NoMsg = "n", Keyed = "k" CONST Limited = "l", Private = "p" ' $INCLUDE: 'spritvar.h' ' $INCLUDE: 'wsockqb.bi' ' Definition of module-common variables and constants ' $INCLUDE: 'sprvini.h' ' Definition of the morse code ' $INCLUDE: 'morse.h' DEFINT A-Z DIM SHARED Sign$(FIRSTE TO LASTE + 5), Base$(FIRSTE TO LASTE + 5), PendingKey$ DIM NumHook$(1 TO 1024) DIM DEFAULTSEED(FIRSTE TO LASTE + 5) AS STRING Encrypt(MORSE) = FALSE: Encrypt(SCHLONG) = FALSE Encrypt(VENOM) = FALSE: Encrypt(SPRIT) = FALSE DEFAULTSEED(VENOM) = "DEFGHIJKLMNOPQRSTUVWXYZABCxyzabcdefghijklmnopqrstuvw214365,/09.87" DEFAULTSEED(SCHLONG) = "NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm,/.0987654321" DEFAULTSEED(LATIN1) = CHR$(229) + CHR$(228) + CHR$(246) + CHR$(197) + CHR$(196) + CHR$(214) Sign$(SPRIT) = " *" + CHR$(IRCULINE) + CHR$(IRCULINE) + "[" + CHR$(IRCREV) + CHR$(IRCREV) + CHR$(IRCBOLD) + "SP" Sign$(SPRIT) = Sign$(SPRIT) + "RiT" + CHR$(IRCBOLD) + CHR$(IRCREV) + CHR$(IRCREV) + "]*" Sign$(UDEF1) = " *" + CHR$(IRCULINE) + CHR$(IRCULINE) + "[" + CHR$(IRCREV) + CHR$(IRCREV) + CHR$(IRCBOLD) + "SP" Sign$(UDEF1) = Sign$(UDEF1) + "RiT" + CHR$(IRCBOLD) + CHR$(IRCREV) + CHR$(IRCREV) + "]" + CHR$(IRCREV) + CHR$(IRCREV) + "*" Sign$(UDEF2) = " " + CHR$(IRCREV) + CHR$(IRCREV) + "*" + CHR$(IRCULINE) + CHR$(IRCULINE) + "[" + CHR$(IRCREV) + CHR$(IRCREV) + CHR$(IRCBOLD) + "SP" Sign$(UDEF2) = Sign$(UDEF2) + "RiT" + CHR$(IRCBOLD) + CHR$(IRCREV) + CHR$(IRCREV) + "]*" Sign$(UDEF3) = CHR$(IRCBOLD) + CHR$(IRCBOLD) + " *" + CHR$(IRCULINE) + CHR$(IRCULINE) + "[" + CHR$(IRCREV) + CHR$(IRCREV) + CHR$(IRCBOLD) + "SP" Sign$(UDEF3) = Sign$(UDEF3) + "RiT" + CHR$(IRCBOLD) + CHR$(IRCREV) + CHR$(IRCREV) + "]*" Sign$(UDEF4) = " *[" + CHR$(IRCREV) + CHR$(IRCREV) + CHR$(IRCBOLD) + "SP" Sign$(UDEF4) = Sign$(UDEF4) + "RiT" + CHR$(IRCBOLD) + CHR$(IRCREV) + CHR$(IRCREV) + "]*" Sign$(SPRIT2) = " *" + "[" + CHR$(IRCBOLD) + "SP" + CHR$(IRCREV) Sign$(SPRIT2) = Sign$(SPRIT2) + CHR$(IRCREV) + "RiT/" + CHR$(IRCULINE) + "II" + CHR$(IRCULINE) + CHR$(IRCREV) + CHR$(IRCREV) + CHR$(IRCBOLD) + "]*" Sign$(MORSE) = " *" + CHR$(IRCULINE) + CHR$(IRCULINE) + "[" + CHR$(IRCBOLD) + "SPRiT/" + CHR$(IRCULINE) + "MORSE" + CHR$(IRCULINE) + CHR$(IRCBOLD) + "]*" Sign$(SCHLONG) = " -" + CHR$(IRCULINE) + CHR$(IRCREV) + CHR$(IRCREV) + CHR$(IRCULINE) + CHR$(IRCBOLD) + CHR$(IRCULINE) + CHR$(IRCBOLD) + CHR$(IRCBOLD) + CHR$(IRCULINE) Sign$(SCHLONG) = Sign$(SCHLONG) + "sch" + CHR$(IRCBOLD) + CHR$(IRCBOLD) + "l" + CHR$(IRCBOLD) + CHR$(IRCBOLD) + "ong" + CHR$(IRCBOLD) + "-" Sign$(VENOM) = " -<" + CHR$(IRCBOLD) + CHR$(IRCULINE) + CHR$(IRCREV) + CHR$(IRCREV) + CHR$(IRCULINE) + CHR$(IRCBOLD) + CHR$(IRCULINE) + CHR$(IRCULINE) + "!" + CHR$(IRCBOLD) + "Ve" + CHR$(IRCULINE) + CHR$(IRCULINE) Sign$(VENOM) = Sign$(VENOM) + "No" + CHR$(IRCULINE) + CHR$(IRCULINE) + "M" + CHR$(IRCBOLD) + "!>-" DefaultBase$ = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890./," Base$(SCHLONG) = DefaultBase$ Base$(VENOM) = DefaultBase$ Base$(SPRIT) = DefaultBase$ + " †„”Ž™!" + CHR$(34) + "@#$%&(){[]}\=`'*_-:;<>|~" Base$(UDEF1) = Base$(SPRIT) Base$(UDEF2) = Base$(SPRIT) Base$(UDEF3) = Base$(SPRIT) Base$(UDEF4) = Base$(SPRIT) Base$(LATIN1) = "†„”Ž™" RestoreCodeKey LATIN1 ' Default messages IF DefMes$(KICK) = "" THEN DefMes$(KICK) = "Drick " + CHR$(IRCULINE) + "SPR" + CHR$(IRCBOLD) + "I" + CHR$(IRCBOLD) + "T" + CHR$(IRCULINE) + "!" DIM WaitFor$(1 TO 10), ThenSend$(1 TO 10), InitStr$(1 TO 10) FOR a = FIRSTE TO LASTE IF Seed$(a) = "" THEN RestoreCodeKey a NEXT RANDOMIZE TIMER NoMOTD = FALSE PostTakeOver = FALSE HideNAMES = 0 HideMODE = 0 Channels% = 0 Me$ = "" WIDTH , 50 ' 50 rows CLS vpage = 0 ' screen to be visual at start SCREEN , , 1, vpage LOCATE 49, 1 SCREEN , , 0, vpage ' back to active screen 0 IQuit = FALSE StdIn = TRUE 'ifn = FREEFILE 'ON ERROR GOTO InitFileError 'StdIn = FALSE 'OPEN "sprit.rc" FOR INPUT AS ifn ServerHost$ = "" ComSetup$ = "Com1:9600,n,8,1" ReadConfig "sprit.cfg", Me$, ident$, host$, realname$, LaunchIRC$ ' Init winsock ReturnValue% = WSInit ' If WSOCKXS.VXD is not loaded, run WSLOADER.EXE IF ReturnValue% = -4 THEN SHELL "WSLOADER.EXE" t0! = TIMER DO UNTIL ReturnValue% <> -4 OR TIMER - t0! > 1 ' Wait maximum one second ReturnValue% = WSInit LOOP IF ReturnValue% <> 0 THEN PRINT "Error initializing WSXS. Error: "; ReturnValue% ReturnValue& = WSACleanup DisableMessage SelfDestruct SYSTEM END IF ' * more WSA stuff DIM SHARED wsadata AS wsadataStruc retVal% = WSAStartup(&H202, wsadata) PRINT "* Starting winsock... " ' * end of WSA stuff IF LaunchIRC$ = "" THEN LaunchIRC$ = "'^]'." 'PRINT "+ Enter setup mode (y/N)?" 'in$ = LCASE$(INPUT$(1)) 'IF in$ = "y" THEN QueryUserInfo Me$, ident$, host$, RealName$ PRINT "* Checking encryption keys..."; IF Seed$(SPRIT) = "" THEN Seed$(SPRIT) = GenKey$(SPRIT) FOR a = UDEF1 TO UDEF4 IF Seed$(a) = "" THEN Seed$(a) = GenKey$(a) NEXT IF Seed$(SPRIT2) = "" THEN Seed$(SPRIT2) = "Sprit rox my Ass" PRINT "OK." 'IF CSRLIN < 46 THEN ' VIEW PRINT CSRLIN + 1 TO 49 'ELSE ' VIEW PRINT 36 TO 49 'END IF 'CLS IF ServerHost$ = "" THEN COM(1) ON ELSE DIM SHARED IrcRecv AS STRING * 1024 END IF Foo: IF ServerHost$ = "" THEN PRINT "Opening COM device..." CChan = FREEFILE OPEN ComSetup$ + ",RB9216" FOR RANDOM AS CChan ON COM(1) GOSUB ComEvent ELSE IF inetaddr(ip$) <> INADDRNONE THEN IPAddr$ = inetaddr(ServerHost$) ELSE PRINT "* Resolving IRC Host... "; ResolveName ServerHost$, a$, b$, c%, d%, IPAddr$, 0, e& END IF PRINT inetntoa(IPAddr$) END IF ' Serial login IF ServerHost$ = "" THEN PRINT #CChan, CHR$(13) PRINT "Wait..." SLEEP 1 PRINT "Logging in..." ByteCount& = 0 Waited = 1: Inited = 1 DO IF NOT EOF(1) THEN tmp$ = INPUT$(1, CChan) ByteCount& = ByteCount& + 1 IF InitStr$(Inited) <> "" THEN PRINT #CChan, InitStr$(Inited) Inc Inited END IF IF WaitFor$(Waited) <> "" THEN IF LEN(MiniBuf$) >= LEN(WaitFor$(Waited)) THEN IF RIGHT$(MiniBuf$, LEN(WaitFor$(Waited))) = WaitFor$(Waited) THEN PRINT #CChan, ThenSend$(Waited) Inc Waited END IF END IF END IF IF (ByteCount& MOD 256) = 0 THEN OldX = POS(0): OldY = CSRLIN LOCATE 50, 1: PRINT ByteCount&; : LOCATE OldY, OldX END IF IF INSTR(MiniBuf$, " closed by foreign host.") > 0 GOTO LoginProblem IF (INSTR(MiniBuf$, LaunchIRC$) > 0) THEN EXIT DO IF tmp$ <> CHR$(10) THEN MiniBuf$ = MiniBuf$ + tmp$ IF tmp$ = CHR$(13) THEN PRINT translate$(0, LATIN1, MiniBuf$); : MiniBuf$ = "" tmp$ = "" a$ = INKEY$ IF a$ = CHR$(27) THEN END ELSEIF a$ = " " THEN GOTO LoginProblem END IF LOOP ELSE DIM SHARED Message AS MessageStruc DIM SHARED PostponedMessage AS MessageStruc DIM SHARED MessageToHandle AS MessageStruc DIM SHARED HasPostponedMessage AS INTEGER HasPostponedMessage = 0 EnableMessage DIM SHARED NewSocket& NewSocket& = socket(AFINET, SOCKSTREAM, IPPROTOTCP) 'PRINT "Allocated TCP socket... "; HEX$(NewSocket&) PRINT "* Connecting... "; DIM SHARED ConnectBuffer AS sockaddr ConnectBuffer.sinfamily = 2 ConnectBuffer.sinport = htons(6667) ConnectBuffer.sinaddr = IPAddr$ ConnectBuffer.sinzero = STRING$(8, 0) retVal& = WSAAsyncSelect(NewSocket&, GetHWnd, &H401, FDCONNECT) IF retVal& <> 0 THEN PRINT "WSAAsyncSelect() failed: "; WSAGetLastError GOSUB WsaDestruct SYSTEM END IF retVal& = connect(NewSocket&, ConnectBuffer, LEN(ConnectBuffer)) IF retVal& <> 0 THEN errCode& = WSAGetLastError IF errCode& <> WSAEWOULDBLOCK THEN PRINT "Error connecting to host: error "; retVal& PRINT "Error code: "; errCode& IF errCode& = WSAECONNREFUSED THEN PRINT "(Connection refused.)" END IF GOSUB WsaDestruct SYSTEM END IF END IF DO IF INKEY$ <> "" THEN PRINT "Aborted by user." GOSUB WsaDestruct SYSTEM END IF LOOP UNTIL GetMessage(Message) IF GetHigh16(Message.lParam) = 0 THEN PRINT "OK!" ELSE PRINT "Connect error: "; GetHigh16(Message.lParam) GOSUB WsaDestruct SYSTEM END IF retVal& = WSAAsyncSelect(NewSocket&, GetHWnd, &H401, FDREAD + FDCLOSE) IF (retVal& <> 0) THEN PRINT "Error setting socket in asynch mode: "; WSAGetLastError GOSUB WsaDestruct SYSTEM END IF END IF QueryUserInfo Me$, ident$, host$, realname$ NickSeq$ = "NICK " + Me$ UserSeq$ = "USER " + ident$ + " " + host$ + " localhost :" + realname$ PRINT "* Sending user data to server..." ToServer NickSeq$ ToServer UserSeq$ PRINT "* Waiting for server reply..." DO IF INKEY$ <> "" THEN PRINT "Aborted by user." GOSUB WsaDestruct SYSTEM END IF LOOP UNTIL GetMessage(Message) PostponedMessage = Message HasPostponedMessage = 1 VIEW PRINT 1 TO 48 CLS LOCATE 48, 1 InitSeq = 0 ON ERROR GOTO 0 GOSUB Minute TIMER ON ON TIMER(60) GOSUB Minute ' Update status every 60 seconds IF COMMAND$ <> "" THEN ' do we have a command line? nf = FREEFILE OPEN COMMAND$ FOR INPUT AS nf StdIn = FALSE ' yep, then use it rather than stdin END IF DO WHILE NOT IQuit ' MAIN LOOP IF StdIn = FALSE THEN ' Do we use stdin or file input? IF nf > 0 THEN LINE INPUT #nf, ltp$ ' read one line from file IF EOF(nf) THEN StdIn = TRUE: CLOSE nf ' if eof, close and fall ELSE ' back to stdin LINE INPUT #ifn, ltp$ IF EOF(ifn) THEN StdIn = TRUE: CLOSE ifn END IF ELSE ltp$ = CommandParse$(GetLine$) ' now it's stdin; invoke interface END IF ToServer ltp$ 'IF Me$ = "" THEN IRCParse Stderr$("You don't have a nickname") LOOP CLOSE GOSUB WsaDestruct END WsaDestruct: DoWsaDestruct RETURN Minute: Inc elapsed UpdStatus ' update the status bar 'IF MID$(TIME$, 4, 2) = "00" THEN ' if new hours, politely inform the user ' PAst INFO ' COLOR 13: PRINT "The time is "; ' COLOR 15: PRINT TIME$ 'END IF IF Idle = LastIdle THEN Inc IdleMinutes 'IF (IdleMinutes MOD 5) = 0 THEN IF vpage <> 2 THEN vpage = 2 ELSE vpage = 0 ELSE IdleMinutes = 0 END IF SCREEN , , 0, vpage LastIdle = Idle RETURN ' back to whatever InitFileError: IF ERR = 53 THEN PAst INTERR COLOR 12: PRINT "No rc file (sprit.rc)." ELSE COLOR 12: PRINT "" END IF StdIn = TRUE RESUME NEXT AnyError: IRCParse ":" + Me$ + " QUIT :errorcode" + STR$(ERR) RESUME NEXT ComEvent: DO UNTIL EOF(CChan) Cin$ = INPUT$(1, CChan) ' PRINT Cin$; ByteCount& = ByteCount& + 1 'SBeep IF (Cin$ = CHR$(10)) OR (Cin$ = CHR$(13)) THEN 'SCREEN , , 3, vpage 'PRINT ComBuffer$ 'SCREEN , , 3, vpage ComBuffer$ = translate$(0, LATIN1, ComBuffer$) IF LEFT$(ComBuffer$, 5) = "ERROR" THEN CurY = CSRLIN: CurX = POS(0) VIEW PRINT 1 TO 48 LOCATE 48, 1 IF INSTR(ComBuffer$, "Closing Link") > 0 THEN PAst INTERR: COLOR 12 fp = INSTR(ComBuffer$, "(") PRINT "Connection closed: "; ColorPrint MID$(ComBuffer$, fp + 1, LEN(ComBuffer$) - fp - 1) PRINT #CChan, "exit" END ELSE PRINT ComBuffer$ END IF IF CurY > 48 THEN VIEW PRINT 49 TO 50 LOCATE 50, CurX END IF END IF IRCParse ComBuffer$ ComBuffer$ = "" ELSE IF Cin$ <> CHR$(13) THEN ComBuffer$ = ComBuffer$ + Cin$ END IF LOOP RETURN LoginProblem: COLOR 12 PRINT "Houston, we have a problem." IF ServerHost$ = "" THEN PRINT #CChan, "quit :error 42: rebooting universe" PRINT #CChan, "exit" PRINT #CChan, "+++" END IF COLOR 15 MiniBuf$ = "" CLOSE CChan GOTO Foo DEFSNG A-Z SUB CapsOff STATIC DEF SEG = 0 POKE &H417, PEEK(&H417) AND &HBF DEF SEG END SUB SUB CapsOn STATIC ' ok, it's stolen, but I just had to have it DEF SEG = 0 POKE &H417, PEEK(&H417) OR &H40 DEF SEG END SUB DEFINT A-Z SUB CheckNetEvent STATIC SHARED ByteCount& DIM hmsg AS MessageStruc IF HasPostponedMessage <> 0 THEN MessageToHandle = PostponedMessage HandleMessage HasPostponedMessage = 0 END IF IF GetMessage(Message) THEN MessageToHandle = Message HandleMessage END IF END SUB DEFSNG A-Z SUB Clreol PRINT SPACE$(80 - POS(0)); LOCATE , 1 END SUB DEFINT A-Z SUB ColorPrint (Orig$) ltp$ = Orig$ IF (INSTR(ltp$, CHR$(2)) = 0) AND (INSTR(ltp$, CHR$(31)) = 0) THEN COLOR 7: PRINT ltp$ ELSE FOR a = FIRSTE TO LASTE IF INSTR(ltp$, Sign$(a)) > 0 THEN ltp$ = translate$(0, a, ltp$) IF a = MORSE THEN ParseMorse = TRUE: split ltp$ COLOR 15: PRINT "["; : COLOR 9: PRINT CodeId$(a); : COLOR 15: PRINT "] "; END IF NEXT ' IF INSTR(ltp$, MorseSign$) > 0 THEN ParseMorse = TRUE: split ltp$: CodeId$ = "Morse" Reverse = FALSE: BOLD = FALSE: ULINE = FALSE: COLOR 7 FOR i = 1 TO LEN(ltp$) IF MID$(ltp$, i, 1) = CHR$(2) THEN IF BOLD = TRUE THEN BOLD = FALSE IF ULINE = TRUE THEN COLOR 3 ELSE COLOR 7 ELSE BOLD = TRUE IF ULINE = TRUE THEN COLOR 11 ELSE COLOR 15 END IF ELSEIF MID$(ltp$, i, 1) = CHR$(31) THEN IF ULINE = TRUE THEN ULINE = FALSE IF BOLD = TRUE THEN COLOR 15 ELSE COLOR 7 ELSE ULINE = TRUE IF BOLD = TRUE THEN COLOR 11 ELSE COLOR 3 END IF ELSEIF MID$(ltp$, i, 1) = CHR$(22) THEN IF Reverse = TRUE THEN IF (ULINE = TRUE) AND (BOLD = TRUE) THEN COLOR 11 ELSEIF ULINE = TRUE THEN COLOR 3 ELSEIF BOLD = TRUE THEN COLOR 15 ELSE COLOR 7 END IF COLOR , 0: Reverse = FALSE ELSE IF ULINE = TRUE THEN COLOR 0, 3 ELSE COLOR 0, 7 END IF Reverse = TRUE END IF ELSEIF ASC(MID$(ltp$, i, 1)) < 31 THEN PRINT "<"; ASC(MID$(ltp$, i, 1)); ">"; ELSEIF ParseMorse AND (MID$(ltp$, i, 1) = " ") THEN Inc w Ut$ = FromMorse$(Out$(w)) PRINT Ut$; ELSEIF NOT ParseMorse THEN PRINT MID$(ltp$, i, 1); END IF NEXT COLOR 7, 0 PRINT END IF END SUB FUNCTION CommandParse$ (ltp$) Inc Idle Source$ = "" IF ltp$ = "" THEN EXIT FUNCTION IF LEFT$(ltp$, 1) = "/" THEN ltp$ = RIGHT$(ltp$, LEN(ltp$) - 1) ELSEIF Query$ <> "" THEN FOR a = LASTE TO FIRSTE STEP -1 IF Encrypt(a) THEN ltp$ = translate$(1, a, ltp$) NEXT lPrivMsg Query$, ltp$ CommandParse$ = Source$ + " PRIVMSG " + Query$ + " :" + ltp$ EXIT FUNCTION END IF split ltp$ ' split'er up Out$(1) = LCASE$(Out$(1)) SELECT CASE Out$(1) ' this stuff is pathetically unfancy. CASE IS = "query" Query$ = StripFirst$(ltp$) CASE IS = "quit" CommandParse$ = Source$ + " QUIT :" + StripFirst$(ltp$) IQuit = TRUE CASE IS = "nick" CommandParse$ = Source$ + " NICK " + Out$(2) LastMe$ = Me$ Me$ = Out$(2) CASE IS = "join" CommandParse$ = Source$ + " JOIN " + Out$(2) + " " + Out$(3) CASE IS = "chans" ListChans CASE IS = "topic", IS = "t" IF (Query$ <> "") AND (StripFirst(ltp$) = "") THEN CommandParse$ = Source$ + " TOPIC " + Query$ ELSE SELECT CASE LEFT$(Out$(2), 1) CASE IS = "#", IS = "&", IS = "+" CommandParse$ = Source$ + " TOPIC " + Out$(2) + " :" + StripBoth$(ltp$) CASE ELSE IF Query$ <> "" THEN CommandParse$ = Source$ + " TOPIC " + Query$ + " :" + StripFirst$(ltp$) ELSE CommandParse$ = Source$ + " TOPIC " + StripFirst$(ltp$) END IF END SELECT END IF CASE IS = "names", IS = "sc" IF (Query$ <> "") AND (Out$(2) = "") THEN CommandParse$ = Source$ + " NAMES " + Query$ ELSE CommandParse$ = Source$ + " NAMES " + Out$(2) END IF CASE IS = "who", IS = "w" IF (Query$ <> "") AND (Out$(2) = "") THEN CommandParse$ = Source$ + " WHO " + Query$ ELSE CommandParse$ = Source$ + " WHO " + Out$(2) END IF CASE IS = "whois", IS = "wi" CommandParse$ = Source$ + " WHOIS " + StripFirst$(ltp$) CASE IS = "parse" nf = FREEFILE OPEN Out$(2) FOR INPUT AS nf StdIn = FALSE CASE IS = "resetcryptkey", IS = "rck" VIEW PRINT 1 TO 48: COLOR , 0 LOCATE 48, 1 kind = WhatKind(Out$(2)) IF (kind = -1) AND (Out$(2) <> "") THEN PAst INTERR: COLOR 12: PRINT "No such code type" ELSEIF Out$(2) = "" THEN kind = SPRIT END IF IF kind <> -1 THEN RestoreCodeKey kind PAst INFO: COLOR 9: PRINT CodeId$(kind); COLOR 15: PRINT " restored to default." END IF CASE IS = "gencryptkey", IS = "gck" VIEW PRINT 1 TO 48: COLOR , 0 LOCATE 48, 1 PAst INFO: COLOR 15 PRINT "Generating new encryption key. /sendkey [codetype] to send." IF Out$(2) = "" THEN Seed$(SPRIT) = GenKey$(SPRIT) ELSE wk = WhatKind(Out$(2)) IF wk = -1 THEN PAst INTERR: COLOR 12: PRINT "Uh-no. I don't know that one." ELSE Seed$(wk) = GenKey$(wk) END IF END IF CASE IS = "savekey" VIEW PRINT 1 TO 48: COLOR , 0 LOCATE 48, 1 wk = WhatKind(Out$(2)) IF Out$(2) = "" THEN wk = SPRIT END IF IF wk > -1 THEN skf = FREEFILE OPEN "keys.dta" FOR APPEND AS skf PRINT #skf, "Key " + CodeId$(wk) + " " + Seed$(wk) CLOSE skf ELSE PAst INTERR: COLOR 12: PRINT "Please enter a valid code type." END IF CASE IS = "sendkey" VIEW PRINT 1 TO 48: COLOR , 0 LOCATE 48, 1 IF Out$(3) = "" THEN kind = SPRIT ELSE kind = WhatKind(Out$(3)) END IF IF Out$(2) = "" THEN PAst INTERR: COLOR 12: PRINT "Please supply target nickname or channel." ELSEIF kind = -1 THEN PAst INTERR: COLOR 12: PRINT "No such code type." ELSE PAst INFO: COLOR 15 PRINT "Sending "; : COLOR 9: PRINT CodeId$(kind); COLOR 15: PRINT " key to "; : COLOR 13: PRINT Out$(2); COLOR 15: PRINT "." CommandParse$ = Source$ + " PRIVMSG " + Out$(2) + " :" + CHR$(1) + "CRYPTKEY " + Seed$(kind) + CHR$(1) END IF CASE IS = "putkey" VIEW PRINT 1 TO 48: COLOR , 0 LOCATE 48, 1 kind = WhatKind(Out$(2)) IF Out$(2) = "" THEN kind = SPRIT IF kind = -1 THEN PAst INTERR: COLOR 12: PRINT "No such code type." ELSEIF PendingKey$ = "" THEN PAst INTERR: COLOR 12: PRINT "No key has been received." ELSE PAst INFO: COLOR 15 PRINT "Received key now active for "; : COLOR 9 PRINT CodeId$(kind); : COLOR 15 PRINT " code." Seed$(kind) = PendingKey$ END IF CASE IS = "code" VIEW PRINT 1 TO 48: COLOR , 0 LOCATE 48, 1 IF Out$(2) <> "" THEN kind = WhatKind(Out$(2)) IF kind = -1 GOTO NoOpt MID$(Out$(2), 1) = UCASE$(MID$(Out$(2), 1, 1)) PAst INFO: COLOR 13 PRINT Out$(2); : COLOR 15 PRINT " code "; IF Encrypt(kind) THEN Encrypt(kind) = FALSE PRINT "disabled." ELSE Encrypt(kind) = TRUE PRINT "enabled." END IF ELSE NoOpt: PAst INFO: COLOR 15: PRINT "Available: "; COLOR 9 FOR i = FIRSTE TO LASTE PRINT CodeId$(i); " "; NEXT PRINT PAst INFO: COLOR 15: PRINT "Active: "; COLOR 9 FOR i = FIRSTE TO LASTE IF Encrypt(i) THEN PRINT CodeId$(i); " "; NEXT PRINT END IF CASE IS = "kick", IS = "k" SELECT CASE LEFT$(Out$(2), 1) CASE IS = "#", IS = "&", IS = "+" KickMes$ = StripFirst$(StripBoth$(ltp$)) IF KickMes$ = "" THEN KickMes$ = DefMes$(KICK) CommandParse$ = Source$ + " KICK " + Out$(2) + " " + Out$(3) + " :" + KickMes$ CASE ELSE IF Query$ <> "" THEN KickMes$ = StripBoth$(ltp$) IF KickMes$ = "" THEN KickMes$ = DefMes$(KICK) CommandParse$ = Source$ + " KICK " + Query$ + " " + Out$(2) + " :" + KickMes$ ELSE KickMes$ = StripBoth$(ltp$) IF KickMes$ = "" THEN KickMes$ = DefMes$(KICK) CommandParse$ = Source$ + " KICK " + Channel$(Channels%) + " " + Out$(2) + " :" + KickMes$ END IF END SELECT CASE IS = "rmkey" IF Out$(2) = "" THEN IF Query$ = "" THEN Chan = Channels% ELSE Chan = GetChan(Query$) END IF ELSE Chan = GetChan(Out$(2)) END IF IF Chan > 0 THEN CommandParse$ = Source$ + " MODE " + Channel$(Chan) + " -k " + mKey$(Cmodes$(Chan)) END IF CASE IS = "randkey", IS = "rndkey", IS = "randomkey" IF Out$(2) = "" THEN IF Query$ = "" THEN Chan = Channels% ELSE Chan = GetChan(Query$) END IF ELSE Chan = GetChan(Out$(2)) END IF IF Chan > 0 THEN IF mKey$(Cmodes$(Chan)) <> "" THEN ToServer Source$ + " MODE " + Channel$(Chan) + " -k " + mKey$(Cmodes$(Chan)) CommandParse$ = Source$ + " MODE " + Channel$(Chan) + " +k " + RandWord$(INT(RND * 4) + 3) END IF CASE IS = "takeover" TC$ = StripFirst$(ltp$) CurY = CSRLIN: CurX = POS(0): VIEW PRINT 1 TO 48: COLOR , 0 LOCATE 48 PAst INFO: COLOR 15 IF LCASE$(TC$) = "off" THEN TakeOver$ = "" PRINT "Takeover mode now disabled." ELSEIF LCASE$(TC$) = "" THEN IF TakeOver$ <> "" THEN PRINT "Takeover mode is active for "; COLOR 13: PRINT TakeOver$ ELSE PRINT "Takeover mode is disabled. Good boy." END IF ELSE TakeOver$ = TC$ PRINT "Setting takeover target to "; COLOR 13: PRINT TakeOver$ END IF IF CurY > 48 THEN VIEW PRINT 49 TO 50: LOCATE CurY, CurX CASE IS = "clear" CLS CASE IS = "part" CommandParse$ = Source$ + " PART " + Out$(2) '--- CTCP stuff CASE IS = "p", IS = "ping" ' CTCP PING using int(timer) ToServer Source$ + " PRIVMSG " + Out$(2) + " :" + CHR$(1) + "PING" + STR$(INT(TIMER)) + CHR$(1) CASE IS = "me" IF Query$ <> "" THEN Target$ = Query$ msg$ = translate$(1, LATIN1, StripFirst$(ltp$)) ELSE Target$ = Out$(2) msg$ = translate$(1, LATEIN1, StripBoth$(ltp$)) END IF cmd$ = "PRIVMSG " + Target$ + " :" + CHR$(1) + "ACTION " + msg$ + CHR$(1) IRCParse (":" + Me$ + " " + cmd$) CommandParse$ = cmd$ CASE IS = "ctcp" ToServer "PRIVMSG " + Out$(2) + " :" + CHR$(1) + StripBoth$(ltp$) + CHR$(1) '--- CASE IS = "m", IS = "msg" SMessage$ = StripBoth$(ltp$) FOR a = LASTE TO FIRSTE STEP -1 IF Encrypt(a) THEN SMessage$ = translate$(1, a, SMessage$) NEXT CommandParse$ = Source$ + " PRIVMSG " + Out$(2) + " :" + SMessage$ lPrivMsg Out$(2), SMessage$ CASE IS = "eo" ' this one is REALLY ugly - coz DOS+QB can't do SCREEN , , 3, vpage ' it better SHELL StripBoth$(ltp$) + ">_sd0" SCREEN , , 0, vpage nf = FREEFILE OPEN "_sd0" FOR INPUT AS nf anf = FREEFILE OPEN "_sd1" FOR OUTPUT AS anf DO UNTIL EOF(nf) LINE INPUT #nf, Foo$ Foo$ = Source$ + " PRIVMSG " + Out$(2) + " :" + Foo$ PRINT #anf, Foo$ LOOP CLOSE nf, anf KILL "_sd0" nf = FREEFILE OPEN "_sd1" FOR INPUT AS nf StdIn = FALSE CASE IS = "exec" SCREEN , , 3 SHELL StripFirst$(ltp$) SCREEN , , 0, vpage CASE IS = "quote" CommandParse$ = Source$ + " " + StripFirst$(ltp$) CASE IS = "mode" CommandParse$ = Source$ + " MODE " + StripFirst$(ltp$) CASE ELSE CurY = CSRLIN: CurX = POS(0) VIEW PRINT 1 TO 48: COLOR , 0 LOCATE 48 PAst INTERR: COLOR 15: PRINT "Say what?!" IF CurY > 48 THEN VIEW PRINT 49 TO 50: LOCATE CurY, CurX END SELECT END FUNCTION SUB Dec (v) v = v - 1 END SUB SUB DoWsaDestruct ' Cleanup WSA ReturnValue& = WSACleanup DisableMessage SelfDestruct END SUB SUB FancyFade DIM r(0 TO 63), g(0 TO 63), b(0 TO 63) FOR a = 0 TO 63 r(a) = -1 vgaPalette a, r(a), g(a), b(a) ore = r(a): ogr = g(a): obl = b(a) DO IF r(a) < 63 THEN Inc r(a) IF g(a) < 63 THEN Inc g(a) IF b(a) < 63 THEN Inc b(a) vgaPalette a, r(a), g(a), b(a) LOOP UNTIL (r(a) = 63) AND (g(a) = 63) AND (b(a) = 63) DO IF r(a) > ore THEN Dec r(a) IF g(a) > ogr THEN Dec g(a) IF b(a) > obl THEN Dec b(a) vgaPalette a, r(a), g(a), b(a) LOOP UNTIL (r(a) = ore) AND (g(a) = ogr) AND (b(a) = obl) NEXT END SUB FUNCTION FromMorse$ (a$) STATIC FromMorse$ = a$ FOR a = 1 TO UBOUND(MorseCode$) IF a$ = MorseCode$(a) THEN FromMorse$ = MID$(MORSEALPHA, a, 1) EXIT FOR END IF NEXT END FUNCTION FUNCTION GenKey$ (kind) lb = LEN(Base$(kind)) FOR a = 1 TO lb DO t$ = MID$(Base$(kind), INT(RND * lb) + 1, 1) LOOP WHILE INSTR(tmp$, t$) > 0 tmp$ = tmp$ + t$ NEXT GenKey$ = tmp$ END FUNCTION FUNCTION GetChan (in$) FOR i = 1 TO Channels% IF LCASE$(Channel$(i)) = LCASE$(in$) THEN EXIT FOR NEXT IF i <= Channels% THEN GetChan = i ELSE GetChan = FALSE END IF END FUNCTION FUNCTION GetLine$ STATIC ' need to remember command history, etc CurY = CSRLIN: CurX = POS(0) ' store cursor position 'UpdStatus ' statusbar again LOCATE 50, 1 PRINT SPACE$(79); LOCATE 50, 1 COLOR 11 ' init the variables to nice default values tmp$ = "" IF CBuf = 0 THEN CBuf = 49 IF LastChan = 0 THEN LastChan = Channels% LOCATE , 1 knapp$ = "" DO WHILE knapp$ <> CHR$(13) ' keyparsing loop knapp$ = "" IF LEN(tmp$) + 1 < 80 THEN LOCATE , LEN(tmp$) + 1, 0 ' LOCATE 50, , 1, 14, 15 DO UNTIL knapp$ <> "" ' wait for a key IF ServerHost$ <> "" THEN CheckNetEvent ' AbsY = CSRLIN: AbsX = POS(0) ' store cursor position knapp$ = INKEY$ LOCATE , , 1 IF LEN(tmp$) = 0 THEN LOCATE , 1 ' IF AbsY < 49 THEN VIEW PRINT 1 TO 48 ' LOCATE AbsY, AbsX LOOP 'LOCATE , LEN(tmp$) + 1, 0 SELECT CASE ASC(knapp$) ' work on ASCII value CASE IS = 0 ' is it a scan code? SELECT CASE ASC(RIGHT$(knapp$, 1)) ' up arrow CASE IS = &H30 ' ALT-B COLOR 0, 7: PRINT "B"; : COLOR 11, 0 tmp$ = tmp$ + CHR$(IRCBOLD) CASE IS = &H16 ' ALT-U COLOR 0, 7: PRINT "U"; : COLOR 11, 0 tmp$ = tmp$ + CHR$(IRCULINE) CASE IS = &H13 ' ALT-R COLOR 0, 7: PRINT "R"; : COLOR 11, 0 tmp$ = tmp$ + CHR$(IRCREV) CASE IS = &H2E COLOR 0, 7: PRINT "C"; : COLOR 11, 0 ' ALT-C tmp$ = tmp$ + CHR$(mIRCSHIT) CASE IS = &H2C ' ALT-Z IF Rovare = TRUE THEN Rovare = FALSE ELSE Rovare = TRUE CASE IS = &H32 ' ALT-M IF IMorse = TRUE THEN IMorse = FALSE ELSE IMorse = TRUE CASE IS = &H24 IF LastInvite$ <> "" THEN ToServer "JOIN " + LastInvite$ ELSE SBeep END IF CASE IS = &H48 SCREEN , , 1, 0 ' look at buffer screen Dec CBuf IF CBuf < 1 THEN CBuf = 48 tmp$ = ScanLine$(CBuf) ' read buffer line SCREEN , , 0, vpage ' back to IRC screen LOCATE , 1: Clreol PRINT tmp$; CASE IS = &H50 ' down arrow, same stuff as SCREEN , , 1, 0 ' above Inc CBuf IF CBuf > 48 THEN CBuf = 1 tmp$ = ScanLine$(CBuf) SCREEN , , 0 LOCATE , 1: Clreol PRINT tmp$; CASE IS = &H44 Inc vpage IF vpage > 3 THEN vpage = 0 END SELECT CASE IS = 1 ' c-a,b and c changes visual vpage = 0 ' screen CASE IS = 2 vpage = 1 CASE IS = 3 vpage = 2 CASE IS = 4 ' a silly DOS shell just coz SCREEN , , 3 ' it's simple. some DOS programs SHELL ' freaks out when the act screen SCREEN , , 0 ' isn't on page 0 CASE IS = 5 IF elajt = TRUE THEN ' I keep quiet about this one elajt = FALSE ' to save me the embarrasment :P CapsOff ELSE elajt = TRUE END IF CASE IS = 9 ' TAB is a shortkey IF nc = TRUE THEN Inc LastChan ' to cycle through IF LastChan > Channels% THEN LastChan = 1 ' all channels IF Channels% > 0 THEN IF LastChan < 1 THEN LastChan = 1 tmp$ = "/m " + Channel$(LastChan) + " " nc = TRUE LOCATE , 1: Clreol ' types out /m #somechannel PRINT tmp$; END IF CASE IS = 8 ' backspace. erase on screen and IF LEN(tmp$) > 0 THEN ' cut the string LOCATE , POS(0) - 1: PRINT " "; : LOCATE , POS(0) - 1 tmp$ = LEFT$(tmp$, LEN(tmp$) - 1) END IF CASE IS = 27 ' ESC, quits. sends a /quit. SCREEN , , 0, vpage ToServer "QUIT :" + translate$(1, SPRIT, Client$ + " v" + Version$ + " gives up after" + CHR$(IRCULINE) + STR$(elapsed) + CHR$(IRCULINE) + " minutes") knapp$ = CHR$(13) CASE IS > 31 ' ASCII value is > 31 = alphanum IF elajt THEN IF IsVocal(knapp$) THEN knapp$ = LCASE$(knapp$) CapsOff ELSE knapp$ = UCASE$(knapp$) CapsOn END IF ELSEIF Rovare THEN IF (NOT IsVocal(knapp$)) AND (knapp$ <> CHR$(32)) THEN knapp$ = knapp$ + "o" + knapp$ END IF ELSEIF IMorse THEN knapp$ = ToMorse$(knapp$) + " " END IF PRINT knapp$; tmp$ = tmp$ + knapp$ END SELECT IF vpage = 0 THEN LOCATE , , 1, 14, 15 ELSE LOCATE , , 0 END IF SCREEN , , 0, vpage ' show the screen the user wants LOOP ' to see, but keep page 0 as act nc = FALSE IF IMorse THEN tmp$ = tmp$ + Sign$(MORSE) SCREEN , , 1, vpage ' my evil buffer trick. switch to PRINT tmp$ ' page 1, print the line, switch SCREEN , , 0, vpage ' back CBuf = 49 ' make us read the correct buffer line next time GetLine$ = tmp$ ' transfer input buffer to the return string VIEW PRINT 1 TO 48 ' define the viewport to the rest of the screen 'IF CurY > 48 THEN CurY = 48 'LOCATE CurY, CurX ' restore cursor position END FUNCTION FUNCTION GetNick$ (ltp$) ' returns the nick portion of a nick!user@host string a = INSTR(ltp$, "!") IF a > 0 THEN GetNick$ = LEFT$(ltp$, a - 1) ELSE GetNick$ = ltp$ END FUNCTION SUB HandleMessage STATIC SHARED ByteCount& bytesRecv& = recv(NewSocket&, IrcRecv, LEN(IrcRecv), 0) IF bytesRecv& > 0 THEN ByteCount& = ByteCount& + bytesRecv& UpdStatus msgBuf$ = msgBuf$ + LEFT$(IrcRecv, bytesRecv&) 'ColorPrint "Buffer data: " + msgBuf$ c = INSTR(msgBuf$, CHR$(10)) DO IF c = 0 THEN EXIT DO 'ColorPrint "Buffer data: " + msgBuf$ row$ = LEFT$(msgBuf$, c - 1) l = INSTR(msgBuf$, CHR$(13)) IF (l <> 0) THEN row$ = LEFT$(row$, l - 1) 'ColorPrint row$ IRCParse row$ q = c IF (l <> 0) THEN q = l msgBuf$ = MID$(msgBuf$, q + 2) c = INSTR(msgBuf$, CHR$(10)) LOOP UNTIL c = 0 'PRINT "Bytes received: "; bytesRecv& 'PRINT "Data: " + LEFT$(IrcRecv, bytesRecv&) ELSE IF bytesRecv& = -1 THEN PRINT "recv() error: "; WSAGetLastError DoWsaDestruct SYSTEM END IF END IF END SUB SUB Inc (i%) i = i + 1 END SUB SUB IRCParse (ltp$) STATIC SHARED HideNAMES, HideMODE, NumHook$(), NoMOTD IF LEFT$(ltp$, 1) = CHR$(10) THEN ltp$ = RIGHT$(ltp$, LEN(ltp$) - 1) split ltp$ ' split the line to parse into Out$() IF LEFT$(Out$(1), 1) = ":" THEN ' does this one begin with the source? Source$ = MID$(Out$(1), 2) ' ok, strip the colon, grab the rest. IRCCmd$ = Out$(2) ' put the rest into nice strings. Target$ = Out$(3) Victim$ = Out$(4) ELSE IRCCmd$ = Out$(1) Target$ = Out$(2) ' had no source END IF 'IF (Source$ = "*") AND (IRCCmd$ <> "PRIVMSG") GOTO Slut IF (Source$ = "*") OR (LEN(ltp$) < 3) GOTO Slut CurY = CSRLIN: CurX = POS(0) VIEW PRINT 1 TO 48: COLOR , 0 LOCATE 48 'paranoid debugging 'COLOR 8: PRINT ltp$ Target$ = GetNick$(Target$) Source$ = GetNick$(Source$) Victim$ = GetNick$(Victim$) IF INSTR(2, ltp$, ":") > 0 THEN ' do we have a second colon? prolly a Parameters$ = MID$(ltp$, INSTR(2, ltp$, ":") + 1) ' parameter string. END IF IRCCmd$ = UCASE$(IRCCmd$) COLOR 13 'PAst INFO 'ColorPrint IRCCmd$ NumIRC = VAL(IRCCmd$) IF NumIRC > 0 THEN IF NumHook$(NumIRC) <> "" THEN ToServer CommandParse$(NumHook$(NumIRC)) SELECT CASE NumIRC CASE 1 TO 3, 372 TO 376 IF NOT NoMOTD THEN PAst INFO ColorPrint Parameters$ END IF CASE 301 PAst INFO: COLOR 13: PRINT Out$(4); COLOR 15: PRINT " is away"; TAB(24); ": "; ColorPrint Parameters$ CASE 311 PAst WHOIS: COLOR 15 PRINT "WHOIS information on "; COLOR 13: PRINT Out$(4); COLOR 5: PRINT "!"; COLOR 13: PRINT Out$(5); COLOR 5: PRINT "@"; COLOR 13: PRINT Out$(6); COLOR 5: PRINT ":" PAst WHOIS: COLOR 15 PRINT "Name "; TAB(24); ": "; ColorPrint Parameters$ CASE 319 PAst WHOIS: COLOR 15 PRINT "On channel(s)"; TAB(24); ": "; COLOR 7: PRINT Parameters$ CASE 312 PAst WHOIS: COLOR 15 PRINT "Using server"; TAB(24); ": "; COLOR 7: PRINT Out$(5); COLOR 5: PRINT " "; ColorPrint Parameters$ CASE 313 PAst WHOIS: COLOR 15 PRINT "IRC Operator"; TAB(24); ": "; COLOR 7: PRINT "Indeed" CASE 317 PAst WHOIS: COLOR 15 PRINT "Idleness"; TAB(24); ": "; COLOR 13: PRINT Out$(5); COLOR 7: PRINT " seconds" CASE 318, 315 PAst WHOIS: COLOR 15: PRINT Parameters$ CASE 324 Mo$ = UnTrail$(StripBoth$(StripBoth$(ltp$))) 'LastMode& = INT(TIMER) IF HideMODE = 0 THEN PAst mode: COLOR 13 PRINT Out$(4); COLOR 5: PRINT " mode is "; COLOR 13: PRINT Mo$ ELSE Dec HideMODE END IF Chan = GetChan(Out$(4)) IF Chan > 0 THEN Cmodes$(Chan) = Mo$ CASE 332 PAst CTOPIC COLOR 13: PRINT Out$(4); COLOR 15: PRINT " topic: "; ColorPrint translate$(0, LATIN1, Parameters$) CASE 333 PAst CTOPIC COLOR 13: PRINT Out$(4); COLOR 15: PRINT " topic set by: "; COLOR 13: PRINT GetNick$(Out$(5)); COLOR 15: PRINT " unixtime "; COLOR 13: PRINT Out$(6) CASE 352 PAst WHOIS COLOR 11: PRINT Out$(4); " "; COLOR 13: PRINT Out$(8); COLOR 5: PRINT " ("; IF INSTR(Out$(9), "*") > 0 THEN COLOR 12 ELSEIF INSTR(Out$(9), "@") > 0 THEN COLOR 15 ELSE COLOR 5 END IF PRINT Out$(9); COLOR 5: PRINT ") "; COLOR 13: PRINT Out$(5); COLOR 5: PRINT "@"; COLOR 13: PRINT Out$(6); " "; ColorPrint Parameters$ CASE 353 split ltp$ 'fancyFade IF (Out$(5) = "*") OR (LEFT$(Out$(5), 1) = "&") GOTO Slut nowOn = GetChan(Out$(5)) IF nowOn <> 0 THEN IF NameListComplete THEN Names$(nowOn) = "" People%(nowOn) = nOut - 6 ELSE IF Names$(nowOn) <> "" THEN Names$(nowOn) = Names$(nowOn) + " " People%(nowOn) = People%(nowOn) + nOut - 6 END IF NameListComplete = 0 FOR i = 6 TO nOut ' put the stuff into a namelist and counter IF LEFT$(Out$(i), 1) = ":" THEN Out$(i) = RIGHT$(Out$(i), LEN(Out$(i)) - 1) Names$(nowOn) = Names$(nowOn) + Out$(i) + " " NEXT Names$(nowOn) = UnTrail$(Names$(nowOn)) END IF CASE 366 IF HideNAMES = 0 THEN PAst INFO COLOR 15: PRINT "Users on "; COLOR 5 SELECT CASE Out$(4) CASE IS = "=" PRINT Out$(4); CASE IS = "@" PRINT "(secret)"; CASE IS = "*" PRINT "(private)"; CASE ELSE PRINT Out$(4); END SELECT IF nowOn > 0 THEN PRINT ": "; Names$(nowOn); ELSE IF Out$(6) <> ":" THEN PRINT ": "; Parameters$; ELSE PRINT " "; END IF END IF PRINT ELSEIF HideNAMES < 0 THEN HideNAMES = 0 END IF NameListComplete = 1 IF HideNAMES > 0 THEN Dec HideNAMES IF IsOp(Me$, TakeOver$) THEN Kicking$ = Names$(GetChan(TakeOver$)) FinalKick$ = "" FOR q = 1 TO LEN(Kicking$) q$ = MID$(Kicking$, q, 1) IF q$ = " " THEN q$ = "," IF q$ = "@" THEN q$ = "" FinalKick$ = FinalKick$ + q$ NEXT MyPlace = INSTR(FinalKick$, Me$) 'if LEN(FinalKick$) - (MyPlace + LEN(Me$))<0 IF People%(GetChan(TakeOver$)) > 1 THEN IF MyPlace + LEN(Me$) - 1 = LEN(FinalKick$) THEN FinalKick$ = LEFT$(FinalKick$, MyPlace - 2) ELSE FinalKick$ = LEFT$(FinalKick$, MyPlace - 1) + RIGHT$(FinalKick$, LEN(FinalKick$) - (MyPlace + LEN(Me$))) END IF ToServer "MODE " + TakeOver$ + " +i" rest 1 ToServer "KICK " + TakeOver$ + " " + FinalKick$ + " :" + DefMes$(KICK) rest 2 PostTakeOver = TRUE END IF TakeOver$ = "" rest 1 END IF CASE 432, 433 IF LastMe$ = "" THEN Me$ = "" ELSE Me$ = LastMe$ ToServer "NICK " + Me$ END IF PAst INTERR COLOR 12: PRINT Parameters$ CASE 401 TO 431, 434 TO 502 PAst INTERR 'COLOR 7: PRINT "("; IRCCmd$; ") "; SELECT CASE NumIRC CASE 401 TO 407, 413, 414, 421, 423, 432 TO 436, 442, 444, 461, 467 TO 477, 482 COLOR 15: PRINT Out$(4); ": "; COLOR 12: PRINT Parameters$ CASE 441 COLOR 15: PRINT Out$(4); COLOR 12: PRINT " isn't on "; COLOR 15: PRINT Out$(5) CASE 443 COLOR 15: PRINT Out$(4); COLOR 12: PRINT " is already on "; COLOR 15: PRINT Out$(5) CASE ELSE COLOR 12: PRINT Parameters$ END SELECT CASE ELSE COLOR 8: PRINT ltp$ END SELECT ELSE SELECT CASE IRCCmd$ CASE IS = "PRIVMSG", IS = "NOTICE" IF NOT ((LEFT$(Parameters$, 1) = CHR$(1)) AND (RIGHT$(Parameters$, 1) = CHR$(1))) THEN IF LEFT$(Target$, 1) <> "#" THEN ' is target a channel? Prefix$ = "*": Suffix$ = "*" ELSE Prefix$ = "<": Suffix$ = ">" ' yes, show as pub END IF IF IRCCmd$ = "NOTICE" THEN Prefix$ = "-": Suffix$ = "-" COLOR 15: PRINT Prefix$; COLOR 13: PRINT Source$; ' if the target isn't me (sts), we want to see why we received it. IF LCASE$(Target$) <> LCASE$(Me$) THEN COLOR 5: PRINT "/"; COLOR 13: PRINT Target$; END IF COLOR 15: PRINT Suffix$; " "; Parameters$ = translate$(0, LATIN1, Parameters$) ColorPrint Parameters$ ELSE CTCPParams$ = MID$(Parameters$, 2, LEN(Parameters$) - 2) split CTCPParams$ IF IRCCmd$ = "NOTICE" THEN '// CTCP replies are NOTICEs SELECT CASE Out$(1) CASE IS = "PING" Ulag = INT(TIMER) - VAL(StripFirst$(CTCPParams$)) PAst INFO: COLOR 5: PRINT "PING reply from "; COLOR 13: PRINT Source$; : COLOR 5: PRINT ":"; COLOR 13: PRINT Ulag; : COLOR 5 PRINT "seconds" CASE ELSE PAst INFO: COLOR 15: PRINT "CTCP "; COLOR 13: PRINT Out$(1); " "; COLOR 15: PRINT "reply from "; COLOR 13: PRINT Source$; IF Target$ <> Me$ THEN COLOR 15: PRINT " to "; COLOR 13: PRINT Target$; ; END IF IF StripFirst$(CTCPParams$) <> "" THEN COLOR 15: PRINT ": "; ColorPrint translate$(0, LATIN1, StripFirst$(CTCPParams$)) END IF END SELECT ELSE SELECT CASE Out$(1) CASE IS = "ACTION" '// but ordinary CTCPs are PRIVMSGs IF GetChan(Target$) > 0 THEN COLOR 15: PRINT "("; COLOR 13: PRINT Target$; COLOR 15: PRINT ") * "; ELSE COLOR 15: PRINT "* "; END IF COLOR 7: PRINT Source$; " "; ColorPrint translate$(0, LATIN1, StripFirst$(CTCPParams$)) CASE IS = "CRYPTKEY" PAst INFO: COLOR 15 PRINT "Encryption key received from "; : COLOR 13 PRINT Source$; : COLOR 15 PRINT ", use /putkey [type] to activate." PendingKey$ = StripFirst$(CTCPParams$) CASE IS = "PING" IF IRCCmd$ = "PRIVMSG" THEN ToServer "NOTICE " + Source$ + " :" + CHR$(1) + "PING " + StripFirst$(CTCPParams$) + CHR$(1) END IF CASE IS = "VERSION" ToServer "NOTICE " + Source$ + " :" + CHR$(1) + "VERSION " + CHR$(31) + CHR$(2) + Client$ + " v" + Version$ + CHR$(2) + CHR$(31) + " by Pipeman" + CHR$(1) CASE ELSE NgtAnnat: PAst INFO: COLOR 15: PRINT "CTCP "; COLOR 13: PRINT Out$(1); " "; COLOR 15 IF StripFirst$(CTCPParams$) <> "" THEN PRINT "("; COLOR 5: PRINT StripFirst$(CTCPParams$); COLOR 15: PRINT ") "; END IF IF Target$ <> Me$ THEN PRINT "to "; COLOR 13: PRINT Target$; " "; COLOR 15 END IF PRINT "from "; COLOR 13: PRINT Source$ END SELECT END IF END IF CASE IS = "TOPIC" PAst CTOPIC COLOR 13: PRINT Source$; COLOR 5: PRINT " changed the "; COLOR 13: PRINT Target$; COLOR 5: PRINT " topic to "; ColorPrint translate$(0, LATIN1, Parameters$) CASE IS = "INVITE" PAst INFO COLOR 13: PRINT Source$; COLOR 15: PRINT " invites you to "; COLOR 13: PRINT Parameters$; LastInvite$ = Parameters$ COLOR 7: PRINT " (press ALT-J to join)" CASE IS = "MODE" PAst mode COLOR 13: PRINT Source$; : COLOR 5 PRINT " sets mode "; : COLOR 13 PRINT Out$(4); FOR q = 5 TO nOut IF Out$(q) <> "" THEN PRINT " "; Out$(q); NEXT COLOR 5 PRINT " on channel "; : COLOR 13 PRINT Target$ ToServer "MODE " + Target$ Inc HideMODE IF Target$ <> TakeOver$ THEN rest 1 IF INSTR(Out$(4), "o") > 0 THEN ToServer "NAMES " + Target$ Inc HideNAMES IF Target$ <> TakeOver$ THEN rest 1 END IF CASE IS = "JOIN" ' IF LEFT$(Target$, 1) = ":" THEN Target$ = RIGHT$(Target$, LEN(Target$) - 1) Target$ = Parameters$ IF Source$ = Me$ THEN Query$ = Target$ IF (Source$ = Me$) AND (GetChan(Target$) = 0) THEN Inc Channels% ' yes, inc no. of channels Channel$(Channels%) = Target$ ' add the channel name to array PAst JOIN: COLOR 13 PRINT "You"; : COLOR 5 PRINT " joined channel "; : COLOR 13 PRINT Target$ ToServer "MODE " + Target$ ELSE IF Source$ <> Me$ THEN Target$ = StripBoth(ltp$) IF LEFT$(Target$, 1) = ":" THEN Target$ = RIGHT$(Target$, LEN(Target$) - 1) END IF nowOn = GetChan(Target$) ' nope - let's fetch the internal Inc People%(nowOn) ' chan number and add the new nick Names$(nowOn) = Names$(nowOn) + " " + Source$ PAst JOIN: COLOR 13 PRINT Source$; : COLOR 5 PRINT " joined channel "; : COLOR 13 PRINT Target$ END IF END IF CASE IS = "NICK" IF LEFT$(Target$, 1) = ":" THEN Target$ = Parameters$ IF (Source$ = Me$) OR (Source$ = "") THEN ' is it me who /nick's? Me$ = Target$ ' yup, update me PAst CNICK COLOR 5: PRINT "You are now known as "; COLOR 13: PRINT Me$ ELSE PAst CNICK ' nope. inform user. COLOR 13: PRINT Source$; COLOR 5: PRINT " is now known as "; COLOR 13: PRINT Target$ END IF NickChange Source$, Target$ ' call sub that updates namelists Inc HideNAMES CASE IS = "PART" PAst PART COLOR 13: PRINT Source$; : COLOR 5: PRINT " left channel "; COLOR 13: PRINT Target$ IF Source$ <> Me$ THEN ToServer "NAMES " + Target$ Inc HideNAMES ELSE justleft = GetChan(Target$) IF justleft < Channels% THEN Channel$(justleft) = Channel$(justleft + 1) People%(justleft) = People%(justleft + 1) Names$(justleft) = Names$(justleft + 1) END IF Dec Channels% END IF CASE IS = "PING" PALETTE 0, 1 ToServer "PONG " + Parameters$ PALETTE 0, 0 CASE IS = "KICK" 'Leave Victim$, Target$ ' someone's kicked. same as PART. almost. :) PAst PART COLOR 13: PRINT Victim$; : COLOR 5: PRINT " has been kicked from "; COLOR 13: PRINT Target$; : COLOR 5: PRINT " by "; COLOR 13: PRINT Source$; : COLOR 5: PRINT " - "; ColorPrint Parameters$ IF Victim$ <> Me$ THEN IF PostTakeOver = FALSE THEN ToServer "NAMES " + Target$ Inc HideNAMES ELSE Dec People%(GetChan(Target$)) IF People%(GetChan(Target$)) = 1 THEN PAst INFO: COLOR 15 PRINT "Finally alone. "; TOKey$ = RandWord$(7) PRINT "Key will be "; COLOR 11: PRINT TOKey$; COLOR 15: PRINT "." Chan = GetChan(Target$) IF mKey$(Cmodes$(Chan)) <> "" THEN ToServer "MODE " + Channel$(Chan) + " -k " + mKey$(Cmodes$(Chan)): rest 2 ToServer "MODE " + Target$ + " -imntl+sk " + TOKey$ PostTakeOver = FALSE rest 2 ToServer "NAMES " + Target$ Inc HideNAMES END IF END IF ELSE justleft = GetChan(Target$) IF justleft < Channels% THEN Channel$(justleft) = Channel$(justleft + 1) People%(justleft) = People%(justleft + 1) Names$(justleft) = Names$(justleft + 1) Cmodes$(justleft) = Cmodes$(justleft + 1) END IF Dec Channels% END IF CASE IS = "QUIT" ' in here, we don't quit - we pull the PAst PART ' friggin' plug. COLOR 13: PRINT Source$; COLOR 5: PRINT " pulls the plug"; IF Parameters$ <> Source$ THEN PRINT " - "; COLOR 13: PRINT Parameters$; COLOR 5: PRINT "." ELSE PRINT "." END IF Signoff Source$ 'IF Source$ = Me$ THEN IQuit = TRUE ' uhoh, it was me. tell the boss. Inc HideNAMES CASE ELSE COLOR 8: PRINT ltp$ END SELECT END IF Slut: 'IF (LastMode& > 0) AND (INT(TIMER) - LastMode& > 6) AND (Query$ <> "") AND (HideMODE > 0) THEN ' ToServer "MODE " + Query$ 'END IF COLOR 7, 0 UpdStatus IF CurY > 48 THEN VIEW PRINT 49 TO 50: LOCATE CurY, CurX END SUB FUNCTION IsCMode (Cnum, ModeChar$) mSplit Cmodes$(Cnum) IF INSTR(mOut$(1), ModeChar$) > 0 THEN IsCMode = TRUE ELSE IsCMode = FALSE END IF END FUNCTION FUNCTION IsOp (NICK$, Chan$) Chan = GetChan(Chan$) IF Chan > 0 THEN Dnames$ = LCASE$(Names$(Chan)): Dnick$ = LCASE$(NICK$) IF INSTR(Dnames$, "@" + Dnick$) > 0 THEN IsOp = TRUE ELSE IsOp = FALSE END IF END IF END FUNCTION FUNCTION IsVocal (in$) IF INSTR("aeiouy†„”", LCASE$(in$)) > 0 THEN IsVocal = TRUE ELSE IsVocal = FALSE END IF END FUNCTION SUB Leave (Source$, Target$) IF Source$ = Me$ THEN Dec Channels% nowOn = GetChan(Target$) IF (Channels% >= nowOn) AND (Channels% > 0) THEN FOR i = nowOn TO Channels% Channel$(i) = Channel$(i - 1) People%(i) = People%(i - 1) Cmodes$(i) = Cmodes$(i - 1) Names$(i) = Names$(i - 1) NEXT END IF ELSE i = GetChan(Target$) split Names$(i) Names$(i) = "" FOR a = 1 TO People%(i) IF StripOp$(Out$(a)) <> Source$ THEN Names$(i) = Names$(i) + Out$(a) IF a < People%(i) THEN Names$(i) = Names$(i) + " " END IF NEXT Names$(i) = UnTrail(Names$(i)) People%(i) = nOut - 1 END IF END SUB DEFSNG A-Z SUB ListChans COLOR 15 IF Channels% > 0 THEN PRINT "Channels are:" FOR i = 1 TO Channels% COLOR 7 PRINT Channel$(i); " ("; Cmodes$(i); "): "; COLOR 9: PRINT Names$(i); ","; People%(i) NEXT ELSE PRINT "You're not on any channel!" END IF END SUB DEFINT A-Z SUB lPrivMsg (To$, msg$) CurY = CSRLIN: CurX = POS(0) VIEW PRINT 1 TO 48: COLOR , 0 LOCATE 48 SELECT CASE LEFT$(To$, 1) CASE IS = "#", IS = "&", IS = "+" COLOR 15: PRINT "("; COLOR 13: PRINT Me$; COLOR 5: PRINT "/"; COLOR 13: PRINT To$; COLOR 15: PRINT ") "; CASE ELSE COLOR 7: PRINT "-> "; COLOR 15: PRINT "*"; COLOR 13: PRINT To$; COLOR 15: PRINT "* "; END SELECT ColorPrint msg$ IF CurY > 48 THEN VIEW PRINT 49 TO 50: LOCATE CurY, CurX END SUB FUNCTION LyxQuery$ (row, col, textcolor, fillcolor, max, tmp$) OldX = POS(0): OldY = CSRLIN IF tmp$ <> "" THEN LOCATE row, col COLOR textcolor PRINT tmp$; END IF LOCATE , , 1 'Imme = TRUE DO LOCATE row, col + LEN(tmp$) COLOR textcolor IF LEN(tmp$) < max THEN fillchar$ = CHR$(SCREEN(CSRLIN, POS(0))) Ny$ = INPUT$(1) IF Ny$ = CHR$(8) THEN IF LEN(tmp$) > 0 THEN tmp$ = LEFT$(tmp$, LEN(tmp$) - 1) LOCATE , col + LEN(tmp$): COLOR fillcolor PRINT fillchar$; END IF ELSEIF Ny$ = CHR$(27) THEN CLS END ELSEIF (ASC(Ny$) > 31) AND LEN(tmp$) < max THEN PRINT Ny$; tmp$ = tmp$ + Ny$ ELSEIF Ny$ = CHR$(1) THEN CHAIN "SPRITCFG" ELSEIF ASC(Ny$) = 13 THEN EXIT DO END IF LOOP LyxQuery$ = tmp$ LOCATE OldY, OldX END FUNCTION FUNCTION mKey$ (inmode$) IF LEFT$(inmode$, 1) = "+" THEN tmp$ = RIGHT$(inmode$, LEN(inmode$) - 1) ELSE tmp$ = inmode$ mSplit tmp$ k = INSTR(mOut$(1), "k") l = INSTR(mOut$(1), "l") IF k = 0 THEN k = 0 ELSEIF (l > 0) AND (k > l) THEN k = 3 ELSEIF (l > 0) AND (k < l) THEN k = 2 ELSEIF l = 0 THEN k = 2 END IF IF k > 0 THEN mKey$ = mOut$(k) ELSE mKey$ = "" END FUNCTION FUNCTION mLimit (inmode$) IF LEFT$(inmode$, 1) = "+" THEN tmp$ = RIGHT$(inmode$, LEN(inmode$) - 1) ELSE tmp$ = inmode$ mSplit tmp$ k = INSTR(mOut$(1), "k") l = INSTR(mOut$(1), "l") IF l = 0 THEN l = 0 ELSEIF (l > 0) AND (k > l) THEN l = 2 ELSEIF (l > 0) AND (k < l) THEN l = 3 ELSEIF k = 0 THEN l = 2 END IF IF l > 0 THEN mLimit = VAL(mOut$(l + 1)) ELSE mLimit = 0 END FUNCTION SUB mSplit (Orig$) v = 1 ERASE mOut$ FOR i = 1 TO LEN(Orig$) IF MID$(Orig$, i, 1) = " " THEN Inc v ELSE mOut$(v) = mOut$(v) + MID$(Orig$, i, 1) END IF NEXT nmOut = nmOut - 1 END SUB DEFSNG A-Z SUB NickChange (Oldnick$, Newnick$) FOR i = 1 TO Channels% IF INSTR(Names$(i), Oldnick$) > 0 THEN split Names$(i) FOR a = 1 TO nOut n$ = Out$(a) prfx$ = "" IF LEFT$(n$, 1) = "@" OR LEFT$(n$, 1) = "+" THEN n$ = RIGHT$(n$, LEN(n$) - 1) prfx$ = LEFT$(Out$(a), 1) END IF IF Oldnick$ = n$ THEN Out$(a) = prfx$ + Newnick$ EXIT FOR END IF NEXT Names$(i) = "" FOR a = 1 TO nOut People%(i) = nOut Names$(i) = Names$(i) + Out$(a) IF a < nOut THEN Names$(i) = Names$(i) + " " NEXT END IF NEXT END SUB DEFINT A-Z SUB PAst (typ) SELECT CASE typ CASE IS = JOIN id$ = ">" CASE IS = PART id$ = "<" CASE IS = CTOPIC id$ = "T" CASE IS = INTERR id$ = "!" CASE IS = INFO id$ = "S" CASE IS = mode id$ = "M" CASE IS = CNICK id$ = "N" CASE IS = WHOIS id$ = "W" CASE ELSE id$ = "?" END SELECT 'CurA = SCREEN(CSRLIN, POS(0), 1) COLOR 15: PRINT "*"; COLOR 14: PRINT id$; COLOR 15: PRINT "* "; 'COLOR CurA END SUB SUB Pause VIEW PRINT SCREEN 12 WIDTH , 60 x = 1 DO WHILE INKEY$ <> CHR$(27) Inc a IF a > 15 THEN a = 1 LOCATE 1, 1 COLOR a PRINT CHR$(a + 192); "Rasmus tar en paus." LOOP CLS END SUB SUB QueryUserInfo (Me$, ident$, host$, realname$) BLOAD "sprintro.dta" Me$ = LyxQuery$(19, 35, 15, 8, 9, Me$) realname$ = LyxQuery$(22, 35, 15, 8, 9, realname$) host$ = LyxQuery$(26, 35, 15, 8, 9, host$) ident$ = LyxQuery$(27, 35, 15, 8, 9, ident$) CLS END SUB DEFSNG A-Z FUNCTION Quot$ (in$) Quot$ = CHR$(34) + in$ + CHR$(34) END FUNCTION DEFINT A-Z FUNCTION RandWord$ (length) ' Generates a fairly memorizable random string. alfastring$ = "abcdefghijklmnopqrstuvwxyz" 'alfastring$ = "NetSaints" FOR a = 1 TO length IF NOT IsVocal(oq$) THEN DO q$ = MID$(alfastring$, INT(RND * LEN(alfastring$)) + 1, 1) LOOP UNTIL IsVocal(q$) ELSE q$ = MID$(alfastring$, INT(RND * LEN(alfastring$)) + 1, 1) END IF tmp$ = tmp$ + q$ oq$ = q$ NEXT MID$(tmp$, 1) = UCASE$(MID$(tmp$, 1, 1)) RandWord$ = tmp$ END FUNCTION SUB ReadConfig (CFile$, Me$, ident$, host$, realname$, LaunchIRC$) SHARED ComSetup$, InitStr$(), WaitFor$(), ThenSend$(), NumHook$(), NoMOTD ParseFile: sf = FREEFILE PRINT "* Parsing " + CFile$ OPEN CFile$ FOR INPUT AS sf DO LINE INPUT #sf, ltp$ IF LEFT$(ltp$, 1) <> "#" THEN split ltp$ SELECT CASE LCASE$(Out$(1)) CASE "network" PRINT "* Got network IRC server hostname " + Out$(2) ServerHost$ = StripFirst$(ltp$) CASE "serial" PRINT "* Got serial options" ComSetup$ = StripFirst$(ltp$) CASE "includedir" PRINT "* Looking for includes in " + Out$(2) IncludeDir$ = Out$(2) CASE "init" PRINT "* Got initstring " + Out$(2) InitStr$(VAL(Out$(2))) = StripBoth$(ltp$) CASE "wf" PRINT "* Got WaitFor " + Out$(2) WaitFor$(VAL(Out$(2))) = StripBoth$(ltp$) CASE "ts" PRINT "* Got ThenSend " + Out$(2) ThenSend$(VAL(Out$(2))) = StripBoth$(ltp$) CASE "nick" PRINT "* Default nickname set to " + Out$(2) Me$ = Out$(2) CASE "altnick" PRINT "* Alternate nickname set to " + Out$(2) LastMe$ = Out$(2) CASE "realname" PRINT "* Realname set to " + StripFirst$(ltp$) realname$ = StripFirst$(ltp$) CASE "userid" PRINT "* User ID set to " + Out$(2) ident$ = Out$(2) CASE "hostname" PRINT "* Hostname set to " + Out$(2) host$ = Out$(2) CASE "crypt" wc = WhatKind(Out$(2)) IF wc > -1 THEN PRINT "* " + CodeId$(wc) + " code active as default" Encrypt(wc) = TRUE ELSE PRINT "* Unknown code " + Out$(2) + " after " + Out$(1) + " statement" END IF CASE "include" file$ = Out$(2) IF (IncludeDir$ <> "") THEN file$ = IncludeDir$ + "\" + file$ ReadConfig file$, Me$, ident$, host$, realname$, LaunchIRC$ CASE "key" wk = WhatKind(Out$(2)) IF wk > -1 THEN IF Seed$(wk) <> "" THEN PRINT "* " + CodeId$(wk) + " code key already present - will be overwritten" END IF Seed$(wk) = StripBoth$(ltp$) PRINT "* Encryption key for " + CodeId$(wk) + " code loaded" ELSE PRINT "* Unknown code " + Out$(2) + " after " + Out$(1) + " statement" END IF CASE "hook" NumHook$(VAL(Out$(2))) = StripBoth$(ltp$) PRINT "* Hook for numeric "; Out$(2); " loaded." CASE "launch" LaunchIRC$ = StripFirst$(ltp$) PRINT "* IRC launched after " + CHR$(34) + LaunchIRC$ + CHR$(34) CASE "nomotd" PRINT "* Will not display Message Of The Day" NoMOTD = TRUE END SELECT END IF LOOP UNTIL EOF(sf) CLOSE sf PRINT "* Done parsing " + CFile$ END SUB DEFSNG A-Z SUB rest (seconds) Stid = TIMER DO LOOP UNTIL TIMER > Stid + seconds END SUB DEFINT A-Z SUB RestoreCodeKey (kind) SHARED DEFAULTSEED() AS STRING Seed$(kind) = DEFAULTSEED(kind) END SUB SUB SBeep SOUND 900, 1 END SUB FUNCTION ScanLine$ (row) ' I'm sure there are better ways but this was simple enough. scans through ' every character on a line, adding them to a buffer... FOR a = 1 TO 80 tmp$ = tmp$ + CHR$(SCREEN(row, a)) NEXT ScanLine$ = UnTrail$(tmp$) ' ... and remove trailing spaces END FUNCTION DEFSNG A-Z SUB Signoff (NICK$) FOR i = 1 TO Channels% IF INSTR(Names$(i), NICK$) > 0 THEN split Names$(i) Names$(i) = "" FOR a = 1 TO People%(i) IF StripOp$(Out$(a)) <> NICK$ THEN Names$(i) = Names$(i) + Out$(a) IF a < People%(i) THEN Names$(i) = Names$(i) + " " END IF NEXT People%(i) = nOut - 1 END IF NEXT END SUB DEFINT A-Z SUB split (Orig$) v = 2 ' ERASE Out$ e = INSTR(Orig$, " ") IF e = 0 THEN Out$(1) = Orig$: nOut = 1: EXIT SUB Out$(1) = LEFT$(Orig$, e - 1) DO b = INSTR(e + 1, Orig$, " ") IF b = 0 THEN Out$(v) = MID$(Orig$, e + 1): EXIT DO Out$(v) = MID$(Orig$, e + 1, b - e - 1) Inc v: e = b LOOP nOut = v END SUB DEFSNG A-Z FUNCTION Stderr$ (SMessage$) Stderr$ = ":" + Client$ + " PRIVMSG " + Me$ + " :" + SMessage$ END FUNCTION FUNCTION StripBoth$ (in$) Fs = INSTR(in$, " ") Fs = INSTR(Fs + 1, in$, " ") IF Fs > 0 THEN StripBoth$ = MID$(in$, Fs + 1) END FUNCTION FUNCTION StripFirst$ (in$) Fs = INSTR(in$, " ") IF Fs > 0 THEN StripFirst$ = MID$(in$, Fs + 1) END FUNCTION DEFINT A-Z FUNCTION StripOp$ (Orig$) IF LEFT$(Orig$, 1) = "@" THEN StripOp$ = RIGHT$(Orig$, LEN(Orig$) - 1) ELSE StripOp$ = Orig$ END IF END FUNCTION FUNCTION ToMorse$ (a$) mc = INSTR(MORSEALPHA, a$) IF mc > 0 THEN ToMorse$ = MorseCode$(mc) ELSE ToMorse$ = a$ END FUNCTION SUB ToServer (ToSend$) SHARED CChan, SByteCount, NewSocket& row$ = translate$(1, LATIN1, ToSend$) + CHR$(13) + CHR$(10) IF ServerHost$ = "" THEN PRINT #CChan, row$; ELSE sent = send(NewSocket&, row$, LEN(row$), 0) END IF SByteCount = SByteCount + LEN(row$) END SUB ' dir: 0=decrypt, 1=encrypt ' FUNCTION translate$ (dir, kind, Orig$) fm$ = Orig$ SELECT CASE kind CASE SCHLONG, VENOM, SPRIT, LATIN1, UDEF1, UDEF2, UDEF3, UDEF4 IF dir = 0 THEN fm$ = LEFT$(fm$, LEN(fm$) - LEN(Sign$(kind))) TIn$ = Seed$(kind) TOut$ = Base$(kind) ELSE TOut$ = Seed$(kind) TIn$ = Base$(kind) END IF FOR a = 1 TO LEN(fm$) t$ = MID$(fm$, a, 1) what = INSTR(TIn$, t$) IF what > 0 THEN tmp$ = tmp$ + MID$(TOut$, what, 1) ELSE tmp$ = tmp$ + t$ END IF NEXT CASE SPRIT2 IF dir = 0 THEN fm$ = LEFT$(fm$, LEN(fm$) - LEN(Sign$(kind))) ' IF dir = 0 THEN ' ELSE FOR a = 1 TO LEN(fm$) TC$ = MID$(Seed$(kind), (a MOD LEN(Seed$(kind)) + 1), 1) t$ = CHR$((ASC(TC$) XOR ASC(MID$(fm$, a, 1)) MOD 128) + 1) 'IF ASC(T$) < 32 THEN NEXT ' END IF tmp$ = fm$ CASE MORSE IF dir = 0 THEN translate$ = fm$ EXIT FUNCTION ELSE FOR a = 1 TO LEN(fm$) tmp$ = tmp$ + ToMorse$(MID$(fm$, a, 1)) + " " NEXT END IF END SELECT IF dir = 1 THEN tmp$ = tmp$ + Sign$(kind) translate$ = tmp$ END FUNCTION FUNCTION undot$ (Orig$) FOR a = 1 TO LEN(Orig$) t$ = MID$(Orig$, a, 1) IF t$ <> "." THEN tmp$ = tmp$ + t$ NEXT undot$ = tmp$ END FUNCTION FUNCTION UnTrail$ (Orig$) FOR a = LEN(Orig$) TO 1 STEP -1 IF MID$(Orig$, a, 1) <> " " THEN EXIT FOR NEXT UnTrail$ = LEFT$(Orig$, a) END FUNCTION SUB UpdStatus SHARED ByteCount&, SByteCount, HideNAMES, HideMODE SCREEN , , 0, vpage CurY = CSRLIN: CurX = POS(0) VIEW PRINT 49 TO 50 LOCATE 49, 1 COLOR 15, 7 Clreol IF Me$ <> "" THEN PRINT " "; Me$; " "; PRINT "["; Channels%; "] "; IF Query$ <> "" THEN PRINT ", query: "; IF IsOp(Me$, Query$) THEN PRINT "@"; PRINT Query$; END IF PRINT " "; HideMODE; FRE(-1); " "; ByteCount&; "/"; SByteCount; LOCATE , 74: PRINT LEFT$(TIME$, 5); ELSE COLOR 4: PRINT "Please enter a nickname with /nick "; END IF COLOR 7, 0 IF CurY < 49 THEN VIEW PRINT 1 TO 48 LOCATE CurY, CurX SCREEN , , 2, vpage CLS COLOR 15, 1 Clreol PRINT Client$ + " v"; Version$; " status report and help screen."; TAB(74); PRINT MID$(TIME$, 1, 5) COLOR , 0 ListChans COLOR 13 IF IdleMinutes > 1 THEN PRINT "You have been idle for"; IdleMinutes; "minutes" COLOR 15 PRINT STRING$(79, "_") COLOR 11 PRINT "Special keys and commands:" COLOR 7 PRINT "CTRL-functions"; TAB(40); "Function keys" COLOR 3 PRINT "C-a"; TAB(8); "IRC screen"; TAB(40); "F10"; TAB(45); "Cycles through screens" PRINT "C-b"; TAB(8); "Buffer screen" PRINT "C-c"; TAB(8); "Status screen" PRINT "C-d"; TAB(8); "Suspend and run DOS interpreter" PRINT "C-e"; TAB(8); "Undocumented feature ;)" SCREEN , , 0, vpage END SUB SUB vgaPalette (a, r, g, b) IF r = -1 THEN OUT &H3C8, a r = INP(&H3C9) g = INP(&H3C9) b = INP(&H3C9) ELSE OUT &H3C8, a OUT &H3C9, r OUT &H3C9, g OUT &H3C9, b END IF END SUB SUB ViewCMode (Cnum) ' Invite = "i", Secret = "s", OpTopic = "t", NoMsg = "n", Keyed = "k" ' Limited = "l", Private = "p" IF IsCMode(Cnum, OpTopic) THEN PRINT "Strict topic "; IF IsCMode(Cnum, NoMsg) THEN PRINT "No external msgs "; IF IsCMode(Cnum, Secret) THEN PRINT "Secret "; IF IsCMode(Cnum, Invite) THEN PRINT "Invite-only "; IF IsCMode(Cnum, Keyed) THEN PRINT "Req. key "; IF IsCMode(Cnum, Private) THEN PRINT "Private "; IF IsCMode(Cnum, Limited) THEN PRINT "Limited "; PRINT END SUB FUNCTION WhatKind (Orig$) WhatKind = -1 tmp$ = LCASE$(Orig$) FOR a = FIRSTE TO UBOUND(CodeId$) IF LCASE$(CodeId$(a)) = tmp$ THEN WhatKind = a NEXT END FUNCTION