Starkkz

bnet.lua

Jul 27th, 2014
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 13.07 KB | None | 0 0
  1. local ffi = require("ffi")
  2. local socket_wrapper = require("socket_wrapper")
  3. local print = print
  4. local tostring = tostring
  5. local tonumber = tonumber
  6. local strsub = string.sub
  7. local setmetatable = setmetatable
  8.  
  9. local function isnil(object)
  10.     if object then
  11.         return strsub(tostring(object), -4) == "NULL"
  12.     end
  13.     return true
  14. end
  15.  
  16. ffi.cdef [[
  17.     void free (void* ptr);
  18.     void *malloc(size_t size);
  19. ]]
  20. ffi.free = ffi.C.free
  21. ffi.alloc = ffi.C.malloc
  22.  
  23. module("bnet")
  24. BNET_MAX_CLIENTS = 32
  25.  
  26. function Shl(A, B)
  27.     if A and B then
  28.         return A * (2 ^ B)
  29.     end
  30. end
  31.  
  32. function CountHostIPs(Host)
  33.     local Addresses, AdressType, AddressLength = socket_wrapper.gethostbyname_(Host)
  34.     if isnil(Addresses) or AddressLength ~= 4 then
  35.         return 0
  36.     end
  37.  
  38.     local Count = 0
  39.     while not isnil(Addresses[Count]) do
  40.         Count = Count + 1
  41.     end
  42.     return Count
  43. end
  44.  
  45. function IntIP(IP)
  46.     local InetADDR = socket_wrapper.inet_addr_(IP)
  47.     local HTONL = socket_wrapper.htonl_(InetADDR)
  48.     return HTONL
  49. end
  50.  
  51. --[[
  52. function StringIP(IP)
  53.     return socket_wrapper.inet_ntoa_(socket_wrapper.htonl_(IP))
  54. end
  55. ]]
  56.  
  57. function ReadAvail(Stream)
  58.     local Size = ffi.new("int", 0)
  59.     if Stream.UDP then
  60.         if Stream.Socket == stream_wrapper.INVALID_SOCKET then
  61.             return 0
  62.         end
  63.         if socket_wrapper.ioctl_(Stream.Socket, stream_wrapper.FIONREAD, Size) then
  64.             return 0
  65.         end
  66.         return tonumber(Size) or 0
  67.     elseif Stream.TCP then
  68.         return Stream:Size()
  69.     end
  70.     return 0
  71. end
  72.  
  73. TUDPStream = {
  74.     Timeout = 0,
  75.     Socket = 0,
  76.     LocalIP = 0,
  77.     LocalPort = 0,
  78.     MessageIP = 0,
  79.     MessagePort = 0,
  80.     RecvSize = 0,
  81.     SendSize = 0,
  82.     UDP = true
  83. }
  84. UDP = {__index = TUDPStream}
  85.  
  86. function TUDPStream:Read(Buffer, Size)
  87.     local Temp
  88.     if Size > self.RecvSize then
  89.         Size = self.RecvSize
  90.     end
  91.  
  92.     if Size > 0 then
  93.         ffi.copy(Buffer, self.RecvBuffer, Size)
  94.         if Size <  self.RecvSize then
  95.             Temp = ffi.alloc(self.RecvBuffer, Size)
  96.             ffi.copy(Temp, self.RecvBuffer + Size, self.RecvSize - Size)
  97.             ffi.free(self.RecvBuffer)
  98.             self.RecvBuffer = Temp
  99.             self.RecvSize = self.RecvSize - Size
  100.         else
  101.             ffi.free(self.RecvBuffer)
  102.             self.RecvSize = 0
  103.         end
  104.     end
  105.  
  106.     return Size
  107. end
  108.  
  109. function TUDPStream:Write(Buffer, Size)
  110.     if Size <= 0 then
  111.         return 0
  112.     end
  113.  
  114.     local Temp = ffi.alloc(self.SendSize + Size)
  115.     if self.SendSize > 0 then
  116.         ffi.copy(Temp, self.SendBuffer, self.SendSize)
  117.         ffi.copy(Temp + self.sendSize, Buffer, Size)
  118.         ffi.free(self.SendBuffer)
  119.         self.SendBuffer = Temp
  120.         self.SendSize = self.SendSize + Size
  121.     else
  122.         ffi.copy(Temp, Buffer, Size)
  123.         self.SendBuffer = Temp
  124.         self.SendSize = Size
  125.     end
  126. end
  127.  
  128. function TUDPStream:Size()
  129.     return self.RecvSize
  130. end
  131.  
  132. function TUDPStream:Eof()
  133.     if self.Socket == socket_wrapper.INVALID_SOCKET then
  134.         return - 1
  135.     end
  136.     return self.RecvSize == 0
  137. end
  138.  
  139. function TUDPStream:Close()
  140.     if self.Socket ~= socket_wrapper.INVALID_SOCKET then
  141.         socket_wrapper.shutdown_(self.Socket, socket_wrapper.SD_BOTH)
  142.         socket_wrapper.closesocket_(self.Socket)
  143.         self.Socket = INVALID_SOCKET
  144.     end
  145. end
  146.  
  147. function CreateUDPStream(Port)
  148.     local Socket = socket_wrapper.socket_(socket_wrapper.AF_INET, socket_wrapper.SOCK_DRAGM, 0)
  149.     if Socket == socket_wrapper.INVALID_SOCKET then
  150.         return nil
  151.     end
  152.  
  153.     if socket_wrapper.bind_(Socket, socket_wrapper.AF_INET, Port) == socket_wrapper.SOCKET_ERROR then
  154.         socket_wrapper.shutdown_(Socket, socket_wrapper.SD_BOTH)
  155.         socket_wrapper.closesocket_(Socket)
  156.         return nil
  157.     end
  158.  
  159.     local Address = ffi.new("struct sockaddr_in")
  160.     local Addr = ffi.cast("struct sockaddr *", Address)
  161.     local SizePtr = ffi.new("int[1]")
  162.     SizePtr[0] = ffi.sizeof(Address)
  163.  
  164.     if socket_wrapper.getsockname_(Socket, Addr, NameLen) == socket_wrapper.SOCKET_ERROR then
  165.         socket_wrapper.shutdown_(Socket, socket_wrapper.SD_BOTH)
  166.         socket_wrapper.closesocket_(Socket)
  167.         return nil
  168.     end
  169.  
  170.     local IP = socket_wrapper.inet_ntoa_(Address.sin_addr)
  171.     local Port = socket_wrapper.ntohs(Address.sin_port)
  172.     local Stream = setmetatable({
  173.         Socket = Socket,
  174.         LocalIP = ffi.string(IP),
  175.         LocalPort = Port
  176.     }, UDP)
  177.     return Stream
  178. end
  179.  
  180. function CloseUDPStream(Stream)
  181.     return Stream and Stream:Close()
  182. end
  183.  
  184. function RecvUDPMsg(Stream)
  185.     if not Stream or Stream.Socket == socket_wrapper.INVALID_SOCKET then
  186.         return false
  187.     end
  188.  
  189.     if socket_wrapper.select_(1, Stream.Socket, 0, nil, 0, nil, self.Timeout) ~= 1  then
  190.         return false
  191.     end
  192.  
  193.     local Size = ffi.new("int", 0)
  194.     if socket_wrapper.ioctl_(Stream.Socket, socket_wrapper.FIONREAD, Size) == socket_wrapper.SOCKET_ERROR then
  195.         return false
  196.     end
  197.  
  198.     if Size <= 0 then
  199.         return false
  200.     end
  201.  
  202.     if Stream.RecvSize > 0 then
  203.         local Temp = ffi.alloc(Stream.RecvSize + Size)
  204.         ffi.copy(Temp, Stream.RecvBuffer, Stream.RecvSize)
  205.         ffi.free(Stream.RecvBuffer)
  206.         Stream.RecvBuffer = Temp
  207.     else
  208.         Stream.RecvBuffer = ffi.alloc(Size)
  209.     end
  210.  
  211.     local MessageIP = ffi.new("int", 0)
  212.     local MessagePort = ffi.new("int", 0)
  213.     local Result = socket_wrapper.recvfrom_(Stream.Socket, Stream.RecvBuffer + Stream.RecvSize, Size, 0, MessageIP, MessagePort)
  214.  
  215.     if Result == socket_wrapper.SOCKET_ERROR or Result == 0 then
  216.         return nil
  217.     else
  218.         Stream.MessageIP = MessageIP
  219.         Stream.MessagePort = MessagePort
  220.         Stream.RecvSize = Stream.RecvSize + Result
  221.         return MessageIP
  222.     end
  223. end
  224.  
  225. function SendUDPMsg(Stream, IP, Port)
  226.     if not Stream or Stream.Socket == socket_wrapper.INVALID_SOCKET or Stream.SendSize == 0 then
  227.         return nil
  228.     end
  229.  
  230.     if socket_wrapper.select_(0, nil, 1, Stream.Socket, 0, nil, 0) ~= 1 then
  231.         return nil
  232.     end
  233.  
  234.     if not Port or Port == 0 then
  235.         Port = Stream.LocalPort
  236.     end
  237.  
  238.     local Result = socket_wrapper.sendto_(Stream.Socket, Stream.SendBuffer, Stream.SendSize, 0, IP, Port)
  239.     if Result == socket_wrapper.SOCKET_ERROR or Result == 0 then
  240.         return nil
  241.     end
  242.  
  243.     if Result == Stream.SendSize then
  244.         ffi.free(Stream.SendBuffer)
  245.         Stream.SendSize = 0
  246.     else
  247.         local Temp = ffi.alloc(Stream.SendSize - Result)
  248.         ffi.copy(Temp, Stream.SendBuffer + Result, Stream.SendSize - Result)
  249.         ffi.free(Stream.SendBuffer)
  250.         Stream.SendBuffer = Temp
  251.     end
  252. end
  253.  
  254. function UDPMsgIP(Stream)
  255.     return Stream and Stream.MessageIP
  256. end
  257.  
  258. function UDPMsgPort(Stream)
  259.     return Stream and Stream.MessagePort
  260. end
  261.  
  262. function UDPStreamIP(Stream)
  263.     return (Stream and Stream.Socket ~= socket_wrapper.INVALID_SOCKET) and Stream.LocalIP
  264. end
  265.  
  266. function UDPStreamPort(Stream)
  267.     return (Stream and Stream.Socket ~= socket_wrapper.INVALID_SOCKET) and Stream.LocalPort
  268. end
  269.  
  270. function UDPTimeouts(Recv)
  271.     if Recv >= 0 then
  272.         TUDPStream.Timeout = Recv
  273.     end
  274. end
  275.  
  276. TTCPStream = {
  277.     Timeouts = {
  278.         [0] = 10000,
  279.         [1] = 0
  280.     },
  281.     Socket = 0,
  282.     LocalIP = 0,
  283.     LocalPort = 0,
  284.     TCP = true
  285. }
  286. TCP = {__index = TTCPStream}
  287.  
  288. function TTCPStream:Connected()
  289.     if self.Socket == socket_wrapper.INVALID_SOCKET then
  290.         return false
  291.     end
  292.     if socket_wrapper.select_(1, self.Socket, 0, nil, 0, nil, 0) ~= 1 or ReadAvail(self) ~= 0 then
  293.         return true
  294.     end
  295.     self:Close()
  296.     return false
  297. end
  298.  
  299. function TTCPStream:Read(Buffer, Size)
  300.     if self.Socket == socket_wrapper.INVALID_SOCKET then
  301.         return 0
  302.     end
  303.  
  304.     if socket_wrapper.select_(1, self.Socket, 0, nil, 0, nil, self.Timeouts[0]) ~= 1 then
  305.         return 0
  306.     end
  307.  
  308.     local Result = socket_wrapper.recv_(self.Socket, self.Buffer, Size)
  309.     if Result == socket_wrapper.SOCKET_ERROR then
  310.         return 0
  311.     end
  312.     return Result
  313. end
  314.  
  315. function TTCPStream:Write(Buffer, Size)
  316.     if self.Socket == socket_wrapper.INVALID_SOCKET then
  317.         return 0
  318.     end
  319.  
  320.     if socket_wrapper.select_(1, nil, 1, self.Socket, 0, nil, 0) ~= 1 then
  321.         return 0
  322.     end
  323.  
  324.     local Result = socket_wrapper.send_(self.Socket, self.Buffer, Size, 0)
  325.     if Result == socket_wrapper.SOCKET_ERROR then
  326.         return 0
  327.     end
  328.     return Result
  329. end
  330.  
  331. function TTCPStream:Size()
  332.     local Size = ffi.new("int[1]")
  333.     if socket_wrapper.ioctl_(self.Socket, FIONREAD, Size) == socket_wrapper.SOCKET_ERROR then
  334.         return 0
  335.     end
  336.     return Size[0]
  337. end
  338.  
  339. function TTCPStream:Eof()
  340.     if self.Socket == socket_wrapper.INVALID_SOCKET then
  341.         return -1
  342.     end
  343.  
  344.     local Result = socket_wrapper.select_(1, self.Socket, 0, nil, 0, nil, self.Timeouts[0])
  345.     if Result == socket_wrapper.SOCKET_ERROR then
  346.         self:Close()
  347.         return -1
  348.     elseif Result == 1 then
  349.         if self:Size() == 0 then
  350.             return -1
  351.         end
  352.         return 0
  353.     end
  354.     return 1
  355. end
  356.  
  357. function TTCPStream:Close()
  358.     if self.Socket ~= socket_wrapper.INVALID_SOCKET then
  359.         socket_wrapper.shutdown_(self.Socket, socket_wrapper.SD_BOTH)
  360.         socket_wrapper.closesocket_(self.Socket)
  361.         self.Socket = socket_wrapper.INVALID_SOCKET
  362.     end
  363. end
  364.  
  365. function TCPStreamConnected(Stream)
  366.     return Stream:Connected()
  367. end
  368.  
  369. function OpenTCPStream(Server, ServerPort, LocalPort)
  370.     if not LocalPort then
  371.         LocalPort = 0
  372.     end
  373.  
  374.     local ServerIP = socket_wrapper.inet_addr_(Server)
  375.     local PAddress
  376.     if ServerIP == socket_wrapper.INADDR_NONE then
  377.         local Addresses, AddressType, AddressLength = socket_wrapper.gethostbyname_(Server)
  378.         if not Addresses or AddressLength ~= 4 then
  379.             return nil
  380.         end
  381.         if not Addresses[0] then
  382.             return nil
  383.         end
  384.         PAddress = Addresses[0]
  385.         local ShlA = Shl(PAddress[3], 24)
  386.         local ShlB = Shl(PAddress[2], 16)
  387.         local ShlC = Shl(PAddress[1], 8)
  388.         ServerIP = ShlA or ShlB or ShlC or PAddress[0]
  389.     end
  390.  
  391.     local Socket = socket_wrapper.socket_(socket_wrapper.AF_INET, socket_wrapper.SOCK_STREAM, 0)
  392.     if Socket == socket_wrapper.INVALID_SOCKET then
  393.         return nil
  394.     end
  395.  
  396.     if socket_wrapper.bind_(Socket, socket_wrapper.AF_INET, LocalPort) == socket_wrapper.SOCKET_ERROR then
  397.         socket_wrapper.shutdown_(Socket, socket_wrapper.SD_BOTH)
  398.         socket_wrapper.closesocket_(Socket)
  399.         return nil
  400.     end
  401.  
  402.     local SAddress = ffi.new("struct sockaddr_in")
  403.     local Addr = ffi.cast("struct sockaddr *", SAddress)
  404.     local SizePtr = ffi.new("int[1]")
  405.     SizePtr[0] = ffi.sizeof(SAddress)
  406.  
  407.     if socket_wrapper.getsockname_(Socket, SAddress, NameLen) == socket_wrapper.SOCKET_ERROR then
  408.         socket_wrapper.shutdown_(Socket, socket_wrapper.SD_BOTH)
  409.         socket_wrapper.closesocket_(Socket)
  410.         return nil
  411.     end
  412.  
  413.     local IP = socket_wrapper.ntohl_(SAddress.sin_addr.s_addr)
  414.     local Port = socket_wrapper.ntohs_(SAddress.sin_port)
  415.     local Stream = setmetatable({
  416.         Socket = Socket,
  417.         LocalIP = ffi.string(IP),
  418.         LocalPort = Port
  419.     }, TCP)
  420.  
  421.     if socket_wrapper.connect_(Socket, ServerIP, socket_wrapper.AF_INET, 4, ServerPort) == socket_wrapper.SOCKET_ERROR then
  422.         socket_wrapper.shutdown_(Socket, socket_wrapper.SD_BOTH)
  423.         socket_wrapper.closesocket_(Socket)
  424.         return nil
  425.     end
  426.     return Stream
  427. end
  428.  
  429. function CloseTCPStream(Stream)
  430.     return Stream and Stream:Close()
  431. end
  432.  
  433. function CreateTCPServer(Port)
  434.     if not Port then
  435.         Port = 0
  436.     end
  437.  
  438.     local Socket = socket_wrapper.socket_(socket_wrapper.AF_INET, socket_wrapper.SOCK_STREAM, 0)
  439.     if Socket == socket_wrapper.INVALID_SOCKET then
  440.         return nil
  441.     end
  442.  
  443.     if socket_wrapper.bind_(Socket, socket_wrapper.AF_INET, Port) == socket_wrapper.SOCKET_ERROR then
  444.         socket_wrapper.shutdown_(Socket, socket_wrapper.SD_BOTH)
  445.         socket_wrapper.closesocket_(Socket)
  446.         return nil
  447.     end
  448.  
  449.     local SAddress = ffi.new("struct sockaddr_in")
  450.     local Addr = ffi.cast("struct sockaddr *", SAddress)
  451.     local SizePtr = ffi.new("int[1]")
  452.     SizePtr[0] = ffi.sizeof(SAddress)
  453.  
  454.     if socket_wrapper.getsockname_(Socket, Addr, SizePtr) == socket_wrapper.SOCKET_ERROR then
  455.         socket_wrapper.shutdown_(Socket, socket_wrapper.SD_BOTH)
  456.         socket_wrapper.closesocket_(Socket)
  457.         return nil
  458.     end
  459.  
  460.     local IP = socket_wrapper.inet_ntoa_(SAddress.sin_addr)
  461.     local Port = socket_wrapper.ntohs_(SAddress.sin_port)
  462.     local Stream = setmetatable({
  463.         Socket = Socket,
  464.         LocalIP = ffi.string(IP),
  465.         LocalPort = Port
  466.     }, TCP)
  467.  
  468.     if socket_wrapper.listen_(Socket, BNET_MAX_CLIENTS) == socket_wrapper.SOCKET_ERROR then
  469.         socket_wrapper.shutdown_(Socket, socket_wrapper.SD_BOTH)
  470.         socket_wrapper.closesocket_(Socket)
  471.         return nil
  472.     end
  473.     return Stream
  474. end
  475.  
  476. function AcceptTCPStream(Stream)
  477.     if not Stream or Stream.Socket == socket_wrapper.INVALID_SOCKET then
  478.         return nil
  479.     end
  480.  
  481.     local Read = ffi.new("int[1]", Stream.Socket)
  482.     if socket_wrapper.select_(1, Read, 0, nil, 0, nil, TTCPStream.Timeouts[1]) ~= 1 then
  483.         return nil
  484.     end
  485.  
  486.     local Address = ffi.new("struct sockaddr_in")
  487.     local Addr = ffi.cast("struct sockaddr *", Address)
  488.     local SizePtr = ffi.new("int[1]")
  489.     SizePtr[0] = ffi.sizeof(Address)
  490.  
  491.     local Result = socket_wrapper.accept_(Stream.Socket, Addr, SizePtr)
  492.     if Result == socket_wrapper.SOCKET_ERROR then
  493.         return nil
  494.     end
  495.  
  496.     local IP = socket_wrapper.inet_ntoa_(Address.sin_addr)
  497.     local Port = socket_wrapper.ntohs_(Address.sin_port)
  498.     local Client = setmetatable({
  499.         Socket = Result,
  500.         LocalIP = ffi.string(IP),
  501.         LocalPort = Port
  502.     }, TCP)
  503.     return Client
  504. end
  505.  
  506. function TCPStreamIP(Stream)
  507.     return Stream and Stream.LocalIP
  508. end
  509.  
  510. function TCPStreamPort(Stream)
  511.     return Stream and Stream.LocalPort
  512. end
  513.  
  514. function TCPTimeouts(Read, Accept)
  515.     if Read < 0 then Read = 0 end
  516.     if Accept < 0 then Accept = 0 end
  517.     TTCPStream.Timeouts[0] = Read
  518.     TTCPStream.Timeouts[1] = Accept
  519. end
  520.  
  521. us = CreateTCPServer(0)
  522. print("New server (TCP) port: "..TCPStreamPort(us))
  523. while true do
  524.     local cl = AcceptTCPStream(us)
  525.     if cl then
  526.         print("new client")
  527.         print("IP: "..TCPStreamIP(cl))
  528.         print("Port: "..TCPStreamPort(cl))
  529.     end
  530. end
Advertisement
Add Comment
Please, Sign In to add comment