netold contains the older library. the new library has all the core features that was in the old library.
274 lines
7.4 KiB
Lua
274 lines
7.4 KiB
Lua
function net:newAUDPServer(port,servercode)
|
|
local c={}
|
|
c.udp=assert(socket.udp())
|
|
c.udp:settimeout(0)
|
|
c.udp:setsockname("*", port)
|
|
c.ips={}
|
|
c.Type="udp"
|
|
c.port=port
|
|
c.ids={}
|
|
c.servercode=servercode
|
|
c.bannedIPs={}
|
|
c.bannedCIDs={}
|
|
c.autoNormalization=false
|
|
function c:setUpdateRate(n)
|
|
print("Not needed in a audp server!")
|
|
end
|
|
function c:banCID(cid)
|
|
table.insert(self.bannedCIDs,cid)
|
|
end
|
|
function c:banIP(ip)
|
|
table.insert(self.bannedIPs,cid)
|
|
end
|
|
function c:send(ip,data,port,cid)
|
|
if self.autoNormalization then
|
|
data=net.normalize(data)
|
|
end
|
|
if self.servercode then
|
|
cid=cid or self:CIDFrom(ip,port)
|
|
if not self.ips[cid] then
|
|
print("Can't determine cid from client... sending the client a new one!")
|
|
local cid=net.resolveID(self)
|
|
print("Sending unique cid to client: "..cid)
|
|
self.ips[cid]={ip,port,0,self.servercode==nil}
|
|
print(ip)
|
|
self.udp:sendto("I!"..cid,ip,port)
|
|
if self.servercode then
|
|
self.udp:sendto("S!",ip,port)
|
|
end
|
|
return
|
|
end
|
|
if net.inList(self.bannedIPs,ip) or net.inList(self.bannedCIDs,cid) then
|
|
self.udp:sendto("BANNED CLIENT", ip, port or self.port)
|
|
elseif self.ips[cid][4] then
|
|
self.udp:sendto(data, ip, port or self.port)
|
|
elseif self.ips[cid][4]==false then
|
|
self.udp:sendto("Make sure your server code is correct!", ip, port)
|
|
end
|
|
else
|
|
self.udp:sendto(data, ip, port or self.port)
|
|
end
|
|
end
|
|
function c:pollClientModules(ip,port)
|
|
self:send(ip,"L!",port)
|
|
end
|
|
function c:CIDFrom(ip,port)
|
|
for i,v in pairs(self.ips) do
|
|
if(ip==v[1] and v[2]==port) then
|
|
return i
|
|
end
|
|
end
|
|
end
|
|
function c:sendAll(data)
|
|
for i,v in pairs(self.ips) do
|
|
self:send(v[1],data,v[2],i)
|
|
end
|
|
end
|
|
function c:sendAllBut(data,cid)
|
|
for i,v in pairs(self.ips) do
|
|
if i~=cid then
|
|
self:send(v[1],data,v[2],i)
|
|
end
|
|
end
|
|
end
|
|
function c:clientRegistered(cid)
|
|
return self.ips[cid]
|
|
end
|
|
function c:clientLoggedIn(cid)
|
|
if not self.clientRegistered(cid) then
|
|
return nil
|
|
end
|
|
return self.ips[cid][4]
|
|
end
|
|
function c:update()
|
|
local data,ip,port=self.udp:receivefrom()
|
|
if net.inList(self.bannedIPs,ip) or net.inList(self.bannedCIDs,cid) then
|
|
print("We will ingore data from a banned client!")
|
|
return
|
|
end
|
|
if data then
|
|
if self.autoNormalization then
|
|
data=net.denormalize(data)
|
|
end
|
|
if data:sub(1,4)=="pong" then
|
|
self.ips[data:sub(5,-1)][3]=os.clock()
|
|
elseif data:sub(1,2)=="S!" then
|
|
local cid=self:CIDFrom(ip,port)
|
|
if data:sub(3,-1)==self.servercode then
|
|
print("Servercode Accepted: "..self.servercode)
|
|
if self.ips[cid] then
|
|
self.ips[cid][4]=true
|
|
else
|
|
print("Server can't keep up! CID: "..cid.." has been skipped! Sending new CID to the client!")
|
|
local cid=net.resolveID(self)
|
|
print("Sending unique cid to client: "..cid)
|
|
self.ips[cid]={ip,port,0,self.servercode==nil}
|
|
print(ip)
|
|
self.udp:sendto("I!"..cid,ip,port)
|
|
if self.servercode then
|
|
self.udp:sendto("S!",ip,port)
|
|
end
|
|
end
|
|
else
|
|
self.udp:sendto("Make sure your server code is correct!", ip, port)
|
|
end
|
|
elseif data:sub(1,2)=="C!" then
|
|
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
|
|
self.OnClientClosed:Fire(self,"Client Closed Connection!",data:sub(3,10),ip,port)
|
|
elseif data=="I!" then
|
|
local cid=net.resolveID(self)
|
|
print("Sending unique cid to client: "..cid)
|
|
self.ips[cid]={ip,port,os.clock(),self.servercode==nil}
|
|
print(ip)
|
|
self.udp:sendto("I!"..cid,ip,port)
|
|
if self.servercode then
|
|
self.udp:sendto("S!",ip,port)
|
|
end
|
|
self.OnClientConnected:Fire(self,cid,ip,port)
|
|
elseif data:sub(1,2)=="L!" then
|
|
cid,cList=data:sub(3,10),data:sub(11,-1)
|
|
local list={}
|
|
for m,v in cList:gmatch("(%S-):(%S-)|") do
|
|
list[m]=v
|
|
end
|
|
self.OnClientsModulesList:Fire(list,cid,ip,port)
|
|
end
|
|
end
|
|
for cid,dat in pairs(self.ips) do
|
|
if not((os.clock()-dat[3])<65) then
|
|
self.ips[cid]=nil
|
|
self.OnClientClosed:Fire(self,"Client lost Connection: ping timeout",cid,ip,port)
|
|
end
|
|
end
|
|
end
|
|
c.OnClientsModulesList=multi:newConnection()
|
|
c.OnDataRecieved=multi:newConnection()
|
|
c.OnClientClosed=multi:newConnection()
|
|
c.OnClientConnected=multi:newConnection()
|
|
c.connectiontest=multi:newAlarm(30)
|
|
c.connectiontest.link=c
|
|
c.connectiontest:OnRing(function(alarm)
|
|
--print("pinging clients!")
|
|
alarm.link:sendAll("ping")
|
|
alarm:Reset()
|
|
end)
|
|
multi:newLoop(function()
|
|
c:update()
|
|
end)
|
|
net.OnServerCreated:Fire(c)
|
|
return c
|
|
end
|
|
|
|
function net:newAUDPClient(host,port,servercode,nonluaServer)
|
|
local c={}
|
|
c.ip=assert(socket.dns.toip(host))
|
|
c.udp=assert(socket.udp())
|
|
c.udp:settimeout(0)
|
|
c.cid="NIL"
|
|
c.lastPing=0
|
|
c.Type="udp"
|
|
c.servercode=servercode
|
|
c.autoReconnect=true
|
|
c.autoNormalization=false
|
|
function c:pollPing(n)
|
|
return not((os.clock()-self.lastPing)<(n or 60))
|
|
end
|
|
function c:send(data)
|
|
if self.autoNormalization then
|
|
data=net.normalize(data)
|
|
end
|
|
self.udp:send("C!"..self.cid..data)
|
|
end
|
|
function c:sendRaw(data)
|
|
if self.autoNormalization then
|
|
data=net.normalize(data)
|
|
end
|
|
self.udp:send(data)
|
|
end
|
|
function c:getCID()
|
|
if self:IDAssigned() then
|
|
return self.cid
|
|
end
|
|
end
|
|
function c:close()
|
|
self:send("E!")
|
|
end
|
|
function c:IDAssigned()
|
|
return self.cid~="NIL"
|
|
end
|
|
function c:update()
|
|
local data=self.udp:receive()
|
|
if data then
|
|
if self.autoNormalization then
|
|
data=net.denormalize(data)
|
|
end
|
|
if data:sub(1,2)=="I!" then
|
|
self.cid=data:sub(3,-1)
|
|
self.OnClientReady:Fire(self)
|
|
elseif data=="S!" then
|
|
self.udp:send("S!"..(self.servercode or ""))
|
|
elseif data=="L!" then
|
|
local mods=""
|
|
local m=""
|
|
for i=1,#net.loadedModules do
|
|
m=net.loadedModules[i]
|
|
mods=mods..m..":"..net.getModuleVersion(m).."|"
|
|
end
|
|
self.udp:send("L!"..self.cid..mods)
|
|
elseif data=="ping" then
|
|
self.lastPing=os.clock()
|
|
self.OnPingRecieved:Fire(self)
|
|
self.udp:send("pong"..self.cid)
|
|
else
|
|
local hook=data:match("!(.-)!")
|
|
self.OnDataRecieved:getConnection(hook):Fire(self,data)
|
|
end
|
|
end
|
|
end
|
|
function c:reconnect()
|
|
if not nonluaServer then
|
|
self.cid="NIL"
|
|
c.udp:send("I!")
|
|
end
|
|
self.OnConnectionRegained:Fire(self)
|
|
end
|
|
c.pingEvent=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
|
|
end)
|
|
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)
|
|
self:hold(3)
|
|
if self.link:IDAssigned()==false then
|
|
self.link.OnServerNotAvailable:Fire("Can't connect to the server: no response from server")
|
|
end
|
|
end)
|
|
c.notConnected.link=c
|
|
if not nonluaServer then
|
|
c.udp:send("I!")
|
|
end
|
|
multi:newLoop(function()
|
|
c:update()
|
|
end)
|
|
multi:newJob(function() c.notConnected() end)
|
|
net.OnClientCreated:Fire(c)
|
|
return c
|
|
end
|