Uses Cfg Uses User Const MRCVersion = 'Mystic Relay Chat MPL v1.1' Const CLBuffer = 25 Const InputSize = 255 Type MRCRec = Record FromUser : String[30] FromSite : String[30] FromRoom : String[30] ToUser : String[30] ToSite : String[30] ToRoom : String[30] Message : String[InputSize] End Type UserRec = Record RecIdx : Integer PermIdx : Integer EnterChatMe : String[80] EnterChatRoom : String[80] EnterRoomMe : String[80] EnterRoomRoom : String[80] LeaveChatMe : String[80] LeaveChatRoom : String[80] LeaveRoomMe : String[80] LeaveRoomRoom : String[80] Name : String[80] DefaultRoom : String[80] Temp1 : String[80] Temp5 : String[80] Temp6 : String[80] Temp7 : String[80] NameColor : String[16] LtBracket : String[16] RtBracket : String[16] UseClock : Boolean ClockFormat : Boolean End Var Plyr : UserRec Var ChatLines : Array [1..CLBuffer] of String[160] Var WinTL, WinTT, WinBL, WinBB : Byte Var WinAttr : Byte Var WinSize : Integer Var PromptX : Byte Var PromptY : Byte Var PromptAttr : Byte Var RoomX, RoomY: Byte Var RoomAttr : Byte Var TopicX, TopicY: Byte Var TopicAttr : Byte Var MyNamePrompt: String Var MyChatRoom : Integer = 1 Var Loop : Integer = 1 Var SiteTag : String Var UserTag : String Var MyRoom : String = '' Var MyTopic : String = '' Var ServFile : MRCRec Var BBSTempStub : String Var ChatLog : String Var PInUse : String Var UserFile : String = JustPath(Progname)+'mrcusers.dat' Var ChatSeed : Integer Var TChars : Array [1..80] of Char Var TAttrs : Array [1..80] of Byte //Include chat.inc Function ReadPlyr(I:Integer):Boolean Var Ret : Boolean = False Var Fptr : File Begin fAssign(Fptr,UserFile,66) fReset(Fptr) If IoResult = 0 Then Begin fSeek(Fptr,(I-1)*SizeOf(Plyr)) If Not fEof(fptr) Then Begin fReadRec(Fptr,Plyr) Ret:=True End fClose(Fptr) End ReadPlyr:=Ret End Procedure SavePlyr(I:Integer) Var Fptr : File Begin fAssign(Fptr,Userfile,66) fReset(Fptr) If IoResult = 0 Then fSeek(Fptr,(I-1)*SizeOf(Plyr)) Else Begin Plyr.RecIdx:=1 fReWrite(Fptr) End fWriteRec(Fptr,Plyr) fClose(Fptr) End Function FindPlyr:Integer Var X,Ret : Integer = 0 Var Done : Boolean = False Var UN : String Begin X:=1 UN:=Upper(StripMCI(Replace(UserAlias,' ','_'))) While ReadPlyr(X) And Not Done Do Begin If StripMCI(Upper(Plyr.Name)) = UN Then Begin Done:=True Ret:=X End X:=X+1 End FindPlyr:=Ret End Procedure NewPlyr Var I : Integer Begin I:=0 While ReadPlyr(I+1) Do I:=I+1 Plyr.RecIdx:=I+1 Plyr.PermIdx:=UserIndex Plyr.EnterChatMe :='|07- |10You have entered chat' Plyr.EnterChatRoom :='|07- |02%1 |14has arrived!' Plyr.LeaveChatMe :='|07- |12You have left chat.' Plyr.LeaveChatRoom :='|07- |12%1 |04has left chat.' Plyr.EnterRoomMe :='|07- |10You are now in |02%3' Plyr.LeaveRoomRoom :='|07- |02%1 |10has left the room.' Plyr.LeaveRoomMe :='|07- |10You have left room |02%3' Plyr.EnterRoomRoom :='|07- |02%1 |10has entered the room.' Plyr.Defaultroom :='lobby' Plyr.NameColor :='|10' Plyr.LtBracket :='|02<' Plyr.RtBracket :='|02>' Plyr.UseClock :=True Plyr.ClockFormat :=False Plyr.Name:=StripMCI(Replace(UserAlias,' ','_')) SavePlyr(Plyr.RecIdx) End Procedure CleanOutTempDir Begin FindFirst(CfgTempPath+'*.mrc',66) While DosError = 0 Do Begin If FileExist(CfgTempPath+DirName) Then FileErase(CfgTempPath+DirName) End FindClose If FileExist(PInUse) Then fileErase(PInUse) If FileExist(ChatLog) Then fileErase(ChatLog) End Function AmIFirst:Boolean Var D,X : Integer Var Ret : Boolean = False Var S : String Begin D:=0 For X:=1 To CfgTnNodes Do Begin S:=BBSTempStub+Int2Str(X)+PathChar+'tchat.inuse' If FileExist(S) And D=0 Then Begin D:=X End End If D = NodeNum Then Ret:=True AmIFirst:=Ret End Procedure UpdateScreen Var X : Integer Begin WriteXY(RoomX,RoomY,RoomAttr,PadRt('#'+MyRoom,30,' ')) WriteXY(TopicX,TopicY,TopicAttr,PadRt(MyTopic,40,' ')) End Procedure ShowChat(Top:Integer) Var C,T,L,Y,X : Integer Var G,V,W : String = '' Var N2D : Boolean = True Begin Y:=CLBuffer-WinSize-Top For X:=1 To WinSize+1 Do Begin GoToXy(1,WinTT+X-1) Write(ChatLines[Y]+'|16|07|$X80 ') Y:=Y+1 End End Function ParseChat(S:String) : MrcREc Var MR : MrcRec Begin MR.FromUser:=WordGet(1,S,'~') MR.FromSite:=WordGet(2,S,'~') //MR.FromRoom:=Str2Int(WordGet(3,S,'~')) MR.FromRoom:=WordGet(3,S,'~') MR.ToUser:=WordGet(4,S,'~') MR.ToSite:=WordGet(5,S,'~') //MR.ToRoom:=Str2Int(WordGet(6,S,'~')) MR.ToRoom:=WordGet(6,S,'~') MR.Message:=WordGet(7,S,'~') ParseChat:=MR End Procedure RedrawScreen Begin DispFile('mrcmain') UpdateScreen ShowChat(0) End Procedure Add2Chat(S:String) Var E,W,L,B,A,X : Integer Var DS,S1,S2,S3 : String='' Begin If Plyr.UseClock Then Begin DS:=TimeStr(DateTime,Plyr.ClockFormat) If Not Plyr.ClockFormat Then Delete(DS,6,3) S:='|07'+DS+'|16|00.|07'+S End S1:=WordGet(1,S,' ') E:=Length(StripMCI(S1))+1 While E>0 Do Begin S3:=S3+' ' E:=E-1 End S1:=S Repeat B:=Length(S1) A:=Length(StripMCI(S1)) L:=79-(A-B) S2:='' W:=StrWrap(S1,S2,L) For X:=2 To CLBuffer Do ChatLines[X-1]:=ChatLines[X] ChatLines[CLBuffer]:=S1 AppendText(ChatLog,ChatLines[CLBuffer]) S1:='|07'+S3+S2 Until S2='' End Procedure MakeChatEntry(S:String) Var Fil : String = CfgDataPath+'mrc'+PathChar+Int2Str(ChatSeed)+Int2Str(Random(9))+Int2Str(Random(9))+'.mrc' Begin AppendText(Fil,S) ChatSeed:=ChatSeed+1 End Procedure SendOut(FU,FS,FR,TU,TS,TR,S:String) Var TX : String Begin TX:=FU+'~'+FS+'~'+FR+'~'+TU+'~'+TS+'~'+TR+'~'+S+'~' MakeChatEntry(TX) End Procedure SendToMe(S:String) Var Me : String = UserTag+'~'+SiteTag+'~'+MyRoom+'~'+UserTag+'~'+SiteTag+'~'+MyRoom+'~'+S+'~' Begin MakeChatEntry(Me) End Procedure SendToAllNotMe(S:String) Begin SendOut(UserTag,SiteTag,MyRoom,'NOTME','','',S) End Procedure SendToRoomNotMe(S:String) Begin SendOut(UserTag,SiteTag,MyRoom,'NOTME','',MyRoom,S) End Procedure SendToAll(S:String) Begin SendOut(UserTag,SiteTag,MyRoom,'','','',S) End Procedure SendToRoom(S:String) Begin SendOut(UserTag,SiteTag,MyRoom,'','',MyRoom,S) End Procedure SendToUser(U,S:String) Begin SendOut(UserTag,SiteTag,MyRoom,U,'','',S) End Procedure SendToClient(S:String) Begin SendOut(UserTag,SiteTag,MyRoom,'CLIENT',SiteTag,MyRoom,S) End Procedure SendToServer(S:String) Begin SendOut(UserTag,SiteTag,MyRoom,'SERVER',SiteTag,MyRoom,S) End Procedure ProcessChat(MR:MRCRec) Var Ok2Send : Boolean = True Var Command,Opt1,Opt2: String Begin If Pos('ROOMTOPIC',Mr.Message) > 0 Then Begin Command:=WordGet(1,Mr.Message,':') opt1:=WordGet(2,Mr.Message,':') opt2:=WordGet(3,Mr.Message,':') If Opt1 = MyRoom Then Begin MyTopic:=Opt2 UpdateScreen Ok2Send:=False End End If MR.ToRoom <> '' Then if Upper(MR.ToRoom) <> Upper(MyRoom) Then Ok2Send:=False If MR.ToUser <> '' Then If Mr.ToUser <> 'NOTME' Then If Length(Mr.ToUser) > 3 Then If Pos(Upper(MR.ToUser),Upper(UserTag))=0 Then Ok2Send:=False Else If Mr.ToUser <> 'NOTME' Then If Upper(Mr.FromUser) = Upper(UserTag) Then Ok2Send:=False If Ok2Send Then Add2Chat(MR.Message) End Procedure ReadChatFiles Var F1 : File Var S : String Var Ret : Boolean = False Begin FindFirst(CfgTempPath+'*.mrc',66) While DOSError = 0 Do Begin Ret:=True fAssign(F1,CfgTempPath+DirName,66) fReset(F1) While Not fEof(F1) Do Begin fReadLn(F1,S) ServFile:=ParseChat(S) ProcessChat(ServFile) End fClose(F1) fileErase(CfgTempPath+DirName) FindNext End FindClose If Ret Then ShowChat(0) End Function UpdateStrings(S,M,U,NR,OR:String):String Begin S:=Replace(S,'%1',M) S:=Replace(S,'%2',U) S:=Replace(S,'%3','#'+NR) S:=Replace(S,'%4','#'+OR) UpdateStrings:=S End Procedure JoinRoom(S:String;B:Boolean) Var NewRoom,OldRoom:String Begin If Length(S) > 0 Then Begin OldRoom:=MyRoom NewRoom:=lower(S) StripB(S,'#') SendToServer('NEWROOM:'+MyRoom+':'+S) If B Then Begin Delay(100) SendToMe(UpdateStrings(Plyr.LeaveRoomMe,Plyr.Name,'',NewRoom,OldRoom)) Delay(100) SendToRoomNotMe(UpdateStrings(Plyr.LeaveRoomRoom,Plyr.Name,'',NewRoom,OldRoom)) Delay(100) MyRoom:=NewRoom SendToMe(UpdateStrings(Plyr.EnterRoomMe,Plyr.Name,'',NewRoom,OldRoom)) Delay(100) SendToRoomNotMe(UpdateStrings(Plyr.EnterRoomRoom,Plyr.Name,'',NewRoom,OldRoom)) End MyRoom:=S SetPromptInfo(4,'#'+S) UpdateScreen End End Procedure ChangeNick(LRNC,N:String;Announce:Boolean) Var ON : String Begin Case LRNC Of // 'N': Plyr.Name:=N 'L': Plyr.LtBracket:=N 'R': Plyr.RtBracket:=N 'C': Plyr.NameColor:=N End SavePlyr(Plyr.RecIdx) MyNamePrompt:=Plyr.LtBracket+Plyr.NameColor+StripMCI(Plyr.Name)+Plyr.RtBracket+'|16|07 ' End Procedure Init Var X,Y: Integer Var K,S : String = '' Begin S:=Int2Str(NodeNum) For X:=1 To 3 Do S:=S+Int2Str(Random(9)) ChatSeed:=Str2Int(S) ChatLog:=CfgTempPath+'mrcchat.log' PInUse:=CfgTempPath+'tchat.inuse' BBSTempStub:=CfgTempPath Y:=Pos(Int2Str(NodeNum),BBSTempStub) If Y > 0 Then Delete(BBSTempStub,Y,Length(Int2Str(NodeNum))+1) Y:=FindPlyr If Y = 0 Then NewPlyr Else ReadPlyr(Y) SiteTag:=StripMCI(Replace(MCI2Str('BN'),' ','_')) UserTag:=StripMCI(Replace(UserAlias,' ','_')) ChangeNick('N',UserTag,False) DispFile('mrcmain') GetScreenInfo(1,WinTL,WinTT,WinAttr) GetScreenInfo(2,WinBL,WinBB,WinAttr) GetScreenInfo(3,PromptX,PromptY,PromptAttr) GetScreenInfo(4,RoomX,RoomY,RoomAttr) GetScreenInfo(5,TopicX,TopicY,TopicAttr) WinSize:=WinBB-WinTT ShowChat(0) AppendText(PInUse,'0') MenuCmd('NA','Mystic Relay Chatting') End Procedure DoHelp Begin Write('|16|11') DispFile('mrchelp') RedrawScreen End Procedure DoWho Begin Write('|16|11') MenuCmd('NW','') RedrawScreen End Procedure ChangeTopic(S:String) Var R : String Begin SendToServer('NEWTOPIC:'+MyRoom+':'+S) UpdateScreen End Procedure DoPrivateMsg(S:String) Var M,U : String Var L : Integer Begin U:=Upper(WordGet(2,S,' ')) L:=Pos(U,Upper(S)) L:=L+Length(U)+1 M:='|02<|10'+Plyr.Name+'|02 private> |07'+Copy(S,L,Length(S)-L+1) SendToUser(U,M) End Procedure DoBroadcast(S:String) Var M : String Begin M:='|05<|13'+Plyr.Name+'|05 broadcast> |07'+Copy(S,4,Length(S)-3) SendToAll(M) End Procedure DoMeAction(S:String) Var R : String Begin R:=Copy(S,5,Length(S)-4) SendToRoom('|13* '+Plyr.Name+' ' + R) End Function InputLine:String Var IX,UL : Integer Var Ch : Char = #13 Begin UL:=Length(StripMCI(MyNamePrompt)) IX:=PromptX+Length(StripMCI(MyNamePrompt)) GoToXy(PromptX,PromptY) Write('|16'+MyNamePrompt+'|17|15|$X79 ') GoToXy(PromptX,PromptY) Write('|16'+MyNamePrompt) While Ch = #13 Or Ch = #32 Do Begin While Not Keypressed Do Begin ReadChatFiles Delay(100) Loop:=Loop+1 If Loop > 10000 Then Loop:=1 If Loop % 2345 = 0 Then Begin SendToServer('IAMHERE') End End Ch:=ReadKey End StuffKey(ch) GoToXy(PromptX,PromptY) Write('|16'+MyNamePrompt+'|17|15|$X79 ') GoToXy(PromptX,PromptY) Write('|16'+MyNamePrompt) InputLine:=Input(79-UL,InputSize,11,'') GoToXy(PromptX,PromptY) Write('|16'+MyNamePrompt+'|17|15|$X79 ') End Procedure DoCls Var X : Integer Begin For X:=1 To CLBuffer Do Begin ChatLines[X]:='' End End Procedure DoScrollBack Begin MenuCmd('GV','mrcscrl;x;y;'+ChatLog) RedrawScreen End Procedure EnterChat Begin Add2Chat(UpdateStrings(Plyr.EnterChatMe,Plyr.Name,'',MyRoom,MyRoom)) SendToAllNotMe(UpdateStrings(Plyr.EnterChatRoom,Plyr.Name,'',MyRoom,MyRoom)) SendToServer('IAMHERE') SendtoServer('MOTD') End Procedure LeaveChat Var Str1 : String Begin Add2Chat(UpdateStrings(Plyr.LeaveChatMe,Plyr.Name,'',MyRoom,MyRoom)) SendToAllNotMe(UpdateStrings(Plyr.LeaveChatRoom,Plyr.Name,'',MyRoom,MyRoom)) SendToServer('LOGOFF'); End Procedure DoSetList Var R,S : String Begin S:='False' If Plyr.UseClock Then S:='True' R:='12Hour (HH:MMa or HHMMp)' If Not Plyr.ClockFormat Then R:='24Hour (HH:MM)' Add2Chat('|07ENTERCHATME |08: '+Plyr.EnterChatMe) Add2Chat('|07ENTERCHATROOM |08: '+Plyr.EnterChatRoom) Add2Chat('|07ENTERROOMME |08: '+Plyr.EnterRoomMe) Add2Chat('|07ENTERROOMROOM |08: '+Plyr.EnterRoomRoom) Add2Chat('|07LEAVECHATME |08: '+Plyr.LeaveChatMe) Add2Chat('|07LEAVECHATROOM |08: '+Plyr.LeaveChatRoom) Add2Chat('|07LEAVEROOMME |08: '+Plyr.LeaveRoomMe) Add2Chat('|07LEAVEROOMROOM |08: '+Plyr.LeaveRoomRoom) Add2Chat('|07DEFAULTROOM |08: '+Plyr.DefaultRoom) Add2Chat('|07NICKCOLOR |08: '+Plyr.NameColor+Plyr.Name) Add2Chat('|07LTBRACKET |08: '+Plyr.LtBracket) Add2Chat('|07RTBRACKET |08: '+Plyr.RtBracket) Add2Chat('|07USECLOCK |08: |07'+S) Add2Chat('|07CLOCKFORMAT |08: |07'+R) ShowChat(0) End Procedure DoSetHelp Var B : Boolean Begin B:=Plyr.UseClock Plyr.UseClock:=False Add2Chat('|07/SET ') Add2Chat('|07Use SET to set various fields to your account') Add2Chat('|07 HELP, LIST, ENTERCHATME, ENTERCHATROOM, ENTERROOMME, ENTERROOMROOM, LEAVECHATME, LEAVECHATROOM, LEAVEROOMROOM, LEAVEROOMME, DEFAULTROOM, NAMECOLOR, LTBRACKET, RTBRACKET, USECLOCK, CLOCKFORMAT') Add2Chat('|07HELP This helps message') Add2Chat('|07LIST List all fields and tabs') Add2Chat('|07ENTERCHATME Displayed to me when I enter chat.') Add2Chat('|07ENTERCHATROOM Displayed to room when I enter chat.') Add2Chat('|07ENTERROOMME Displayed to me when I enter room.' ) Add2Chat('|07ENTERROOMROOM Displayed to room when I enter room.' ) Add2Chat('|07LEAVECHATME Displayed to me when I leave chat.' ) Add2Chat('|07LEAVECHATROOM Displayed to room when I leave chat.' ) Add2Chat('|07LEAVEROOMME Displayed to me when I leave room.') Add2Chat('|07LEAVEROOMROOM Displayed to room when I leave room.') Add2Chat('|07DEFAULTROOM Join this room when you join chat.') Add2Chat('|07NICKCOLOR Change my nickname color (MCI Pipe codes.' ) Add2Chat('|07LTBRACKET Change my left bracket / color (MCI Pipe codes.' ) Add2Chat('|07RTBRACKET Change my right bracket / color (MCI Pipe codes.' ) Add2Chat('|07USECLOCK (Y/N) Use timestamp in chat') Add2Chat('|07CLOCKFORMAT 12 or 24 hour clock format') ShowChat(0) Plyr.UseClock:=B End Procedure ChangeClock(T:Integer;S:String) Begin S:=StripB(Upper(S),' ') Case T Of 1: Begin If Pos('YE',S) > 0 Or Pos('TR',S) > 0 Then Begin Plyr.UseClock:=True Add2Chat('|07CLOCKFORMAT |08: |07True') End Else Begin If Pos('NO',S) > 0 Or Pos('FA',S) > 0 Then Begin Plyr.UseClock:=False Add2Chat('|07CLOCKFORMAT |08: |07False') End Else Add2Chat('Usage: /SET USECLOCK YES||TRUE or /SET USECLOCK NO||FALSE') End ShowChat(0) End 2: Begin If S = '12' Then Begin Plyr.ClockFormat:=True Add2Chat('|07CLOCKFORMAT |08: |0712 hour') End Else Begin If S = '24' Then Begin Plyr.ClockFormat:=False Add2Chat('|07CLOCKFORMAT |08: |0724 hour') End Else Add2Chat('Usage: "/SET CLOCKFORMAT 12" or "/SET CLOCKFORMAT 24"') End ShowChat(0) End End SavePlyr(Plyr.RecIdx) End Procedure DoSet(Line:String) Var Tag,Txt : String Var P : Integer Begin Tag:=WordGet(1,Line,' ') P:=Length(Tag)+1 Delete(Line,1,P) StripB(line,' ') Case Upper(Tag) Of 'HELP': DoSetHelp 'LIST': DoSetList 'ENTERCHATME' : Plyr.EnterChatMe:=Line 'ENTERCHATROOM' : Plyr.EnterChatRoom:=Line 'ENTERROOMME' : Plyr.EnterRoomMe:=Line 'ENTERROOMROOM' : Plyr.EnterRoomRoom:=Line 'LEAVECHATME' : Plyr.LeaveChatMe:=Line 'LEAVECHATROOM' : Plyr.LeaveChatRoom:=Line 'LEAVEROOMROOM' : Plyr.LeaveRoomRoom:=Line 'DEFAULTROOM' : Plyr.DefaultRoom:=Line 'NICKCOLOR' : ChangeNick('C',Line,False) 'LTBRACKET' : ChangeNick('L',Line,False) 'RTBRACKET' : ChangeNick('R',Line,False) 'USECLOCK' : ChangeClock(1,Line) 'CLOCKFORMAT' : ChangeClock(2,Line) '' : DoSetHelp End SavePlyr(Plyr.RecIdx) End Procedure DLChatLog Var X,Y,TS,DS,TempChat : String Var fptr : File Begin DS:=Replace(DateStr(DateTime,1),'/','') TS:=Replace(TimeStr(DateTime,False),':','') TempChat:=CfgTempPath+'mrc_chat_'+Replace(SiteTag,' ','_')+'_'+DS+'_'+TS+'.log' Write('|16|11|CL') If InputYN('Strip MCI color codes? ') Then Begin fAssign(fptr,ChatLog,66) fReset(Fptr) While Not fEof(Fptr) Do Begin fReadLn(Fptr,X) Y:=StripMCI(X) AppendText(TempChat,Y) End fClose(Fptr) End Else FileCopy(ChatLog,TempChat) MenuCmd('F3',TempChat); FileErase(TempChat) RedrawScreen; End Procedure Main Var Done : Boolean = False Var RestOfLine, W1,W2,UIL : String Var IL : String Begin Loop:=1 UpdateScreen Repeat IL:=InputLine If Pos('/',IL) = 1 Then Begin W1:=Upper(WordGet(1,IL,' ')) W2:=WordGet(2,IL,' ') RestOfLine:=IL Delete(RestOfLine,1,Length(W1)) RestOfLine:=StripB(RestOfLine,' ') Case W1 Of '/?' : DoHelp '/B' : DoBroadcast(IL) '/BBSES' : SendToServer('CONNECTED') '/CHANNEL' : SendToServer('CHANNEL') '/CHATTERS' : SendToServer('CHATTERS') '/CLS' : DoCls '/DLCHATLOG': DLChatLog '/JOIN' : JoinRoom(W2,True) '/LIST' : SendToServer('LIST') '/ME' : DoMeAction(IL) '/Q','/QUIT': Begin LeaveChat; Done:=True; End '/ROOMS' : SendToServer('LIST') '/SCROLL' : DoScrollBack '/SET' : DoSet(RestOfLine) '/TOPIC' : ChangeTopic(RestOfLine) '/T','/MSG', '/TELL' : DoPrivateMsg(IL) '/USERS' : SendToServer('USERS') '/WHO' : DoWho '/WHOON' : SendToServer('WHOON') '/MOTD' : SendToServer('MOTD') '/VERSION' : Begin SendToServer('VERSION') Add2Chat('|07- |13'+MRCVersion) End End End Else Begin If Length(IL) > 0 Then SendToRoom(MyNamePrompt+IL) End Until Done End Begin GetThisUser Init RedrawScreen EnterChat JoinRoom(Plyr.DefaultRoom,False) Main Write('|16|11|CL') CleanOutTempDir End