Updated to 2.0.0

Adds the feature of broadcasting a server locally on your network
This commit is contained in:
Ryan 2017-06-15 21:47:26 -04:00
parent 99e606115e
commit b28c1b2f24
9 changed files with 377 additions and 94 deletions

View File

@ -45,7 +45,7 @@ function net.aft:init() -- calling this initilizes the library and binds it to t
s.cachable=10 -- 10 MBs
s.OnDataRecieved(function(self,data,cid,ip,port) -- when the server recieves data this method is triggered
local cmd,arg1,arg2=data:match("!aft! (%S+) (%S+) (%S+)")
--~ print(cmd,arg1,arg2)
--print(cmd,arg1,arg2)
if cmd=="PIECE" then
local FID,piecenum=arg1,tonumber(arg2)
local pp=piecenum-1
@ -67,18 +67,21 @@ function net.aft:init() -- calling this initilizes the library and binds it to t
end
end
end
local ddata
local unpackedDATA=net.aft.transfers[cid][FID].sink:sub((pp*net.aft.pieceSize)+1,(pp+1)*net.aft.pieceSize)
local unpackedDATA1=unpackedDATA:sub(1,384)
local unpackedDATA2=unpackedDATA:sub(385)
local packedDATA=""
--~ if self.autoNormalization==false then -- if we already handled normalization in the main data packet then don't redo
packedDATA=net.normalize(unpackedDATA1)..net.normalize(unpackedDATA2)
--~ end
local hash=""--string.rep("0",64)--bin.new(unpackedDATA):getHash2(64)
local num=#unpackedDATA
if num<384 then
ddata="!aft! TRANS "..piecenum.." "..FID.." | "..net.normalize(unpackedDATA)
else
local unpackedDATA1=unpackedDATA:sub(1,384)
local unpackedDATA2=unpackedDATA:sub(385)
local packedDATA=net.normalize(unpackedDATA1)..net.normalize(unpackedDATA2)
ddata="!aft! TRANS "..piecenum.." "..FID.." | "..packedDATA
end
net.aft.transfers[cid][FID].resendAlarm.piecenum=piecenum
net.aft.transfers[cid][FID].resendAlarm.hash=hash
net.aft.transfers[cid][FID].resendAlarm.hash="" -- not needed anymore
net.aft.transfers[cid][FID].resendAlarm.packedDATA=packedDATA
local ddata="!aft! TRANS "..piecenum.." "..FID.." | "..packedDATA
-- SAFE
if self.allowSmallFileCaching then
net.aft.cache[net.aft.transfers[cid][FID].name][piecenum]=ddata
end
@ -88,6 +91,55 @@ function net.aft:init() -- calling this initilizes the library and binds it to t
self:send(ip,"!aft! DOWNLOAD INVALID_FID NIL NIL NIL",port)
print("ERROR 102")
end
elseif cmd=="UPLOAD" then -- here we set up the spot for file writing
local FID,filename=arg1:match("(.-)|(.+)")
local struct={
FID=FID,
filename=filename,
numpieces=tonumber(arg2) or -1
}
if struct.numpieces==-1 then -- error handling catch it all :)
self:send(ip,"!aft! UPLOAD UPLOAD_REFUSED INVALID_NUMBER_OF_PIECES | |",port)
return
end
self.OnUploadRequest:Fire(struct,cid,ip,port)
if not(struct.deny) then -- block request or allow it
-- If we are allowed to lets do this
if not(net.aft.transfers.DOWNLOADS) then
net.aft.transfers.DOWNLOADS={}
end
if not(net.aft.transfers.DOWNLOADS[FID]) then
net.aft.transfers.DOWNLOADS[FID]={}
end
bin.new(""):tofile(struct.filename)
net.aft.transfers.DOWNLOADS[struct.FID].sink=struct.sink or bin.stream(struct.filename,false)
net.aft.transfers.DOWNLOADS[struct.FID].currentPiece=1
net.aft.transfers.DOWNLOADS[struct.FID].numPieces=tonumber(arg2)
--we got that setup... Lets Request a piece now!
self:send(ip,"!aft! PIECE 1 "..FID.." | |",port) -- request piece # 1
else
self:send(ip,"!aft! UPLOAD UPLOAD_REFUSED "..(struct.reason or "UNSPECIFIED_ERROR").." | |",port)
end
elseif cmd=="TRANS" then
local FID,piece=arg1:match("(.-)|(.+)")
local piece=tonumber(piece) or -1
if pieces==-1 then -- error handling catch it all :)
self:send(ip,"!aft! UPLOAD UPLOAD_CANCLED PIECE_DATA_MALFORMED | |",port)
return
end
if #arg2<512 then
net.aft.transfers.DOWNLOADS[FID].sink:tackE(net.denormalize(arg2))
else
net.aft.transfers.DOWNLOADS[FID].sink:tackE(net.denormalize(arg2:sub(1,512))..net.denormalize(arg2:sub(513)))
end
-- request the next piece
if piece==net.aft.transfers.DOWNLOADS[FID].numPieces then
-- We are done!
self:send(ip,"!aft! DONE "..FID.." | | |",port)
net.aft.transfers.DOWNLOADS[FID].sink:close() -- close the file
else
self:send(ip,"!aft! PIECE "..piece+1 .." "..FID.." | |",port)
end
elseif cmd=="REQUEST" then
local filename=arg1
local struct={
@ -139,10 +191,10 @@ function net.aft:init() -- calling this initilizes the library and binds it to t
c.OnTransferStarted=multi:newConnection()
c.OnTransferCompleted=multi:newConnection()
c.OnFileRequestFailed=multi:newConnection() -- create an aft event
--c.OnFileUploadFailed=multi:newConnection() -- not yet must ensure oneway works well first
c.OnFileUploadFailed=multi:newConnection() -- not yet must ensure oneway works well first
c.OnDataRecieved(function(self,data) -- when the client recieves data this method is triggered
local cmd,pieces,FID,arg1,arg2=data:match("!aft! (%S+) (%S+) (%S+) (%S+) (%S+)")
--~ print(cmd,pieces,FID,arg1,arg2)
--print(cmd,pieces,FID,arg1,arg2)
if cmd=="START" then-- FID filename #pieces
local struct={
FID=FID,
@ -171,10 +223,34 @@ function net.aft:init() -- calling this initilizes the library and binds it to t
net.aft.transfers[FID].piecesRecieved=0
net.aft.transfers[FID].numpieces=tonumber(pieces)
c:requestPiece(FID,1)
elseif cmd=="DONE" then
local FID=pieces
print(net.aft.transfers.UPLOADS[FID].name.." has Finished Uploading!")
self.OnTransferCompleted:Fire(self,net.aft.transfers[FID].name,"U")
net.aft.transfers[FID]=nil -- clean up
elseif cmd=="PIECE" then -- Server is asking for a piece to some file
local pieces=tonumber(pieces)
local pp=pieces-1
local unpackedDATA=net.aft.transfers.UPLOADS[FID].sink:sub((pp*net.aft.pieceSize)+1,(pp+1)*net.aft.pieceSize)
local num=#unpackedDATA
if num<384 then
self:send("!aft! TRANS "..FID.."|"..pieces.." "..net.normalize(unpackedDATA))
else
local unpackedDATA1=unpackedDATA:sub(1,384)
local unpackedDATA2=unpackedDATA:sub(385)
local packedDATA=net.normalize(unpackedDATA1)..net.normalize(unpackedDATA2)
self:send("!aft! TRANS "..FID.."|"..pieces.." "..packedDATA)
end
elseif cmd=="TRANS" then-- self,data,FID,piecenum,hash
if self.autoNormalization==false then -- if we already handled normalization in the main data packet then don't redo
local ddata
if #arg2<512 then
ddata=net.denormalize(arg2)
else
ddata=net.denormalize(arg2:sub(1,512))..net.denormalize(arg2:sub(513))
end
struct={
data=net.denormalize(arg2:sub(1,512))..net.denormalize(arg2:sub(513)),
data=ddata,
FID=FID,
piecenum=tonumber(pieces),
numpieces=net.aft.transfers[FID].numpieces,
@ -194,28 +270,24 @@ function net.aft:init() -- calling this initilizes the library and binds it to t
net.aft.transfers[FID].currentPiece=tonumber(pieces)
self.OnPieceRecieved:Fire(self,struct)
local data,FID,piecenum,hash=struct.data,struct.FID,struct.piecenum,struct.hash
if --[[bin.new(data):getHash2(64)==hash]] true then
net.aft.transfers[FID].sink:tackE(data)
net.aft.transfers[FID].piecesRecieved=net.aft.transfers[FID].piecesRecieved+1
if net.aft.transfers[FID].numpieces<=net.aft.transfers[FID].piecesRecieved then
print(net.aft.transfers[FID].name.." has finished downloading!")
net.aft.transfers[FID].sink:close()
self:send("!aft! COMPLETE "..FID.." NIL") -- for clean up purposes
self.OnTransferCompleted:Fire(self,net.aft.transfers[FID].name)
else
self:requestPiece(FID,piecenum+1) -- get next piece
end
net.aft.transfers[FID].sink:tackE(data)
net.aft.transfers[FID].piecesRecieved=net.aft.transfers[FID].piecesRecieved+1
if net.aft.transfers[FID].numpieces==net.aft.transfers[FID].piecesRecieved then
print(net.aft.transfers[FID].name.." has finished downloading!")
net.aft.transfers[FID].sink:close()
self:send("!aft! COMPLETE "..FID.." NIL") -- for clean up purposes
self.OnTransferCompleted:Fire(self,net.aft.transfers[FID].name)
else
print("Hash Bad! Requesting Again!")
self:requestPiece(FID,piecenum)
self:requestPiece(FID,piecenum+1) -- get next piece
end
elseif cmd=="ERROR" then
elseif cmd=="DOWNLOAD" then
local msg=FID
if pieces=="DOWNLOAD" then
print("Download Error!",msg)
else
print("UPLOAD Error!",msg)
end
self.OnFileRequestFailed:Fire(msg)
print("Download Error!",msg)
elseif cmd=="UPLOAD" then
local msg=FID
self.OnFileUploadFailed:Fire(msg)
print("Upload Error!",msg)
end
end,"aft")
function c:requestFile(filename,sink) -- sinks data through a bin-stream sink if the filename you want otherwise the filename is used instead
@ -224,6 +296,25 @@ function net.aft:init() -- calling this initilizes the library and binds it to t
net.aft.sinks[filename]=sink
end
end
function c:requestUpload(filename)
if io.fileExists(filename) then
local FID=bin.new(filename):getRandomHash(16) -- We need this, but its not as important for client as it is for servers
local file=bin.stream(filename)
if not net.aft.transfers.UPLOADS then
net.aft.transfers.UPLOADS={}
end
if not net.aft.transfers.UPLOADS[FID] then
net.aft.transfers.UPLOADS[FID]={}
end
net.aft.transfers.UPLOADS[FID].sink=file -- client file management is much simpler since we only have to worry about 1 reciever/sender
net.aft.transfers.UPLOADS[FID].name=filename
net.aft.transfers.UPLOADS[FID].size=file:getSize()
net.aft.transfers.UPLOADS[FID].pieces=math.ceil(net.aft.transfers.UPLOADS[FID].size/net.aft.pieceSize)
self:send("!aft! UPLOAD "..FID.."|"..filename.." "..net.aft.transfers.UPLOADS[FID].pieces)-- Lets send the FID we will be using and the number of pieces the server should look out for
else
self.OnFileUploadFailed:Fire("File specified not found! "..filename.." does not exist!")
end
end
function c:requestPiece(FID,piecenum)
self:send("!aft! PIECE "..FID.." "..piecenum)
end

View File

@ -20,7 +20,6 @@ function net.chatting:init() -- calling this initilizes the library and binds it
s.OnUserLoggedIn(function(user,cid,ip,port,dTable)
dTable=loadstring("return "..dTable)()
local USERID=bin.new(user):getHash(32)
print(USERID)
net.chatting.users[USERID]={dTable.nick,cid,ip,port,dTable} -- add users that log in to the userlist
net.chatting.users[ip]=USERID -- add users that log in to the userlist
local users={}

View File

@ -1,7 +1,8 @@
require("net.identity")
net:registerModule("email",{1,0,0})
-- needs rewriting, where it uses the identity module and can send an email. EX: server:email(user,subject,body)
smtp = require 'socket.smtp'
ssl = require 'ssl'
ssl = require 'ssl' -- server side only so noworries for love2d users
function net.email.init(from,user,pass)
net.OnServerCreated:connect(function(s)

View File

@ -5,12 +5,13 @@ Adds
net.identity:init()
]]
net:registerModule("identity",{2,0,1})--1.0.1 Note: Added eaiser ways to get user data using only cid
net:registerModule("identity",{2,1,0})--1.0.1 Note: Added eaiser ways to get user data using only cid
function net.hash(text,n)
n=n or 16
return bin.new(text.."jgmhktyf"):getHash(n)
end
net.identity.UIDS={}
net.identity.UIDS.ids={}
function net.identity:init() -- calling this initilizes the library and binds it to the servers and clients created
--Server Stuff
net.OnServerCreated(function(s)
@ -24,27 +25,43 @@ function net.identity:init() -- calling this initilizes the library and binds it
local nick,dTable=userdata:match("%S-|%S-|(%S-)|(.+)")
return nick,loadstring("return "..(dTable or "{}"))()
end
function s:modifyUserData(user,oldpass,pass,nick,dTable)
if self:_isRegistered(user) then
local userdata=bin.load(self.userFolder..net.hash(user)..".dat")
local args={}
local _pass,_nick,_dTable=userdata:match("%S-|(%S-)|(%S-)|(.+)")
if oldpass~=_pass then
args.invalidPass=true
pass=_pass
end
if not nick then nick=_nick args.invalidNick=true end
table.merge(_dTable or {}, dTable or {})
bin.new(string.format("%s|%s|%s|%s\n",user,pass,nick,dTable)):tofile(self.userFolder..net.hash(user)..".dat")
else
return false
end
end
function s:getUserCred(user)
local userdata=bin.load(self.userFolder..net.hash(user)..".dat")
return userdata:match("%S-|(%S-)|")
end
function s:getUSERID(cid) -- Quality of life functions
function s:getUSERID(cid)
return (net.identity.UIDS[cid] or "User Not Logged In!")
end
function s:getUsername(cid) -- Quality of life functions
function s:getUsername(cid)
return self:userLoggedIn(cid)
end
function s:getNickname(cid) -- Quality of life functions
function s:getNickname(cid)
return self.loggedIn[self:getUsername(cid)].nick
end
function s:getdTable(cid) -- Quality of life functions
function s:getdTable(cid)
return self.loggedIn[self:getUsername(cid)]
end
function s:getUserData(cid) -- Quality of life functions
function s:getUserDat(cid)
return self:getUserDataHandle(self:getUsername(cid))
end
function s:nickTaken(nick)
--
function s:getNickFromUSERID(USERID)
return bin.load(self.userFolder..net.hash(user)..".dat"):match("%S-|%S-|(%S-)|")
end
function s:userLoggedIn(cid)
for i,v in pairs(self.loggedIn) do
@ -60,20 +77,20 @@ function net.identity:init() -- calling this initilizes the library and binds it
end
self.userFolder=loc
end
s:setDataLocation("USERS")
s:setDataLocation("USERS/")
function s:logoutUser(user)
net.identity.UIDS.ids[user.UID]=nil
self.loggedIn[user]=nil
end
function s:loginUser(user,cid)
net.identity.UIDS[cid]=bin.new(user):getHash(32)
net.identity.UIDS[cid]=net.hash(user)
local nick,dTable=self:getUserData(user)
self.loggedIn[user]={}
table.merge(self.loggedIn[user],dTable or {})
self.loggedIn[user].cid=cid
self.loggedIn[user].nick=nick
self.loggedIn[user].UID=net.resolveID(net.identity.UIDS)
return self:getUserDataHandle(user)
return self.loggedIn[user]
end
function s:getUserDataHandle(user)
return self.loggedIn[user]
@ -110,10 +127,6 @@ function net.identity:init() -- calling this initilizes the library and binds it
self:send(ip,"!identity! REGISTERREFUSED <-|Nickname too short|->",port)
return
end
if not self.allowDuplicateNicks and self:nickTaken(nick) then
self:send(ip,"!identity! REGISTERREFUSED <-|Nickname already taken|->",port)
return
end
for i=1,#rets do
if rets[i][1]==false then
print("Server refused to accept registration request!")
@ -121,14 +134,29 @@ function net.identity:init() -- calling this initilizes the library and binds it
return
end
end
bin.new(string.format("%s|%s|%s|%s\n",user,pass,nick,dTable)):tofile(self.userFolder..net.hash(user)..".dat")
self:send(ip,"!identity! REGISTEREDGOOD <-|"..user.."|->",port)
if not allowDuplicateNicks then
if not self.dupnickfilemanager then
self.dupnickfilemanager=bin.stream("Nicks.dat",false)
multi:newFunction(function(func) -- anom func, allows for fancy multitasking
local dupnickfilemanager=bin.stream(self.userFolder.."Nicks.dat",false)
local isValid=func:newCondition(function() return t~=nil end)
local tab={}
local t=dupnickfilemanager:getBlock("s")
if self.allowDuplicateNicks==false then
while func:condition(isValid) do
tab[#tab]=t
if t==nick then
self:send(ip,"!identity! REGISTERREFUSED <-|Duplicate Nicks are not allowed|->",port)
dupnickfilemanager:close()
return
end
end
t=dupnickfilemanager:getBlock("s")
end
self.dupnickfilemanager:addBlock(nick)
end
dupnickfilemanager:addBlock(nick.."|"..bin.new(user):getHash(32))
dupnickfilemanager:close()
bin.new(string.format("%s|%s|%s|%s\n",user,pass,nick,dTable)):tofile(self.userFolder..net.hash(user)..".dat")
self:send(ip,"!identity! REGISTEREDGOOD <-|"..user.."|->",port)
func=nil -- we dont want 1000s+ of these anom functions lying around
return
end)()-- lets call the function
end
return
elseif cmd=="login" then
@ -138,7 +166,6 @@ function net.identity:init() -- calling this initilizes the library and binds it
self:send(ip,"!identity! LOGINBAD <-|nil|->",port)
return
end
print(pass,_pass)
if pass==_pass then
if self:userLoggedIn(cid) then
self.OnAlreadyLoggedIn:Fire(self,user,cid,ip,port)

View File

@ -1,12 +1,47 @@
require("net.identity")
require("net.aft")
require("net.users")
require("net.db")
net:registerModule("inbox",{1,0,0})
--self.OnUserLoggedIn:Fire(user,cid,ip,port,bin.ToStr(handle))
--allows the storing of messages that the user can recieve and view whenever. Allows user to also send messeges to users that are even offline!
--requires an account setup and nick name to be set at account creation
if not io.dirExists("INBOX") then
io.mkDir("INBOX")
end
net.inbox.dbfmt=db.format([=[
[INBOX]{
string MSG 0x800 -- contents of the message
}
[MAIL]{
string NAME 0x20 -- username
string UID 0x10 -- User ID
string NICK 0x20 -- Nickname
number[3] DATE -- list of numbers
table INBO INBOX -- Inbox
}
]=])
net.OnServerCreated:connect(function(s)
s.OnUserLoggedIn(function(user,cid,ip,port,dTable)
if not io.dirExists("INBOX/"..self:getUSERID(cid)) then -- Make sure inbox stuff is set up
io.mkDir("INBOX/"..self:getUSERID(cid))
bin.new():tofile("info.dat")
end
end)
s.OnDataRecieved(function(self,data,CID_OR_HANDLE,IP_OR_HANDLE,PORT_OR_IP)
if self:userLoggedIn(cid) then -- If the user is logged in we do the tests
--
local cmd,arg1,arg2=data:match("!inbox! (%S+) (%S+) (%S+)")
if cmd=="SEND" then
--
elseif cmd=="LIST" then
--
elseif cmd=="OPEN" then
--
elseif cmd=="DELETE" then
--
elseif cmd=="CLEAR" then
--
end
else
return
end
@ -16,4 +51,20 @@ net.OnClientCreated:connect(function(c)
c.OnDataRecieved(function(self,data)
--
end,"inbox")
function c:sendMessage(USERID,msg) -- USERID who, msg being sent. Server handles time stamps
self:send("!inbox! SEND "..USERID.." "..msg)
end
function c:checkInbox() -- returns list of msgIDs
self:send("!inbox! LIST NIL NIL")
end
function c:checkMsg(msgId)
self:send("!inbox! OPEN "..msgId.." NIL") -- server sends back msg content as a file
end
function c:deleteMessage(msgID)
self:send("!inbox! DELETE "..msgId.." NIL")
end
function c:clearInbox()
self:send("!inbox! CLEAR NIL NIL")
end
--
end)

View File

@ -1,12 +1,38 @@
--[[
UPCOMMING ADDITIONS
AUDP - advance udp/ Ensures packets arrive and handles late packets.
P2P - peer to peer (Server to set up initial connection)
Relay - offput server load (locally)
Threading - Simple threading (UDP/AUDP Only)
Priority handling
]]
--[[
TODO: Finish stuff for Priority handling
]]
function table.merge(t1, t2)
for k,v in pairs(t2) do
if type(v) == 'table' then
if type(t1[k] or false) == 'table' then
table.merge(t1[k] or {}, t2[k] or {})
else
t1[k] = v
end
else
t1[k] = v
end
end
return t1
end
function string.trim(s)
local from = s:match"^%s*()"
return from > #s and "" or s:match(".*%S", from)
end
socket=require("socket")
http=require("socket.http")
mime=require("mime")
net={}
net.Version={1,5,0}
net._VERSION="1.5.0"
net.Version={2,0,0} -- This will probably stay this version for quite a while... The modules on the otherhand will be more inconsistant
net._VERSION="2.0.0"
net.OnServerCreated=multi:newConnection()
net.OnClientCreated=multi:newConnection()
net.loadedModules={}
@ -19,6 +45,19 @@ function net.denormalize(input)
local unenc=mime.unb64(input)
return unenc
end
function net.getLocalIP()
local someRandomIP = "192.168.1.122"
local someRandomPort = "3102"
local mySocket = socket.udp()
mySocket:setpeername(someRandomIP,someRandomPort)
local dat = (mySocket:getsockname())
mySocket:close()
return dat
end
function net.getExternalIP()
local data=http.request("http://whatismyip.org/")
return data:match("600;\">(%d-.%d-.%d-.%d-)</span>")
end
function net:registerModule(mod,version)
if net[mod] then
error("Module by the name: "..mod.." has already been registered! Remember some modules are internal and use certain names!")
@ -60,6 +99,30 @@ function net.setTrigger(funcW,funcE)
multi:newTrigger(func)
end
net:registerModule("net",net.Version)
-- Client broadcast
function net:newCastedClient(name) -- connects to the broadcasted server
local listen = socket.udp() -- make a new socket
listen:setsockname(net.getLocalIP(), 11111)
listen:settimeout(0)
local timer=multi:newTimer()
while true do
local data, ip, port = listen:receivefrom()
if timer:Get()>3 then
error("Timeout! Server by the name: "..name.." has not been found!")
end
if data then
local n,tp,ip,port=data:match("(%S-)|(%S-)|(%S-):(%d+)")
if n:match(name) then
print("Found Server!",n,tp,ip,port)
if tp=="tcp" then
return net:newTCPClient(ip,tonumber(port))
else
return net:newClient(ip,tonumber(port))
end
end
end
end
end
-- UDP Stuff
function net:newServer(port,servercode)
local c={}
@ -83,6 +146,15 @@ function net:newServer(port,servercode)
function c:banIP(ip)
table.insert(self.bannedIPs,cid)
end
c.broad=socket.udp()
c.hostip=net.getLocalIP()
function c:broadcast(name)
local loop=multi:newTLoop(function(dt,loop)
self.broad:setoption('broadcast',true)
self.broad:sendto(name.."|"..self.Type.."|"..self.hostip..":"..self.port, "255.255.255.255", 11111)
self.broad:setoption('broadcast',false)
end,1)
end
function c:send(ip,data,port,cid)
if self.autoNormalization then
data=net.normalize(data)
@ -154,7 +226,7 @@ function net:newServer(port,servercode)
data=net.denormalize(data)
end
if data:sub(1,4)=="pong" then
print("Recieved pong from: "..data:sub(5,-1))
--print("Recieved pong from: "..data:sub(5,-1))
self.ips[data:sub(5,-1)][3]=os.clock()
elseif data:sub(1,2)=="S!" then
local cid=self:CIDFrom(ip,port)
@ -177,8 +249,8 @@ function net:newServer(port,servercode)
self.udp:sendto("Make sure your server code is correct!", ip, port)
end
elseif data:sub(1,2)=="C!" then
local hook=data:match("!(.-)!")
self.OnDataRecieved:getConnection(hook):Fire(hook,data:sub(11,-1),data:sub(3,10),ip,port)
local hook=(data:sub(11,-1)):match("!(.-)!")
self.OnDataRecieved:getConnection(hook):Fire(self,data:sub(11,-1),data:sub(3,10),ip,port)
elseif data:sub(1,2)=="E!" then
self.ips[data:sub(3,10)]=nil
obj.ids[data:sub(3,10)]=false
@ -216,7 +288,7 @@ function net:newServer(port,servercode)
c.connectiontest=multi:newAlarm(30)
c.connectiontest.link=c
c.connectiontest:OnRing(function(alarm)
print("pinging clients!")
--print("pinging clients!")
alarm.link:sendAll("ping")
alarm:Reset()
end)
@ -231,8 +303,8 @@ function net:newClient(host,port,servercode,nonluaServer)
local c={}
c.ip=assert(socket.dns.toip(host))
c.udp=assert(socket.udp())
c.udp:setpeername(c.ip, port)
c.udp:settimeout(0)
c.udp:setpeername(c.ip, port)
c.cid="NIL"
c.lastPing=0
c.Type="udp"
@ -352,6 +424,16 @@ function net:newTCPServer(port)
c.updaterRate=1
c.autoNormalization=false
c.updates={}
c.links={}
c.broad=socket.udp()
c.hostip=net.getLocalIP()
function c:broadcast(name)
local loop=multi:newTLoop(function(dt,loop)
self.broad:setoption('broadcast',true)
self.broad:sendto(name.."|"..self.Type.."|"..self.hostip..":"..self.port, "255.255.255.255", 11111)
self.broad:setoption('broadcast',false)
end,1)
end
function c:setUpdateRate(n)
self.updaterRate=n
end
@ -377,6 +459,12 @@ function net:newTCPServer(port)
handle:send(data)
end
end
function c:sendAllData(handle,data)
if self.autoNormalization then
data=net.normalize(data)
end
handle:send(data)
end
function c:pollClientModules(ip,port)
self:send(ip,"L!",port)
end
@ -427,6 +515,7 @@ function net:newTCPServer(port)
end
end
self.Link.OnClientClosed:Fire(self.Link,"Client Closed Connection!",self.client,self.client,ip)
self.Link.links[self.client]=nil -- lets clean up
self:Destroy()
end
if data then
@ -438,7 +527,7 @@ function net:newTCPServer(port)
return
end
local hook=data:match("!(.-)!")
self.Link.OnDataRecieved:getConnection(hook):Fire(self.Link,data,self.client,self.client,ip)
self.Link.OnDataRecieved:getConnection(hook):Fire(self.Link,data,self.client,self.client,ip,self)
if data:sub(1,2)=="L!" then
cList=data
local list={}
@ -455,6 +544,7 @@ function net:newTCPServer(port)
function updater:setReceiveMode(mode)
self.rMode=mode
end
self.links[client]=updater
end
end
c.OnClientsModulesList=multi:newConnection()
@ -491,7 +581,6 @@ function net:newTCPClient(host,port)
self.sMode=mode
end
function c:send(data)
if not self.tcp then return end
if self.autoNormalization then
data=net.normalize(data)
end
@ -509,7 +598,6 @@ function net:newTCPClient(host,port)
end
end
function c:sendRaw(data)
if not self.tcp then return end
if self.autoNormalization then
data=net.normalize(data)
end
@ -542,21 +630,21 @@ function net:newTCPClient(host,port)
self.OnDataRecieved:getConnection(hook):Fire(self,data)
end
end
c.reconnect=multi:newFunction(function(func,self)
self.tcp=socket.connect(self.ip,self.port)
if self.tcp==nil then
print("Can't connect to the server: No response from server!")
func:hold(3)
self:reconnect()
func=nil
return
end
self.OnConnectionRegained:Fire(self)
self.tcp:settimeout(0)
--self.tcp:setoption('tcp-nodelay', true)
self.tcp:setoption('keepalive', true)
func=nil
end)
function c:reconnect()
multi:newFunction(function(func)
self.tcp=socket.connect(self.ip,self.port)
if self.tcp==nil then
print("Can't connect to the server: No response from server!")
func:hold(3)
self:reconnect()
return
end
self.OnConnectionRegained:Fire(self)
self.tcp:settimeout(0)
--self.tcp:setoption('tcp-nodelay', true)
self.tcp:setoption('keepalive', true)
end)
end
c.event=multi:newEvent(function(event)
return event.link:IDAssigned()
end)

View File

@ -1,6 +1,6 @@
net.OnServerCreated:connect(function(s)
print("The logging Module has been loaded onto the server!")
s.OnDataRecieved:connect(function(self,data,cid,ip,port)
s.OnDataRecieved:fConnect(function(self,data,cid,ip,port)
log(tostring(ip)..":"..tostring(port),"Server-log.log")
log(data,"Server-log.log")
end)

View File

@ -11,7 +11,7 @@ function net.settings:init() -- calling this initilizes the library and binds it
--Server Stuff
net.OnServerCreated:connect(function(s)
print("The Settings Module has been loaded onto the server!")
s.OnDataRecieved:connect(function(self,data,cid,ip,port) -- when the server recieves data this method is triggered
s.OnDataRecieved(function(self,data,cid,ip,port) -- when the server recieves data this method is triggered
local namespace,args=data:match("!settings! (%s+) (.+)")
local args
if namespace then
@ -23,7 +23,7 @@ function net.settings:init() -- calling this initilizes the library and binds it
end
end
end
end)
end,"settings")
function s:regSetting(namespace,settings)
if not net.settings.config[namespace] then
net.settings.config[namespace]={}
@ -35,9 +35,9 @@ function net.settings:init() -- calling this initilizes the library and binds it
end)
--Client Stuff
net.OnClientCreated:connect(function(c)
c.OnDataRecieved:connect(function(self,data) -- when the client recieves data this method is triggered
c.OnDataRecieved:(function(self,data) -- when the client recieves data this method is triggered
--First Lets make sure we are getting Setting data
end)
end,"setings")
function sendSetting(namespace,args)
self:send("!settings! "..namespace.." "..args)
end

View File

@ -1,17 +1,43 @@
require("net")
require("net.aft")
net:registerModule("version",{1,0,0}) -- allows communication of versions for modules
net.version.HOSTS={
["Lua"]=1,
["LuaJIT"]=1,
["Love2d"]=2, -- Yes love2d uses luaJIT, but the filesystem works a bit differently
["Corona"]=3,
}
net.version.OS={
["Windows"]=1,
["Unix"]=2,
["RPI"]=3,
}
--net.version.EOL="\60\69\110\100\45\79\102\45\70\105\108\101\45\84\114\97\110\115\102\101\114\62"
net.OnServerCreated:connect(function(s)
s.OnDataRecieved(function(self,data,CID_OR_HANDLE,IP_OR_HANDLE,PORT_OR_IP)
--
local cmd,arg1,arg2=data:match("!version! ")
end,"version")
s.OnClientConnected(function(self,CID_OR_HANDLE,IP_OR_HANDLE,PORT_OR_IP)
s:pollClientModules(IP_OR_HANDLE,PORT_OR_IP)
end)
s.OnClientsModulesList(function(list,CID_OR_HANDLE,IP_OR_HANDLE,PORT_OR_IP)
--
multi:newFunction(function(func) -- anom func, allows for fancy multitasking
multi:newFunction(function(self)
local range=self:newRange()
for i in range(1,#self.loadedModules) do
local mod=self.loadedModules[i]
self:send(IP_OR_HANDLE,"!version! CHECK "..mod.." NIL",PORT_OR_IP) -- sends command to client to return the version of the module
end
end)()
func=nil -- we dont want 1000s+ of these anom functions lying around
end)()-- lets call the function
self:send(IP_OR_HANDLE,"!version! HOST NIL NIL",PORT_OR_IP)
end)
end)
net.OnClientCreated:connect(function(c)
c.OnDataRecieved(function(self,data)
--
local cmd,module,arg1=data:match("!version! (%S+) (%S+) (%S+)")
if cmd=="CHECK" then
self:send("!version! VER "..self.loadedModules[module].." "..net.getModuleVersion(module))
elseif cmd=="UPDATE" then
--
end
end,"version")
end)