From 131fef7866d39344455b623b4df9b5402c49177b Mon Sep 17 00:00:00 2001 From: mewrrythekibby Date: Tue, 10 Feb 2026 13:35:44 -0600 Subject: [PATCH] Add colors to mewny --- mewny.rb | 97 +++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 72 insertions(+), 25 deletions(-) diff --git a/mewny.rb b/mewny.rb index 827f1b4..4c385a4 100755 --- a/mewny.rb +++ b/mewny.rb @@ -31,7 +31,7 @@ OptionParser.new do |opt| options[:server] = false end opt.on('-HHOST', '--host HOST', String, - '(client only) Host to connect to (defaults to `localhost`)') do |o| + '(client only) Host to connect to (defaults to `localhost`)') do |o| options[:host] = o end opt.on('-rROWS', '--rows ROWS', Integer, @@ -48,9 +48,9 @@ OptionParser.new do |opt| # X -- eXposed '(server only) Serve publicly, rather than privately. Please ONLY add this option if you entierly know what you\'re doing and have permission from/are the server owner. Say please to expose.' ) do |o| - if o == "please" - options[:server_host] = PUBLIC_HOST - end + if o == "please" + options[:server_host] = PUBLIC_HOST + end end opt.on('-x', '--private', # x -- not visible @@ -74,11 +74,20 @@ VERSION = { :SRV_TXT => '0.01', :CLN_TXT => '0.01', :CLN_ARO => '0.02', + :SRV_CO8 => '0.30', # 8-color + :CLN_CO8 => '0.30', # 8-color } def do_server server = TCPServer.new(SRV_HOST, PORT) sockets = [server] + sockats = { + server => { + :color => { + :co8 => 7 + } + } + } puts "PORT: #{PORT}" puts "GRID SIZE: #{ROWS}r#{COLS}c" @@ -87,14 +96,20 @@ def do_server pre = "#{ROWS}r#{COLS}c >>> " buffer = pre.ljust(ROWS*COLS)[0...ROWS*COLS] + cobuf = Array.new(ROWS*COLS, { + :co8 => 7 + }) windex = pre.length # Wipe your buffer clean with your write index - windex %= buffer.length + windex = windex%buffer.length motions = [] - def new_buf_wi_out(buf, wi, newtext, motions: []) + def new_buf_cob_wi_out(buf, cob, wi, newtext, newcolors, motions: []) buf = buf.dup + cob = cob.dup out = '' nti = 0 # New Text Index + wco = {} #Writing Color + cur = motions.length > 0 #Update cursor at end while (nti < newtext.length) || (motions.length > 0) if motions.length > 0 && nti >= motions[0][:nti] case motions[0][:dir] @@ -107,40 +122,61 @@ def do_server when 'r' wi += 1 end - wi %= ROWS*COLS + wi = wi%(ROWS*COLS) motions.shift # remove first motion end + next if nti >= newtext.length + if newcolors[nti] != wco + wco = newcolors[nti] + if wco.has_key? :co8 + out << "#{VERSION[:SRV_CO8]}|#{wco[:co8]}\n" + end + end out << "#{VERSION[:SRV_TXT]}|" out << ((wi/COLS)+1).to_s + '|' out << ((wi%COLS)+1).to_s + '|' - next if nti >= newtext.length loop do out << newtext[nti] buf[wi] = newtext[nti] + cob[wi] = wco wi += 1 nti += 1 + break if newcolors[nti] != wco break if motions.length > 0 && nti >= motions[0][:nti] break if nti >= newtext.length break if wi%COLS == 0 end - wi %= ROWS*COLS + wi = wi%(ROWS*COLS) out << "\n" end - [buf, wi, out] + if cur + out << "#{VERSION[:SRV_TXT]}|" + out << ((wi/COLS)+1).to_s + '|' + out << ((wi%COLS)+1).to_s + "|\n" + end + [buf, cob, wi, out] end loop do - ready, = IO.select(sockets) + ready, = IO.select(sockets) newtext = '' + newcolors = [] ready.each do |sck| if sck == server client = server.accept + sockats[client] = { + :color => { + :co8 => 7 + } + } sockets << client puts "Connection: #{client.peeraddr}" - client.puts new_buf_wi_out(buffer,0,buffer)[2] + client.puts new_buf_cob_wi_out(buffer,cobuf,0,buffer,cobuf)[3] if buffer.length > 1 - client.puts new_buf_wi_out(buffer,windex-1,buffer[windex-1])[2] + client.puts new_buf_cob_wi_out( + buffer,cobuf,windex-1, + buffer[windex-1],[cobuf[windex-1]])[3] end next end @@ -150,15 +186,18 @@ def do_server puts "Disconnect: #{sck.peeraddr}" sck.close sockets.delete(sck) + sockats.delete(sck) next end ver, msg = msg.chomp.split('|',2) + next unless msg != nil case ver when VERSION[:CLN_TXT] - next unless msg != nil newtext << clean_chars(msg) + msg.length.times do + newcolors << sockats[sck][:color].dup + end when VERSION[:CLN_ARO] - next unless msg != nil dir = 'l' case msg when 'A' @@ -174,15 +213,17 @@ def do_server end motions << { :nti => newtext.length - 1, - :dir => dir + :dir => dir, } + when VERSION[:CLN_CO8] + sockats[sck][:color][:co8] = msg.to_i.clamp(0,7) end rescue Errno::ECONNRESET, Errno::EPIPE puts "Disconnect (err): #{sck.peeraddr}" sck.close sockets.delete(sck) end - buffer, windex, out = new_buf_wi_out(buffer,windex,newtext,motions:motions) + buffer, cobuf, windex, out = new_buf_cob_wi_out(buffer,cobuf,windex,newtext,newcolors,motions:motions) motions = [] clients = sockets - [server] clients.each do |c| @@ -223,6 +264,7 @@ def do_client begin print "\x1b[?1049h\x1b[2J\x1b[3J" # Open and clear alternate buffer + print "\x1b[m" # Reset color #reader = Thread.new do Thread.new do @@ -230,17 +272,21 @@ def do_client msg = socket.gets exit 0 unless msg ver, msg = msg.split('|',2) - next unless ver == VERSION[:SRV_TXT] next unless msg != nil - # In message version 0.01 and lower, - # all messages are in an assumed format... - row,col,chars = msg.split('|',3) - print "\x1b[#{row};#{col}H#{chars.chomp}" + case ver + when VERSION[:SRV_TXT] + row,col,chars = msg.split('|',3) + print "\x1b[#{row};#{col}H#{chars.chomp}" + when VERSION[:SRV_CO8] + next if ENV["TERM"].downcase == "dumb" + print "\x1b[3#{msg.to_i.clamp(0,7)}m" + end end end + socket.puts "#{VERSION[:CLN_CO8]}|#{rand(1..7)}" while (char = STDIN.noecho(&:getch)) - exit unless char != "\x04" # ^D + exit if char == "\x04" # ^D if char == "\x1b" # Detect arrows char2 = STDIN.noecho(&:getch) if /[A-D]/.match? (char3 = STDIN.noecho(&:getch).upcase) @@ -251,12 +297,13 @@ def do_client end elsif (char == "\x08" || # backspace char == "\x7F" ) # delete - socket.puts "#{VERSION[:CLN_ARO]}|D" - next + socket.puts "#{VERSION[:CLN_ARO]}|D" + next end socket.puts "#{VERSION[:CLN_TXT]}|#{clean_chars(char)}" end ensure + print "\x1b[m" # Reset color print "\x1b[?1049l" # Back to regular buffer end end