Advertisement
Snusmumriken

RUDP parser

Sep 4th, 2017
208
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.18 KB | None | 0 0
  1. --[[                 first pack   last pack  need confirm
  2. local s = parser.encode{
  3.     flags = {         --flags:
  4.         fp = true,      -- first packet
  5.         lp = true,      -- last packet
  6.         ld = true,      -- need confirm (request or response for lost packets)
  7.         sm = true       -- service message
  8.     },
  9.     id =     math.random(999), -- id of message (x32)
  10.     count =  22,               -- count of parts in message (x32)
  11.     part =   21,               -- current part number (x32)
  12.     window = 4,                -- data-travel window size (N msgs per loop)
  13.     hash =   'qwer',           -- hash of message
  14.     data =   'yolooooo'        -- data of message
  15. }
  16. ]]
  17.  
  18. local byte = {}
  19. local insert = table.insert
  20. function byte.split(str, a, b)
  21.     if type(a) == 'table' then
  22.         local t = {}
  23.         local cursor = 0
  24.         for i = 1, #a do
  25.             t[i] = str:sub(cursor+1, cursor+a[i])
  26.             cursor = cursor + #(t[#t])
  27.         end
  28.         if b then return unpack(t) end
  29.         return t
  30.     end
  31.     a, b = a or 0, b or 1
  32.     return str:sub(a+1, a+b)
  33. end
  34.  
  35. local max_int = 2^8
  36. function byte.encode(num, len)
  37.     local char = string.char
  38.     if len and num > max_int^len - 1 then
  39.         error('Encode too big number: %d, max is %d', num, max^len)
  40.     end
  41.     local t={}
  42.     while num > 0 do
  43.         local rest = num % 255
  44.         t[#t + 1] = char(rest)
  45.         num = (num - rest) / 255
  46.     end
  47.     if len and #t < len then insert(t, ('\0'):rep(len - #t)) end
  48.     return table.concat(t)
  49. end
  50.  
  51. function byte.decode(c)
  52.     local insert = table.insert
  53.     local n = 0
  54.     c = c:reverse()
  55.     for j = 1, #c do
  56.         n = n + c:sub(j, j):byte()*255^(#c-j)
  57.     end
  58.     return n
  59. end
  60.  
  61. math.randomseed(os.time())
  62. local parser = {}
  63.  
  64. local h_max = 4228250624
  65. local h_const = 0.6180339887*16
  66. local floor, ceil = math.floor, math.ceil
  67.  
  68. function parser.hash(str, n)
  69.     local sum = 0
  70.     for i = 1, #str, ceil(#str / (n or 30)) do
  71.         sum = sum + str:sub(i, i):byte()
  72.     end
  73.     return floor(h_max * (sum * h_const % 1))
  74. end
  75.  
  76. local encode, decode = byte.encode, byte.decode
  77. local char, remove, split = string.char, table.remove, byte.split
  78. local sleep = require'socket'.sleep
  79.  
  80. --[[
  81.     encode table {
  82.         flags = {
  83.                 fp = true/false
  84.                 sp = true/false
  85.                 ld = true/false
  86.                 sm = true/false
  87.             },
  88.         id     = int,
  89.         count  = int,
  90.         part   = int,
  91.         window = int,
  92.         hash   = int,
  93.         data   = string
  94.     }
  95. ]]
  96.  
  97. print('DECODE QWER', decode('qwer'))
  98. local f_mask = {'fp', 'sp', 'ld', 'sm'}
  99. function parser.encode(m)
  100.     local encode = encode
  101.     local buffer = {}
  102.     local fl, _bit = 0, 128
  103.     for i = 1, #f_mask do
  104.         if m.flags[f_mask[i]] then
  105.             fl = fl + _bit
  106.         end
  107.         _bit = _bit * .5
  108.     end
  109.     buffer[1]  = 'R'                                 -- 1
  110.     buffer[2]  = string.char(fl)         -- 1
  111.     buffer[3]  = 'U'                                 -- 1
  112.     buffer[4]  = encode(m.id, 4)     -- 4
  113.     buffer[5]  = encode(m.count, 4)  -- 4
  114.     buffer[6]  = encode(m.part, 4)   -- 4
  115.     buffer[7]  = encode(m.window)    -- 1
  116.     buffer[8]  = 'D'                 -- 1
  117.     buffer[9]  = encode(m.hash, 4)   -- 4
  118.     buffer[10] = 'P'                 -- 1
  119.     buffer[11] = m.data              -- data
  120.     return table.concat(buffer)
  121. end
  122.  
  123. local sub = string.sub
  124. local c_mask = {[1] = 'R', [3] = 'U', [17] = 'D', [22] = 'P'}
  125.  
  126.  
  127. -- checking message as RUDP-packet
  128. function parser.check(data)
  129.     return data:sub(1,1)   == 'R' and data:sub(3,3)   == 'U'
  130.        and data:sub(17,17) == 'D' and data:sub(22,22) == 'P'
  131.          and data:sub(2, 2):byte() % 16 == 0
  132. end
  133.  
  134. -- R, U, D and P signs position
  135. local sign = {10, 8, 3, 1}
  136. -- order of flags in le-byte
  137. local d_flags = {'fp', 'sp', 'ld', 'sm'}
  138. function parser.decode(data, force)
  139.     if not parser.check(data) and not force then return end
  140.     local decode = decode
  141.    
  142.     local raw = byte.split(data, {1, 1, 1, 4, 4, 4, 1, 1, 4, 1})
  143.    
  144.     -- remove signature
  145.     remove(raw, 10)
  146.     remove(raw, 8)
  147.     remove(raw, 3)
  148.     remove(raw, 1)
  149.    
  150.     -- SUPER FLAG EXTRACTOR 6000
  151.     local buffer = {}
  152.     buffer.flags = {}
  153.    
  154.     local flag, base = decode(raw[1]), 128
  155.     for i, v in ipairs(d_flags) do
  156.         if flag - base >= 0 then
  157.             buffer.flags[v] = true
  158.             flag = flag - base
  159.         end
  160.         base = base * .5
  161.     end
  162.  
  163.     buffer.id = decode(raw[2])
  164.     buffer.count = decode(raw[3])
  165.     buffer.part = decode(raw[4])
  166.     buffer.window = decode(raw[5])
  167.     buffer.hash = decode(raw[6])
  168.     buffer.data = data:sub(23)
  169.     return buffer
  170. end
  171.  
  172. return parser
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement