View difference between Paste ID: pDNfjk30 and QTwgLZMA
SHOW: | | - or go back to the newest paste.
1-
-- Minified CRC32 blob - MIT license - from here: https://raw.githubusercontent.com/davidm/lua-digest-crc32lua/master/lmod/digest/crc32lua.lua
1+
-- converts a value between 0 and 127 to bits, least significant bits first
2-
do
2+
local function to_bits(charbyte)
3-
	local type=type;local require=require;local setmetatable=setmetatable;local a=bit.bxor;local b=bit.bnot;local c=bit.band;local d=bit.brshift;local e=0xEDB88320;local function f(g)local h={}local i=setmetatable({},h)function h:__index(j)local k=g(j)i[j]=k;return k end;return i end;local l=f(function(m)local n=m;for o=1,8 do local p=c(n,1)n=d(n,1)if p==1 then n=a(n,e)end end;return n end)local function q(r,n)n=b(n or 0)local s=d(n,8)local t=l[a(n%256,r)]return b(a(s,t))end;local function u(v,n)n=n or 0;for m=1,#v do n=q(v:byte(m),n)end;return n end;function crc32(v,n)if type(v)=='string'then return u(v,n)else return q(v,n)end end
3+
	if charbyte > 127 then error "invalid character" end
4
	local out = {}
5
	for i = 0, 6 do 
6-
local function get_byte(num, byte)
6+
		local bitmask = bit.blshift(1, i)
7-
    return bit.band(bit.brshift(num, byte * 8), 0xFF)
7+
		local bit = bit.brshift(bit.band(bitmask, charbyte), i)
8
		table.insert(out, bit)
9
	end
10-
local function from_bytes(b)
10+
	return out
11-
    local n = 0
11+
12-
    for ix, byte in pairs(b) do
12+
13-
        n = bit.bor(n, bit.blshift(byte, (ix - 1) * 8))
13+
local function from_bits(bit_table)
14
	local int = 0
15-
    return n
15+
	for i = 0, 6 do
16
		local index = i + 1 -- Lua...
17
		int = bit.bor(int, bit.blshift(bit_table[index], i))
18-
local side = settings.get "bundlenet.side" or "back"
18+
19
	return int
20-
local function send_raw(str)
20+
21-
	local i = 1
21+
22-
	for i = 1, math.ceil(#str / 2) do
22+
local rx_side = settings.get "rx_side" or "right"
23-
		local first = str:byte(i * 2 - 1)
23+
local tx_side = settings.get "tx_side" or "left"
24-
		local second = str:byte(i * 2) or 0
24+
25-
		local u16 = first * 256 + second
25+
local function send(str)
26-
		rs.setBundledOutput(side, u16)
26+
	str = "\127" .. str
27-
		sleep(0.1)
27+
	for i = 1, #str do
28
		local byte = str:byte(i)
29-
	rs.setBundledOutput(side, 0)
29+
		for _, bit in ipairs(to_bits(byte)) do
30
			rs.setOutput(tx_side, bit == 1)
31
			sleep(0.1)
32-
local function receive_raw(length)
32+
33
	end
34-
	local count = 0
34+
	rs.setOutput(tx_side, false)
35-
	os.pullEvent "redstone"
35+
36
37-
		local u16 = rs.getBundledInput(side)
37+
local function receive(char_callback)
38-
		local first = string.char(math.floor(u16 / 256))
38+
39-
		if not length and first == "\0" then break
39+
	repeat
40-
		else
40+
		os.pullEvent "redstone"
41-
			count = count + 1
41+
	until rs.getInput(rx_side)
42-
			str = str .. first
42+
43-
			if count == length then break end
43+
		local bits = {}
44-
			local second = string.char(u16 % 256)
44+
		for i = 0, 6 do
45-
			if not length and second == "\0" then break
45+
			if rs.getInput(rx_side) then 
46
				table.insert(bits, 1)
47-
				count = count + 1
47+
48-
				str = str .. second
48+
				table.insert(bits, 0)
49-
				if count == length then break end
49+
50
			sleep(0.1)
51
		end
52-
		sleep(0.1)
52+
		local char = string.char(from_bits(bits))
53
		if char == "\0" then break end
54-
	return str
54+
		if char ~= "\127" and char_callback then char_callback(char) end
55
		str = str .. char
56
	end
57-
local function u32_to_string(u32)
57+
	return str:sub(2)
58-
	return string.char(get_byte(u32, 0), get_byte(u32, 1), get_byte(u32, 2), get_byte(u32, 3))
58+
59
60
local w, h = term.getSize()
61-
local function string_to_u32(str)
61+
local send_window = window.create(term.current(), 1, h, w, 1)
62-
	return from_bytes{str:byte(1), str:byte(2), str:byte(3), str:byte(4)}
62+
local message_window = window.create(term.current(), 1, 1, w, h - 1)
63
64
local function exec_in_window(w, f)
65-
local function send(data)
65+
    local x, y = term.getCursorPos()
66-
	local length = u32_to_string(#data)
66+
    local last = term.redirect(w)
67-
	local checksum = u32_to_string(crc32(data))
67+
    f()
68-
	print("len", length, "checksum", checksum)
68+
    term.redirect(last)
69-
	send_raw(length)
69+
    w.redraw()
70-
	send_raw(checksum)
70+
    term.setCursorPos(x, y)
71-
	send_raw(data)
71+
72
 
73
local function write_char(txt)
74-
local function receive()
74+
    exec_in_window(message_window, function()
75-
	local length = receive_raw(4)
75+
        write(txt)
76-
	--sleep(0.1)
76+
    end)
77-
	local checksum = receive_raw(4)
77+
78-
	print("len", length, "checksum", checksum, "l", string_to_u32(length), "c", string_to_u32(checksum))
78+
79-
	--sleep(0.1)
79+
local function sender()
80-
	local data = receive_raw(string_to_u32(length))
80+
    term.redirect(send_window)
81-
	if crc32(data) ~= string_to_u32(checksum) then return false, "checksum mismatch", data end
81+
    term.setBackgroundColor(colors.lightGray)
82-
	return true, data
82+
    term.setTextColor(colors.white)
83
    term.clear()
84
    while true do
85-
local option = ...
85+
        local msg = read()
86
		send(msg)
87-
if option == "send" then
87+
88-
	write "Send: "
88+
89-
	local text = read()
89+
90-
	send(text)
90+
local function receiver()
91-
elseif option == "raw_receive" then
91+
92-
	print(receive_raw())
92+
		receive(write_char)
93-
elseif option == "receive" then
93+
		write_char "\n"
94-
	print(receive())
94+
95
end
96
97-
return { send = send, receive = receive }
97+
parallel.waitForAll(sender, receiver)