Working on rewrite

This commit is contained in:
Ryan Ward 2021-07-06 08:56:48 -04:00
parent 56981f5b83
commit 7633e87ab9
7 changed files with 893 additions and 610 deletions

View File

@ -1,17 +1,12 @@
package.path="?/init.lua;"..package.path package.path = "./?/init.lua;./?.lua;"..package.path
local multi = require("multi") local net = require("net.udp")
local net = require("net") local client = net:newUDPClient("localhost",12345)
client = net:newTCPClient("localhost",12345)
client:enableBinaryMode() client:send("Test!")
local file = bin.new()
client.OnDataRecieved(function(self,data) client.OnDataRecieved(function(c,data)
if data == "END" then print("Response: ",data)
file:tofile("test2.mp3") --c:send("Testing again!")
print("File transfered!")
else
file:tackE(data)
end
end) end)
client.OnClientReady:holdUT() -- waits until the client is ready... You can also connect to this event as well and have code do stuff too
client:send("Hello Server!")
multi:mainloop() multi:mainloop()

45
net/clientbase.lua Normal file
View File

@ -0,0 +1,45 @@
local multi, thread = require("multi"):init()
local client = {}
client.__index = client
client.OnDataRecieved = multi:newConnection()
client.OnServerNotAvailable = multi:newConnection()
client.OnClientReady = multi:newConnection()
client.OnClientDisconnected = multi:newConnection()
client.OnConnectionRegained = multi:newConnection()
client.OnPreSend = multi:newConnection()
client.OnPreRecieved = multi:newConnection()
client.updaterRate = 1
client.sMode = "*l"
client.rMode = "*l"
function client:init(type)
self.Type = type
self.process = multi:newProcessor()
self.process.Start()
end
function client:send(data)
if self.Type == "udp" then
local dat = {data = data}
self.OnPreSend:Fire(dat)
self.udp:send(dat.data)
elseif self.Type == "tcp" then
local ind, err = self.tcp:send(data)
if err == "closed" then
self.OnClientDisconnected:Fire(self,err)
elseif err == "timeout" then
self.OnClientDisconnected:Fire(self,err)
end
end
end
function client:close()
--
end
function client:setUpdateRate(n)
self.updaterRate = n
end
function client:setReceiveMode(mode)
self.rMode = mode
end
function client:setSendMode(mode)
self.sMode = mode
end
return client

View File

@ -11,8 +11,8 @@
]] ]]
function table.merge(t1, t2) function table.merge(t1, t2)
for k, v in pairs(t2) do for k, v in pairs(t2) do
if type(v) == 'table' then if type(v) == "table" then
if type(t1[k] or false) == 'table' then if type(t1[k] or false) == "table" then
table.merge(t1[k] or {}, t2[k] or {}) table.merge(t1[k] or {}, t2[k] or {})
else else
t1[k] = v t1[k] = v
@ -39,16 +39,19 @@ for i = 97,122 do
char[#char + 1] = string.char(i) char[#char + 1] = string.char(i)
end end
local isHyphen = {[9] = 1, [14] = 1, [19] = 1, [24] = 1} local isHyphen = {[9] = 1, [14] = 1, [19] = 1, [24] = 1}
math.randomseed(os.time()) math.random()
local multi = require("multi") math.random()
math.random()
local multi, thread = require("multi").init()
local socket = require("socket") local socket = require("socket")
local http = require("socket.http") local http = require("socket.http")
local https=require("ssl.https")
local mime = require("mime") local mime = require("mime")
--ssl=require("ssl") --ssl=require("ssl")
--https=require("ssl.https") --https=require("ssl.https")
local net = {} local net = {}
net.Version={3,0,0} -- This will probably stay this version for quite a while... The modules on the otherhand will be more inconsistant net.Version = {4, 0, 0} -- This will probably stay this version for quite a while... The modules on the otherhand will change more often
net._VERSION="3.0.0" net._VERSION = "4.0.0"
net.ClientCache = {} net.ClientCache = {}
net.OnServerCreated = multi:newConnection() net.OnServerCreated = multi:newConnection()
net.OnClientCreated = multi:newConnection() net.OnClientCreated = multi:newConnection()
@ -57,19 +60,25 @@ net.OnCastedClientInfo=multi:newConnection()
net.autoInit = true net.autoInit = true
net.ConnectionDriver = {} net.ConnectionDriver = {}
net.BroadcastDriver = {} net.BroadcastDriver = {}
math.randomseed(math.ceil(os.time()+(os.clock()*1000)))
net.generateGUID = function(t) net.generateGUID = function(t)
local pass = {} local pass = {}
local a = 0 local a = 0
local x = "" local x = ""
for z = 1,36 do for i in string.format("%x",os.time()+math.ceil(os.time()+os.clock()*1000)):gmatch(".") do
table.insert(pass,i)
end
for z = 9, 36 do
if isHyphen[z] then if isHyphen[z] then
x='-' x = "-"
else else
a = math.random(1, #char) a = math.random(1, #char)
x = char[a] x = char[a]
end end
table.insert(pass, x) table.insert(pass, x)
if t == z then break end if t == z then
break
end
end end
z = nil z = nil
return tostring(table.concat(pass)) return tostring(table.concat(pass))
@ -92,12 +101,15 @@ function net.getLocalIP()
return dat return dat
end end
function net.getExternalIP() function net.getExternalIP()
local data=http.request("http://whatismyip.host") local data = https.request("https://www.whatismypublicip.com/")
return data:match("(%d+.%d+.%d+.%d+)") return data:match("(%d+%.%d+%.%d+%.%d+)")
end end
function net:registerModule(mod, version) function net:registerModule(mod, version)
if net[mod] then if net[mod] then
error("Module by the name: "..mod.." has already been registered! Remember some modules are internal and use certain names!") error(
"Module by the name: " ..
mod .. " has already been registered! Remember some modules are internal and use certain names!"
)
end end
table.insert(self.loadedModules, mod) table.insert(self.loadedModules, mod)
net[mod] = {} net[mod] = {}
@ -148,10 +160,10 @@ function net:newCastedClient(name) -- connects to the broadcasted server
error("Timeout! Server by the name: " .. name .. " has not been found!") error("Timeout! Server by the name: " .. name .. " has not been found!")
end end
if data then if data then
print("found!",data) --print("found!", data)
local n, tp, ip, port = data:match("(%S-)|(%S-)|(%S-):(%d+)") local n, tp, ip, port = data:match("(%S-)|(%S-)|(%S-):(%d+)")
if n:match(name) then if n:match(name) then
print("Found Server!",n,tp,ip,port) --print("Found Server!", n, tp, ip, port)
if tp == "tcp" then if tp == "tcp" then
return net:newTCPClient(ip, tonumber(port)) return net:newTCPClient(ip, tonumber(port))
else else
@ -165,7 +177,9 @@ function net:newCastedClients(name) -- connects to the broadcasted server
local listen = socket.udp() -- make a new socket local listen = socket.udp() -- make a new socket
listen:setsockname(net.getLocalIP(), 11111) listen:setsockname(net.getLocalIP(), 11111)
listen:settimeout(0) listen:settimeout(0)
multi:newTLoop(function(self) multi:newThread("net.castedTask",function()
while true do
thread.skip(24)
local data, ip, port = listen:receivefrom() local data, ip, port = listen:receivefrom()
if data then if data then
local n, tp, ip, port = data:match("(%S-)|(%S-)|(%S-):(%d+)") local n, tp, ip, port = data:match("(%S-)|(%S-)|(%S-):(%d+)")
@ -181,297 +195,314 @@ function net:newCastedClients(name) -- connects to the broadcasted server
net.OnCastedClientInfo:Fire(client, n, ip, port) net.OnCastedClientInfo:Fire(client, n, ip, port)
end end
end end
end,.1):setName("net.castedTask")
end end
-- UDP Stuff
function net:newUDPServer(port,servercode,nonluaServer)
local c={}
c.udp=assert(socket.udp())
c.udp:settimeout(0)
c.udp:setsockname("*", port)
c.ips={}
c.Type="udp"
if port == 0 then
_, c.port = c.udp:getsockname()
end
c.ids={}
c.servercode=servercode
c.bannedIPs={}
c.bannedCIDs={}
c.autoNormalization=false
function c:setUpdateRate(n)
print("Not needed in a udp server!")
end
function c:banCID(cid)
table.insert(self.bannedCIDs,cid)
end
function c:banIP(ip)
table.insert(self.bannedIPs,cid)
end
c.broad=socket.udp()
c.hostip=net.getLocalIP()
function c:broadcast(name)
table.insert(net.BroadcastDriver,function(loop,dt)
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) end)
end end
function c:send(ip,data,port,cid) -- -- UDP Stuff
if self.autoNormalization then -- function net:newUDPServer(port, servercode, nonluaServer)
data=net.normalize(data) -- local c = {}
end -- c.udp = assert(socket.udp())
if self.servercode then -- c.udp:settimeout(0)
cid=cid or self:CIDFrom(ip,port) -- c.udp:setsockname("*", port)
if not self.ips[cid] then -- c.ips = {}
print("Can't determine cid from client... sending the client a new one!") -- c.Type = "udp"
local cid=net.resolveID(self) -- if port == 0 then
print("Sending unique cid to client: "..cid) -- _, c.port = c.udp:getsockname()
self.ips[cid]={ip,port,0,self.servercode==nil} -- end
print(ip) -- c.ids = {}
self.udp:sendto("I!"..cid,ip,port) -- c.servercode = servercode
if self.servercode then -- c.bannedIPs = {}
self.udp:sendto("S!",ip,port) -- c.bannedCIDs = {}
end -- c.autoNormalization = false
return -- function c:setUpdateRate(n)
end -- --print("Not needed in a udp server!")
if net.inList(self.bannedIPs,ip) or net.inList(self.bannedCIDs,cid) then -- end
self.udp:sendto("BANNED CLIENT", ip, port or self.port) -- function c:banCID(cid)
elseif self.ips[cid][4] then -- table.insert(self.bannedCIDs, cid)
self.udp:sendto(data, ip, port or self.port) -- end
elseif self.ips[cid][4]==false then -- function c:banIP(ip)
self.udp:sendto("Make sure your server code is correct!", ip, port) -- table.insert(self.bannedIPs, cid)
end -- end
else -- c.broad = socket.udp()
self.udp:sendto(data, ip, port or self.port) -- c.hostip = net.getLocalIP()
end -- function c:broadcast(name)
end -- table.insert(net.BroadcastDriver,
function c:pollClientModules(ip,port) -- function(loop, dt)
self:send(ip,"L!",port) -- self.broad:setoption("broadcast", true)
end -- self.broad:sendto(name .. "|" .. self.Type .. "|" .. self.hostip .. ":" .. self.port, "255.255.255.255", 11111)
function c:CIDFrom(ip,port) -- self.broad:setoption("broadcast", false)
for i,v in pairs(self.ips) do -- end)
if(ip==v[1] and v[2]==port) then -- end
return i -- function c:send(ip, data, port, cid)
end -- if self.autoNormalization then
end -- data = net.normalize(data)
end -- end
function c:sendAll(data) -- if self.servercode then
for i,v in pairs(self.ips) do -- cid = cid or self:CIDFrom(ip, port)
self:send(v[1],data,v[2],i) -- if not self.ips[cid] then
end -- --print("Can't determine cid from client... sending the client a new one!")
end -- local cid = net.resolveID(self)
function c:sendAllBut(data,cid) -- --print("Sending unique cid to client: " .. cid)
for i,v in pairs(self.ips) do -- self.ips[cid] = {ip, port, 0, self.servercode == nil}
if i~=cid then -- --print(ip)
self:send(v[1],data,v[2],i) -- self.udp:sendto("I!" .. cid, ip, port)
end -- if self.servercode then
end -- self.udp:sendto("S!", ip, port)
end -- end
function c:clientRegistered(cid) -- return
return self.ips[cid] -- end
end -- if net.inList(self.bannedIPs, ip) or net.inList(self.bannedCIDs, cid) then
function c:clientLoggedIn(cid) -- self.udp:sendto("BANNED CLIENT", ip, port or self.port)
if not self.clientRegistered(cid) then -- elseif self.ips[cid][4] then
return nil -- self.udp:sendto(data, ip, port or self.port)
end -- elseif self.ips[cid][4] == false then
return self.ips[cid][4] -- self.udp:sendto("Make sure your server code is correct!", ip, port)
end -- end
function c:update() -- else
local data,ip,port=self.udp:receivefrom() -- self.udp:sendto(data, ip, port or self.port)
if net.inList(self.bannedIPs,ip) or net.inList(self.bannedCIDs,cid) then -- end
print("We will ignore data from a banned client!") -- end
return -- function c:pollClientModules(ip, port)
end -- self:send(ip, "L!", port)
if data then -- end
if self.autoNormalization then -- function c:CIDFrom(ip, port)
data=net.denormalize(data) -- for i, v in pairs(self.ips) do
end -- if (ip == v[1] and v[2] == port) then
if data:sub(1,4)=="pong" then -- return i
--print("Recieved pong from: "..data:sub(5,-1)) -- end
self.ips[data:sub(5,-1)][3]=os.clock() -- end
elseif data:sub(1,2)=="S!" then -- end
local cid=self:CIDFrom(ip,port) -- function c:sendAll(data)
if data:sub(3,-1)==self.servercode then -- for i, v in pairs(self.ips) do
print("Servercode Accepted: "..self.servercode) -- self:send(v[1], data, v[2], i)
if self.ips[cid] then -- end
self.ips[cid][4]=true -- end
else -- function c:sendAllBut(data, cid)
print("Server can't keep up! CID: "..cid.." has been skipped! Sending new CID to the client!") -- for i, v in pairs(self.ips) do
local cid=net.resolveID(self) -- if i ~= cid then
print("Sending unique cid to client: "..cid) -- self:send(v[1], data, v[2], i)
self.ips[cid]={ip,port,0,self.servercode==nil} -- end
print(ip) -- end
self.udp:sendto("I!"..cid,ip,port) -- end
if self.servercode then -- function c:clientRegistered(cid)
self.udp:sendto("S!",ip,port) -- return self.cids[cid]
end -- end
end -- function c:clientLoggedIn(cid)
else -- if not self.clientRegistered(cid) then
self.udp:sendto("Make sure your server code is correct!", ip, port) -- return nil
end -- end
elseif data:sub(1,2)=="C!" then -- return self.ips[cid][4]
local hook=(data:sub(11,-1)):match("!(.-)!") -- end
self.OnDataRecieved:getConnection(hook):Fire(self,data:sub(11,-1),data:sub(3,10),ip,port) -- function c:update()
elseif data:sub(1,2)=="E!" then -- local data, ip, port = self.udp:receivefrom()
self.ips[data:sub(3,10)]=nil -- if net.inList(self.bannedIPs, ip) or net.inList(self.bannedCIDs, cid) then
obj.ids[data:sub(3,10)]=false -- --print("We will ignore data from a banned client!")
self.OnClientClosed:Fire(self,"Client Closed Connection!",data:sub(3,10),ip,port) -- return
elseif data=="I!" then -- end
local cid=net.resolveID(self) -- if data then
print("Sending unique cid to client: "..cid) -- if self.autoNormalization then
self.ips[cid]={ip,port,os.clock(),self.servercode==nil} -- data = net.denormalize(data)
print(ip) -- end
self.udp:sendto("I!"..cid,ip,port) -- if data:sub(1, 4) == "pong" then
if self.servercode then -- --print("Recieved pong from: "..data:sub(5,-1))
self.udp:sendto("S!",ip,port) -- self.ips[data:sub(5, -1)][3] = os.clock()
end -- elseif data:sub(1, 2) == "S!" then
self.OnClientConnected:Fire(self,cid,ip,port) -- local cid = self:CIDFrom(ip, port)
elseif data:sub(1,2)=="L!" then -- if data:sub(3, -1) == self.servercode then
cid,cList=data:sub(3,10),data:sub(11,-1) -- --print("Servercode Accepted: " .. self.servercode)
local list={} -- if self.ips[cid] then
for m,v in cList:gmatch("(%S-):(%S-)|") do -- self.ips[cid][4] = true
list[m]=v -- else
end -- --print("Server can't keep up! CID: " .. cid .. " has been skipped! Sending new CID to the client!")
self.OnClientsModulesList:Fire(list,cid,ip,port) -- local cid = net.resolveID(self)
end -- --print("Sending unique cid to client: " .. cid)
end -- self.ips[cid] = {ip, port, 0, self.servercode == nil}
for cid,dat in pairs(self.ips) do -- --print(ip)
if not((os.clock()-dat[3])<65) then -- self.udp:sendto("I!" .. cid, ip, port)
self.ips[cid]=nil -- if self.servercode then
self.OnClientClosed:Fire(self,"Client lost Connection: ping timeout",cid,ip,port) -- self.udp:sendto("S!", ip, port)
end -- end
end -- end
end -- else
c.OnClientsModulesList=multi:newConnection() -- self.udp:sendto("Make sure your server code is correct!", ip, port)
c.OnDataRecieved=multi:newConnection() -- end
c.OnClientClosed=multi:newConnection() -- elseif data:sub(1, 2) == "C!" then
c.OnClientConnected=multi:newConnection() -- local hook = (data:sub(11, -1)):match("!(.-)!")
c.connectiontest=multi:newAlarm(30):setName("net.pingOutTask") -- self.OnDataRecieved:getConnection(hook):Fire(self, data:sub(11, -1), data:sub(3, 10), ip, port)
c.connectiontest.link=c -- elseif data:sub(1, 2) == "E!" then
c.connectiontest:OnRing(function(alarm) -- self.ips[data:sub(3, 10)] = nil
alarm.link:sendAll("ping") -- obj.ids[data:sub(3, 10)] = false
alarm:Reset() -- self.OnClientClosed:Fire(self, "Client Closed Connection!", data:sub(3, 10), ip, port)
end) -- elseif data == "I!" then
table.insert(net.ConnectionDriver,c) -- local cid = net.resolveID(self)
net.OnServerCreated:Fire(c) -- --print("Sending unique cid to client: " .. cid)
return c -- self.ips[cid] = {ip, port, os.clock(), self.servercode == nil}
end -- --print(ip)
local pingManager = {} -- self.udp:sendto("I!" .. cid, ip, port)
function net:newUDPClient(host,port,servercode,nonluaServer) -- if self.servercode then
local c={} -- self.udp:sendto("S!", ip, port)
c.ip=assert(socket.dns.toip(host)) -- end
c.udp=assert(socket.udp()) -- self.OnClientConnected:Fire(self, cid, ip, port)
c.udp:settimeout(0) -- elseif data:sub(1, 2) == "L!" then
c.udp:setpeername(c.ip, port) -- cid, cList = data:sub(3, 10), data:sub(11, -1)
c.cid="NIL" -- local list = {}
c.lastPing=0 -- for m, v in cList:gmatch("(%S-):(%S-)|") do
c.Type="udp" -- list[m] = v
c.servercode=servercode -- end
c.autoReconnect=true -- self.OnClientsModulesList:Fire(list, cid, ip, port)
c.autoNormalization=false -- end
function c:pollPing(n) -- end
return not((os.clock()-self.lastPing)<(n or 60)) -- for cid, dat in pairs(self.ips) do
end -- if not ((os.clock() - dat[3]) < 65) then
function c:send(data) -- self.ips[cid] = nil
if self.autoNormalization then -- self.OnClientClosed:Fire(self, "Client lost Connection: ping timeout", cid, ip, port)
data=net.normalize(data) -- end
end -- end
self.udp:send("C!"..self.cid..data) -- end
end -- c.OnClientsModulesList = multi:newConnection()
function c:sendRaw(data) -- c.OnDataRecieved = multi:newConnection()
if self.autoNormalization then -- c.OnClientClosed = multi:newConnection()
data=net.normalize(data) -- c.OnClientConnected = multi:newConnection()
end -- c.connectiontest = multi:newAlarm(30):setName("net.pingOutTask")
self.udp:send(data) -- c.connectiontest.link = c
end -- c.connectiontest:OnRing(
function c:getCID() -- function(alarm)
if self:IDAssigned() then -- alarm.link:sendAll("ping")
return self.cid -- alarm:Reset()
end -- end
end -- )
function c:close() -- table.insert(net.ConnectionDriver, c)
self:send("E!") -- net.OnServerCreated:Fire(c)
end -- return c
function c:IDAssigned() -- end
return self.cid~="NIL" -- local pingManager = {}
end -- function net:newUDPClient(host, port, servercode, nonluaServer)
function c:update() -- local c = {}
local data=self.udp:receive() -- c.ip = assert(socket.dns.toip(host))
if data then -- c.udp = assert(socket.udp())
if self.autoNormalization then -- c.udp:settimeout(0)
data=net.denormalize(data) -- c.udp:setpeername(c.ip, port)
end -- c.cid = "NIL"
if data:sub(1,2)=="I!" then -- c.lastPing = 0
self.cid=data:sub(3,-1) -- c.Type = "udp"
self.OnClientReady:Fire(self) -- c.servercode = servercode
elseif data=="S!" then -- c.autoReconnect = true
self.udp:send("S!"..(self.servercode or "")) -- c.autoNormalization = false
elseif data=="L!" then -- function c:pollPing(n)
local mods="" -- return not ((os.clock() - self.lastPing) < (n or 60))
local m="" -- end
for i=1,#net.loadedModules do -- function c:send(data)
m=net.loadedModules[i] -- if self.autoNormalization then
mods=mods..m..":"..net.getModuleVersion(m).."|" -- data = net.normalize(data)
end -- end
self.udp:send("L!"..self.cid..mods) -- self.udp:send("C!" .. self.cid .. data)
elseif data=="ping" then -- end
self.lastPing=os.clock() -- function c:sendRaw(data)
self.OnPingRecieved:Fire(self) -- if self.autoNormalization then
self.udp:send("pong"..self.cid) -- data = net.normalize(data)
else -- end
local hook=data:match("!(.-)!") -- self.udp:send(data)
self.OnDataRecieved:getConnection(hook):Fire(self,data) -- end
end -- function c:getCID()
end -- if self:IDAssigned() then
end -- return self.cid
function c:reconnect() -- end
if not nonluaServer then -- end
self.cid="NIL" -- function c:close()
c.udp:send("I!") -- self:send("E!")
end -- end
self.pingEvent:Resume() -- function c:IDAssigned()
self.OnConnectionRegained:Fire(self) -- return self.cid ~= "NIL"
end -- end
c.pingEvent=multi:newEvent(function(self) return self.link:pollPing() end) -- function c:update()
c.pingEvent:OnEvent(function(self) -- local data = self.udp:receive()
if self.link.autoReconnect then -- if data then
self.link.OnServerNotAvailable:Fire("Connection to server lost: ping timeout! Attempting to reconnect...") -- if self.autoNormalization then
self.link.OnClientDisconnected:Fire(self,"closed") -- data = net.denormalize(data)
self.link:reconnect() -- end
else -- if data:sub(1, 2) == "I!" then
self.link.OnServerNotAvailable:Fire("Connection to server lost: ping timeout!") -- self.cid = data:sub(3, -1)
self.link.OnClientDisconnected:Fire(self,"closed") -- self.OnClientReady:Fire(self)
end -- elseif data == "S!" then
self:Pause() -- self.udp:send("S!" .. (self.servercode or ""))
end):setName("net.pingInTask") -- elseif data == "L!" then
c.pingEvent.link=c -- local mods = ""
c.OnPingRecieved=multi:newConnection() -- local m = ""
c.OnDataRecieved=multi:newConnection() -- for i = 1, #net.loadedModules do
c.OnServerNotAvailable=multi:newConnection() -- m = net.loadedModules[i]
c.OnClientReady=multi:newConnection() -- mods = mods .. m .. ":" .. net.getModuleVersion(m) .. "|"
c.OnClientDisconnected=multi:newConnection() -- end
c.OnConnectionRegained=multi:newConnection() -- self.udp:send("L!" .. self.cid .. mods)
c.notConnected=multi:newFunction(function(self) -- elseif data == "ping" then
multi:newAlarm(3):OnRing(function(alarm) -- self.lastPing = os.clock()
if self.link:IDAssigned()==false then -- self.OnPingRecieved:Fire(self)
self.link.OnServerNotAvailable:Fire("Can't connect to the server: no response from server") -- self.udp:send("pong" .. self.cid)
end -- else
alarm:Destroy() -- local hook = data:match("!(.-)!")
end):setName("net.clientTimeout") -- self.OnDataRecieved:getConnection(hook):Fire(self, data)
end) -- end
c.notConnected.link=c -- end
if not nonluaServer then -- end
c.udp:send("I!") -- function c:reconnect()
end -- if not nonluaServer then
table.insert(net.ConnectionDriver,c) -- self.cid = "NIL"
multi.nextStep(function() c.notConnected() end) -- c.udp:send("I!")
net.OnClientCreated:Fire(c) -- end
return c -- self.pingEvent:Resume()
end -- self.OnConnectionRegained:Fire(self)
multi:newThread(function() -- end
-- c.pingEvent =
end) -- multi:newEvent(
-- function(self)
-- return self.link:pollPing()
-- end
-- )
-- c.pingEvent:OnEvent(
-- function(self)
-- if self.link.autoReconnect then
-- self.link.OnServerNotAvailable:Fire("Connection to server lost: ping timeout! Attempting to reconnect...")
-- self.link.OnClientDisconnected:Fire(self, "closed")
-- self.link:reconnect()
-- else
-- self.link.OnServerNotAvailable:Fire("Connection to server lost: ping timeout!")
-- self.link.OnClientDisconnected:Fire(self, "closed")
-- end
-- self:Pause()
-- end
-- ):setName("net.pingInTask")
-- c.pingEvent.link = c
-- c.OnPingRecieved = multi:newConnection()
-- c.OnDataRecieved = multi:newConnection()
-- c.OnServerNotAvailable = multi:newConnection()
-- c.OnClientReady = multi:newConnection()
-- c.OnClientDisconnected = multi:newConnection()
-- c.OnConnectionRegained = multi:newConnection()
-- c.notConnected =
-- multi:newFunction(
-- function(self)
-- multi:newAlarm(3):OnRing(
-- function(alarm)
-- if self.link:IDAssigned() == false then
-- self.link.OnServerNotAvailable:Fire("Can't connect to the server: no response from server")
-- end
-- alarm:Destroy()
-- end
-- ):setName("net.clientTimeout")
-- end
-- )
-- c.notConnected.link = c
-- if not nonluaServer then
-- c.udp:send("I!")
-- end
-- table.insert(net.ConnectionDriver, c)
-- multi.nextStep(
-- function()
-- c.notConnected()
-- end
-- )
-- net.OnClientCreated:Fire(c)
-- return c
-- end
--TCP Stuff --TCP Stuff
function net:newTCPClientObject(fd) function net:newTCPClientObject(fd)
local c = {} local c = {}
@ -524,8 +555,7 @@ function net:newTCPClientObject(fd)
local data, err, dat, len local data, err, dat, len
if self.rMode == "b" then if self.rMode == "b" then
thread.hold(function() thread.hold(function()
dat = client:receive(self.numspace) return client:receive(self.numspace)
return dat
end) end)
len = bin.new(dat):getBlock("n", self.numspace) len = bin.new(dat):getBlock("n", self.numspace)
data, err = client:receive(len) data, err = client:receive(len)
@ -547,7 +577,7 @@ function net:newTCPClientObject(fd)
data = net.denormalize(data) data = net.denormalize(data)
end end
if net.inList(self.bannedIPs, ip) then if net.inList(self.bannedIPs, ip) then
print("We will ingore data from a banned client!") --print("We will ingore data from a banned client!")
return return
end end
local hook = data:match("!(.-)!") local hook = data:match("!(.-)!")
@ -602,11 +632,14 @@ function net:newTCPServer(port)
self.sMode = "b" self.sMode = "b"
end end
function c:broadcast(name) function c:broadcast(name)
table.insert(net.BroadcastDriver,function(loop,dt) table.insert(
self.broad:setoption('broadcast',true) net.BroadcastDriver,
function(loop, dt)
self.broad:setoption("broadcast", true)
self.broad:sendto(name .. "|" .. self.Type .. "|" .. self.hostip .. ":" .. self.port, "255.255.255.255", 11111) self.broad:sendto(name .. "|" .. self.Type .. "|" .. self.hostip .. ":" .. self.port, "255.255.255.255", 11111)
self.broad:setoption('broadcast',false) self.broad:setoption("broadcast", false)
end) end
)
end end
function c:setUpdateRate(n) function c:setUpdateRate(n)
self.updaterRate = n self.updaterRate = n
@ -615,10 +648,10 @@ function net:newTCPServer(port)
self.rMode = mode self.rMode = mode
end end
function c:setSendMode(mode) function c:setSendMode(mode)
self.rMode=mode self.sMode = mode
end end
function c:banCID(cid) function c:banCID(cid)
print("Function not supported on a tcp server!") --print("Function not supported on a tcp server!")
end end
function c:banIP(ip) function c:banIP(ip)
table.insert(self.bannedIPs, cid) table.insert(self.bannedIPs, cid)
@ -645,7 +678,7 @@ function net:newTCPServer(port)
self:send(ip, "L!", port) self:send(ip, "L!", port)
end end
function c:CIDFrom(ip, port) function c:CIDFrom(ip, port)
print("Method not supported when using a TCP Server!") --print("Method not supported when using a TCP Server!")
return "CIDs in TCP work differently!" return "CIDs in TCP work differently!"
end end
function c:sendAll(data) function c:sendAll(data)
@ -671,27 +704,26 @@ function net:newTCPServer(port)
end end
function c:update() function c:update()
local client = self.tcp:accept(self.rMode) local client = self.tcp:accept(self.rMode)
if not client then return end if not client then
return
end
table.insert(self.ips, client) table.insert(self.ips, client)
client:settimeout(0) client:settimeout(0)
--client:setoption('tcp-nodelay', true) client:setoption("keepalive", true)
client:setoption('keepalive', true)
ip, port = client:getpeername() ip, port = client:getpeername()
if ip and port then if ip and port then
print("Got connection from: ",ip,port)
-- local updater=multi:newUpdater(skip):setName("net.tcpClientObj")
-- self.updates[client]=updater
self.OnClientConnected:Fire(self, client, client, ip) self.OnClientConnected:Fire(self, client, client, ip)
--updater:OnUpdate(function(self)
multi:newThread("ServerClientHandler",function() multi:newThread("ServerClientHandler",function()
while true do while true do
thread.skip(1) thread.skip(1)
local data, err, dat, len local data, err, dat, len
if self.rMode == "b" then if self.rMode == "b" then
thread.hold(function() thread.hold(
function()
dat = client:receive(self.numspace) dat = client:receive(self.numspace)
return dat return dat
end) end
)
len = bin.new(dat):getBlock("n", self.numspace) len = bin.new(dat):getBlock("n", self.numspace)
data, err = client:receive(len) data, err = client:receive(len)
else else
@ -713,7 +745,6 @@ function net:newTCPServer(port)
data = net.denormalize(data) data = net.denormalize(data)
end end
if net.inList(self.bannedIPs, ip) then if net.inList(self.bannedIPs, ip) then
print("We will ingore data from a banned client!")
return return
end end
local hook = data:match("!(.-)!") local hook = data:match("!(.-)!")
@ -729,13 +760,6 @@ function net:newTCPServer(port)
end end
end end
end) end)
-- updater:SetSkip(self.updaterRate)
-- updater.client=client
-- updater.Link=self
-- function updater:setReceiveMode(mode)
-- self.rMode=mode
-- end
-- self.links[client]=updater
end end
end end
c.OnClientsModulesList = multi:newConnection() c.OnClientsModulesList = multi:newConnection()
@ -751,12 +775,12 @@ function net:newTCPClient(host,port)
c.ip = assert(socket.dns.toip(host)) c.ip = assert(socket.dns.toip(host))
c.tcp = socket.connect(c.ip, port) c.tcp = socket.connect(c.ip, port)
if not c.tcp then if not c.tcp then
print("Can't connect to the server: no response from server") --print("Can't connect to the server: no response from server")
return false return false
end end
c.tcp:settimeout(0) c.tcp:settimeout(0)
--c.tcp:setoption('tcp-nodelay', true) --c.tcp:setoption('tcp-nodelay', true)
c.tcp:setoption('keepalive', true) c.tcp:setoption("keepalive", true)
c.Type = "tcp" c.Type = "tcp"
c.autoReconnect = true c.autoReconnect = true
c.rMode = "*l" c.rMode = "*l"
@ -795,7 +819,7 @@ function net:newTCPClient(host,port)
elseif err == "timeout" then elseif err == "timeout" then
self.OnClientDisconnected:Fire(self, err) self.OnClientDisconnected:Fire(self, err)
elseif err then elseif err then
print(err) --print(err)
end end
end end
function c:sendRaw(data) function c:sendRaw(data)
@ -814,13 +838,17 @@ function net:newTCPClient(host,port)
return true return true
end end
function c:update() function c:update()
if not self.tcp then return end if not self.tcp then
return
end
local data, err, dat local data, err, dat
if self.rMode == "b" then if self.rMode == "b" then
thread.hold(function() thread.hold(
function()
dat = self.tcp:receive(self.numspace) dat = self.tcp:receive(self.numspace)
return dat return dat
end) end
)
len = bin.new(dat):getBlock("n", self.numspace) len = bin.new(dat):getBlock("n", self.numspace)
data, err = self.tcp:receive(len) data, err = self.tcp:receive(len)
else else
@ -831,7 +859,7 @@ function net:newTCPClient(host,port)
elseif err == "timeout" then elseif err == "timeout" then
self.OnClientDisconnected:Fire(self, err) self.OnClientDisconnected:Fire(self, err)
elseif err then elseif err then
print(err) --print(err)
end end
if data then if data then
if self.autoNormalization then if self.autoNormalization then
@ -842,28 +870,37 @@ function net:newTCPClient(host,port)
end end
end end
function c:reconnect() function c:reconnect()
multi:newFunction(function(func) multi:newFunction(
function(func)
self.tcp = socket.connect(self.ip, self.port) self.tcp = socket.connect(self.ip, self.port)
if self.tcp == nil then if self.tcp == nil then
print("Can't connect to the server: No response from server!") --print("Can't connect to the server: No response from server!")
multi:newAlarm(3):OnRing(function(alarm) multi:newAlarm(3):OnRing(
function(alarm)
self:reconnect() self:reconnect()
alarm:Destroy() alarm:Destroy()
return return
end):setName("net.timeoutTask") end
):setName("net.timeoutTask")
end end
self.OnConnectionRegained:Fire(self) self.OnConnectionRegained:Fire(self)
self.tcp:settimeout(0) self.tcp:settimeout(0)
--self.tcp:setoption('tcp-nodelay', true) --self.tcp:setoption('tcp-nodelay', true)
self.tcp:setoption('keepalive', true) self.tcp:setoption("keepalive", true)
end)
end end
c.event=multi:newEvent(function(event) )
end
c.event =
multi:newEvent(
function(event)
return event.link:IDAssigned() return event.link:IDAssigned()
end):OnEvent(function(event) end
):OnEvent(
function(event)
event.link.OnClientReady:Fire(event.link) event.link.OnClientReady:Fire(event.link)
event:Destroy() event:Destroy()
end) end
)
c.event:setName("net.handshakeTask") c.event:setName("net.handshakeTask")
c.event.link = c c.event.link = c
c.OnClientReady = multi:newConnection() c.OnClientReady = multi:newConnection()
@ -875,7 +912,9 @@ function net:newTCPClient(host,port)
return c return c
end end
net.timer = multi:newTimer():Start() net.timer = multi:newTimer():Start()
multi:newThread("ClientServerHandler",function() multi:newThread(
"ClientServerHandler",
function()
while true do while true do
thread.skip() thread.skip()
for i = 1, #net.ConnectionDriver do for i = 1, #net.ConnectionDriver do
@ -889,5 +928,6 @@ multi:newThread("ClientServerHandler",function()
net.timer:Reset() net.timer:Reset()
end end
end end
end) end
)
return net return net

84
net/serverbase.lua Normal file
View File

@ -0,0 +1,84 @@
local multi, thread = require("multi"):init()
local socket = require("socket")
local net = require("net")
local server = {}
local bCaster = 0
server.__index = server
server.OnClientsModulesList = multi:newConnection()
server.OnPreRecieved = multi:newConnection()
server.OnDataRecieved = multi:newConnection()
server.OnClientClosed = multi:newConnection()
server.OnClientConnected = multi:newConnection()
server.OnPreSend = multi:newConnection()
server.updaterRate = 1
server.rMode = "*l"
server.sMode = "*l"
function server:init(type)
self.idleRate = 5
self.bannedCIDs = {}
self.bannedIPs = {}
self.broad = socket.udp()
self.localIP = net.getLocalIP()
self.Type = type
self.ips = {}
self.cids = {}
self.process = multi:newProcessor()
self.process.Start()
end
function server:setIdleRate(minutes)
self.idleRate = minutes
end
function server:setUpdateRate(n)
self.updaterRate = n
end
function server:banCID(cid)
table.insert(self.bannedCIDs,cid)
end
function server:banIP(ip)
table.insert(self.bannedIPs)
end
function server:setRecieveMode(mode)
self.rMode = mode
end
function server:setSendMode(mode)
self.sMode = mode
end
function server:broadcast(name)
bCaster = bCaster + 1
self.process:newThread("Broadcast Handler<"..bCaster..">",function()
while true do
thread.yield()
self.broad:setoption("broadcast",true)
self.broad:sendto(table.concat({name,self.Type,self.localIP},"|")..":"..self.port, "255.255.255.255", 11111)
self.broad:setoption("broadcast", false)
end
end)
end
function server:send(data,cid)
if self.Type == "udp" then
---
elseif self.Type == "tcp" then
--
end
end
function server:getCid(ip,port)
if self.cids[ip .. port] then
return self.cids[ip .. port]
end
end
function server:sendAll(data)
for i,v in pairs(self.cids) do
self:send(data,cid)
end
end
function server:sendAllBut(data,cid)
for i,v in pairs(self.cids) do
if v~=cid then
self:send(data,cid)
end
end
end
function server:clientRegistered(cid)
return self.cids[cid]
end
return server

30
net/tcp/init.lua Normal file
View File

@ -0,0 +1,30 @@
local net = require("net")
local clientbase = require("net.clientbase")
local serverbase = require("net.serverbase")
local multi, thread = require("multi"):init()
local GLOBAL, THREAD = require("multi.integration.threading"):init()
function net:newTCPClient(host, port)
local c = {}
setmetatable(c,clientbase)
c:init("tcp")
c.ip = assert(socket.dns.toip(host))
c.tcp = socket.connect(c.ip,port)
c.tcp:settimeout(0)
c.tcp:setoption("keepalive",true)
c.updateThread = c.process:newThread("TCPServer Thread<"..udpcount..">",function()
while true do
thread.skip(c.updaterRate)
local data = thread.hold(function()
return c.udp:receive()
end)
local dat = {data = data}
c.OnPreSend:Fire(dat)
c.OnDataRecieved:Fire(c,dat.data)
end
end).OnError(function(a,b,c)
print(a,b,c)
end)
return c
end

100
net/udp/init.lua Normal file
View File

@ -0,0 +1,100 @@
local net = require("net")
local clientbase = require("net.clientbase")
local serverbase = require("net.serverbase")
local multi, thread = require("multi"):init()
local GLOBAL, THREAD = require("multi.integration.threading"):init()
local CID = {}
CID.__index = cid
local udpcount = 0
CID.ip = "0.0.0.0"
CID.port = 0
function net:newUDPServer(port)
local c = {}
setmetatable(c,serverbase)
c:init("udp")
c.udp = assert(socket.udp())
c.udp:settimeout(0)
c.udp:setsockname("*",port)
c.bannedIPs = {}
c.bannedCIDs = {}
local inactivity = {}
if port == 0 then
_,c.port = c.udp:getsockname()
else
c.port = port
end
function c:send(data,cid)
local dat = {data = data, cid = cid}
self.OnPreSend:Fire(dat)
self.udp:sendto(dat.data,dat.cid.ip,dat.cid.port)
end
udpcount = udpcount + 1
c.updateThread = c.process:newThread("UDPServer Thread<"..udpcount..">",function()
local sideJob = thread:newFunction(function()
thread.sleep(60*c.idleRate)
for i,v in pairs(c.cids) do
thread.skip(1)
if os.clock() - v.activity >= 60*c.idleRate then
c.OnClientClosed:Fire(v)
c.cids[i] = nil
end
end
return true
end)
while true do
thread.skip(c.updaterRate)
local data, ip, port = c.udp:receivefrom()
sideJob().connect(function(yes,a,b,c)
if yes then
sideJob:Resume()
end
end)
sideJob:Pause()
if data then
local cid = c:getCid(ip,port)
if not cid then
local cd = {}
setmetatable(cd,CID)
cd.ip = ip
cd.port = port
cd.activity = os.clock()
c.cids[ip .. port] = cd
cid = cd
end
print("Refreshing CID: ",cid," Activity!")
cid.activity = os.clock()
local dat = {data = data,cid = cid}
c.OnPreRecieved:Fire(dat)
c.OnDataRecieved:Fire(c,dat.data,dat.cid)
end
end
end).OnError(function(...)
print(...)
end)
c.activityMonitor = c.process:newThread("Activity Monitor",function()
--
end)
return c
end
function net:newUDPClient(host, port)
local c = {}
setmetatable(c,clientbase)
c:init("udp")
c.ip = assert(socket.dns.toip(host))
c.udp = assert(socket.udp())
c.udp:settimeout(0)
c.udp:setpeername(c.ip,port)
c.updateThread = c.process:newThread("UDPServer Thread<"..udpcount..">",function()
while true do
thread.skip(c.updaterRate)
local data = thread.hold(function()
return c.udp:receive()
end)
local dat = {data = data}
c.OnPreSend:Fire(dat)
c.OnDataRecieved:Fire(c,dat.data)
end
end)
return c
end
return net

View File

@ -1,20 +1,9 @@
package.path="?/init.lua;"..package.path package.path = "./?/init.lua;./?.lua;"..package.path
local multi = require("multi") local net = require("net.udp")
local net = require("net") local server = net:newUDPServer(12345)
local GLOBAL, THREAD = require("multi.integration.lanesManager").init()
server = net:newTCPServer(12345) server.OnDataRecieved(function(serv, data,cid)
server:enableBinaryMode() print("Response: ",data)
print("Server hosted on "..net.getExternalIP().." listening on port: 12345") server:send("Hello!",cid)
server.OnDataRecieved(function(self,data,cid,ip,port)
print(data)
local file = bin.load("test.mp3")
local dat = file:read(1024)
while dat do
thread.sleep(.002)
self:send(ip,dat,port,cid)
dat = file:read(1024)
end
self:send(ip,dat or "",port,cid)
self:send(ip,"END",port,cid)
end) end)
multi:mainloop() multi:mainloop()