Advertisement
Xemiru

xIRC_Server

Nov 28th, 2012
181
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 18.05 KB | None | 0 0
  1. ---- Check arguments.
  2.  
  3. local tArgs = { ... }
  4. local version = "v0.2"
  5. local revision = "rev130"
  6. if #tArgs > 3 or #tArgs < 1 then
  7.  print("Usage: ircserver <servername> <hidden [true/false]>")
  8.  return
  9. end
  10. if tArgs[2] ~= "true" and tArgs[2] ~= "false" then
  11.  print("Usage: ircserver <servername> <hidden [true/false]>")
  12.  return
  13. end
  14.  
  15. ---- Variables and functions for startup.
  16.  
  17. local susuccess = true
  18. local monitor
  19. local modemside
  20. local monitorside
  21. local serverpassword = ""
  22. local servername = tArgs[1]
  23. local hidden = tArgs[2]
  24.  
  25. local function printHeader(headerstring)
  26.  term.clear()
  27.  term.setCursorPos(1,1)
  28.  local tx,ty = term.getSize()
  29.  print(headerstring)
  30.  write(" ")
  31.  repeat
  32.   cx,cy = term.getCursorPos()
  33.   write("-")
  34.  until cx == tx - 1
  35.  term.setCursorPos(1,3)
  36. end
  37.  
  38. ---- Startup.
  39.  
  40. printHeader("xIRC Server "..version.." "..revision.." - Setup")
  41. write("Searching for a modem.")
  42. textutils.slowWrite("...", 1)
  43. sleep(1)
  44. term.setCursorPos(1,4)
  45.  
  46. for k,v in ipairs(rs.getSides()) do
  47.  if peripheral.getType(v) == "modem" then
  48.   print("Found a modem. Enabling rednet.")
  49.   modemside = v
  50.   break
  51.  end
  52. end
  53.  
  54. if modemside == nil then
  55.  print("Failed to find a modem.")
  56.  print("This requires a modem to function correctly.")
  57.  print("Terminating.")
  58.  sleep(3)
  59.  term.clear()
  60.  term.setCursorPos(1,1)
  61.  susuccess = false
  62.  return
  63. else
  64.  rednet.open(modemside)
  65. end
  66.  
  67. write("Searching for a monitor.")
  68. textutils.slowWrite("...", 1)
  69. sleep(1)
  70. term.setCursorPos(1,6)
  71.  
  72. for k,v in ipairs(rs.getSides()) do
  73.  if peripheral.getType(v) == "monitor" then
  74.   local monitor
  75.   monitor = peripheral.wrap(v)
  76.   tx, ty = monitor.getSize()
  77.   if tx < 45 or ty < 11 then
  78.    print("Found a monitor, but is too small.")
  79.    print("Minimum size for a monitor is 4x3.")
  80.    break
  81.   else
  82.    print("Found a monitor. Utilizing for logging.")
  83.    monitorside = v
  84.    break
  85.   end
  86.  end
  87. end
  88.  
  89. if monitorside == nil then
  90.  print("Failed to find a monitor.")
  91.  print("Disabling chat display.")
  92. end
  93.  
  94. print("Enter the password to access the server panel.")
  95. write(">> ")
  96. cx,cy = term.getCursorPos()
  97. serverpassword = read("*")
  98. term.setCursorPos(1, cy + 1)
  99. write("Setup complete, finalizing.")
  100. textutils.slowWrite("...", 1)
  101.  
  102. if susuccess == false then
  103.  return
  104. end
  105.  
  106. sleep(1)
  107.  
  108. ---- Interior Variables and Functions.
  109.  
  110. -- Command registration.
  111.  
  112. local commands = {}
  113. local commandusage = {}
  114. commands["help"] = "Show all commands or help for one command."
  115. commands["leave"] = "Leave the chat server."
  116. commands["online"] = "Show who's online."
  117. commands["realname"] = "Gets a person's real name."
  118. commands["nick"] = "Get an alternate name."
  119. commands["me"] = "Send your message in a 3rd person POV."
  120. commands["poke"] = "Poke a chatter."
  121. commands["afk"] = "Alert the server that you're AFK."
  122. commands["id"] = "Get your computer's, or someone else's Computer ID."
  123. commands["login"] = "Acknowledge your operator position."
  124. commands["kick"] = "[A] Kick a person from the server."
  125. commands["ban"] = "[A] Prevent entry of a computer."
  126. commands["unban"] = "[A] Allow entry of a banned computer."
  127. commands["mute"] = "[A] Enable/Disable a chatter's speech."
  128. commands["op"] = "[PA] Allow another chatter to become a server operator."
  129. commands["deop"] = "[PA] Remove a chatter's position from operator."
  130. commands["stop"] = "[PA] Terminate the server."
  131. commandusage["help"] = "/help [command]"
  132. commandusage["leave"] = "/leave"
  133. commandusage["online"] = "/online"
  134. commandusage["realname"] = "/realname <target's nick>"
  135. commandusage["nick"] = "/nick <new name>"
  136. commandusage["me"] = "/me <message>"
  137. commandusage["poke"] = "/poke <target>"
  138. commandusage["afk"] = "/afk"
  139. commandusage["id"] = "/id <target>"
  140. commandusage["login"] = "/login <password>"
  141. commandusage["kick"] = "/kick <target>"
  142. commandusage["ban"] = "/ban <target>"
  143. commandusage["mute"] = "/mute <target>"
  144. commandusage["op"] = "/op <target>"
  145. commandusage["deop"] = "/deop <target>"
  146. commandusage["stop"] = "/stop"
  147.  
  148. --
  149.  
  150. local banlist = {}
  151. local connected = {}
  152. local current = 0
  153.  
  154. local function validateCmd(command)
  155.  local isCorrect = false
  156.  for k,v in pairs(commands) do
  157.   if k == command then
  158.    isCorrect = true
  159.    break
  160.   end
  161.  end
  162.  
  163.  return isCorrect
  164. end
  165.  
  166. local function process(message)
  167.  local returned = {}
  168.  message:gsub("{(.-)}", function(word)
  169.   --Format: "{actiontype} {input}"
  170.   returned[#returned+1] = word
  171.  end)
  172.  
  173.  return unpack(returned)
  174. end
  175.  
  176. local function sendAction(target, actiontype, input)
  177.  if connected[target] ~= nil then
  178.   rednet.send(tonumber(connected[target].id), "{"..actiontype.."} {"..input.."}")
  179.  end
  180. end
  181.  
  182. local function broadcastAction(actiontype, input)
  183.  for k,v in pairs(connected) do
  184.   rednet.send(tonumber(v.id), "{"..actiontype.."} {"..input.."}")
  185.  end
  186. end
  187.  
  188. local function broadcast(message)
  189.  for k,v in pairs(connected) do
  190.   rednet.send(tonumber(v.id), "{message} {"..message.."}")
  191.  end
  192.  
  193.  if monitorside ~= nil then
  194.   print(message)
  195.  end
  196. end
  197.  
  198. local function sendMessage(target, message)
  199.  if connected[target] ~= nil then
  200.   rednet.send(tonumber(connected[target].id), "{message} {"..message.."}")
  201.  end
  202. end
  203.  
  204. local function getChatterData(sName)
  205.  local returned = {}
  206.  for k,v in pairs(connected) do
  207.   if string.lower(v.name) == string.lower(sName) then
  208.    returned = v
  209.    success = true
  210.    break
  211.   end
  212.  end
  213.  
  214.  return returned;
  215. end
  216.  
  217. local function getCommandType(command)
  218.  local cmdtype = ""
  219.  if command == "help" or command == "leave" or command == "nick" or command == "me" or command == "realname" or command == "poke" or command == "afk" or command == "id" or command == "login" then
  220.   cmdtype = "normal"
  221.  elseif command == "kick" or command == "ban" or command == "unban" or command == "mute" then
  222.   cmdtype = "mod"
  223.  elseif command == "op" or command == "deop" or command == "stop" then
  224.   cmdtype = "pmod"
  225.  end
  226.  
  227.  return cmdtype
  228. end
  229.  
  230. ---- Interior/Shutdown.
  231.  
  232. printHeader("xIRC Server "..version.." "..revision.." - Setup")
  233. print("Your server is now ready.")
  234. print("To access the panel, go on the server with a client and use /login <password>, the password being the one you entered during setup.")
  235.  
  236. if monitorside ~= nil then
  237.  monitor = peripheral.wrap(monitorside)
  238.  term.redirect(monitor)
  239.  term.clear()
  240.  term.setCursorPos(1,1)
  241.  term.setCursorBlink(true)
  242. end
  243.  
  244. while true do
  245.  event, sender, message = os.pullEventRaw()
  246.  if event == "rednet_message" then
  247.   local ssender = "-"..sender.."-"
  248.   local isOnline = true
  249.   local isNameDuplicate = false
  250.   local isBanned = false
  251.   local actiontype,input = process(message)
  252.  
  253.   if connected[ssender] == nil then
  254.    isOnline = false
  255.   end
  256.  
  257.   for k,v in pairs(connected) do
  258.    if actiontype == "join" and input == tostring(v.name) then
  259.     isNameDuplicate = true
  260.    end
  261.   end
  262.  
  263.   for k,v in pairs(banlist) do
  264.    if k == input then
  265.     isBanned = true
  266.    end
  267.   end
  268.  
  269.   if connected[ssender] ~= nil then
  270.    if connected[ssender].isAfk == true then
  271.     connected[ssender].isAfk = false
  272.     broadcast("[Sys> "..connected[ssender].nick.." is no longer AFK.")
  273.    end
  274.   end
  275.  
  276.   if actiontype == "finder" then
  277.    rednet.send(sender, "{"..servername.."} {"..hidden.."}")
  278.   elseif actiontype == "join" then
  279.    if isNameDuplicate == true then
  280.     sendAction(ssender, "result", "nameconflict")
  281.    elseif isOnline == true then
  282.     sendAction(ssender, "result", "idconflict")
  283.    elseif isBanned == true then
  284.     sendAction(ssender, "result", "banned")
  285.    else
  286.     rednet.send(sender, "{result} {j-success}")
  287.     connected[ssender] = {}
  288.     connected[ssender].name = input
  289.     connected[ssender].nick = input
  290.     connected[ssender].id = sender
  291.     connected[ssender].chatop = "none"
  292.     connected[ssender].muted = false
  293.     connected[ssender].isAfk = false
  294.     broadcast("[Sys> "..connected[ssender].name.." joined the chat.")
  295.     local sent = "[Sys> Online: "
  296.     for k,v in pairs(connected) do
  297.      sent = sent..connected[k].name..", "
  298.     end
  299.     sendMessage(ssender, string.sub(sent, 1, -3)..".")
  300.    end
  301.   elseif actiontype == "leave" then
  302.    if isOnline == true then
  303.     broadcast("[Sys> "..connected[ssender].name.." left the chat.")
  304.     connected[ssender] = nil
  305.    end
  306.   elseif actiontype == "message" then
  307.    if isOnline == true and connected[ssender].muted == false then
  308.     broadcast("["..connected[ssender].nick.."> "..input)
  309.    else
  310.     sendMessage(ssender, "[Sys> You are muted, and unable to speak.")
  311.    end
  312.   elseif actiontype == "command" then
  313.    if isOnline == true then
  314.     local command
  315.     local args = {}
  316.     local count = 1
  317.     local isMod = false
  318.     local isPMod = false
  319.     for word in input:gmatch("[%a%d]+") do
  320.      if count == 1 then
  321.       command = tostring(word)
  322.       count = count + 1
  323.      else
  324.       args[count-1] = word
  325.       count = count + 1
  326.      end
  327.     end
  328.     if connected[ssender].chatop == "m" or connected[ssender].chatop == "pm" then
  329.      isMod = true
  330.     end
  331.    
  332.     if connected[ssender].chatop == "pm" then
  333.      isPMod = true
  334.     end
  335.    
  336.     local commandtype = getCommandType(command)
  337.     if validateCmd(command) ~= true then
  338.      sendMessage(ssender, "[Sys> That command doesn't exist.")
  339.     end
  340.    
  341.     if command == "help" then
  342.      if #args == 0 then
  343.       sendMessage(ssender, "[Sys> Possible commands: ")
  344.       sendMessage(ssender, "[Sys> help, leave, nick, me,")
  345.       sendMessage(ssender, "[Sys> realname, poke, afk, id,")
  346.       sendMessage(ssender, "[Sys> login, kick, ban, unban,")
  347.       sendMessage(ssender, "[Sys> online, mute, op, deop, stop")
  348.       sendMessage(ssender, "[Sys> To know how to use these commands, type /help <command>.")
  349.      elseif #args == 1 then
  350.       if validateCmd(args[1]) == true then
  351.        sendMessage(ssender, "[Sys> "..commands[args[1]])
  352.       else
  353.        sendMessage(ssender, "[Sys> That command doesn't exist.")
  354.       end
  355.      else
  356.       sendMessage(ssender, "[Sys> Arguments insufficient or overflowing.")
  357.      end
  358.     elseif command == "nick" then
  359.      if #args == 1 then
  360.       connected[ssender].nick = args[1]
  361.       broadcast("[Sys> "..connected[ssender].name.."'s new display name is "..connected[ssender].nick..".")
  362.      else
  363.       sendMessage(ssender, "[Sys> Arguments insufficient or overflowing.")
  364.      end
  365.     elseif command == "realname" then
  366.      if #args == 1 then
  367.       if getChatterData(args[1]) ~= nil then
  368.        sendMessage(ssender, "[Sys> "..connected[ssender].nick.."'s real name is "..connected[ssender].name..".")
  369.       else
  370.        sendMessage(ssender, "[Sys> That player doesn't exist, or does not have data.")
  371.       end
  372.      else
  373.       sendMessage(ssender, "[Sys> Arguments insufficient or overflowing.")
  374.      end
  375.     elseif command == "me" then
  376.      local sent = ""
  377.      for k,v in ipairs(args) do
  378.       sent = sent.." "..v
  379.      end
  380.      
  381.      broadcast("* "..connected[ssender].nick..sent)
  382.     elseif command == "online" then
  383.      local sent = "[Sys> Online: "
  384.      for k,v in pairs(connected) do
  385.       sent = sent..connected[k].name..", "
  386.      end
  387.      sendMessage(ssender, string.sub(sent, 1, -3)..".")
  388.     elseif command == "poke" then
  389.      if #args == 1 then
  390.       if getChatterData(args[1]) ~= nil then
  391.        sendMessage("-"..getChatterData(args[1]).id.."-", "[Sys> "..connected[ssender].nick.." poked you.")
  392.        sendMessage(ssender, "[Sys> You poked "..getChatterData(args[1]).nick..".")
  393.       else
  394.        sendMessage(ssender, "[Sys> That player doesn't exist, or does not have data.")
  395.       end
  396.      else
  397.       sendMessage(ssender, "[Sys> Arguments insufficient or overflowing.")
  398.      end
  399.     elseif command == "afk" then
  400.      if connected[ssender].isAfk == false then
  401.       broadcast("[Sys> "..connected[ssender].nick.." went AFK.")
  402.       connected[ssender].isAfk = true
  403.      else
  404.       broadcast("[Sys> "..connected[ssender].nick.." is no longer AFK.")
  405.       connected[ssender].isAfk = false
  406.      end
  407.     elseif command == "id" then
  408.      if #args < 2 then
  409.       if #args == 1 then
  410.        if getChatterData(args[1]) ~= nil then
  411.         sendMessage(ssender, "[Sys> "..getChatterData(args[1]).nick.."'s computer ID is "..tostring(getChatterData(args[1]).id)..".")
  412.        else
  413.         sendMessage(ssender, "[Sys> That player doesn't exist, or does not have data.")
  414.        end
  415.       else
  416.        sendMessage(ssender, "[Sys> Your computer ID is "..tostring(connected[ssender].id)..".")
  417.       end
  418.      else
  419.       sendMessage(ssender, "[Sys> Arguments insufficient or overflowing.")
  420.      end
  421.     elseif command == "login" then
  422.      if #args == 1 then
  423.       if args[1] == serverpassword then
  424.        broadcast("[Sys> "..connected[ssender].nick.." is now registered as a server primary operator.")
  425.        connected[ssender].chatop = "pm"
  426.       else
  427.        sendMessage(ssender, "[Sys> Incorrect password.")
  428.       end
  429.      else
  430.       sendMessage(ssender, "[Sys> Arguments insufficient or overflowing.")
  431.      end
  432.     end
  433.    
  434.     if isMod == true then
  435.      if command == "ban" then
  436.       if #args == 1 then
  437.        if getChatterData(args[1]) ~= nil then
  438.         local sent = ""
  439.         for k,v in ipairs(args) do
  440.          if #args < 2 then
  441.           break
  442.          end
  443.          
  444.          if k ~= 1 then
  445.           sent = sent.." "..v
  446.          end
  447.         end
  448.        
  449.         if getChatterData(args[1]).chatop ~= "pm" and getChatterData(args[1]).chatop ~= "m" then
  450.          banlist[getChatterData(args[1]).name] = getChatterData(args[1]).id
  451.          sendAction("-"..getChatterData(args[1]).id.."-", "ban", sent)
  452.          broadcast("[Sys> "..getChatterData(args[1]).name.." has been banned from the server.")
  453.          broadcast("[Sys> Reason:"..sent)
  454.          connected["-"..getChatterData(args[1]).id.."-"] = nil
  455.         else
  456.          sendMessage(ssender, "[Sys> You may not ban other operators.")
  457.         end
  458.        else
  459.         sendMessage(ssender, "[Sys> That player doesn't exist, or does not have data.")
  460.        end
  461.       else
  462.        sendMessage(ssender, "[Sys> Arguments insufficient or overflowing.")
  463.       end
  464.      elseif command == "unban" then
  465.       if #args == 1 then
  466.        local success = false
  467.        for k,v in ipairs(banlist) do
  468.         if k == args[1] then
  469.          banlist[k] = nil
  470.          success = true
  471.         end
  472.        end
  473.        
  474.        if success == true then
  475.         broadcast("[Sys> "..args[1].."'s ban has been lifted.")
  476.        else
  477.         sendMessage(ssender, "[Sys> Unable to find ban data.")
  478.        end
  479.       else
  480.        sendMessage(ssender, "[Sys> Arguments insufficient or overflowing.")
  481.       end
  482.      elseif command == "kick" then
  483.       if #args == 1 then
  484.        if getChatterData(args[1]) ~= nil then
  485.         local sent = ""
  486.         for k,v in ipairs(args) do
  487.          if #args < 2 then
  488.           break
  489.          end
  490.          
  491.          if k ~= 1 then
  492.           sent = sent.." "..v
  493.          end
  494.         end
  495.        
  496.         if getChatterData(args[1]).chatop ~= "pm" and getChatterData(args[1]).chatop ~= "m" then
  497.          sendAction("-"..getChatterData(args[1]).id.."-", "kick", sent)
  498.          broadcast("[Sys> "..getChatterData(args[1]).name.." has been kicked from the server.")
  499.          broadcast("[Sys> Reason:"..sent)
  500.          connected["-"..getChatterData(args[1]).id.."-"] = nil
  501.         else
  502.          sendMessage(ssender, "[Sys> You may not kick other operators.")
  503.         end
  504.        else
  505.         sendMessage(ssender, "[Sys> That player doesn't exist, or does not have data.")
  506.        end
  507.       else
  508.        sendMessage(ssender, "[Sys> Arguments insufficient or overflowing.")
  509.       end
  510.      elseif command == "mute" then
  511.       if #args == 1 then
  512.        if getChatterData(args[1]) ~= nil then
  513.        else
  514.         sendMessage(ssender, "[Sys> That player doesn't exist, or does not have data.")
  515.        end
  516.       else
  517.        sendMessage(ssender, "[Sys> Arguments insufficient or overflowing.")
  518.       end
  519.      end
  520.     end
  521.    
  522.     if isPMod == true then
  523.      if command == "op" then
  524.       if #args == 1 then
  525.        if getChatterData(args[1]) ~= nil then
  526.         if getChatterData(args[1]).chatop == "pm" then
  527.          sendMessage(ssender, "[Sys> A Primary Operator is the highest op rank. You do not need to promote this person.")
  528.         else
  529.          getChatterData(args[1]).chatop = "m"
  530.          sendMessage(ssender, "[Sys> Successfully promoted "..getChatterData(args[1]).name.." permissions.")
  531.         end
  532.        else
  533.         sendMessage(ssender, "[Sys> Failed to promoted permissions. Is the target online?")
  534.        end
  535.       else
  536.        sendMessage(ssender, "[Sys> Arguments insufficient or overflowing.")
  537.       end
  538.      elseif command == "deop" then
  539.       if #args == 1 then
  540.        if getChatterData(args[1]) ~= nil then
  541.         if getChatterData(args[1]).chatop == "pm" then
  542.          sendMessage(ssender, "[Sys> You cannot revoke permissions of a Primary Operator.")
  543.         else
  544.          getChatterData(args[1]).chatop = "none"
  545.          sendMessage(ssender, "[Sys> Successfully revoked "..getChatterData(args[1]).name.." permissions.")
  546.         end
  547.        else
  548.         sendMessage(ssender, "[Sys> Failed to revoke permissions. Is the target online?")
  549.        end
  550.       else
  551.        sendMessage(ssender, "[Sys> Arguments insufficient or overflowing.")
  552.       end
  553.      elseif command == "stop" then
  554.       broadcastAction("terminate", "")
  555.       for k,v in ipairs(rs.getSides()) do
  556.        rednet.close(v)
  557.       end
  558.       term.clear()
  559.       term.restore()
  560.       term.clear()
  561.       term.setCursorPos(1,1)
  562.       print("[Sys> Server terminated.")
  563.       return
  564.      end
  565.     end
  566.    
  567.     if getCommandType(command) == "mod" then
  568.      if isMod == false then
  569.       sendMessage(ssender, "[Sys> This command requires Operator permissions.")
  570.      end
  571.     elseif getCommandType(command) == "pmod" then
  572.      if isPMod == false and isMod == false then
  573.       sendMessage(ssender, "[Sys> This command requires Primary Operator permissions.")
  574.      end
  575.     end
  576.    end
  577.   end
  578.  elseif event == "terminate" then
  579.   broadcastAction("terminate", "")
  580.   for k,v in ipairs(rs.getSides()) do
  581.    rednet.close(v)
  582.   end
  583.   term.clear()
  584.   term.restore()
  585.   term.clear()
  586.   term.setCursorPos(1,1)
  587.   print("[Sys> Server terminated.")
  588.   return
  589.  end
  590. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement