uses
  System, System.Net, System.Net.Sockets, System.Threading, crt;
 
type
  TByteArray = array of byte;
 
var
  client: array [1..64] of TCPClient;
  s_str: array [1..64] of NetworkStream;
  s_raw: TByteArray;
  listener: system.Net.Sockets.TcpListener;
  s_ip, msg, cl_str, s_name: string;
  s_port, length, i, n: integer;
  thr: array [1..64] of thread;
 
procedure chat(data: object); 
var
  i, err:integer;
  name: string;
begin
  Val(data.ToString, i, err);
  s_str[i] := client[i].GetStream;
  length := s_str[i].Read(s_raw, 0, s_raw.Length);
  name := System.Text.Encoding.Default.GetString(s_raw, 0, length);
  writeln('Есть клиент ', name, '.');
  msg := Concat('Добро пожаловать на сервер ', s_name, ', ', name, '!');
  s_str[i].Write(System.Text.Encoding.Default.GetBytes(msg), 0, msg.Length);
  try
    while true do 
    begin
      length := s_str[i].Read(s_raw, 0, s_raw.Length);
      cl_str := System.Text.Encoding.Default.GetString(s_raw, 0, length);
      writeln(name, ': ', cl_str);
      for j:integer:=1 to n do begin
        s_str[j] := client[j].GetStream;
        msg := name + ' [' + DateTime.Now.ToString + ']: ' + cl_str{+#13#10};
        if s_str[j].CanWrite then
          s_str[j].Write(System.Text.Encoding.Default.GetBytes(msg), 0, msg.Length)
          
        else
          writeln('Ошибка. Невозможно отправить сообщение клиенту.');
      end;
      if cl_str='+help' then begin
      for j:integer:=1 to n do begin
      writeln('Bot: Список команд');
        s_str[j] := client[j].GetStream;
        msg := 'BOT' + ' [' + DateTime.Now.ToString + ']: ' + 'Список команд'{+#13#10};
          s_str[j].Write(System.Text.Encoding.Default.GetBytes(msg), 0, msg.Length);

 
          writeln('Bot: +help - Список команд');
        s_str[j] := client[j].GetStream;
        msg := 'BOT' + ' [' + DateTime.Now.ToString + ']: ' + '+help - Список команд'{+#13#10};
          s_str[j].Write(System.Text.Encoding.Default.GetBytes(msg), 0, msg.Length);
      
      end;
      end;
    end;
  except
    textcolor(4);
    writeln('Клиент отключился.');
    textcolor(2);
  end;
end;
 
 
begin
  s_raw := TByteArray(System.Array.CreateInstance(typeof(byte), 1024));
  try
    textcolor(14);
    write('Введите IP: ');
    readln(s_ip);
    write('Введите порт: ');
    readln(s_port);
    listener := TCPListener.Create(IPAddress.Parse(s_ip), s_port);
    write('Введите название сервера: ');
    readln(s_name);
    listener.Start(64);
    textcolor(2);
    writeln('Готово. Ожидаем подключения...');
  except
    textcolor(4);
    writeln('Ошибка. Приложение будет закрыто.');
    sleep(2500);
    exit;
  end;
  i := 0;
  while true do
    if listener.Pending then
    begin
      i += 1;
      n:=i;
      client[i] := listener.AcceptTcpClient();
      thr[i] := new Thread(chat);
      thr[i].Start(i);
    end;
end.