Okay, another question. I don't know why but when I have connected the client to the server and try to send a message to it, it returns a nil message
Server
os.loadAPI( "hash" )
os.loadAPI( "AES" )
os.loadAPI( "base64" )
term.clear()
term.setCursorPos( 1, 1 )
rednet.open( "back" )
local SNet = dofile( "SNet" )
local network = SNet.host( "TsT", "server", "test" )
if network then
print( "Server is now running" )
while true do
local e = { os.pullEvent( "rednet_message" ) }
local id, message = network:handle( unpack( e ) )
print( type( message ) ) --# It prints nil here
if id and type( message ) == "string" then
local time = textutils.formatTime( os.time(), true )
term.write( "[" .. time .. "][" .. id .. "] " .. message )
end
end
else
error( "Failed to host server", 0 )
end
Client
rednet.open( "back" )
os.loadAPI( "hash" )
os.loadAPI( "AES" )
os.loadAPI( "base64" )
local SNet = dofile( "SNet" )
term.clear()
term.setCursorPos( 1, 1 )
print( "Connecting to server.." )
local server = SNet.connect( "TsT", "server", "test" )
if not server then
error( "Couldn't connect to server", 0 )
end
while true do
write( "> " )
local input = read()
server:send( server.id, input )
end
SNet API
--[[
[API] SNet
@version 1.0, 2014-12-18
@author TheOddByte
--]]
local SNet = {}
SNet.__index = SNet
--# Check that all the needed APIs are loaded
assert( hash ~= nil, "hash API needed for this script" )
assert( base64 ~= nil, "base64 API needed for this script" )
assert( AES ~= nil, "AES API needed for this script" )
--# Local functions
local function exists( protocol, hostname )
local id = rednet.lookup( protocol, hostname )
return type( id ) == "number" and true, id or false
end
local function encrypt( _data, key )
local data
if type( _data ) == "table" then
data = {}
for k, v in pairs( _data ) do
local index = AES.encrypt( key, k )
local value = AES.encrypt( key, v )
data[base64.encode( index )] = base64.encode( value )
end
elseif type( _data ) == "string" then
data = AES.encrypt( key, _data )
data = base64.encode( data )
end
return data
end
local function decrypt( data, key )
local result = {}
if type( data ) == "table" then
result = {}
for k, v in pairs( data ) do
local index = base64.decode( k )
index = AES.decrypt( key, index )
local value = base64.decode( v )
value = AES.decrypt( key, value )
result[index] = value
end
elseif type( data ) == "string" then
result = base64.decode( data )
result = AES.decrypt( key, data )
end
return result
end
SNet.connect = function( protocol, hostname, server_key )
local valid, host_id = exists( protocol, hostname )
if valid then
local net = {
isHost = false;
key = hash.sha256( tostring( math.ceil(os.time())*host_id ) );
id = host_id;
protocol = protocol;
hostname = hostname;
}
local packet = {
["request"] = "snet.connect";
["seed"] = tostring( os.time()*math.random() );
}
net.key = hash.sha256( tostring( packet["seed"]*host_id ) )
--# Share the seed with the server
rednet.send( host_id, encrypt( packet, server_key ), protocol )
--# Get the response from the server
local id, packet
local time, timer, timeout = 0, os.startTimer( 1 ), 10
repeat
id, packet = rednet.receive( protocol, 1 )
time = time + 1
until id == host_id and type( packet ) == "table" or time == timeout
if id == host_id then
if packet["response"] and packet["response"] == "success" then
return setmetatable( net, SNet )
end
end
end
return nil
end
SNet.host = function( protocol, hostname, key )
if not exists( protocol, hostname ) then
local net = {
key = key;
isHost = true;
connections = {};
protocol = protocol;
hostname = hostname;
}
rednet.host( protocol, hostname )
return setmetatable( net, SNet )
end
return nil
end
function SNet:isValidID( id )
if self.isHost then
if self.connections[tostring(id)] then
return true;
end
else
if id == self.id then
return true;
end
end
return false
end
function SNet:handle( ... )
local e = { ... }
if e[1] == "rednet_message" then
if self.isHost then
if self:isValidID( e[2] ) and e[4] == self.protocol then
return e[2], decrypt( e[3], self.connections[tostring(e[2])] ) --# It's here that it sends the message, it's here something goes wrong
else
if e[4] == self.protocol then
local packet = decrypt( e[3], self.key )
if type( packet ) == "table" and packet["request"] and packet["request"] == "snet.connect" then
print( "\nAdded " .. e[2] .. "\n" )
self.connections[tostring( e[2] )] = hash.sha256( tostring( packet["seed"]*os.getComputerID() ) )
self:send( e[2],{
["response"] = "success";
})
return nil
end
end
end
else
if self:isValidID( e[2] ) then
return e[2], decrypt( e[3], self.key )
end
end
else
return nil
end
end
function SNet:send( id, message )
if self:isValidID( id ) then
if self.isHost then
rednet.send( id, encrypt( message, self.connections[tostring(id)] ), self.protocol )
else
rednet.send( id, encrypt( message, self.key ), self.protocol )
end
end
end
function SNet:receive( timeout )
if timeout then
local time, timer, e = 0, os.startTimer( 1 )
repeat
e = { os.pullEvent() }
if e[1] == "timer" and e[2] == timer then
time = time + 1
end
until e[1] == "rednet_message" and self:isValidID( e[2] ) and e[4] == self.protocol or time == timeout
if e[1] == "rednet_message" then
return e[2], decrypt( message, self.key )
else
return nil
end
else
local e, message
repeat
e = { os.pullEvent( "rednet_message" ) }
if e[1] == "rednet_message" then
message = decrypt( message, self.key )
end
until self:isValidID( e[2] ) and e[4] == self.protocol
return e[2], message
end
end
function SNet:disconnect()
self:send( self.id, {
["request"] = "snet.disconnect";
})
end
return SNet
Anyone have a clue what the problem is here?