This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
WhiteFusion's profile picture

P2P Chat V2

Started by WhiteFusion, 01 September 2013 - 04:14 AM
WhiteFusion #1
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
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(
Server
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()
imthe666st #2
Posted 07 September 2013 - 02:09 PM
Upload the Code to pastebin please.
Going to test it now anyway :)/>

#EDIT
You forgot a ")" at the end :P/>
Hmm.. well I tried to do a ping to a server.

Spoiler

Well I don't know why it asks me this. Also try to add comments to your code, naming variables in a api as "x", "y" and "z" isn't very understandable :/