mysticbbs/mystic/bbs_nodechat.pas

519 lines
14 KiB
ObjectPascal

Unit bbs_NodeChat;
// ====================================================================
// Mystic BBS Software Copyright 1997-2013 By James Coyle
// ====================================================================
//
// This file is part of Mystic BBS.
//
// Mystic BBS is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Mystic BBS is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Mystic BBS. If not, see <http://www.gnu.org/licenses/>.
//
// ====================================================================
{$I M_OPS.PAS}
Interface
Procedure Node_Chat;
Implementation
Uses
m_Strings,
m_DateTime,
m_FileIO,
BBS_Records,
BBS_DataBase,
BBS_Common,
BBS_NodeInfo,
BBS_User,
BBS_Core;
Var
ChatSize : Integer;
ChatUpdate : LongInt;
TextPos : Integer;
TopPage : Integer;
LinePos : Integer;
Full : Boolean;
Procedure FullReDraw;
Var
Count : Integer;
Temp : Integer;
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 (Session.RoomFile);
Seek (Session.RoomFile, R - 1);
Read (Session.RoomFile, Session.Room);
Close (Session.RoomFile);
Session.Chat.Room := R;
Session.CurRoom := R;
Assign (CF, bbsCfg.DataPath + 'chat' + strI2S(Session.NodeNum) + '.dat');
Reset (CF);
Write (CF, Session.Chat);
Close (CF);
Send_Node_Message (5, strI2S(Session.NodeNum) + ';' + 'Now chatting in channel ' + strI2S(Session.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(Session.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(Session.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 : Integer;
Begin
If TextPos < mysMaxMsgLines Then
Inc (TextPos)
Else
For Count := 2 to mysMaxMsgLines Do
Session.Msgs.MsgText[Count - 1] := Session.Msgs.MsgText[Count];
Session.Msgs.MsgText[TextPos] := Str;
End;
Var
Str : String;
StrLen : Integer;
Indent : Integer;
Lines : Integer;
OldAttr : Byte;
OldX : Byte;
OldY : Byte;
MsgFile : File of NodeMsgRec;
Msg : NodeMsgRec;
Begin
GetKeyNodeChatFunc := False;
If Session.User.InChat or Session.InUserEdit Then Exit;
If (TimerSeconds - ChatUpdate <> 0) or Forced Then Begin
Assign (MsgFile, Session.TempPath + 'chat.tmp');
If ioReset(MsgFile, SizeOf(Msg), fmRWDN) Then Begin
OldAttr := Console.TextAttr;
OldX := Console.CursorX;
OldY := Console.CursorY;
While Not Eof(MsgFile) Do Begin
Read (MsgFile, Msg);
If Msg.MsgType in [1, 4..7] Then Begin
Session.io.OutRaw (Session.io.Pipe2Ansi(16));
Case Msg.MsgType of
1 : If Msg.Room = 0 Then
Str := strReplace(Session.GetPrompt(319), '|&1', Msg.FromWho)
Else
If Msg.Room = Session.CurRoom Then
Str := strReplace(Session.GetPrompt(181), '|&1', Msg.FromWho)
Else
Continue;
4 : Str := strReplace(Session.GetPrompt(218), '|&1', Msg.FromWho);
5 : Str := Session.GetPrompt(226);
6 : Str := strReplace(Session.GetPrompt(229), '|&1', Msg.FromWho);
7 : Begin
Reset (Session.RoomFile);
Seek (Session.RoomFile, Session.CurRoom - 1);
Read (Session.RoomFile, Session.Room);
Close (Session.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 + Msg.Message) > 79 Then Begin
Str := Str + Copy(Msg.Message, 1, 79 - StrLen);
AddText(Str);
Delete (Msg.Message, 1, 79 - StrLen);
Str := strRep(' ', Indent);
End Else Begin
AddText(Str + Msg.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 (Console.CursorX, True)
Else Begin
Session.io.AnsiMoveX(1);
Session.io.AnsiClrEOL;
End;
Session.io.OutPipe (Str);
Session.io.OutPipeLn (Msg.Message);
End;
End;
End;
Close (MsgFile);
Erase (MsgFile);
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(Session.CurRoom);
Session.io.PromptInfo[2] := Session.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 bbsCfg.INetTNNodes Do
If GetChatRecord(A, Temp) Then
If Temp.InChat Then Begin
Reset (Session.RoomFile);
Seek (Session.RoomFile, Temp.Room - 1);
Read (Session.RoomFile, RM);
Close (Session.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;
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 bbsCfg.INetTNNodes Do
If GetChatRecord(Count, Temp) Then
If strUpper(Temp.Name) = UserName Then Begin
Send_Node_Message (4, strI2S(Count) + ';' + Text, 0);
Exit;
End;
Send_Node_Message (5, strI2S(Session.NodeNum) + ';' + 'User ' + UserName + ' not found', 0); //++lang
End;
Procedure ChatScrollBack;
Var
Ch : Char;
TopSave : Integer;
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 := Session.Chat.Available;
Session.Chat.InChat := True;
Session.Chat.Available := False;
Assign (Session.ChatFile, bbsCfg.DataPath + 'chat' + strI2S(Session.NodeNum) + '.dat');
Reset (Session.ChatFile);
Write (Session.ChatFile, Session.Chat);
Close (Session.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;
Session.AllowMessages := False;
Session.io.GetKeyCallBack := @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 - Console.CursorX + 1, 250, 19, '')
Else
Str := Session.io.GetInput (79 - Console.CursorX + 1, 250, 11, '');
If Str[1] = '/' Then Begin
Session.io.GetKeyCallBack := NIL;
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, Session.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;
WhosOnline;
Chat_Template;
FullReDraw;
End Else
If Str2 = '/TOPIC' Then Begin
Session.Room.Name := Copy(Str, strWordPos(2, Str, ' '), Length(Str));
Reset (Session.RoomFile);
Seek (Session.RoomFile, Session.CurRoom - 1);
Write (Session.RoomFile, Session.Room);
Close (Session.RoomFile);
Send_Node_Message (7, '0;Topic changed to "' + Session.Room.Name + '"', Session.CurRoom); // ++lang
End;
Session.io.GetKeyCallBack := @GetKeyNodeChatFunc;
End Else
If Str <> '' Then Begin
Send_Node_Message (1, '0;' + Str, Session.CurRoom);
If Not Full Then Session.io.OutRawLn('');
GetKeyNodeChatFunc(True);
End;
Until False;
Session.io.GetKeyCallBack := NIL;
Session.Chat.InChat := False;
Session.Chat.Available := Avail;
Session.AllowMessages := True;
Assign (Session.ChatFile, bbsCfg.DataPath + 'chat' + strI2S(Session.NodeNum) + '.dat');
Reset (Session.ChatFile);
Write (Session.ChatFile, Session.Chat);
Close (Session.ChatFile);
FileErase(Session.TempPath + 'chat.tmp');
Send_Node_Message (5, '0;' + Session.User.ThisUser.Handle + ' has left chat', 0); //++lang
End;
End.