add arrow support
This commit is contained in:
parent
71e504e273
commit
c32a4143dc
1 changed files with 90 additions and 19 deletions
109
mewny.rb
Normal file → Executable file
109
mewny.rb
Normal file → Executable file
|
|
@ -68,7 +68,11 @@ PORT = options[:port]
|
||||||
|
|
||||||
ROWS = options[:rows]
|
ROWS = options[:rows]
|
||||||
COLS = options[:cols]
|
COLS = options[:cols]
|
||||||
VERSION = 0.01
|
VERSION = {
|
||||||
|
:SRV_TXT => '0.01',
|
||||||
|
:CLN_TXT => '0.01',
|
||||||
|
:CLN_ARO => '0.02',
|
||||||
|
}
|
||||||
|
|
||||||
def do_server
|
def do_server
|
||||||
server = TCPServer.new(SRV_HOST, PORT)
|
server = TCPServer.new(SRV_HOST, PORT)
|
||||||
|
|
@ -82,28 +86,44 @@ def do_server
|
||||||
buffer = pre.ljust(ROWS*COLS)[0...ROWS*COLS]
|
buffer = pre.ljust(ROWS*COLS)[0...ROWS*COLS]
|
||||||
windex = pre.length # Wipe your buffer clean with your write index
|
windex = pre.length # Wipe your buffer clean with your write index
|
||||||
windex %= buffer.length
|
windex %= buffer.length
|
||||||
|
motions = []
|
||||||
|
|
||||||
def new_buf_wi_out(buf, wi, newtext)
|
def new_buf_wi_out(buf, wi, newtext, motions: [])
|
||||||
buf = buf.dup
|
buf = buf.dup
|
||||||
out = ''
|
out = ''
|
||||||
nti = 0 # New Text Index
|
nti = 0 # New Text Index
|
||||||
while nti < newtext.length
|
while (nti < newtext.length) || (motions.length > 0)
|
||||||
out << "#{VERSION}|"
|
if motions.length > 0 && nti >= motions[0][:nti]
|
||||||
|
case motions[0][:dir]
|
||||||
|
when 'u'
|
||||||
|
wi -= COLS
|
||||||
|
when 'd'
|
||||||
|
wi += COLS
|
||||||
|
when 'l'
|
||||||
|
wi -= 1
|
||||||
|
when 'r'
|
||||||
|
wi += 1
|
||||||
|
end
|
||||||
|
wi %= ROWS*COLS
|
||||||
|
motions.shift # remove first motion
|
||||||
|
end
|
||||||
|
out << "#{VERSION[:SRV_TXT]}|"
|
||||||
out << ((wi/COLS)+1).to_s + '|'
|
out << ((wi/COLS)+1).to_s + '|'
|
||||||
out << ((wi%COLS)+1).to_s + '|'
|
out << ((wi%COLS)+1).to_s + '|'
|
||||||
|
next if nti >= newtext.length
|
||||||
loop do
|
loop do
|
||||||
out << newtext[nti]
|
out << newtext[nti]
|
||||||
buf[wi] = newtext[nti]
|
buf[wi] = newtext[nti]
|
||||||
wi += 1
|
wi += 1
|
||||||
nti += 1
|
nti += 1
|
||||||
|
break if motions.length > 0 && nti >= motions[0][:nti]
|
||||||
break if nti >= newtext.length
|
break if nti >= newtext.length
|
||||||
break if wi%COLS == 0
|
break if wi%COLS == 0
|
||||||
end
|
end
|
||||||
wi = 0 if wi >= (ROWS*COLS)
|
|
||||||
wi %= ROWS*COLS
|
wi %= ROWS*COLS
|
||||||
out << "\n"
|
out << "\n"
|
||||||
end
|
end
|
||||||
[buf, wi, out] # << Implicit return
|
[buf, wi, out]
|
||||||
end
|
end
|
||||||
|
|
||||||
loop do
|
loop do
|
||||||
|
|
@ -130,17 +150,47 @@ def do_server
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
ver, msg = msg.chomp.split('|',2)
|
ver, msg = msg.chomp.split('|',2)
|
||||||
next unless ver.to_f <= VERSION
|
case ver
|
||||||
next unless msg != nil
|
when VERSION[:CLN_TXT]
|
||||||
newtext << msg
|
next unless msg != nil
|
||||||
|
newtext << clean_chars(msg)
|
||||||
|
when VERSION[:CLN_ARO]
|
||||||
|
next unless msg != nil
|
||||||
|
dir = 'l'
|
||||||
|
case msg
|
||||||
|
when 'A'
|
||||||
|
dir = 'u'
|
||||||
|
when 'B'
|
||||||
|
dir = 'd'
|
||||||
|
when 'C'
|
||||||
|
dir = 'r'
|
||||||
|
when 'D'
|
||||||
|
dir = 'l'
|
||||||
|
else
|
||||||
|
next
|
||||||
|
end
|
||||||
|
motions << {
|
||||||
|
:nti => newtext.length - 1,
|
||||||
|
:dir => dir
|
||||||
|
}
|
||||||
|
end
|
||||||
rescue Errno::ECONNRESET, Errno::EPIPE
|
rescue Errno::ECONNRESET, Errno::EPIPE
|
||||||
puts "Disconnect (err): #{sck.peeraddr}"
|
puts "Disconnect (err): #{sck.peeraddr}"
|
||||||
sck.close
|
sck.close
|
||||||
sockets.delete(sck)
|
sockets.delete(sck)
|
||||||
end
|
end
|
||||||
buffer, windex, out = new_buf_wi_out(buffer,windex,newtext)
|
buffer, windex, out = new_buf_wi_out(buffer,windex,newtext,motions:motions)
|
||||||
|
motions = []
|
||||||
clients = sockets - [server]
|
clients = sockets - [server]
|
||||||
clients.each { |c| c.puts out }
|
clients.each do |c|
|
||||||
|
begin
|
||||||
|
c.puts out
|
||||||
|
rescue Errno::ECONNRESET, Errno::EPIPE
|
||||||
|
puts "Disconnect (err): #{c.peeraddr}"
|
||||||
|
c.close
|
||||||
|
sockets.delete(c)
|
||||||
|
end
|
||||||
|
end
|
||||||
#if out != ''
|
#if out != ''
|
||||||
# puts "#{windex}: (#{(windex/COLS)+1},#{(windex%COLS)+1})"
|
# puts "#{windex}: (#{(windex/COLS)+1},#{(windex%COLS)+1})"
|
||||||
#end
|
#end
|
||||||
|
|
@ -148,6 +198,20 @@ def do_server
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def clean_chars(chars)
|
||||||
|
out = ''
|
||||||
|
chars.each_char do |char|
|
||||||
|
if char.ord < 0x20 # Non printing
|
||||||
|
out << '^'+(char.ord + 0x40).chr
|
||||||
|
elsif char.ord == 0x7F # DEL (Non print)
|
||||||
|
out << '^?'
|
||||||
|
else
|
||||||
|
out << char
|
||||||
|
end
|
||||||
|
end
|
||||||
|
out
|
||||||
|
end
|
||||||
|
|
||||||
def do_client
|
def do_client
|
||||||
socket = TCPSocket.new(HOST, PORT)
|
socket = TCPSocket.new(HOST, PORT)
|
||||||
|
|
||||||
|
|
@ -163,24 +227,31 @@ def do_client
|
||||||
msg = socket.gets
|
msg = socket.gets
|
||||||
exit 0 unless msg
|
exit 0 unless msg
|
||||||
ver, msg = msg.split('|',2)
|
ver, msg = msg.split('|',2)
|
||||||
next unless ver.to_f <= VERSION
|
next unless ver == VERSION[:SRV_TXT]
|
||||||
next unless msg != nil
|
next unless msg != nil
|
||||||
# In message version 0.01 and lower,
|
# In message version 0.01 and lower,
|
||||||
# all messages are in an assumed format...
|
# all messages are in an assumed format...
|
||||||
row,col,chars = msg.split('|',3)
|
row,col,chars = msg.split('|',3)
|
||||||
print "\x1b[#{row};#{col}H#{chars}\x1b[A"
|
print "\x1b[#{row};#{col}H#{chars.chomp}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
while (char = STDIN.noecho(&:getch))
|
while (char = STDIN.noecho(&:getch))
|
||||||
exit unless char != "\x04" # ^D
|
exit unless char != "\x04" # ^D
|
||||||
if char.ord < 0x20 # Non printing
|
if char == "\x1b" # Detect arrows
|
||||||
char = '^'+(char.ord + 0x40).chr
|
char2 = STDIN.noecho(&:getch)
|
||||||
elsif char.ord == 0x7F # DEL (Non print)
|
if /[A-D]/.match? (char3 = STDIN.noecho(&:getch).upcase)
|
||||||
char = '^?'
|
socket.puts "#{VERSION[:CLN_ARO]}|#{char3}"
|
||||||
|
next
|
||||||
|
else
|
||||||
|
char << char2+char3
|
||||||
|
end
|
||||||
|
elsif (char == "\x08" || # backspace
|
||||||
|
char == "\x7F" ) # delete
|
||||||
|
socket.puts "#{VERSION[:CLN_ARO]}|D"
|
||||||
|
next
|
||||||
end
|
end
|
||||||
next unless
|
socket.puts "#{VERSION[:CLN_TXT]}|#{clean_chars(char)}"
|
||||||
socket.puts "#{VERSION}|#{char}"
|
|
||||||
end
|
end
|
||||||
ensure
|
ensure
|
||||||
print "\x1b[?1049l" # Back to regular buffer
|
print "\x1b[?1049l" # Back to regular buffer
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue