#!/usr/bin/env ruby require 'socket' require 'optparse' PUBLIC_HOST = '0.0.0.0' PRIVATE_HOST = '127.0.0.1' options = { :port => 7570, :host => PRIVATE_HOST, :rows => 24, :cols => 40, } OptionParser.new do |opt| opt.on('-pPORT', '--port PORT', Integer, 'Port to serve on (defaults to 7570)') do |o| options[:port] = o end opt.on('-rROWS', '--rows ROWS', Integer, 'The number of rows to have in the shared buffer') do |o| options[:rows] = o end opt.on('-cCOLS', '--cols COLS', Integer, 'The number of columns to have in the shared buffer') do |o| options[:cols] = o end opt.on('-s', '--public', Boolean, 'Serve publicly, rather than privately') do options[:host] = PUBLIC_HOST end opt.on('-S', '--private', Boolean, 'Serve privately, rather than publicly (default)') do options[:host] = PRIVATE_HOST end opt.on('-h', '--help', 'Get help with this command') do puts opt exit end end.parse!(into: options) HOST = options[:host] PORT = options[:port] ROWS = options[:rows] COLS = options[:cols] VERSION = 0.01 server = TCPServer.new(HOST, PORT) sockets = [server] puts "PORT: #{PORT}" puts "GRID SIZE: #{ROWS}r#{COLS}c" puts 'Listening...' pre = "#{ROWS}r#{COLS}c >>> " buffer = pre.ljust(ROWS*COLS)[0...ROWS*COLS] windex = pre.length # Wipe your buffer clean with your write index windex %= buffer.length def new_buf_wi_out(buf, wi, newtext) buf = buf.dup out = '' nti = 0 # New Text Index while nti < newtext.length out << "#{VERSION}|" out << ((wi/COLS)+1).to_s + '|' out << ((wi%COLS)+1).to_s + '|' loop do out << newtext[nti] buf[wi] = newtext[nti] wi += 1 nti += 1 break if nti >= newtext.length break if wi%COLS == 0 end wi = 0 if wi >= (ROWS*COLS) wi %= ROWS*COLS out << "\n" end return [buf, wi, out] end loop do ready, = IO.select(sockets) newtext = '' ready.each do |sck| if sck == server client = server.accept sockets << client puts "Connection: #{client.peeraddr}" client.puts new_buf_wi_out(buffer,0,buffer)[2] if buffer.length > 1 client.puts new_buf_wi_out(buffer,windex-1,buffer[windex-1])[2] end next end begin msg = sck.gets unless msg puts "Disconnect: #{sck.peeraddr}" sck.close sockets.delete(sck) next end ver, msg = msg.chomp.split('|',2) next unless ver.to_f <= VERSION next unless msg != nil newtext << msg 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) clients = sockets - [server] clients.each { |c| c.puts out } #if out != '' # puts "#{windex}: (#{(windex/COLS)+1},#{(windex%COLS)+1})" #end end end