Advertisement
billysback

Multinet

Nov 23rd, 2012
244
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.10 KB | None | 0 0
  1.  
  2. function split(str, pat)
  3.     local t = {}  -- NOTE: use {n = 0} in Lua-5.0
  4.     if str ~= nil then
  5.        local fpat = "(.-)" .. pat
  6.        local last_end = 1
  7.        local s, e, cap = str:find(fpat, 1)
  8.        while s do
  9.           if s ~= 1 or cap ~= "" then
  10.          table.insert(t,cap)
  11.           end
  12.           last_end = e+1
  13.           s, e, cap = str:find(fpat, last_end)
  14.        end
  15.        if last_end <= #str then
  16.           cap = str:sub(last_end)
  17.           table.insert(t, cap)
  18.        end
  19.     else
  20.         print("##ERROR failed to split ["..str.."] by:"..pat)
  21.     end
  22.     return t
  23. end
  24.  
  25. local function getTableSize(table)
  26.     local sz = 0
  27.     for k,v in pairs(table) do
  28.         sz = sz + 1
  29.     end
  30.     return sz
  31. end
  32.  
  33. function unformatTable(string, join)
  34.     return split(string, join)
  35. end
  36.  
  37. function formatTable(table, join, start)
  38.     if start == nil then start = 1 end
  39.     local str = ""
  40.     for i=start,#table do
  41.         if i == start then str = table[i] else str = str..join..table[i] end
  42.     end
  43.     return str
  44. end
  45.  
  46. function formatComplexTable(table, join, op)
  47.     local str = ""
  48.     for k,v in pairs(table) do
  49.         if type(v) ~= "function" and type(v) ~= "nil" then
  50.             if str == "" then
  51.                 str = k..op..v
  52.             else
  53.                 str = str..join..k..op..v
  54.             end
  55.         end
  56.     end
  57.     return str
  58. end
  59.  
  60. function unformatComplexTable(string, join, op)
  61.     local table = split(string, join)
  62.     local ntable = {}
  63.     for i=1,#table do
  64.         local splt = split(table[i], op)
  65.         if splt[1] ~= nil then
  66.             ntable[splt[1]] = splt[2]
  67.         end
  68.     end
  69.     return ntable
  70. end
  71.  
  72. function createServer(sname, sid)
  73.     local server = {
  74.         name = sname,
  75.         id = sid,
  76.         users = { },
  77.         data = { },
  78.         getPlayerList = function(self)
  79.             local list = {}
  80.             for k,v in pairs(self.users) do
  81.                 list[#list + 1] = k
  82.             end
  83.             return list
  84.         end,
  85.         sendPlayerList = function(self, player)
  86.             local p = self.users[player]
  87.             if p ~= nil then
  88.                 rednet.send(p[1], formatTable(self:getPlayerList(), "#@#"))
  89.             end
  90.         end,
  91.         getUsers = function(self)
  92.             return self.users
  93.         end,
  94.         addPlayer = function(self, player, id, data)
  95.             self:getUsers()[player] = {id, data}
  96.         end,
  97.         removePlayer = function(self, player)
  98.             local users = self.users
  99.             if users == nil then users = {} end
  100.             users[player] = nil
  101.             self.users = users
  102.         end,
  103.         addSData = function(self, name, info)
  104.             local data = self.data
  105.             if data == nil then data = {} end
  106.             data[name] = info
  107.             self.data = data
  108.         end,
  109.         getSData = function(self)
  110.             local val = self.data
  111.             if val ~= nil then
  112.                 val = formatComplexTable(val, "#@#", "#=#")
  113.                 return val
  114.             end
  115.             return nil
  116.         end,
  117.         getPlayer = function(self, id)
  118.             local users = self.users
  119.             if users == nil then users = {} end
  120.             for k,v in pairs(users) do
  121.                 if v[1] == id then return k end
  122.             end
  123.             self.users = users
  124.             return nil
  125.         end,
  126.         getID = function(self, player)
  127.             local users = self.users
  128.             if users == nil then users = {} end
  129.             local p = users[player]
  130.             if p ~= nil then return p[1] else
  131.                 return nil
  132.             end
  133.             self.users = users
  134.         end,
  135.         getData = function(self, player)
  136.             local users = self.users
  137.             if users == nil then users = {} end
  138.             local p = users[player]
  139.             if p ~= nil then return p[2] else
  140.                 return data
  141.             end
  142.             self.users = users
  143.         end,
  144.         setData = function(self, player, data)
  145.             local users = self.users
  146.             if users == nil then users = {} end
  147.             local p = users[player]
  148.             if p ~= nil then
  149.                 p[2] = data
  150.             end
  151.             self.users = users
  152.         end,
  153.         pingUsers = function(self, info)
  154.             local users = self.users
  155.             if users == nil then users = {} end
  156.             for k,v in pairs(users) do
  157.                 rednet.send(v[1], info)
  158.             end
  159.             self.users = users
  160.         end,
  161.         waitForCommand = function(self)
  162.             local id, message, distance = rednet.receive()
  163.             local users = self.users
  164.             if users == nil then users = {} end
  165.             local data = self.data
  166.             if data == nil then data = {} end
  167.            
  168.             local typ = nil
  169.             if id ~= nil then
  170.                 if message:sub(1, 5) == "JOIN " then
  171.                     local splt = split(message, " ")
  172.                     local name = formatTable(splt, " ", 2)
  173.                     users[name] = { id, {} }
  174.                     typ = 1
  175.                 elseif message == "LEAVE" then
  176.                     self:removePlayer(self:getPlayer(id))
  177.                     typ = 2
  178.                 elseif message == "GET_DATA" then
  179.                     if self:getPlayer(id) ~= nil then
  180.                         local player = self:getPlayer(id)
  181.                         local dat = self:getData(player)
  182.                         if dat ~= nil then
  183.                             rednet.send(id, formatTable(dat, "#@#"))
  184.                             typ = 3
  185.                         end
  186.                     end
  187.                 elseif message:sub(1, string.len("SET_DATA ")) == "SET_DATA " then
  188.                     local type = 11
  189.                     if self:getPlayer(id) ~= nil then
  190.                         local splt = split(message, " ")
  191.                         local ftabl = formatTable(splt, " ", 2)
  192.                         local table = unformatTable(ftabl, "#@#")
  193.                         if table ~= nil then
  194.                             self.setData(self, self:getPlayer(id), table)
  195.                             typ = 8
  196.                         end
  197.                     end
  198.                 elseif message == "GET_PLAYERLIST" then
  199.                     if self:getPlayer(id) ~= nil then
  200.                         local fmt = formatTable(self:getPlayerList(), "#@#")
  201.                         rednet.send(id, "PLS::"..fmt)
  202.                         typ = 4
  203.                     end
  204.                 elseif message == "@#@GET_NAME@#@" then
  205.                     rednet.send(id, "~S~"..self.name)
  206.                     typ = 5
  207.                 elseif message == "GET_SERVER_DATA" then
  208.                     if self:getPlayer(id) ~= nil then
  209.                         rednet.send(id, self:getSData())
  210.                         typ = 6
  211.                     end
  212.                 elseif message:sub(1, string.len("SET_SERVER_DATA@#@")) == "SET_SERVER_DATA@#@" then
  213.                     if self:getPlayer(id) ~= nil then
  214.                         local splt = split(message, "@#@")
  215.                         local piece = splt[3]
  216.                         local name = splt[2]
  217.                         if name == "#LEN#" then name = #data end
  218.                         if name == "#LEN+#" then name = #data + 1 end
  219.                         self:addSData(name, piece)
  220.                         typ = 7
  221.                     end
  222.                 end
  223.             end
  224.             if typ ~= nil then
  225.                 return tonumber(typ)
  226.             else
  227.                 return "INVALID"
  228.             end
  229.             self.users = users
  230.             self.data = data
  231.         end,
  232.     }
  233.     return server
  234. end
  235.  
  236. function createUser(uname, sname, uid, sid)
  237.     local user = {
  238.         name = uname,
  239.         id = uid,
  240.         server_name = sname,
  241.         server_id = sid,
  242.         joinServer = function(self)
  243.             rednet.send(self.server_id, "JOIN "..self.name)
  244.         end,
  245.         leaveServer = function(self)
  246.             rednet.send(self.server_id, "LEAVE")
  247.         end,
  248.         getPlayerList = function(self)
  249.             rednet.send(self.server_id, "GET_PLAYERLIST")
  250.             local id, message, distance = rednet.receive()
  251.             local typ = string.sub(message, 1, 5)
  252.             message = message:sub(6, -1)
  253.             local n = 1
  254.             while id ~= self.server_id and typ ~= "PLS::" and n < 20 do
  255.                 id, message, distance = rednet.receive()
  256.                 typ = string.sub(message, 1, 5)
  257.                 message = message:sub(6, -1)   
  258.                 n = n + 1
  259.             end
  260.             if n < 20 then
  261.                 return unformatTable(message, "#@#")
  262.             end
  263.             return nil
  264.         end,
  265.         getData = function(self)
  266.             rednet.send(self.server_id, "GET_DATA")
  267.             local id, message, distance = rednet.receive()
  268.             if id == self.server_id then
  269.                 return unformatTable(message, "#@#")
  270.             end
  271.             return nil
  272.         end,
  273.         setData = function(self, table)
  274.             rednet.send(self.server_id, "SET_DATA "..formatTable(table, "#@#", 1))
  275.         end,
  276.         getSData = function(self)
  277.             rednet.send(self.server_id, "GET_SERVER_DATA")
  278.             local id, message, distance = rednet.receive()
  279.             if id == self.server_id then
  280.                 return unformatComplexTable(message, "#@#", "#=#")
  281.             end
  282.             return nil
  283.         end,
  284.         setSData = function(self, name, piece)
  285.             rednet.send(self.server_id, "SET_SERVER_DATA@#@"..name.."@#@"..piece)
  286.         end,
  287.         waitForPing = function(self)
  288.             local id, message, distance = rednet.receive()
  289.             if id ~= nil and id == self.server_id then
  290.                 return message
  291.             end
  292.             return nil
  293.         end,
  294.         isFromServer = function(self, id)
  295.             return id == self.server_id
  296.         end,
  297.     }
  298.     return user
  299. end
  300.  
  301. function getServers()
  302.     local servers = {}
  303.     local n = 0
  304.     local i = 0
  305.     local ok = true
  306.     rednet.broadcast("@#@GET_NAME@#@")
  307.     while ok and i < 500 do
  308.         local id, message, distance = rednet.receive(2)
  309.         if id ~= nil then
  310.             local str = message:sub(1, 3)
  311.             if str == "~S~" then
  312.                 local sname = message:sub(4, -1)
  313.                 servers[sname] = id
  314.                 n = 0
  315.             else
  316.                 n = n + 1
  317.                 if n > 5 then ok = false end
  318.             end
  319.         else
  320.             ok = false
  321.         end
  322.         i = i + 1
  323.     end
  324.     return servers
  325. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement