Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Script to interact with ME Bridge via Chat Box commands
- -- Version: 1.14 (Startup msg change, Purple brackets, + Prev Features)
- -- ================== Configuration ==================
- local allowedPrefixes = {
- "!",
- "hey ada " -- Lowercase for case-insensitive check
- }
- local initialAdminUser = "YourMinecraftUsername" -- !! SET THIS TO YOUR USERNAME !!
- local userDbFilename = "user_db.txt"
- local listallFilename = "item_list.txt"
- local wisdomFilename = "wisdoms.txt"
- local wisdomPastebinId = "wPKJMFkN"
- local maxAmbiguityOptions = 3
- -- Permission Levels
- local LEVEL_ADMIN = "admin"
- local LEVEL_USER = "user"
- -- ================== Global Variables ==================
- local users = {}
- local itemNameLookup = nil
- local displayNameLookup = nil
- local wisdomList = {}
- local buildError = nil
- local chatBox = nil
- local bridge = nil
- -- ================== Helper Functions ==================
- -- Updated reply function: Uses purple "&5Ada&r" prefix and purple brackets
- local function reply(message)
- if chatBox then
- os.sleep(0.5)
- -- Use &5 for purple prefix name, &r to reset color after name.
- -- Add "[]" as brackets argument, and "&5" as bracketColor argument.
- chatBox.sendMessage(message, "&5Ada&r", "[]", "&5")
- else
- print("Error: Chat Box not available.")
- end
- end
- -- (loadUsers, saveUsers, addToLookup, buildItemDatabase, resolveItemName, updateWisdomsFromPastebin, loadWisdoms functions remain the same as v1.11/v1.13 - condensed)
- local function saveUsers() local sU,err=textutils.serialize(users);if not sU then print("Serialize Err:"..(err or"?"));reply("CRIT ERR:Save User Prep Fail.");return false end;local f,fE=fs.open(userDbFilename,"w");if not f then print("File Open Err:"..(fE or"?"));reply("CRIT ERR:Save User DB Open Fail.");return false end;f.write(sU);f.close();print("User DB saved.");return true end
- local function loadUsers() if not fs.exists(userDbFilename)then print("User DB ('"..userDbFilename.."') missing. Creating...");users={};if initialAdminUser and initialAdminUser~=""then print("Adding admin:"..initialAdminUser);users[initialAdminUser]=LEVEL_ADMIN;if not saveUsers()then print("CRIT:Fail initial save!")end else print("Warn:No initial admin.");reply("Warn:User DB empty.")end;return end;local f,fE=fs.open(userDbFilename,"r");if not f then print("File Open Err:"..(fE or"?"));reply("ERR:Load User DB Fail.");users={};return end;local sU=f.readAll();f.close();if sU==""then print("User DB empty.");users={};if initialAdminUser and initialAdminUser~=""then users[initialAdminUser]=LEVEL_ADMIN;if not saveUsers()then print("CRIT:Fail initial save!")end end;return end;local ok,lD=pcall(textutils.unserialize,sU);if not ok or type(lD)~="table"then print("Unserialize Err:"..(lD or"?"));reply("ERR:Load User Data Fail.");users={};else users=lD;print("User DB loaded("..table.maxn(users).." users).")end end
- local function addToLookup(lS,lD,d) if d and d.name then local fN=d.name;local sN=fN:match(".*:(.+)"); local dN=d.displayName; if sN then sN=sN:lower();if not lS[sN]then lS[sN]={}end;local fS=false;for _,eN in ipairs(lS[sN])do if eN==fN then fS=true;break end end;if not fS then table.insert(lS[sN],fN)end end; if dN then dN=dN:lower():gsub("^%s*%[",""):gsub("%]%s*$",""):gsub("^%s*(.-)%s*$","%1");if dN~=""then if not lD[dN]then lD[dN]={}end;local fD=false;for _,eN in ipairs(lD[dN])do if eN==fN then fD=true;break end end;if not fD then table.insert(lD[dN],fN)end end end end end
- local function buildItemDatabase(b) print("Building DB...");buildError=nil;local lS,lD,sC={},{},0; local sI,sE=b.listItems();if sI then print("Proc stored...");for _,d in ipairs(sI)do addToLookup(lS,lD,d)end;sC=sC+1 else print("Warn:Stored fail:"..(sE or "?"));buildError=(buildError and buildError.."; "or"").."Fail stored" end; local cI,cE=b.listCraftableItems();if cI then print("Proc craftable...");for _,d in ipairs(cI)do addToLookup(lS,lD,d)end;sC=sC+1 else print("Warn:Craftable fail:"..(cE or "?"));buildError=(buildError and buildError.."; "or"").."Fail craftable" end; if sC>0 then print("DB built.");if sC==1 then print("Warn:DB incomplete.")end else print("Error:Failed DB build.")end;return lS,lD end
- local function resolveItemName(uIn) if buildError and not itemNameLookup and not displayNameLookup then return nil,"DB build fail:"..buildError end;if not itemNameLookup or not displayNameLookup then return nil,"Item DB not built/empty."end;if uIn:find(":")then return uIn,nil end;local iL=uIn:lower();local sM=itemNameLookup[iL];if sM and #sM==1 then return sM[1],nil end;local dM=displayNameLookup[iL];if dM and #dM==1 then return dM[1],nil end;local cmb,add={}, {};if sM then for _,n in ipairs(sM)do if not add[n]then table.insert(cmb,n);add[n]=true end end end;if dM then for _,n in ipairs(dM)do if not add[n]then table.insert(cmb,n);add[n]=true end end end;if #cmb==0 then return nil,"Item '"..uIn.."' not found."elseif #cmb==1 then return cmb[1],nil else local p={};for i=1,math.min(#cmb,maxAmbiguityOptions)do table.insert(p,cmb[i])end;local msg="Ambiguous:'"..uIn.."'. Try:"..table.concat(p,", ")..". Be specific.";return nil,msg end end
- local function updateWisdomsFromPastebin() if not wisdomPastebinId or wisdomPastebinId==""or wisdomPastebinId=="YOUR_ID_HERE"then print("Pastebin ID skip.");return false,"Pastebin ID not set."end; local tmp="wisdom_temp.txt";print("Downloading wisdom "..wisdomPastebinId.."..."); if not http then print("ERR:HTTP disabled.");return false,"HTTP disabled."end; local ok=shell.run("pastebin","get",wisdomPastebinId,tmp); if not ok then print("ERR:Pastebin DL fail.");fs.delete(tmp);return false,"Pastebin DL fail."end; print("DL OK. Appending..."); local tmpF,tmpE=fs.open(tmp,"r"); if not tmpF then print("ERR open tmp:"..(tmpE or"?"));fs.delete(tmp);return false,"Open DL fail."end; local mainF,mainE=fs.open(wisdomFilename,"a"); if not mainF then print("ERR open main:"..(mainE or"?"));tmpF.close();fs.delete(tmp);return false,"Open wisdom fail."end; local lines=0; while true do local l=tmpF.readLine();if l==nil then break end;l=l:match("^%s*(.-)%s*$");if l~=""then mainF.writeLine(l);lines=lines+1 end end; mainF.close();tmpF.close();fs.delete(tmp);print("Appended "..lines.." wisdoms."); return true,"Appended "..lines.." wisdoms." end
- local function loadWisdoms() print("Loading wisdoms from "..wisdomFilename.."...");wisdomList={}; if not fs.exists(wisdomFilename)then print("Warn:Wisdom file missing.");reply("Warn:wisdoms.txt missing.");return end; local f,err=fs.open(wisdomFilename,"r");if not f then print("Err open wisdom:"..(err or"?"));reply("Err:Open wisdom fail.");return end; local lN=0;while true do local l=f.readLine();if l==nil then break end;l=l:match("^%s*(.-)%s*$");if l~=""then table.insert(wisdomList,l);lN=lN+1 end end;f.close();print("Loaded "..lN.." wisdoms.");if lN==0 then reply("Warn:wisdoms.txt empty.")end end
- -- ================== Main Script Execution ==================
- print("Ada Script Initializing...") -- Changed name here too
- print("Attempting to find peripherals...")
- chatBox = peripheral.find("chatBox")
- bridge = peripheral.find("meBridge")
- if not chatBox then print("CRIT ERR: Chat Box not found!"); return end
- if not bridge then print("CRIT ERR: ME Bridge not found!"); reply("CRIT ERR: ME Bridge not found."); return end
- print("Peripherals found successfully.")
- loadUsers()
- local updated, updateMsg = updateWisdomsFromPastebin(); if not updated then reply("Warn: Wisdom update fail: " .. updateMsg) end
- itemNameLookup, displayNameLookup = buildItemDatabase(bridge)
- loadWisdoms()
- if buildError then reply("Warning: " .. buildError .. ". Name resolution may fail.") end
- print("Initialization complete. Listening...")
- -- *** CHANGED Startup Message ***
- reply("All Systems running." .. (buildError and " (Warning: Item DB incomplete)" or "")) -- Public reply
- -- ================== Main Event Loop ==================
- while true do
- local eventData = {os.pullEvent()}
- local eventType = eventData[1]
- if eventType == "chat" then
- local username=eventData[2]; local message=eventData[3]; local isHidden=eventData[5]
- if not isHidden then
- local matchedPrefix = nil; local originalMatchedPrefix = nil
- local messageLower = message:lower()
- for _, prefix in ipairs(allowedPrefixes) do
- if messageLower:sub(1, #prefix) == prefix:lower() then
- matchedPrefix = prefix:lower(); originalMatchedPrefix = prefix; break
- end
- end
- if matchedPrefix then
- if not users[username] then print("Denied unregistered: "..username); reply("Access Denied."); goto continue end
- local userLevel = users[username]; print("Cmd '" .. message .. "' from " .. username .. " (" .. userLevel .. ")")
- local commandPart = message:sub(#originalMatchedPrefix + 1)
- local cmdName = commandPart:match("^%s*([^%s]+)") or ""; cmdName = cmdName:lower()
- local remainingArgs = commandPart:match("^%s*[^%s]+%s+(.*)") or ""
- -- === Command Handling ===
- if cmdName == "help" then local hM="Cmds: help, status, list <item>, listall, craft <#><item>, iscraftable <item>, rebuilddb, wisdom"; if userLevel==LEVEL_ADMIN then hM=hM..", user <add|rm|list>, updatewisdoms" end; reply(hM)
- -- Admin commands
- elseif cmdName == "user" then if userLevel~=LEVEL_ADMIN then reply("Perm Denied: Admin.") else local sC=remainingArgs:match("^%s*([^%s]+)")or""; local sA=remainingArgs:match("^%s*[^%s]+%s+(.*)")or""; sC=sC:lower(); if sC=="add" then local n,l=sA:match("^%s*([^%s]+)"),sA:match("^%s*[^%s]+%s+([^%s]+)")or LEVEL_USER; l=l:lower(); if not n then reply("Use: user add <n> [admin|user]")elseif l~=LEVEL_ADMIN and l~=LEVEL_USER then reply("Bad lvl.")elseif users[n] then reply("User exists.")else users[n]=l;if saveUsers()then reply("User "..n.." added("..l..").")else reply("ERR: Save fail.");users[n]=nil end end elseif sC=="remove" then local n=sA:match("^%s*([^%s]+)"); if not n then reply("Use: user rm <n>")elseif not users[n] then reply("User not found.")else local aC=0;for _,l in pairs(users)do if l==LEVEL_ADMIN then aC=aC+1 end end;if users[n]==LEVEL_ADMIN and aC<=1 then reply("Cannot remove last admin.")else users[n]=nil;if saveUsers()then reply("User "..n.." removed.")else reply("ERR: Save fail.");users[n]="error"end end end elseif sC=="list" then local uL="Users:\n";local c=0;for n,l in pairs(users)do uL=uL.."- "..n.."("..l..")\n";c=c+1 end;if c==0 then reply("No users.")else reply(uL)end else reply("Use: user <add|rm|list>") end end
- elseif cmdName == "updatewisdoms" then if userLevel~=LEVEL_ADMIN then reply("Perm Denied: Admin.") else reply("Attempting manual wisdom update..."); local ok, msg = updateWisdomsFromPastebin(); if ok then loadWisdoms(); reply("Wisdom update finished: " .. msg) else reply("Wisdom update failed: " .. msg) end end
- -- User commands
- elseif cmdName == "wisdom" then if #wisdomList>0 then local rI=math.random(1,#wisdomList); reply(wisdomList[rI]) else reply("No wisdom found.") end -- Removed "Ada says: "
- elseif cmdName == "listall" then print("Getting items..."); reply("Saving list to " .. listallFilename); local allItems,err=bridge.listItems(); if allItems then local file,fE=fs.open(listallFilename,"w"); if not file then print("Err open: "..(fE or "?")); reply("Err saving.") else print("Saving..."); file.writeLine("--- Item List ---"); for _,d in ipairs(allItems) do file.writeLine(string.format("N:%s|DN:%s|A:%d",d.name or "?",d.displayName or "?",d.amount or 0)) end; file.writeLine("--- End List ---"); file.close(); print("Saved."); reply("Saved list.") end else print("Err list: "..(err or "?")); reply("Err listing.") end
- elseif cmdName == "rebuilddb" then reply("Rebuilding DB..."); itemNameLookup, displayNameLookup = buildItemDatabase(bridge); if buildError then reply("Warn: "..buildError) else reply("DB rebuilt.") end
- elseif cmdName == "status" then local e,mE,u,iS,iT=bridge.getEnergyStorage(),bridge.getMaxEnergyStorage(),bridge.getEnergyUsage(),bridge.getUsedItemStorage(),bridge.getTotalItemStorage(); reply(string.format("AE2 Status|E:%s/%s|Use:%s|Items:%s/%s bytes",tostring(e or "?"),tostring(mE or "?"),tostring(u or "?"),tostring(iS or "?"),tostring(iT or "?")))
- elseif (cmdName=="list" or cmdName=="iscraftable") and remainingArgs~="" then local uIn=remainingArgs; local rN,rE=resolveItemName(uIn); if not rN then reply(rE or "Resolve failed.") else if cmdName=="list" then local iD,err=bridge.getItem({name=rN}); if iD then reply(string.format("Item:%s(C:%s)Amt:%d(WARN!)",iD.displayName or rN,tostring(iD.isCraftable),(iD.amount or 0))) else local cr,cErr=bridge.isItemCraftable({name=rN}); if cr then reply(string.format("Item:%s(C:true)Amt:0(WARN!)",rN)) else reply("Item '"..rN.."' not found/err: "..(err or cErr or "?")) end end elseif cmdName=="iscraftable" then local cr,err=bridge.isItemCraftable({name=rN}); if err then reply("Err check "..rN..": "..err) else reply(rN.." is "..(cr and "craftable" or "not craftable")) end end end
- elseif cmdName == "craft" then local count=tonumber(remainingArgs:match("^%s*(%d+)%s+")); local uIn=remainingArgs:match("^%s*%d+%s+(.*)"); if not count or not uIn or uIn=="" then reply("Use: !craft <#> <item>") else local rN,rE=resolveItemName(uIn); if not rN then reply(rE or "Resolve failed.") elseif count<=0 then reply("Bad count.") else reply("Crafting "..count.." "..rN.."..."); os.sleep(0.1); local s,m=bridge.craftItem({name=rN,count=count}); if s then reply("Job started.") else reply("Job failed: "..(m or "?")) end end end
- else reply("Unknown cmd/args. Use '" .. (allowedPrefixes[1]:lower() or "?") .. "help'.") end
- end -- end if matchedPrefix
- end -- end if not isHidden
- end -- end if eventType == "chat"
- ::continue::
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement