Advertisement
Starkkz

UDP Packet manager

Dec 7th, 2014
622
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.22 KB | None | 0 0
  1. UDP = {
  2.     Server = {
  3.         Create = function (Port)
  4.             local Socket = IO.CreateUDPStream(Port)
  5.             if Socket then
  6.                 local Server = setmetatable(
  7.                     {
  8.                         Socket = Socket,
  9.                         RecvPackets = {},
  10.                         SendPackets = {},
  11.                         SendID = {},
  12.                         PacketID = {},
  13.                         PacketType = {},
  14.                         Ping = {},
  15.                         PingRequest = {},
  16.                     }, UDP.ServerMT
  17.                 )
  18.                 return Server
  19.             end
  20.         end,
  21.  
  22.         CreatePacketType = function (Name, Function)
  23.             -- So we create a function that reads packets of certain type ID
  24.             assert(type(ID) == "number", "CreatePacketType must contain a id identifier")
  25.             assert(type(Function) == "function", "CreatePacketType must contain a function")
  26.             local PacketID = #self.PacketType + 1
  27.             self.PacketID[Name] = PacketID
  28.             self.PacketType[PacketID] = Function
  29.  
  30.             -- Function = self.PacketType[self.PacketID[ type name of the packet ]]
  31.             -- Function = self.PacketType[ type id of the packet]
  32.         end,
  33.  
  34.         packetType = function (Name, IP, Port)
  35.             -- Let's that this client has a packet type ID for the type name of this packet, but the rest of the clients have different type IDs
  36.             if IP and Port then
  37.                 local Address = IP..":"..Port
  38.                 if self.SendID[Address] then
  39.                     return self.SendID[Address][Name]
  40.                 end
  41.             end
  42.             -- Otherwise we send an already known type
  43.             return self.PacketID[Name]
  44.         end,
  45.  
  46.         newPacketIDToIP = function (IP, Port)
  47.             local Address = IP..":"..Port
  48.             if not self.SendPackets[Address] then
  49.                 self.SendPackets[Address] = {}
  50.             end
  51.             local Packet = {}
  52.             local PacketPrevID = #self.SendPackets[Address]
  53.             local PacketID = PacketPrevID + 1
  54.             if PacketID >= 65536 then
  55.                 PacketID = 0
  56.             end
  57.             Packet.ID = PacketID
  58.             Packet.Prev = PacketPrevID
  59.             self.SendPackets[Address][PacketID] = Packet
  60.             return Packet, PacketID
  61.         end,
  62.  
  63.         newPacketFromIP = function (IP, Port, ID)
  64.             local Address = IP..":"..Port
  65.             if not self.RecvPackets[Address] then
  66.                 self.RecvPackets[Address] = {Current = Packet.ID}
  67.             end
  68.             local Packet = {ID = ID}
  69.             local PacketPrevID = Packet.ID - 1
  70.             if PacketPrevID < 0 then
  71.                 PacketPrevID = 65535
  72.             end
  73.             Packet.Prev = PacketPrevID
  74.             self.RecvPackets[Address][Packet.ID] = Packet
  75.  
  76.             if self.RecvPackets[Address].Current == Packet.Prev then
  77.                 self.RecvPackets[Address].Current = Packet.ID
  78.             end
  79.             return Packet, Packet.ID
  80.         end,
  81.  
  82.         NewPacket = function (Name, IP, Port, Data)
  83.             -- We create a packet for
  84.             local Type = self:packetType(Name, IP, Port)
  85.             if Type then
  86.                 local Stream = IO.CreateBankStream()
  87.                 if Stream then
  88.                     if Data and string.len(Data) > 32 then
  89.                         IO.WriteString(Stream, Data)
  90.                         IO.SeekStream(Stream, 0)
  91.                     end
  92.  
  93.                     local Packet = self:newPacketIDToIP(IP, Port)
  94.                     Packet.Type = Type
  95.                     Packet.Stream = Stream
  96.                     Packet.IP = IP
  97.                     Packet.Port = Port
  98.                     Packet.Retries = 0
  99.                     Packet.SendLast = 0
  100.                     return Packet
  101.                 end
  102.             end
  103.         end,
  104.  
  105.         NewPacketFrom = function (Type, ID, IP, Port, Data)
  106.             local Stream = IO.CreateBankStream()
  107.             if Stream then
  108.                 if Data then
  109.                     IO.WriteString(Stream, Data)
  110.                 end
  111.  
  112.                 local Packet = self:newPacketFromIP(IP, Port, ID)
  113.                 Packet.Type = Type
  114.                 Packet.Stream = Stream
  115.                 Packet.IP = IP
  116.                 Packet.Port = Port
  117.                 return Packet
  118.             end
  119.         end,
  120.  
  121.         Delete = {
  122.             -- Different functions to delete already read/sent packets
  123.             RecvPacket = function (Packet)
  124.                 local Address = Packet.IP..":"..Port
  125.                 if self.RecvPackets[Address] then
  126.                     self.RecvPackets[Address][Packet.ID] = nil
  127.                     if table.empty(self.RecvPackets[Address]) then
  128.                         self.RecvPackets[Address] = nil
  129.                     end
  130.                 end
  131.             end,
  132.  
  133.             SendPacket = function (Packet)
  134.                 local Address = Packet.IP..":"..Port
  135.                 if self.SendPackets[Address] then
  136.                     self.SendPackets[Address][Packet.ID] = nil
  137.                     if table.empty(self.SendPackets[Address]) then
  138.                         self.SendPackets[Address] = nil
  139.                     end
  140.                 end
  141.             end,
  142.  
  143.             RecvPacketID = function (IP, Port, PacketID)
  144.                 local Address = IP..":"..Port
  145.                 if self.RecvPackets[Address] then
  146.                     self.RecvPackets[Address][PacketID] = nil
  147.                     if table.empty(self.RecvPackets[Address]) then
  148.                         self.RecvPackets[Address] = nil
  149.                     end
  150.                 end
  151.             end,
  152.  
  153.             SendPacketID = function (IP, Port, PacketID)
  154.                 local Address = IP..":"..Port
  155.                 if self.SendPackets[Address] then
  156.                     self.SendPackets[Address][PacketID] = nil
  157.                     if table.empty(self.SendPackets[Address]) then
  158.                         self.SendPackets[Address] = nil
  159.                     end
  160.                 end
  161.             end,
  162.         },
  163.  
  164.         NextPacket = function ()
  165.             -- Gets the next packet from the queue
  166.             for Address, Packets in pairs(self.RecvPackets) do
  167.                 for ID, Packet in pairs(Packets) do
  168.                     if Packets.Current >= Packet.ID then
  169.                         return Packet
  170.                     end
  171.                 end
  172.             end
  173.         end,
  174.  
  175.         ReceivePackets = function ()
  176.             while IO.RecvUDPMsg(self.Socket) do
  177.                 -- Reads messages from the UDP socket
  178.                 local MsgSize = IO.ReadAvail(self.Socket)
  179.                 local MsgIP = IO.UDPMsgIP(self.Socket)
  180.                 local MsgPort = IO.UDPMsgPort(self.Socket)
  181.                 if MsgSize >= 1 then
  182.                     MsgSize = MsgSize - 1
  183.                     local MsgType = IO.ReadByte(self.Socket)
  184.                     if MsgType == 0 then
  185.                         -- DELETE PACKET
  186.                         if MsgSize >= 2 then
  187.                             local PacketID = IO.ReadShort(self.Socket)
  188.                             self.Delete.SendPacketID(self, IP, Port, PacketID)
  189.                         end
  190.                     elseif MsgType == 1 then
  191.                         -- RECEIVED PACKET
  192.                         if MsgSize >= 2 then
  193.                             local PacketType = IO.ReadShort(self.Socket)
  194.                             local PacketID = IO.ReadShort(self.Socket)
  195.                             MsgSize = MsgSize - 4
  196.  
  197.                             local PacketDatagram = IO.ReadString(self.Socket, MsgSize)
  198.                             if string.len(PacketDatagram) > 0 then
  199.                                 self:NewPacketFrom(PacketType, PacketID, MsgIP, MsgPort, PacketDatagram)
  200.  
  201.                                 IO.WriteByte(self.Socket, 0)
  202.                                 IO.WriteShort(self.Socket, PacketID)
  203.                                 IO.SendUDPMsg(self.Socket, MsgIP, MsgPort)
  204.                             end
  205.                         end
  206.                     end
  207.                 end
  208.             end
  209.  
  210.             local NextPacket = self:NextPacket()
  211.             while NextPacket do
  212.                 -- As long as we can read packets, we have to parse them with our already known functions
  213.                 local PacketProtocol = self.PacketType[NextPacket.Type]
  214.                 if PacketProtocol then
  215.                     PacketProtocol(NextPacket)
  216.                 end
  217.                 self.Delete.RecvPacket(self, NextPacket)
  218.                 NextPacket = self:NextPacket()
  219.             end
  220.         end,
  221.  
  222.         SendPackets = function ()
  223.             -- We re-send the packets that haven't been received
  224.             for Address, Packets in pairs(self.SendPackets) do
  225.                 for PacketID, Packet in pairs(Packets) do
  226.                     if os.clock() - Packet.SendLast >= 0.125 then
  227.                         Packet.Retries = Packet.Retries + 1
  228.                         Packet.SendLast = Packet.SendLast + 1
  229.                         local Datagram = IO.ReadString(Packet.Stream, IO.StreamSize(Packet.Stream))
  230.                         IO.SeekStream(Packet.Stream, 0)
  231.  
  232.                         IO.WriteString(self.Socket, Datagram)
  233.                         IO.SendUDPMsg(self.Socket, Packet.IP, Packet.Port)
  234.  
  235.                         if Packet.Retries >= 16 then
  236.                             -- If this packet failed to send 16 times during 2 seconds, it is cancelled
  237.                             self.Delete.SendPacket(self, Packet)
  238.                         end
  239.                     end
  240.                 end
  241.             end
  242.         end,
  243.  
  244.         Update = function ()
  245.             -- Update function, so we just need to call this instead of two
  246.             self:SendPackets()
  247.             self:ReceivePackets()
  248.         end,
  249.     }
  250. }
  251. UDP.ServerMT = {__index = UDP.Server, __type = "udp server"}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement