~aleteoryx/ntalk

4b44b80934c45f1a6a0f4a407c41c108b41f11de — Aleteoryx 2 months ago dbf338e
new client!
1 files changed, 177 insertions(+), 0 deletions(-)

A ntalk.tcl
A ntalk.tcl => ntalk.tcl +177 -0
@@ 0,0 1,177 @@
#!/bin/env wish

set confdir ~/.config/ntalk
set scriptpath "${confdir}/cscript.tcl"
file mkdir $confdir

### UI SETUP ###

frame .foot
entry .foot.input
label .foot.msgs -textvariable lastmsg

scrollbar .scroll -command {.buffer yview}
text .buffer -width 72 -yscrollcommand {.scroll set} -takefocus 1

pack .foot.msgs -side right 
pack .foot.input -side bottom -fill x

pack .foot -side bottom -fill x
pack .scroll -side right -fill y
pack .buffer -fill both

if {[catch {package require history}] == 0} {
	history::init .foot.input
	bind .foot.input <Return> {
		if {[.foot.input get] != {}} {
			history::add .foot.input [.foot.input get]
		}
	}
}


### CONNECTING ###

if [file readable $scriptpath] {
	set fp [open $scriptpath]
	.buffer insert 1.0 [read $fp]
	close $fp
} else {
	.buffer insert 1.0 {# input connection script, then hit C-RET
set sok [socket localhost 44322]
set user marmalade
}
}

bind .buffer <Control-Return> {
	set cscript [.buffer get 1.0 end]
}
.buffer mark set insert end
vwait cscript
bind .buffer <Control-Return> {}
.buffer configure -state disabled

set fp [open $scriptpath w]
puts $fp [string trim $cscript]
close $fp

eval $cscript
fconfigure $sok -translation lf; # dammit
set lastmsg 0


### NETCODE ###

proc sendl {line} {
	global sok
	regsub "\n" $line " " line
	puts $sok $line
	flush $sok
}
proc recvl {} {
	global sok
	gets $sok
}
proc recvlines {{bd 0}} {
	global lastmsg
	set n [recvl]
	for {set i 0} {$i < $n} {incr i} {
		bufpush [recvl]
		if $bd bufdown
	}
	set lastmsg [recvl]
}

proc bufpush {line} {
	.buffer configure -state normal
	.buffer insert end "$line\n"
	.buffer configure -state disabled
	update
}
proc bufdown {} {
	.buffer yview moveto 1
	update
}
proc bufclear {} {
	.buffer configure -state normal
	.buffer replace 1.0 end {}
	.buffer configure -state disabled
	update
}

proc send {line} {
	sendl "SEND $line"
	recvl
}

proc poll {} {
	global lastmsg
	sendl "POLL $lastmsg"
	recvl
}

proc hist {} {
	bufclear
	sendl HIST
	recvlines 1
}

proc last {n} {
	bufclear
	sendl "LAST $n"
	recvlines 1
}

proc skip {} {
	global lastmsg
	sendl "SKIP $lastmsg"
	recvlines
}


### ACTUAL CLIENT CODE LMAO ###

proc sendmsg {msg} {
	global lastmsg
	set msgid [send $msg]
	if {$msgid == $lastmsg} {
		bufpush "$msg\n"
	} else { skip }
	bufdown
}

proc pollmsgs {} {
	if {[poll] != "0"} { skip }
	after 10000 pollmsgs
}


### BOOT ###

last 16
after 10000 pollmsgs
bind .foot.input <Return> [concat [bind .foot.input <Return>] ";" {
	set line [.foot.input get]
	switch -glob -- $line {
		/hist {
			hist
		}
		{/last *} {
			last [string range $line 6 end]
		}
		{/send *} {
			send [string range $line 6 end]
		}
		/me* {
			sendmsg "${user}[string range $line 3 end]"
		}
		{/my *} {
			sendmsg "${user}'s [string range $line 4 end]"
		}
		default {
			sendmsg "$user: $line"
		}
	}

	.foot.input delete 0 end
}]