498 lines
13 KiB
ObjectPascal
498 lines
13 KiB
ObjectPascal
|
Unit bbs_NodeChat;
|
||
|
|
||
|
{$I M_OPS.PAS}
|
||
|
|
||
|
Interface
|
||
|
|
||
|
Procedure Node_Chat;
|
||
|
|
||
|
Implementation
|
||
|
|
||
|
Uses
|
||
|
m_Strings,
|
||
|
m_DateTime,
|
||
|
m_FileIO,
|
||
|
bbs_NodeInfo,
|
||
|
bbs_Common,
|
||
|
bbs_User,
|
||
|
bbs_Core;
|
||
|
|
||
|
Var
|
||
|
ChatSize : Byte;
|
||
|
ChatUpdate : LongInt;
|
||
|
TextPos : Byte;
|
||
|
TopPage : Byte;
|
||
|
LinePos : Byte;
|
||
|
Full : Boolean;
|
||
|
|
||
|
Procedure FullReDraw;
|
||
|
Var
|
||
|
Count : Byte;
|
||
|
Temp : Byte;
|
||
|
Begin
|
||
|
If Not Full Then Exit;
|
||
|
|
||
|
Session.io.AnsiGotoXY (1, Session.io.ScreenInfo[1].Y);
|
||
|
|
||
|
Temp := TopPage;
|
||
|
|
||
|
For Count := 0 to ChatSize Do Begin
|
||
|
Session.io.AnsiClrEOL;
|
||
|
If Temp <= TextPos Then Begin
|
||
|
Session.io.OutPipeLn (Session.Msgs.MsgText[Temp]);
|
||
|
Inc (Temp);
|
||
|
End Else
|
||
|
Session.io.OutRawLn('');
|
||
|
End;
|
||
|
End;
|
||
|
|
||
|
Procedure Change_Room (R : Byte);
|
||
|
Var
|
||
|
CF : File of ChatRec;
|
||
|
Begin
|
||
|
If (R < 1) or (R > 99) Then Exit;
|
||
|
|
||
|
Reset (RoomFile);
|
||
|
Seek (RoomFile, R-1);
|
||
|
Read (RoomFile, Room);
|
||
|
Close (RoomFile);
|
||
|
|
||
|
Chat.Room := R;
|
||
|
CurRoom := R;
|
||
|
|
||
|
Assign (CF, Config.DataPath + 'chat' + strI2S(Session.NodeNum) + '.dat');
|
||
|
Reset (CF);
|
||
|
Write (CF, Chat);
|
||
|
Close (CF);
|
||
|
|
||
|
Send_Node_Message (5, strI2S(Session.NodeNum) + ';' + 'Now chatting in channel ' + strI2S(CurRoom), 0); //++lang
|
||
|
End;
|
||
|
|
||
|
Procedure Update_Topic;
|
||
|
Begin
|
||
|
If Not Full Then Exit;
|
||
|
|
||
|
{ look around and make common function called goscreeninfo(num) that }
|
||
|
{ goes to an x/y position and changes the attribute }
|
||
|
|
||
|
Session.io.AnsiGotoXY (Session.io.ScreenInfo[4].X, Session.io.ScreenInfo[4].Y);
|
||
|
Session.io.AnsiColor (Session.io.ScreenInfo[4].A);
|
||
|
|
||
|
Session.io.OutRaw (strPadR(strI2S(CurRoom), 2, ' '));
|
||
|
|
||
|
Session.io.AnsiGotoXY (Session.io.ScreenInfo[5].X, Session.io.ScreenInfo[5].Y);
|
||
|
Session.io.AnsiColor (Session.io.ScreenInfo[5].A);
|
||
|
|
||
|
Session.io.OutRaw (strPadR(Room.Name, 40, ' '));
|
||
|
End;
|
||
|
|
||
|
Function GetKeyNodeChatFunc (Forced : Boolean) : Boolean;
|
||
|
{ 1 = node chat broadcast message (if room = 0)
|
||
|
node chat regular text (if room = room user is in)
|
||
|
4 = node chat private message
|
||
|
5 = chat broadcast (ie: xxx has entered chat)
|
||
|
6 = chat action (ie: g00r00 claps his hands)
|
||
|
7 = chat topic update }
|
||
|
|
||
|
Procedure AddText (Str : String);
|
||
|
Var
|
||
|
Count : Byte;
|
||
|
Begin
|
||
|
If TextPos < 200 Then
|
||
|
Inc (TextPos)
|
||
|
Else
|
||
|
For Count := 2 to 200 Do
|
||
|
Session.Msgs.MsgText[Count - 1] := Session.Msgs.MsgText[Count];
|
||
|
|
||
|
Session.Msgs.MsgText[TextPos] := Str;
|
||
|
End;
|
||
|
|
||
|
Var
|
||
|
Str : String;
|
||
|
StrLen : Byte;
|
||
|
Indent : Byte;
|
||
|
Lines : Byte;
|
||
|
OldAttr : Byte;
|
||
|
OldX : Byte;
|
||
|
OldY : Byte;
|
||
|
Begin
|
||
|
GetKeyNodeChatFunc := False;
|
||
|
|
||
|
If Session.User.InChat or Session.InUserEdit Then Exit;
|
||
|
|
||
|
If (TimerSeconds - ChatUpdate <> 0) or Forced Then Begin
|
||
|
|
||
|
Assign (NodeMsgFile, Session.TempPath + 'chat.tmp');
|
||
|
FileMode := 66;
|
||
|
{$I-} Reset (NodeMsgFile); {$I+}
|
||
|
If IoResult = 0 Then Begin
|
||
|
|
||
|
OldAttr := Screen.TextAttr;
|
||
|
OldX := Screen.CursorX;
|
||
|
OldY := Screen.CursorY;
|
||
|
|
||
|
While Not Eof(NodeMsgFile) Do Begin
|
||
|
Read (NodeMsgFile, NodeMsg);
|
||
|
|
||
|
If NodeMsg.MsgType in [1, 4..7] Then Begin
|
||
|
Session.io.OutRaw (Session.io.Pipe2Ansi(16));
|
||
|
|
||
|
Case NodeMsg.MsgType of
|
||
|
1 : If NodeMsg.Room = 0 Then
|
||
|
Str := strReplace(Session.GetPrompt(319), '|&1', NodeMsg.FromWho)
|
||
|
Else
|
||
|
If NodeMsg.Room = CurRoom Then
|
||
|
Str := strReplace(Session.GetPrompt(181), '|&1', NodeMsg.FromWho)
|
||
|
Else
|
||
|
Continue;
|
||
|
4 : Str := strReplace(Session.GetPrompt(218), '|&1', NodeMsg.FromWho);
|
||
|
5 : Str := Session.GetPrompt(226);
|
||
|
6 : Str := strReplace(Session.GetPrompt(229), '|&1', NodeMsg.FromWho);
|
||
|
7 : Begin
|
||
|
Reset (RoomFile);
|
||
|
Seek (RoomFile, CurRoom - 1);
|
||
|
Read (RoomFile, Room);
|
||
|
Close (RoomFile);
|
||
|
|
||
|
Update_Topic;
|
||
|
Str := Session.GetPrompt(226);
|
||
|
End;
|
||
|
End;
|
||
|
|
||
|
If Full Then Begin
|
||
|
StrLen := Length(Str);
|
||
|
Indent := Length(strStripMCI(Str));
|
||
|
Lines := 0;
|
||
|
|
||
|
Repeat
|
||
|
Inc (Lines);
|
||
|
|
||
|
If Length(Str + NodeMsg.Message) > 79 Then Begin
|
||
|
Str := Str + Copy(NodeMsg.Message, 1, 79 - StrLen);
|
||
|
AddText(Str);
|
||
|
Delete (NodeMsg.Message, 1, 79 - StrLen);
|
||
|
Str := strRep(' ', Indent);
|
||
|
End Else Begin
|
||
|
AddText(Str + NodeMsg.Message);
|
||
|
Break;
|
||
|
End;
|
||
|
Until False;
|
||
|
|
||
|
If LinePos + Lines > Session.io.ScreenInfo[2].Y Then Begin
|
||
|
Indent := (ChatSize DIV 2) - 2;
|
||
|
TopPage := TextPos - Indent;
|
||
|
LinePos := Session.io.ScreenInfo[1].Y + Indent + 1;
|
||
|
FullReDraw;
|
||
|
End Else Begin
|
||
|
Session.io.AnsiGotoXY(1, LinePos);
|
||
|
For Indent := Lines DownTo 1 Do Begin
|
||
|
Session.io.AnsiClrEOL;
|
||
|
Session.io.OutPipeLn(Session.Msgs.MsgText[TextPos - Indent + 1]);
|
||
|
Inc (LinePos);
|
||
|
End;
|
||
|
End;
|
||
|
|
||
|
Session.io.AnsiGotoXY (OldX, OldY);
|
||
|
End Else Begin
|
||
|
If Session.io.Graphics = 0 Then
|
||
|
Session.io.OutBS (Screen.CursorX, True)
|
||
|
Else Begin
|
||
|
Session.io.AnsiMoveX(1);
|
||
|
Session.io.AnsiClrEOL;
|
||
|
End;
|
||
|
|
||
|
Session.io.OutPipe (Str);
|
||
|
Session.io.OutPipeLn (NodeMsg.Message);
|
||
|
End;
|
||
|
End;
|
||
|
End;
|
||
|
|
||
|
Close (NodeMsgFile);
|
||
|
Erase (NodeMsgFile);
|
||
|
|
||
|
If Not Full And Not Forced Then Begin
|
||
|
Session.io.PromptInfo[1] := Session.User.ThisUser.Handle;
|
||
|
Session.io.OutFull ('|CR' + Session.GetPrompt(427));
|
||
|
End;
|
||
|
|
||
|
Session.io.AnsiColor (OldAttr);
|
||
|
|
||
|
GetKeyNodeChatFunc := True;
|
||
|
End;
|
||
|
|
||
|
ChatUpdate := TimerSeconds;
|
||
|
End;
|
||
|
End;
|
||
|
|
||
|
Procedure Node_Chat;
|
||
|
|
||
|
Procedure Chat_Template;
|
||
|
Begin
|
||
|
If Not Full Then Begin
|
||
|
Session.io.OutFile('teleconf', True, 0);
|
||
|
Exit;
|
||
|
End;
|
||
|
|
||
|
Session.io.PromptInfo[1] := strI2S(CurRoom);
|
||
|
Session.io.PromptInfo[2] := Room.Name;
|
||
|
|
||
|
Session.io.OutFile ('ansitele', True, 0);
|
||
|
|
||
|
ChatSize := Session.io.ScreenInfo[2].Y - Session.io.ScreenInfo[1].Y;
|
||
|
|
||
|
Update_Topic;
|
||
|
End;
|
||
|
|
||
|
Procedure Show_Users_In_Chat;
|
||
|
Var
|
||
|
A : Byte;
|
||
|
Temp : ChatRec;
|
||
|
RM : RoomRec;
|
||
|
Begin
|
||
|
Session.io.OutFullLn (Session.GetPrompt(332));
|
||
|
|
||
|
For A := 1 to Config.INetTNMax Do Begin
|
||
|
Assign (ChatFile, Config.DataPath + 'chat' + strI2S(A) + '.dat');
|
||
|
{$I-} Reset (ChatFile); {$I+}
|
||
|
If IoResult = 0 Then Begin
|
||
|
Read (ChatFile, Temp);
|
||
|
Close (ChatFile);
|
||
|
If Temp.InChat Then Begin
|
||
|
Reset (RoomFile);
|
||
|
Seek (RoomFile, Temp.Room - 1);
|
||
|
Read (RoomFile, RM);
|
||
|
Close (RoomFile);
|
||
|
Session.io.PromptInfo[1] := Temp.Name;
|
||
|
Session.io.PromptInfo[2] := strI2S(A);
|
||
|
Session.io.PromptInfo[3] := strI2S(Temp.Room);
|
||
|
Session.io.PromptInfo[4] := RM.Name;
|
||
|
Session.io.OutFullLn (Session.GetPrompt(333));
|
||
|
End;
|
||
|
End;
|
||
|
End;
|
||
|
|
||
|
Session.io.OutFullLn (Session.GetPrompt(453));
|
||
|
|
||
|
Chat_Template;
|
||
|
FullReDraw;
|
||
|
End;
|
||
|
|
||
|
Procedure Send_Private_Message (Str : String);
|
||
|
Var
|
||
|
UserName : String;
|
||
|
Text : String;
|
||
|
Count : Byte;
|
||
|
Temp : ChatRec;
|
||
|
Begin
|
||
|
UserName := strUpper(strReplace(strWordGet(2, Str, ' '), '_', ' '));
|
||
|
Text := Copy(Str, strWordPos(3, Str, ' '), Length(Str));
|
||
|
|
||
|
If Text = '' Then Exit;
|
||
|
|
||
|
For Count := 1 to Config.INetTNMax Do Begin
|
||
|
Assign (ChatFile, Config.DataPath + 'chat' + strI2S(Count) + '.dat');
|
||
|
{$I-} Reset (ChatFile); {$I+}
|
||
|
If IoResult = 0 Then Begin
|
||
|
Read (ChatFile, Temp);
|
||
|
Close (ChatFile);
|
||
|
If strUpper(Temp.Name) = UserName Then Begin
|
||
|
Send_Node_Message (4, strI2S(Count) + ';' + Text, 0);
|
||
|
Exit;
|
||
|
End;
|
||
|
End;
|
||
|
End;
|
||
|
|
||
|
Send_Node_Message (5, strI2S(Session.NodeNum) + ';' + 'User ' + UserName + ' not found', 0); //++lang
|
||
|
End;
|
||
|
|
||
|
Procedure ChatScrollBack;
|
||
|
Var
|
||
|
Ch : Char;
|
||
|
TopSave : Byte;
|
||
|
Begin
|
||
|
If Not Full Then Exit;
|
||
|
|
||
|
TopSave := TopPage;
|
||
|
|
||
|
Session.io.AnsiGotoXY (1, Session.io.ScreenInfo[3].Y);
|
||
|
Session.io.AnsiClrEOL;
|
||
|
Session.io.OutFull (Session.GetPrompt(237));
|
||
|
|
||
|
Repeat
|
||
|
Ch := Session.io.GetKey;
|
||
|
|
||
|
If Ch = #27 Then Break;
|
||
|
|
||
|
If Session.io.IsArrow Then
|
||
|
Case Ch of
|
||
|
#71 : If TopPage > 1 Then Begin
|
||
|
TopPage := 1;
|
||
|
FullReDraw;
|
||
|
End;
|
||
|
#72 : If TopPage > 1 Then Begin
|
||
|
Dec(TopPage);
|
||
|
FullReDraw;
|
||
|
End;
|
||
|
#73,
|
||
|
#75 : If TopPage > 1 Then Begin
|
||
|
If TopPage < ChatSize Then
|
||
|
TopPage := 1
|
||
|
Else
|
||
|
Dec (TopPage, ChatSize);
|
||
|
FullReDraw;
|
||
|
End;
|
||
|
#79 : If TopPage < TopSave Then Begin
|
||
|
TopPage := TopSave;
|
||
|
FullReDraw;
|
||
|
End;
|
||
|
#80 : If TopPage < TopSave Then Begin
|
||
|
Inc(TopPage);
|
||
|
FullReDraw;
|
||
|
End;
|
||
|
#77,
|
||
|
#81 : If TopPage < TopSave Then Begin
|
||
|
If TopPage + ChatSize > TopSave Then
|
||
|
TopPage := TopSave
|
||
|
Else
|
||
|
Inc (TopPage, ChatSize);
|
||
|
FullReDraw;
|
||
|
End;
|
||
|
End;
|
||
|
Until False;
|
||
|
|
||
|
TopPage := TopSave;
|
||
|
FullReDraw;
|
||
|
End;
|
||
|
|
||
|
Var
|
||
|
Str : String;
|
||
|
Str2 : String;
|
||
|
Avail : Boolean;
|
||
|
Begin
|
||
|
Full := Session.User.ThisUser.UseFullChat And (Session.io.Graphics > 0);
|
||
|
|
||
|
Set_Node_Action (Session.GetPrompt(347));
|
||
|
|
||
|
Avail := Chat.Available;
|
||
|
Chat.InChat := True;
|
||
|
Chat.Available := False;
|
||
|
|
||
|
Assign (ChatFile, Config.DataPath + 'chat' + strI2S(Session.NodeNum) + '.dat');
|
||
|
Reset (ChatFile);
|
||
|
Write (ChatFile, Chat);
|
||
|
Close (ChatFile);
|
||
|
|
||
|
FileErase(Session.TempPath + 'chat.tmp');
|
||
|
|
||
|
Send_Node_Message (5, '0;' + Session.User.ThisUser.Handle + ' has entered chat', 0); //++lang
|
||
|
|
||
|
Change_Room (1);
|
||
|
|
||
|
Chat_Template;
|
||
|
|
||
|
TopPage := 1;
|
||
|
TextPos := 0;
|
||
|
LinePos := Session.io.ScreenInfo[1].Y;
|
||
|
|
||
|
FullReDraw;
|
||
|
|
||
|
GetKeyFunc := GetKeyNodeChatFunc;
|
||
|
|
||
|
Repeat
|
||
|
Session.io.PromptInfo[1] := Session.User.ThisUser.Handle;
|
||
|
|
||
|
If Full Then Session.io.AnsiGotoXY (1, Session.io.ScreenInfo[3].Y) Else Session.io.OutRawLn('');
|
||
|
|
||
|
Session.io.OutFull (Session.GetPrompt(427));
|
||
|
|
||
|
If Full Then
|
||
|
Str := Session.io.GetInput (79 - Screen.CursorX + 1, 250, 19, '')
|
||
|
Else
|
||
|
Str := Session.io.GetInput (79 - Screen.CursorX + 1, 250, 11, '');
|
||
|
|
||
|
If Str[1] = '/' Then Begin
|
||
|
GetKeyFunc := NoGetKeyFunc;
|
||
|
|
||
|
Str2 := strUpper(strWordGet(1, Str, ' '));
|
||
|
|
||
|
If Str2 = '/B' Then Begin
|
||
|
Str2 := Copy(Str, strWordPos(2, Str, ' '), Length(Str));
|
||
|
If Str2 <> '' Then
|
||
|
Send_Node_Message (1, '0;' + Str2, 0)
|
||
|
End Else
|
||
|
If Str2 = '/CLS' Then Begin
|
||
|
TopPage := 1;
|
||
|
TextPos := 0;
|
||
|
LinePos := Session.io.ScreenInfo[1].Y;
|
||
|
|
||
|
FullReDraw;
|
||
|
End Else
|
||
|
If Str2 = '/?' Then Begin
|
||
|
Session.io.OutFile ('telehelp', True, 0);
|
||
|
Chat_Template;
|
||
|
FullReDraw
|
||
|
End Else
|
||
|
If Str2 = '/SCROLL' Then
|
||
|
ChatScrollBack
|
||
|
Else
|
||
|
If Str2 = '/Q' Then
|
||
|
Break
|
||
|
Else
|
||
|
If Str2 = '/ME' Then Begin
|
||
|
Str := Copy(Str, 5, Length(Str));
|
||
|
|
||
|
If Str <> '' Then
|
||
|
Send_Node_Message (6, '0;' + Str, CurRoom);
|
||
|
End Else
|
||
|
If Str2 = '/MSG' Then
|
||
|
Send_Private_Message(Str)
|
||
|
Else
|
||
|
If Str2 = '/NAMES' Then
|
||
|
Show_Users_In_Chat
|
||
|
Else
|
||
|
If Str2 = '/JOIN' Then Begin
|
||
|
Change_Room (strS2I(strWordGet(2, Str, ' ')));
|
||
|
Update_Topic;
|
||
|
End Else
|
||
|
If Str2 = '/WHO' Then Begin
|
||
|
Session.io.AnsiClear;
|
||
|
Show_Whos_Online;
|
||
|
Chat_Template;
|
||
|
FullReDraw;
|
||
|
End Else
|
||
|
If Str2 = '/TOPIC' Then Begin
|
||
|
Room.Name := Copy(Str, strWordPos(2, Str, ' '), Length(Str));
|
||
|
|
||
|
Reset (RoomFile);
|
||
|
Seek (RoomFile, CurRoom - 1);
|
||
|
Write (RoomFile, Room);
|
||
|
Close (RoomFile);
|
||
|
|
||
|
Send_Node_Message (7, '0;Topic changed to "' + Room.Name + '"', CurRoom); // ++lang
|
||
|
End;
|
||
|
|
||
|
GetKeyFunc := GetKeyNodeChatFunc;
|
||
|
End Else
|
||
|
If Str <> '' Then Begin
|
||
|
Send_Node_Message (1, '0;' + Str, CurRoom);
|
||
|
If Not Full Then Session.io.OutRawLn('');
|
||
|
GetKeyNodeChatFunc(True);
|
||
|
End;
|
||
|
Until False;
|
||
|
|
||
|
GetKeyFunc := NoGetKeyFunc;
|
||
|
Chat.InChat := False;
|
||
|
Chat.Available := Avail;
|
||
|
|
||
|
Assign (ChatFile, Config.DataPath + 'chat' + strI2S(Session.NodeNum) + '.dat');
|
||
|
Reset (ChatFile);
|
||
|
Write (ChatFile, Chat);
|
||
|
Close (ChatFile);
|
||
|
|
||
|
FileErase(Session.TempPath + 'chat.tmp');
|
||
|
|
||
|
Send_Node_Message (5, '0;' + Session.User.ThisUser.Handle + ' has left chat', 0); //++lang
|
||
|
End;
|
||
|
|
||
|
End.
|