Updated to 2.0.0
Adds the feature of broadcasting a server locally on your network
This commit is contained in:
parent
99e606115e
commit
b28c1b2f24
155
net/aft.lua
155
net/aft.lua
@ -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
|
||||
|
||||
@ -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={}
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
138
net/init.lua
138
net/init.lua
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user