git.strcat.st

/strcat/barevclients.git/ - summarytreelogarchive

subject
add muc support to barevclient.pas
commit
b6ffe95579e71976cc97246f37fd85416053039d
date
2026-05-08T00:09:13Z
message
diff
 barevclient.pas | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 104 insertions(+), 4 deletions(-)

diff --git a/barevclient.pas b/barevclient.pas
index 19608de..9c764da 100644
--- a/barevclient.pas
+++ b/barevclient.pas
@@ -20,6 +20,10 @@ type
     procedure OnFTProgress(B: TBarevBuddy; const Sid: string; Done, Total: Int64);
     procedure OnFTComplete(B: TBarevBuddy; const Sid, Path: string);
     procedure OnFTError(B: TBarevBuddy; const Sid, Err: string);
+    procedure OnRoomMsg(const RoomJID, FromNick, MessageText: string);
+    procedure OnRoomJoin(const RoomJID, Nick: string);
+    procedure OnRoomLeft(const RoomJID, Nick: string);
+    procedure OnRoomNick(const RoomJID, OldNick, NewNick: string);
   end;
 
   TNetThread = class(TThread)
@@ -86,6 +90,28 @@ begin
   WriteLn('*** FT error sid=', Sid, ' err=', Err);
 end;
 
+procedure THandler.OnRoomMsg(const RoomJID, FromNick, MessageText: string);
+begin
+  WriteLn;
+  WriteLn('*** [', RoomJID, '] ', FromNick, ': ', MessageText);
+  Write('> '); Flush(Output);
+end;
+
+procedure THandler.OnRoomJoin(const RoomJID, Nick: string);
+begin
+  WriteLn('*** [', RoomJID, '] join: ', Nick);
+end;
+
+procedure THandler.OnRoomLeft(const RoomJID, Nick: string);
+begin
+  WriteLn('*** [', RoomJID, '] left: ', Nick);
+end;
+
+procedure THandler.OnRoomNick(const RoomJID, OldNick, NewNick: string);
+begin
+  WriteLn('*** [', RoomJID, '] nick: ', OldNick, ' -> ', NewNick);
+end;
+
 constructor TNetThread.Create(AClient: TBarevClient);
 begin
   inherited Create(False);
@@ -106,9 +132,14 @@ procedure ShowHelp;
 begin
   WriteLn('Commands:');
   WriteLn('  help');
+  WriteLn('  /alias <name> <jid_or_roomjid>');
+  WriteLn('  /set <alias_or_jid_or_roomjid>');
   WriteLn('  add <nick> <ipv6> [port]');
   WriteLn('  connect <jid>');
   WriteLn('  msg <jid> <text>');
+  WriteLn('  joinroom <room_jid> [nick]');
+  WriteLn('  leaveroom <room_jid>');
+  WriteLn('  roommsg <room_jid> <text>');
   WriteLn('  typing <jid>');
   WriteLn('  paused <jid>');
   WriteLn('  sendfile <jid> <path>');
@@ -121,9 +152,23 @@ procedure RunLoop;
 var
   Line, Cmd, A1, A2, A3, Sid: string;
   Parts: TStringList;
+  Aliases: TStringList;
+  CurrentTarget: string;
   B: TBarevBuddy;
+  function ResolveTarget(const S: string): string;
+  var
+    i: Integer;
+  begin
+    Result := S;
+    i := Aliases.IndexOfName(S);
+    if i >= 0 then
+      Result := Trim(Aliases.ValueFromIndex[i]);
+  end;
 begin
   Parts := TStringList.Create;
+  Aliases := TStringList.Create;
+  Aliases.NameValueSeparator := '=';
+  CurrentTarget := '';
   try
     while True do
     begin
@@ -139,6 +184,18 @@ begin
       Cmd := LowerCase(Parts[0]);
 
       if Cmd = 'help' then ShowHelp
+      else if Cmd = '/alias' then
+      begin
+        if Parts.Count < 3 then begin WriteLn('usage: /alias <name> <jid_or_roomjid>'); Continue; end;
+        Aliases.Values[Parts[1]] := Parts[2];
+        WriteLn('alias set: ', Parts[1], ' -> ', Parts[2]);
+      end
+      else if Cmd = '/set' then
+      begin
+        if Parts.Count < 2 then begin WriteLn('usage: /set <alias_or_jid_or_roomjid>'); Continue; end;
+        CurrentTarget := ResolveTarget(Parts[1]);
+        WriteLn('current target: ', CurrentTarget);
+      end
       else if Cmd = 'quit' then Break
       else if Cmd = 'add' then
       begin
@@ -151,16 +208,35 @@ begin
       else if Cmd = 'connect' then
       begin
         if Parts.Count < 2 then WriteLn('usage: connect <jid>')
-        else if Client.ConnectToBuddy(Parts[1]) then WriteLn('connect ok')
+        else if Client.ConnectToBuddy(ResolveTarget(Parts[1])) then WriteLn('connect ok')
         else WriteLn('connect failed');
       end
       else if Cmd = 'msg' then
       begin
         if Parts.Count < 3 then begin WriteLn('usage: msg <jid> <text>'); Continue; end;
-        A1 := Parts[1];
-        A2 := Copy(Line, Pos(A1, Line) + Length(A1) + 1, MaxInt);
+        A1 := ResolveTarget(Parts[1]);
+        A2 := Copy(Line, Pos(Parts[1], Line) + Length(Parts[1]) + 1, MaxInt);
         if Client.SendMessage(A1, A2) then WriteLn('send ok') else WriteLn('send failed');
       end
+      else if Cmd = 'joinroom' then
+      begin
+        if Parts.Count < 2 then begin WriteLn('usage: joinroom <room_jid_or_alias> [nick]'); Continue; end;
+        A1 := ResolveTarget(Parts[1]);
+        if Parts.Count >= 3 then A2 := Parts[2] else A2 := '';
+        if Client.JoinRoom(A1, A2) then WriteLn('join ok') else WriteLn('join failed');
+      end
+      else if Cmd = 'leaveroom' then
+      begin
+        if Parts.Count < 2 then begin WriteLn('usage: leaveroom <room_jid_or_alias>'); Continue; end;
+        if Client.LeaveRoom(ResolveTarget(Parts[1])) then WriteLn('leave ok') else WriteLn('leave failed');
+      end
+      else if Cmd = 'roommsg' then
+      begin
+        if Parts.Count < 3 then begin WriteLn('usage: roommsg <room_jid_or_alias> <text>'); Continue; end;
+        A1 := ResolveTarget(Parts[1]);
+        A2 := Copy(Line, Pos(Parts[1], Line) + Length(Parts[1]) + 1, MaxInt);
+        if Client.SendRoomMessage(A1, A2) then WriteLn('room send ok') else WriteLn('room send failed');
+      end
       else if Cmd = 'typing' then
       begin
         if Parts.Count < 2 then WriteLn('usage: typing <jid>')
@@ -197,10 +273,30 @@ begin
         else if Client.FileTransfer.RejectOffer(Parts[1]) then WriteLn('reject ok')
         else WriteLn('reject failed');
       end
-      else WriteLn('unknown command');
+      else
+      begin
+        if CurrentTarget <> '' then
+        begin
+          if Pos('@', CurrentTarget) > 0 then
+          begin
+            if Pos(' ', CurrentTarget) = 0 then
+            begin
+              if Client.SendMessage(CurrentTarget, Line) then WriteLn('send ok')
+              else
+              begin
+                if Client.SendRoomMessage(CurrentTarget, Line) then WriteLn('room send ok')
+                else WriteLn('send failed');
+              end;
+            end;
+          end;
+        end
+        else
+          WriteLn('unknown command');
+      end;
     end;
   finally
     Parts.Free;
+    Aliases.Free;
   end;
 end;
 
@@ -233,6 +329,10 @@ begin
     Client.FileTransfer.OnProgress := @H.OnFTProgress;
     Client.FileTransfer.OnComplete := @H.OnFTComplete;
     Client.FileTransfer.OnError := @H.OnFTError;
+    Client.OnRoomMessage := @H.OnRoomMsg;
+    Client.OnRoomOccupantJoined := @H.OnRoomJoin;
+    Client.OnRoomOccupantLeft := @H.OnRoomLeft;
+    Client.OnRoomOccupantNickChanged := @H.OnRoomNick;
 
     if not Client.Start then Halt(1);