Posted 01 September 2013 - 06:14 AM
After just generally screwing around with ComputerCraft for the first time, which was a year ago, I made a program that was a simple peer to peer messaging program; someone sends a message while the other end waits until the message comes.
So after so long, I've looked back to my year old program that was rotting in my recovered folder after my last unfortunate computer issue and took on the project to recode the whole script from scratch.
The idea is to make a client that would send a serialized table to a server for it to process and respond accordingly before saving the message on it's filesystem. When the recipient requests for what's in their inbox, the server complies and responds back with the message.
Also ideas of making relays for those computers that are far away from the server is also something I have considered, considering this won't be much of a hassle considering the client is programed to send a table to a user-defined ID. When doing this in reverse, I have gotten the idea of when a computer makes it's first message to a server, whether be a ping, check, etc, the relay would save the location where the ID came from when it was jumping from relay to relay.
Currently, the code is still a work in progress, but feel free to look at the progress as of now.
Client
Server
So after so long, I've looked back to my year old program that was rotting in my recovered folder after my last unfortunate computer issue and took on the project to recode the whole script from scratch.
The idea is to make a client that would send a serialized table to a server for it to process and respond accordingly before saving the message on it's filesystem. When the recipient requests for what's in their inbox, the server complies and responds back with the message.
Also ideas of making relays for those computers that are far away from the server is also something I have considered, considering this won't be much of a hassle considering the client is programed to send a table to a user-defined ID. When doing this in reverse, I have gotten the idea of when a computer makes it's first message to a server, whether be a ping, check, etc, the relay would save the location where the ID came from when it was jumping from relay to relay.
Currently, the code is still a work in progress, but feel free to look at the progress as of now.
Client
Spoiler
print("Loading P2PChat API by WhiteTec Software...")
--[[ P2P Chat Help File Link! ]]
function version()
print("You are using the P2PChat API by WhiteTec Software\nVersion: 1")
end
function ping(x,y,z)
local reddata = {}
local success = 0
rednet.open(y)
for i=1,x do
reddata[1] = "PING"
rednet.send(z, textutils.serialize(reddata))
local id, mesg, dist = rednet.receive(1)
if mesg == nil then
print("No response.")
else
local decoded = textutils.unserialize(mesg)
if decoded[1] == "PONG" then
print("Got response from "..(id).." at "..(dist).." blocks away")
success = success+1
else
print("Malformed packet from "..(id).." at "..(dist).." blocks away")
end
end
sleep(0.5)
end
--rednet.close(y)
return success
end
function editor(x)
if x == nil then
temp = fs.open("serverid", "r")
data = temp.readAll()
temp.close()
else
temp = fs.open("serverid", "w")
temp.write(x)
temp.close()
data = "Wrote"
end
end
function check()
if fs.exists("serverid") then
editor()
else
temp = fs.open("serverid", "w")
temp.close()
editor()
end
if data == "" then
firstrun()
else
server = tonumber(data)
main()
end
end
function firstrun()
print("")
textutils.slowPrint("Welcome to P2P Chat by WhiteTec Software.", 50)
print("Input your local server ID.")
serverid = read()
serverid = tonumber(serverid)
print("Input where the connection is on your computer. (Back, Front, etc.)")
port = read()
checkport(port)
print("Checking if server is online...\n")
isgood = ping(5,port,serverid)
function starttest()
if isgood == 5 then
print("Connection successful!\nPress a key to start the menu.")
editor(serverid)
server = serverid
os.pullEvent("key")
term.clear()
term.setCursorPos(1,1)
main()
elseif isgood < 5 then
print("Connection had failures, try again or start set-up?\n[y/n/s]")
local question = read()
if question == "y" then
starttest()
elseif question == "s" then
firstrun()
else
print("\nPress a key to start the menu.")
editor(serverid)
server = serverid
os.pullEvent("key")
term.clear()
term.setCursorPos(1,1)
main()
end
end
end
starttest()
end
function receive(x,y)
if 0<x<=60 or y == "Force" then
local id, mesg, dist = rednet.receive(x)
local decoded = textutils.unserialize(mesg)
return id, decoded, dist
else
return false
end
end
function checkport(x)
if peripheral.getType(x) == nil then
print("No Device")
firstrun()
elseif peripheral.isPresent(x) == false or peripheral.getType(x) ~= "modem" then
print("Invalid Device: "..(firstToUpper(peripheral.getType(x))).."")
firstrun()
end
local temp = peripheral.wrap(x)
if temp.isWireless() then
print("Wirelessly Connected\n")
else
print("Wired Connection\n")
end
end
function firstToUpper(str)
return (str:gsub("^%l", string.upper))
end
function main()
term.clear()
term.setCursorPos(1,1)
textutils.slowPrint("Welcome to P2P Chat by WhiteTec Software.", 50)
print("Please put in what you want to do.")
os.pullEvent("key")
term.clear()
term.setCursorPos(1,1)
firstrun()
end
print("P2PChat API Ready.")
check(
Spoiler
function rt()
local ntime = os.time()
ntime = textutils.formatTime( ntime, false)
return ntime
end
term.clear()
term.setCursorPos(1,1)
print(""..(rt())..": Loading P2P Chat Server Version 1 by WhiteTec software...")
function rt()
local ntime = os.time()
ntime = textutils.formatTime( ntime, false)
return ntime
end
function editor(x,y)
if x == nil then
temp = fs.open(y, "r")
fdata = temp.readAll()
temp.close()
else
temp = fs.open(y, "w")
temp.write(x)
temp.close()
return true
end
end
function listen()
rednet.open(port)
print(""..(rt())..": Listening...")
local id, mesg, dist = rednet.receive()
checkreply(id, mesg, dist)
end
function checkreply(x,y,z)
print(""..(rt())..": Message received from "..(x).." at "..(z).." blocks away.")
local decoded = textutils.unserialize(y)
if decoded[1] == "PING" then
pingreply(x)
elseif decoded[1] == "MESSAGE" then
archive(decoded,x)
elseif decoded[1] == "CHECK" then
sendinbox(x)
else
invaild(x,"INVALIDCOMMAND")
end
end
function invaild(x,y)
if y == "INVALIDCOMMAND" then
print(""..(rt())..": Invalid command was received.")
elseif y == "NORECIPIENT" then
print(""..(rt())..": No recipient was received.")
end
local reddata = {}
reddata[1] = "ERROR"
reddata[4] = y
rednet.send(x,textutils.serialize(reddata))
end
function pingreply(x)
print(""..(rt())..": Pinged. Responding back...")
local reddata = {}
reddata[1] = "PONG"
rednet.send(x,textutils.serialize(reddata))
listen()
end
function archive(x,y)
local r = x[2]
local s = x[3]
print(""..(s).." sent message to "..(r)..", saving...")
if r == nil or r == "" then
invaild(y,"NORECIPIENT")
listen()
else
editor(editortextutils.serialize(x),tostring(r))
listen()
end
end
function sendinbox(x)
print(""..(rt())..": "..(x).." requested Inbox")
if fs.exists(tostring(x)) then
print(""..(rt())..": "..(x).." has mail, sending...")
editor(nil,tostring(x))
rednet.send(x,fdata)
listen()
else
print(""..(rt())..": "..(x).." has no mail, sending error...")
local t = {}
t[1] = "ERROR"
t[4] = "NOMESSAGE"
rednet.send(x,textutils.serialize(t))
listen()
end
end
print(""..(rt())..": Server loaded, starting service...")
print("Choose a port to connect to.")
port = read()
listen()