TheOddByte

[ComputerCraft][MoarPeripherals] Teams

Aug 3rd, 2015
1,526
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --[[
  2.     [Program] MoarPeripherals - Teams
  3.     @version 1.0, 2015-08-03
  4.     @author TheOddByte
  5.    
  6.    
  7.     # Commands
  8.    
  9.     ##team help <-command>
  10.     ##team list
  11.     ##team create <name> <-password>
  12.     ##team join <name> <-password>
  13.     ##team say <text>
  14.     ##team info
  15.     ##team members
  16.     ##team removepassword
  17.     ##team setpassword <password>
  18.     ##team kick <username> <-reason>
  19.     ##team ban <username> <-reason>
  20.     ##team unban <username>
  21.     ##team disband confirm <-password>
  22. --]]
  23.  
  24.  
  25. local chatbox = peripheral.find( "chatbox_admin" ) or peripheral.find( "chatbox" )
  26. if not chatbox then
  27.     error( "No chatbox attached" )
  28. else
  29.     chatbox.setLabel( "Teams" )
  30. end
  31.  
  32.  
  33. --# Check if it's a regular or an admin chatbox
  34. if chatbox.setSayRange then
  35.     chatbox.setSayRange( -1 )
  36.     chatbox.setTellRange( -1 )
  37.     chatbox.setReadRange( -1 )
  38. end
  39.  
  40.  
  41. local autorestart  = true --# Should the program restart automatically?
  42. local time         = 5*60 --# The time of between backup creations( in seconds )
  43. local timer        = os.startTimer( time )
  44.  
  45.  
  46.  
  47. local users, teams = {}, {}
  48. local list = {
  49.     "help", "list", "create", "join", "info", "members", "say",
  50.     "kick", "ban", "unban", "disband", "setpassword", "removepassword",
  51. }    
  52.  
  53.  
  54. local function save( data, path )
  55.     local f = assert( fs.open( path, "w" ), "could not open file for writing" )
  56.     f.writeLine( textutils.serialize( data ) )
  57.     f.close()
  58. end
  59.  
  60.  
  61. local function load( path )
  62.     local f = assert( fs.open( path, "r" ), "could not open file for reading" )
  63.     local data = textutils.unserialize( f.readAll() )
  64.     f.close()
  65.     return data
  66. end
  67.  
  68. local function getLength( t )
  69.     local n = 0
  70.     for k, v in pairs( t ) do
  71.         n = n + 1
  72.     end
  73.     return n
  74. end
  75.  
  76. local function broadcast( username, team, message )
  77.     chatbox.setLabel( username )
  78.     for i = 1, #teams[team].users do
  79.         chatbox.tell( teams[team].users[i], message )
  80.     end
  81.     chatbox.setLabel( "Teams" )
  82. end
  83.  
  84.  
  85. local commands = {
  86.     ["help"] = {
  87.         description = "Lists all available commands";
  88.         action = function( username, ... )
  89.             local command
  90.             local tArgs = {...}
  91.             if #tArgs > 0 then
  92.                 for i = 1, #list do
  93.                     if tArgs[1]:lower() == list[i] then
  94.                         command = list[i]
  95.                         break
  96.                     end
  97.                 end
  98.             end
  99.             chatbox.tell( username, "Optional usage: ##team help <command>" )
  100.             chatbox.tell( username, "# Commands Available" )
  101.             local text = ""
  102.             for i = 1, #list do
  103.                 text = text .. list[i] .. ( i ~= #list and ", " or "" )
  104.             end
  105.             chatbox.tell( username, text )
  106.         end;
  107.     };
  108.     ["create"] = {
  109.         description = "Creates a new team";
  110.         action = function( username, ... )
  111.             local args = {...}
  112.             if #args >= 1 then
  113.                 if not users[username] then
  114.                     local name, password = unpack( args )
  115.                     if not teams[name] then
  116.                         teams[name] = {
  117.                             leader    = username;
  118.                             password  = password;
  119.                             users     = {username};
  120.                             blacklist = {};
  121.                         }
  122.                         users[username] = name;
  123.                         chatbox.tell( username, "Team successfully created" )
  124.                         if password then
  125.                             chatbox.tell( username, "Password set to: " .. password )
  126.                         end
  127.                     else
  128.                         chatbox.tell( username, "Team does already exist" )
  129.                     end
  130.                 else
  131.                     chatbox.tell( username, "You can't create a new team because you already belong to a team" )
  132.                 end
  133.             else
  134.                 chatbox.tell( username, "##team create <name> <-password>" )
  135.             end
  136.         end;
  137.     };
  138.     ["join"] = {
  139.         description = "Join a team";
  140.         action = function( username, ... )
  141.             local args = {...}
  142.             if #args >= 1 then
  143.                 local name, password = unpack( args )
  144.                 if not users[username] then
  145.                     if teams[name] then
  146.                         if teams[name].blacklist[username] then
  147.                             local reason = type( teams[name].blacklist[username] ) == "string" and teams[name].blacklist[username] or nil
  148.                             chatbox.tell( username, "You've been banned from this team " .. (reason and ("because of \"" .. reason .. "\"") or "" ) )
  149.                             return
  150.                         end
  151.                         local pass = teams[name].password
  152.                         if pass then
  153.                             if password then
  154.                                 if password == pass then
  155.                                     table.insert( teams[name].users, username )
  156.                                     users[username] = name;
  157.                                     chatbox.tell( username, "Successfully joined team!" )
  158.                                 else
  159.                                     chatbox.tell( username, "Invalid password" )
  160.                                 end
  161.                             else
  162.                                 chatbox.tell( username, "This team has a password" )
  163.                             end
  164.                         else
  165.                             table.insert( teams[name].users, username )
  166.                             users[username] = name;
  167.                             chatbox.tell( username, "Successfully joined team!" )
  168.                         end
  169.                     else
  170.                         chatbox.tell( username, "There's no such team" )
  171.                     end
  172.                 else
  173.                     chatbox.tell( username, "You're already in a team!" )
  174.                 end
  175.             else
  176.                 chatbox.tell( username, "##team join <name> <-password>" )
  177.             end
  178.         end;
  179.     };
  180.    
  181.     ["disband"] = {
  182.         description = "Disbands the team";
  183.         action = function( username, ... )
  184.             local args = {...}
  185.             if users[username] then
  186.                 local name = users[username]
  187.                 local text, password = unpack( args )
  188.                 if teams[name].leader == username then
  189.                     if text and text == "confirm" then
  190.                         local disband = false
  191.                         if teams[name].password then
  192.                             if password then
  193.                                 if password == teams[name].password then
  194.                                     disband = true
  195.                                 else
  196.                                     chatbox.tell( username, "Invalid password" )
  197.                                 end
  198.                             else
  199.                                 chatbox.tell( username, "You need to input the password in order to disband the team" )
  200.                             end
  201.                         else
  202.                             disband = true
  203.                         end
  204.                         if disband then
  205.                             broadcast( "Alert", name, username .. " has disbanded the team" )
  206.                             for _, user in ipairs( teams[name].users ) do
  207.                                 users[user] = nil
  208.                             end
  209.                             teams[name] = nil
  210.                         end
  211.                     else
  212.                         chatbox.tell( username, "You need to confirm that you want to disband the team, \"##disband confirm <-password>\"" )
  213.                     end
  214.                 else
  215.                     chatbox.tell( username, "You're not the leader of this team, only the leader can disband the team" )
  216.                 end
  217.             else
  218.                 chatbox.tell( "You're not in a team, what're you expecting to disband? .-." )
  219.             end
  220.         end
  221.     };
  222.    
  223.     ["say"] = {
  224.         description = "Say something to the team";
  225.         action = function( username, ... )
  226.             local args = {...}
  227.             if users[username] then
  228.                 if #args >= 1 then
  229.                     local text = ""
  230.                     for i = 1, #args do
  231.                         text = text .. args[i] .. " "
  232.                     end
  233.                     broadcast( username, users[username], text )
  234.                 else
  235.                     chatbox.tell( username, "##team say <message>" )
  236.                 end
  237.             else
  238.                 chatbox.tell( username, "You're not in a team, no-one will hear you" )
  239.             end
  240.         end;
  241.     };
  242.    
  243.     ["info"] = {
  244.         description = "Show info about the current team";
  245.         action = function( username, ... )
  246.             local args = {...}
  247.             if users[username] then
  248.                 local team = teams[users[username]]
  249.                 chatbox.tell( username, "# Team info" )
  250.                 chatbox.tell( username, "Team name: " .. users[username] )
  251.                 chatbox.tell( username, "Team Leader: " .. team.leader )
  252.                 chatbox.tell( username, "Members: " .. #team.users )
  253.             else
  254.                 chatbox.tell( username, "You're not in a team, can not show any info" )
  255.             end
  256.         end;
  257.     };
  258.    
  259.     ["members"] = {
  260.         descriptions = "Shows all members in the current team";
  261.         action = function( username, ... )
  262.             local args = {...}
  263.             if users[username] then
  264.                 local team = teams[users[username]]
  265.                 local text = ""
  266.                 for _, user in ipairs( team.users ) do
  267.                     text = text .. user .. ", "
  268.                 end
  269.                 text = text:sub( 1, #text - 2 )
  270.                 chatbox.tell( username, "# Team Members" )
  271.                 chatbox.tell( username, text )
  272.             else
  273.                 chatbox.tell( username, "You're not in a team, can not show any info" )
  274.             end
  275.         end;
  276.     };
  277.    
  278.     ["removepassword"] = {
  279.         description = "Removes the password of the team";
  280.         action = function( username, ... )
  281.             if users[username] then
  282.                 local name = users[username]
  283.                 if teams[name].leader == username then
  284.                     broadcast( "Alert", name, username .. " has removed the password" )
  285.                     teams[name].password = nil
  286.                 else
  287.                     chatbox.tell( username, "You're not the leader of this team, only the leader can remove the password" )
  288.                 end
  289.             else
  290.                 chatbox.tell( username, "You don't belong to any team, don't expect to remove a password of something that doesn't exist" )
  291.             end
  292.         end;
  293.     };
  294.     ["setpassword"] = {
  295.         description = "Set/Change password of the team";
  296.         action = function( username, ... )
  297.             local args = {...}
  298.             local password = unpack( args )
  299.             if users[username] then
  300.                 local name = users[username]
  301.                 if teams[name].leader == username then
  302.                     if password then
  303.                         teams[name].password = password
  304.                         broadcast( "Alert", name, username .. " has changed the password" )
  305.                         chatbox.tell( username, "Password set to: " .. password )
  306.                     else
  307.                         chatbox.tell( username, "You need to specify a password, \"##team setpassword <password>\"" )
  308.                     end
  309.                 else
  310.                     chatbox.tell( username, "You're not the leader of this team, only the leader can change the password" )
  311.                 end
  312.             else
  313.                 chatbox.tell( username, "You don't belong to any team, so this command is pretty useless for you" )
  314.             end
  315.         end;
  316.     };
  317.    
  318.     ["kick"] = {
  319.         description = "Kicks a user from the team";
  320.         action = function( username, ... )
  321.             local args = {...}
  322.             local user = args[1]
  323.             local reason
  324.             if #args >= 2 then
  325.                 reason = ""
  326.                 for i = 2, #args do
  327.                     reason = reason .. args[i] .. " "
  328.                 end
  329.                 reason = reason:sub( 1, #reason - 1 )
  330.             end
  331.             if users[username] then
  332.                 local name = users[username]
  333.                 if teams[name].leader == username then
  334.                     if user then
  335.                         if users[user] and users[user] == name then
  336.                             if user == username then
  337.                                 chatbox.tell( username, "You can't kick yourself" )
  338.                             else
  339.                                 chatbox.tell( user, "You've been kicked from this team " .. (reason and ("because of \"" .. reason .. "\"") or "" ) )
  340.                                 for i = 1, #teams[name].users do
  341.                                     if teams[name].users[i] == user then
  342.                                         table.remove( teams[name].users, i )
  343.                                         break
  344.                                     end
  345.                                 end
  346.                                 broadcast( "Alert", name, username .. " has kicked " .. user .. " from the team " .. (reason and ("because of \"" .. reason .. "\"") or "" ) )
  347.                             end
  348.                         else
  349.                             chatbox.tell( username, "This user does not belong to this team" )
  350.                         end
  351.                     else
  352.                         chatbox.tell( username, "You need to specify a username" )
  353.                     end
  354.                 else
  355.                     chatbox.tell( username, "You're not the leader of this team, only the leader can kick people" )
  356.                 end
  357.             else
  358.                 chatbox.tell( username, "You don't belong to any team, so this command is pretty useless for you" )
  359.             end
  360.         end;
  361.     };
  362.    
  363.     ["ban"] = {
  364.         description = "Bans a user from the team";
  365.         action = function( username, ... )
  366.             local args = {...}
  367.             local user = args[1]
  368.             local reason
  369.             if #args >= 2 then
  370.                 reason = ""
  371.                 for i = 2, #args do
  372.                     reason = reason .. args[i] .. " "
  373.                 end
  374.                 reason = reason:sub( 1, #reason - 1 )
  375.             end
  376.             if users[username] then
  377.                 local name = users[username]
  378.                 if teams[name].leader == username then
  379.                     if user then
  380.                         if users[user] and users[user] == name then
  381.                             if user == username then
  382.                                 chatbox.tell( username, "You can't ban yourself" )
  383.                             else
  384.                                 chatbox.tell( user, "You've been banned from this team " .. (reason and ("because of \"" .. reason .. "\"") or "" ) )
  385.                                 for i = 1, #teams[name].users do
  386.                                     if teams[name].users[i] == user then
  387.                                         table.remove( teams[name].users, i )
  388.                                         break
  389.                                     end
  390.                                 end
  391.                                 teams[name].blacklist[user] = type( reason ) == "string" and reason or true
  392.                                 broadcast( "Alert", name, username .. " has banned " .. user .. " from the team " .. (reason and ("because of \"" .. reason .. "\"") or "" ) )
  393.                             end
  394.                         else
  395.                             chatbox.tell( username, "This user does not belong to this team" )
  396.                         end
  397.                     else
  398.                         chatbox.tell( username, "You need to specify a username" )
  399.                     end
  400.                 else
  401.                     chatbox.tell( username, "You're not the leader of this team, only the leader can ban people" )
  402.                 end
  403.             else
  404.                 chatbox.tell( username, "You don't belong to any team, so this command is pretty useless for you" )
  405.             end
  406.         end;
  407.     };
  408.    
  409.     ["unban"] = {
  410.         description = "Unbans a user from the team";
  411.         action = function( username, ... )
  412.             local args = {...}
  413.             local user = args[1]
  414.             local reason
  415.             if #args >= 2 then
  416.                 reason = ""
  417.                 for i = 2, #args do
  418.                     reason = reason .. args[i] .. " "
  419.                 end
  420.                 reason = reason:sub( 1, #reason - 1 )
  421.             end
  422.             if users[username] then
  423.                 local name = users[username]
  424.                 if teams[name].leader == username then
  425.                     if user then
  426.                         if teams[name].blacklist[user] then
  427.                             chatbox.tell( user, "You've been unbanned from the team: \"" .. name .. "\"" )
  428.                             teams[name].blacklist[user] = false
  429.                             broadcast( "Alert", name, username .. " has unbanned " .. user .. " from the team " )
  430.                         else
  431.                             chatbox.tell( username, "This user does not belong to this team" )
  432.                         end
  433.                     else
  434.                         chatbox.tell( username, "You need to specify a username" )
  435.                     end
  436.                 else
  437.                     chatbox.tell( username, "You're not the leader of this team, only the leader can ban people" )
  438.                 end
  439.             else
  440.                 chatbox.tell( username, "You don't belong to any team, so this command is pretty useless for you" )
  441.             end
  442.         end;
  443.     };
  444.    
  445.     ["list"] = {
  446.         descriptions = "Lists all teams";
  447.         action = function( username, ... )
  448.             if getLength( teams ) > 0 then
  449.                 chatbox.tell( username, "# Teams Available" )
  450.                 local text = ""
  451.                 for k, v in pairs( teams ) do
  452.                     text = text .. k .. ", "
  453.                 end
  454.                 text = text:sub( 1, #text - 2 )
  455.                 chatbox.tell( username, text )
  456.             else
  457.                 chatbox.tell( username, "There are no teams, why don't you create one? \"##team create <name> <-password>\"" )
  458.             end
  459.         end
  460.     };
  461. }
  462.  
  463.  
  464. local function backup()
  465.     save( users, "teams-users.data" )
  466.     save( teams, "teams-teams.data" )
  467. end
  468.  
  469.  
  470. local function main()
  471.  
  472.     if fs.exists( "teams-users.data" ) then
  473.         users = load( "teams-users.data" )
  474.     end
  475.     if fs.exists( "teams-teams.data" ) then
  476.         teams = load( "teams-teams.data" )
  477.     end
  478.    
  479.     local key_commands = {
  480.         "join", "create", "kick", "ban", "unban", "disband", "setpassword", "removepassword",
  481.     }
  482.    
  483.     while true do
  484.        
  485.         local e = { os.pullEvent() }
  486.        
  487.         if e[1] == "chatbox_command" then
  488.             local username, command  = e[3], e[4]:match( "^%s*team%s+(.+)$" )
  489.             if command ~= nil and command ~= "" then
  490.                 local args = {}
  491.                 for arg in command:gmatch( "%S+" ) do
  492.                     table.insert( args, arg )
  493.                 end
  494.                 command = args[1]:lower()
  495.                 table.remove( args, 1 )
  496.                 if commands[command] then
  497.                     commands[command].action( username, unpack( args ) )
  498.                 else
  499.                     chatbox.tell( username, "Invalid command, try \"help\" for a list of commands" )
  500.                 end
  501.                 for i, v in ipairs( key_commands ) do
  502.                     if command == v then
  503.                         backup()
  504.                         break
  505.                     end
  506.                 end
  507.             else
  508.                 if e[4] == "team" then
  509.                     chatbox.tell( username, "Usage" )
  510.                     chatbox.tell( username, "##team <command> <...>" )
  511.                     chatbox.tell( username, "# Commands Available" )
  512.                     local text = ""
  513.                     for i = 1, #list do
  514.                         text = text .. list[i] .. ( i ~= #list and ", " or "" )
  515.                     end
  516.                     chatbox.tell( username, text )
  517.                 end
  518.             end
  519.            
  520.         elseif e[1] == "timer" and e[2] == timer then
  521.             backup()
  522.             timer = os.startTimer( time )
  523.         end
  524.     end
  525. end
  526.  
  527.  
  528.  
  529. if autorestart then
  530.     while true do
  531.         term.clear()
  532.         term.setCursorPos( 1, 1 )
  533.         print( "MoarPeripherals - Teams" )
  534.         local ok, err = pcall( main )
  535.     end
  536. else
  537.     term.clear()
  538.     term.setCursorPos( 1, 1 )
  539.     print( "MoarPeripherals - Teams" )
  540.     local ok, err = pcall( main )
  541.     if not ok and err ~= "Terminated" then
  542.         term.clear()
  543.         term.setCursorPos( 1, 1 )
  544.         printerror( "An unexpected error occured: " .. err )
  545.     end
  546. end
RAW Paste Data