Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local peripheralList = peripheral.getNames()
- local modemside
- local modemPeripheral
- local chatPeripheral
- local tempList = {}
- local lastChatMessage = {}
- local lastChatNames = {}
- local fileHandler
- local eventHandler
- local keepRunning = true
- --Modify this if you want to rename your AI. It will then respond to that new name.
- --TODO: Add function to change name via commands
- local aiName = "OLLAND"
- --This is the original SysOp screenname that will always have permission via chat
- local sysOpName = "ERNA_VIDA"
- --[[
- Requires HTTPS to be enabled. Downloads a new program
- The program must always be named the same as the command you later want to use with it.
- IE: For the command "Olland tell time" the program must be named "TELLTIME"
- ]]
- function downloadNewSource(args)
- if shell.run("pastebin", "get", args[1], args[2]) then
- talk("Program "..args[2].." successfully downloaded.")
- else
- talk("Program "..args[2].." could not be downloaded.")
- end
- end --End downloadNewSource()
- --[[
- This adds a server to the list of ones olland has to call. Thiss isn't used in the core but can be useful for other programs.
- The computer info has to be set at the server and needs to be a table with keys "computerType" and "computerAlias".
- To get the AI ID its expected that a wireless modem be open and listening for a computer to send out a "AIREQNEWSERVER" message
- then replying with the serialized computer info table and waiting for the ACK message sent directly to it.
- ]]
- function addServer()
- if modemSide then
- rednet.open(modemSide)
- rednet.broadcast("AIREQNEWSERVER")
- local senderId, message, distance = rednet.receive(10)
- if message then
- sleep(1)
- rednet.send(senderId,"ACK")
- local replyTable = textutils.unserialize(message)
- local serverTable = loadTable("serverTable")
- if not serverTable[replyTable["computerType"]] then
- serverTable[replyTable["computerType"]] = {}
- end
- serverTable[replyTable["computerType"]][replyTable["computerAlias"]] = senderId
- saveTable("serverTable",serverTable)
- talk("A new server of type "..replyTable["computerType"].." with alias "..replyTable["computerAlias"].." has been added.")
- else
- talk("No new devices replied, no devices added.")
- end
- rednet.close(modemSide)
- else
- talk("I don't have a wireless modem to add servers with.")
- end
- end --End addServer()
- --Self explanatory. Uses either the attached miscperipherals chatbox or the console to talk.
- --TODO: Peripheral glasses support
- function talk(message)
- if chatPeripheral then
- chatPeripheral.say(aiName..": "..message)
- else
- print(aiName..": "..message.."\n")
- end
- end --End talk()
- --This is the part of the script that actually executes commands, first interpreting them
- function executeCommand(commandToExecute, arguments, requestorPermLevel)
- --These tables store the list of known aliases and the actual commands olland understands, respectively
- local commandsAliasing = loadTable("commandsAlias")
- local commandList = loadTable("commandList")
- --This will eventually (or in some caes currently do) store the actual comands and argument table Olland can work with
- local translatedCommand = string.upper(commandToExecute)
- local translatedArgs = arguments
- --This loops through de-aliasing commands until it reaches an actual command.
- --Aliased commands can themselves be aliased, but it still shouldn't go through this loop more than once
- --Aliased arguments will be inserted, with passed arguments inserted into blank spots in the aliased argument list
- while commandsAliasing and commandsAliasing[translatedCommand] do
- local commandTable = commandsAliasing[translatedCommand]
- local aliasedArgs = commandTable["args"]
- local tempArgs = textutils.unserialize(textutils.serialize(translatedArgs))
- local passedArgs = 1
- for i = 1, #aliasedArgs do
- if aliasedArgs[i] and not (aliasedArgs[i] == "") then
- translatedArgs[i] = aliasedArgs[i]
- else
- translatedArgs[i] = tempArgs[passedArgs]
- passedArgs = passedArgs + 1
- end
- end
- translatedCommand = commandTable["command"]
- end
- --The hard coded functions are called first, all require a permission level of 10 (SysOp)
- --See the function declarations for info
- if translatedCommand == "SHUTDOWN" and requestorPermLevel >= 10 then
- keepRunning = false
- talk("Goodbye.")
- elseif translatedCommand == "ADDUSER" and requestorPermLevel >= 10 then
- addUser(translatedArgs)
- elseif translatedCommand == "ADDSERVER" and requestorPermLevel >= 10 then
- addServer()
- elseif translatedCommand == "DOWNLOADNEWSOURCE" and requestorPermLevel >=10 then
- downloadNewSource(translatedArgs)
- elseif translatedCommand == "ADDCOMMAND" and requestorPermLevel >= 10 then
- addCommand(translatedArgs)
- elseif translatedCommand == "ADDCOMMANDALIAS" and requestorPermLevel >= 10 then
- --This de-aliases the command to be aliased, allowing users to alias already aliased commands
- --IE: "Tell time" is already aliased as "what time is it", but "what time is it" can be aliased
- --itself as "give me the time" and still work.
- while commandsAliasing and commandsAliasing[translatedArgs[1]] do
- local commandTable = commandsAliasing[translatedArgs[1]]
- local aliasedArgs = commandTable["args"]
- local tempArgs = textutils.unserialize(textutils.serialize(translatedArgs))
- local passedArgs = 3
- for i = 1, #aliasedArgs do
- if aliasedArgs[i] and not aliasedArgs[i] == "" then
- tempArgs[i + 2] = aliasedArgs[i]
- else
- tempArgs[i + 2] = translatedArgs[passedArgs]
- passedArgs = passedArgs + 1
- end
- end
- translatedArgs = tempArgs
- translatedArgs[1] = commandTable["command"]
- end
- addCommandAlias(translatedArgs)
- --This calls other programs and passes in the arguments specified if the user has appropriate permission
- --Also passes the requestor perm level so that some functions of the called program can be restricted based on that
- elseif commandList[translatedCommand] and requestorPermLevel >= commandList[translatedCommand] then
- if modemSide then
- rednet.open(modemSide)
- end
- talk(assert(loadfile(translatedCommand))(textutils.serialize(translatedArgs),requestorPermLevel))
- if modemSide then
- rednet.close(modemSide)
- end
- --These send a message if the command exists but the user doesn't have permission to it or the command doesn't exist
- elseif commandList[translatedCommand] and requestorPermLevel < commandList[translatedCommand] then
- talk("I'm afraid you don't have proper premission for that command.")
- else
- talk("I don't recognize that command")
- end
- commandsAliasing = {}
- end --End executeCommand
- --[[
- This adds a new function alias. This command needs to be called in the below format:
- aiName add command alias, command to alias, alias, alias arguments
- Alias arguments must include all arguments command to alias takes, with blanks left for arguments still expected
- IE: function1(arg1,arg2,arg3) could be aliased as "Olland add command alias, function1, alias name, 1,,3"
- When called later, it would be done as "Olland alias name, 2" which would be equivilent to "Olland function1,1,2,3"
- ]]
- function addCommandAlias(commandInfo)
- local commandList = loadTable("commandList")
- local commandsAliasing = loadTable("commandsAlias")
- if commandList and commandList[commandInfo[1]] then
- local argTable = {}
- for i = 1, #commandInfo do
- if i > 2 then
- argTable[i - 2] = commandInfo[i]
- end
- end
- commandsAliasing[commandInfo[2]] = {}
- commandsAliasing[commandInfo[2]]["command"] = commandInfo[1]
- commandsAliasing[commandInfo[2]]["args"] = argTable
- saveTable("commandsAlias",commandsAliasing)
- talk("Command \""..commandInfo[1].."\" aliased as \""..commandInfo[2].."\" successfully.")
- else
- talk("The command you're trying to alias does not seem to exist.")
- end
- end --End addCommandAlias()
- --[[
- This adds a new command. The file for the command must already exist
- The file for a command must be the command text with no spaces and all capitalized
- IE: Command "this command" must have an existing file "THISCOMMAND"
- The Second parameter must be a number representing the minimum permission level of a user to
- access this command.
- ]]
- function addCommand(commandToAdd)
- if fs.exists(commandToAdd[1]) and commandToAdd[2] then
- local commands = loadTable("commandList")
- commands[commandToAdd[1]] = tonumber(commandToAdd[2])
- saveTable("commandList",commands)
- talk("Command "..commandToAdd[1].." with permission level "..commandToAdd[2].." added successfully.")
- elseif not commandToAdd[2] then
- talk("You need to specify what permission level is acceptable for this.")
- else
- talk("The source code file for "..commandToAdd[1].." does not exist. No command added.")
- end
- end --End addCommand()
- --This is used to split up argument lists (though it will technically work on anything)
- --This returns a table of the split up values based on splitChar
- function splitArguments(stringToSplit, splitChar)
- if stringToSplit then
- local startSearch = 1
- local startSplit, endSplit = string.find(stringToSplit.."",splitChar,startSearch)
- local argsTable = {}
- local count = 1
- while startSplit do
- argsTable[count] = string.sub(stringToSplit.."",startSearch,startSplit - 1)
- startSearch = endSplit + 1
- startSplit, endSplit = string.find(stringToSplit.."",splitChar,startSearch)
- count = count + 1
- end
- argsTable[count] = string.sub(stringToSplit.."",startSearch)
- return argsTable
- else
- return {}
- end
- end --End splitArguments()
- --This is used to add a user with two arguments expected, username and permission level (as a number)
- --TODO: Consider moving this to a include file so it can be used across called applications
- function addUser(userToAdd)
- local userTable = loadTable("usersList")
- userTable[userToAdd[1]] = userToAdd[2]
- saveTable("userList",userTable)
- talk("User "..userToAdd[1].." has been added with a permission level of "..userToAdd[2]..".")
- end --End addUser()
- --This is called to save a table to a file
- --TODO: Consider moving this to a include file so it can be used across called applications
- function saveTable(fileName, sourceTable)
- fileHandler = fs.open(fileName, "w")
- fileHandler.write(textutils.serialize(sourceTable))
- fileHandler.close()
- end --End saveTable()
- --This is called to load a table from a file. Returns an empty table if the file does not exist
- function loadTable(fileName)
- if fs.exists(fileName) then
- fileHandler = fs.open(fileName, "r")
- local tableData = textutils.unserialize(fileHandler.readAll())
- fileHandler.close()
- return tableData
- else
- return {}
- end
- end --End loadTable()
- --This just scans for peripherals its expecting (wireless modem and a chatbox)
- --TODO: Add peripheral glasses bridge support
- for i = 1, #peripheralList do
- if peripheral.getType(peripheralList[i]) == "modem" and peripheral.call(peripheralList[i], "isWireless") then
- modemSide = peripheralList[i]
- modemPeripheral = peripheral.wrap(modemSide)
- elseif peripheral.getType(peripheralList[i]) == "chat" then
- chatPeripheral = peripheral.wrap(peripheralList[i])
- end
- end
- --Generic greeting on boot. Creative, right?
- talk("Greetings! Please let me know if you need anything.")
- --If the commandList file does not yet exist, create it with the built in commands
- --Essential to allow aliasing of the built in commands
- if (not fs.exists("commandList")) then
- local commandList = {}
- commandList["ADDUSER"] = 10
- commandList["ADDSERVER"] = 10
- commandList["ADDCOMMAND"] = 10
- commandList["ADDCOMMANDALIAS"] = 10
- commandList["DOWNLOADNEWSOURCE"] = 10
- commandList["SHUTDOWN"] = 10
- saveTable("commandList",commandList)
- end
- --The main loop of the program
- while keepRunning do
- --Either gets chat events or events directly to the console
- if chatPeripheral then
- event, lastChatNames[1], lastChatMessage[1], lastChatNames[2], lastChatMessage[2], lastChatNames[3], lastChatMessage[3], lastChatNames[4], lastChatMessage[4], lastChatNames[5], lastChatMessage[5] = os.pullEvent("chat")
- else
- print("Enter Command: ")
- lastChatNames[1] = "CONSOLE"
- lastChatMessage[1] = read()
- end
- local counter = 1
- --Gets the list of valid users
- tempTable = loadTable("userList")
- --Filters through the list of chat names from the last chat event
- while lastChatNames[counter] do
- --If anyone started a command with the aiName, checks to see if it should bother executing
- if string.upper(string.sub(lastChatMessage[counter],1,string.len(aiName))) == aiName then
- --Gets the actual command and breaks out the arguments
- local command = string.gsub(string.sub(lastChatMessage[counter],string.len(aiName)+1)," ","")
- local commaStart,commaEnd = string.find(command,",")
- local arguments = {}
- if commaEnd then
- commaEnd = commaEnd + 1
- local argString = string.upper(string.sub(command,commaEnd))
- arguments = splitArguments(argString,",")
- command = string.sub(command,1,commaStart - 1)
- end
- --Checks if the sysOp or a registered user made the request. If so, executes the command, if not, stops.
- if string.upper(lastChatNames[counter]) == sysOpName or string.upper(lastChatNames[counter]) == "CONSOLE" then
- executeCommand(command,arguments,10)
- elseif tempTable and tempTable[lastChatNames[counter]] then
- executeCommand(command,arguments,tempTable[lastChatNames[counter]])
- end
- arguments = {}
- end
- counter = counter + 1
- end
- --Clears the tables for the next run through the loop
- lastChatNames = {}
- lastChatMessage = {}
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement