From 8ea73c533440d7f73f96f8110b9f597a26a75241 Mon Sep 17 00:00:00 2001
From: Dirk Koopman <djk@tobit.co.uk>
Date: Mon, 25 Jun 2007 21:19:19 +0100
Subject: [PATCH] add continuous chat mode (like talk)

---
 cmd/chat.pl           | 44 +++++++++++++++++++++++------------
 perl/DXCommandmode.pm | 53 ++++++++++++++++++++++++++++++++++++-------
 perl/Messages         |  4 ++++
 3 files changed, 78 insertions(+), 23 deletions(-)

diff --git a/cmd/chat.pl b/cmd/chat.pl
index 2aa62943..b65ca928 100644
--- a/cmd/chat.pl
+++ b/cmd/chat.pl
@@ -5,39 +5,53 @@
 #
 # Copyright (c) 2003 Dirk Koopman G1TLH
 #
-# $Id$
 #
 
 my ($self, $line) = @_;
+#$DB::single = 1;
+
 my @f = split /\s+/, $line, 2;
 return (1, $self->msg('e5')) if $self->remotecmd || $self->inscript;
-return (1, $self->msg('e34')) unless @f == 2;
+return (1, $self->msg('e34')) unless @f >= 1;
 return (1, $self->msg('e28')) unless $self->registered;
 
 my $target = uc $f[0];
 
 return (1, $self->msg('e35', $target)) unless grep uc $_ eq $target, @{$self->user->group};
 
+$f[1] ||= '';
+
 my $from = $self->call;
-my $text = unpad $f[1];
+my $text = $f[1] ;
 my $t = ztime(time);
 my $toflag = '*';
+my @out;
 
 # change ^ into : for transmission
 $line =~ s/\^/:/og;
 
-my @bad;
-if (@bad = BadWords::check($line)) {
-	$self->badcount(($self->badcount||0) + @bad);
-	LogDbg('DXCommand', "$self->{call} swore: $line (with words:" . join(',', @bad) . ")");
-	Log('chat', $target, $from, "[to $from only] $line");
-	return (1, "$target de $from <$t>: $line");
+if ($text) {
+	my @bad;
+	if (@bad = BadWords::check($line)) {
+		$self->badcount(($self->badcount||0) + @bad);
+		LogDbg('DXCommand', "$self->{call} swore: $line (with words:" . join(',', @bad) . ")");
+		Log('chat', $target, $from, "[to $from only] $line");
+		return (1, "$target de $from <$t>: $line");
+	}
+
+	$self->send_chats($target, $text);
+} else {
+	my $ref = $self->talklist;
+	if ($ref) {
+		push @out, $self->msg('chattoomany', $target, $self->talklist->[0]);
+	} else {
+		$self->talklist([ $target ]);
+		push @out, $self->msg('chatinst', $target);
+		$self->state('chat');
+	}
+	Log('chat', $target, $from, "Started chat mode on $target");
+	push @out, $self->chat_prompt;
 }
 
-#PC12^IZ4DYU^*^PSE QSL INFO TO A71AW TNX IN ADV 73's^<group>^IK5PWJ-6^0^H21^~
-my $msgid = DXProt::nextchatmsgid();
-$text = "#$msgid $text";
-
-$main::me->normal(DXProt::pc93($target, $from, undef, $text));
 
-return (1, ());
+return (1, @out);
diff --git a/perl/DXCommandmode.pm b/perl/DXCommandmode.pm
index 32830c28..30ad8c56 100644
--- a/perl/DXCommandmode.pm
+++ b/perl/DXCommandmode.pm
@@ -302,10 +302,14 @@ sub normal
 		$self->conn->{echo} = $self->conn->{decho};
 		delete $self->conn->{decho};
 		$self->state('prompt');
-	} elsif ($self->{state} eq 'talk') {
+	} elsif ($self->{state} eq 'talk' || $self->{state} eq 'chat') {
 		if ($cmdline =~ m{^(?:/EX|/ABORT)}i) {
 			for (@{$self->{talklist}}) {
-				$self->send_talks($_,  $self->msg('talkend'));
+				if ($self->{state} eq 'talk') {
+					$self->send_talks($_,  $self->msg('talkend'));
+				} else {
+					$self->send_chats($_,  $self->msg('chatend', $_));
+				}
 			}
 			$self->state('prompt');
 			delete $self->{talklist};
@@ -322,12 +326,16 @@ sub normal
 						LogDbg('DXCommand', "$self->{call} swore: $l with words:" . join(',', @bad) . ")");
 					} else {
 						for (@{$self->{talklist}}) {
-							$self->send_talks($_, $l);
+							if ($self->{state} eq 'talk') {
+								$self->send_talks($_, $l);
+							} else {
+								$self->send_chats($_, $l)
+							}
 						}
 					}
 				}
 			}
-			$self->send($self->talk_prompt);
+			$self->send($self->{state} eq 'talk' ? $self->talk_prompt : $self->chat_prompt);
 		} elsif ($self->{talklist} && @{$self->{talklist}}) {
 			# send what has been said to whoever is in this person's talk list
 			my @bad;
@@ -336,10 +344,15 @@ sub normal
 				LogDbg('DXCommand', "$self->{call} swore: $cmdline with words:" . join(',', @bad) . ")");
 			} else {
 				for (@{$self->{talklist}}) {
-					$self->send_talks($_, $rawline);
+					if ($self->{state} eq 'talk') {
+						$self->send_talks($_, $rawline);
+					} else {
+						$self->send_chats($_, $rawline);
+					}
 				}
 			}
 			$self->send($self->talk_prompt) if $self->{state} eq 'talk';
+			$self->send($self->chat_prompt) if $self->{state} eq 'chat';
 		} else {
 			# for safety
 			$self->state('prompt');
@@ -398,16 +411,40 @@ sub send_talks
 	}
 }
 
-sub talk_prompt
+sub send_chats
 {
 	my $self = shift;
+	my $target = shift;
+	my $text = shift;
+
+	my $msgid = DXProt::nextchatmsgid();
+	$text = "#$msgid $text";
+	$main::me->normal(DXProt::pc93($target, $self->{call}, undef, $text));
+}
+
+sub special_prompt
+{
+	my $self = shift;
+	my $prompt = shift;
 	my @call;
 	for (@{$self->{talklist}}) {
 		my ($to, $via) = /(\S+)>(\S+)/;
 		$to = $_ unless $to;
 		push @call, $to;
 	}
-	return $self->msg('talkprompt', join(',', @call));
+	return $self->msg($prompt, join(',', @call));
+}
+
+sub talk_prompt
+{
+	my $self = shift;
+	return $self->special_prompt('talkprompt');
+}
+
+sub chat_prompt
+{
+	my $self = shift;
+	return $self->special_prompt('chatprompt');
 }
 
 #
@@ -813,7 +850,7 @@ sub send
 sub local_send
 {
 	my ($self, $let, $buf) = @_;
-	if ($self->{state} eq 'prompt' || $self->{state} eq 'talk') {
+	if ($self->{state} eq 'prompt' || $self->{state} eq 'talk' || $self->{state} eq 'chat') {
 		if ($self->{enhanced}) {
 			$self->send_later($let, $buf);
 		} else {
diff --git a/perl/Messages b/perl/Messages
index c3b1a144..323c8603 100644
--- a/perl/Messages
+++ b/perl/Messages
@@ -28,6 +28,10 @@ package DXM;
 				buddya => '$_[0] has been added to your buddies',
 				buddyu => '$_[0] has been removed from your buddies',
 				call1 => 'Callsign lookup via $_[0]:',
+				chatend => 'Finished chatting on $_[0]',
+				chatinst => 'Entering Chatmode on $_[0], /EX to end, /<cmd> to run a command',
+				chatprompt => 'Chat ($_[0])>',
+				chattoomany => 'Not allowed, already in $_[1], use /chat $_[0]',
 				conother => 'Sorry $_[0] you are connected to me on another port',
 				concluster => 'Sorry $_[0] you are already connected elsewhere on the cluster (on $_[1])',
 				conscript => 'no connect script called \"$_[0]\" found in $main::root/connect',
-- 
2.43.0