diff --git a/installer.lua b/installer.lua index 654fb17..bb67c0f 100644 --- a/installer.lua +++ b/installer.lua @@ -202,14 +202,10 @@ return false end - local sData = response.readAll() - response.close() - - sData = sData:gsub("local installation = \"kristify\"", "local installation = \""..pathToInstall.."\"") - local file = fs.open("/kristify.lua", 'w') - file.write(sData) + file.write(response.readAll()) file.close() + response.close() for _=1,3 do status:addLine("") @@ -526,9 +522,13 @@ :setBackground(colors.green) :setForeground(colors.white) :onClick(function() + settings.define("kristiy.path", {definition="The location of Kristify's installation", type="string", default="kristify"}) + settings.set("kristify.path", pathToInstall) + settings.save() + local script = "shell.run(\"kristify.lua\")" - local file = "startKristify.lua" if checkbox:getValue() then + local file if fs.exists("/startup.lua") then file = fs.open("/startup.lua",'a') else diff --git a/kristify.lua b/kristify.lua index f896235..5ca6e0b 100644 --- a/kristify.lua +++ b/kristify.lua @@ -1,4 +1,4 @@ -local installation = "kristify" +local installation = settings.get("kristify.path") or "kristify" local owner,repo = "kristify","themes" local tArgs = {...} diff --git a/src/backend.lua b/src/backend.lua index d7aa72c..2ccdae4 100644 --- a/src/backend.lua +++ b/src/backend.lua @@ -13,18 +13,6 @@ logger:info("Starting Kristify! Thanks for choosing Kristify. <3") logger:debug("Debugging mode is enabled!") -if string.find(_HOST, "CraftOS-PC", 1, true) then - logger:error("CraftOS-PC detected. There is a bug in CraftOS-PC that makes kristify not work. This has been reported to the author.") - return -end - -if config == nil then - logger:error("Config not found! Check documentation for more info.") - return -end - -logger:debug("CraftOS-PC not detected") - local speaker = speakerLib:new({ config = config }) @@ -140,8 +128,7 @@ end end elseif data.type == "KRISTLY-ERROR" then - logger:error("Received kristly error: " .. data.error) - return + error("Received kristly error: " .. data.error) else logger:debug("Ignoring packet: " .. data.type) end diff --git a/src/frontend.lua b/src/frontend.lua index 14dd820..0f5a337 100644 --- a/src/frontend.lua +++ b/src/frontend.lua @@ -14,19 +14,17 @@ file.close() local func,err = load(data, path, "bt", _ENV) if not func then - ctx.logger:error("Could not load layout \'data/"..path..".lua\'! ("..err..")") - return + error("Could not load layout \'data/"..path..".lua\'! ("..err..")") end local success,obj = pcall(func,ctx,frame) if not success then - ctx.logger:error(obj) - return + error(obj) end frame:addObject(obj) elseif fs.exists(pathXML) then frame:addLayout(pathXML) else - ctx.logger:error("Layout \'data/"..path.."\' does not exist!") + error("Layout \'data/"..path.."\' does not exist!") end return frame end @@ -171,7 +169,7 @@ local titleEnd = base:getDeepObject("_title_end") if titleEnd then local _, nY = titleEnd:getPosition() - titleEnd:setPosition(nX + (math.floor(nW)*factor*1.5), nY) + titleEnd:setPosition(nX+(math.floor(nW*factor)), nY) end local watermark = base:getDeepObject("_watermark") diff --git a/src/init.lua b/src/init.lua index 0afe9c7..ba0e849 100644 --- a/src/init.lua +++ b/src/init.lua @@ -1,226 +1,227 @@ --- make a copy of package.path -local sSrc = fs.getDir(shell.getRunningProgram()) -local sRoot = fs.combine(sSrc, "..") -local sData = fs.combine(sRoot, "data") -local sPage = fs.combine(sData, "pages") +local sourcePath = fs.getDir(shell.getRunningProgram()) +local rootPath = fs.combine(sourcePath, "..") +local dataPath = fs.combine(rootPath, "data") +local pagesPath = fs.combine(dataPath, "pages") +local ctx = {} -local ctx +local function init() + ctx = { products = {}, theme = {}, config = {}, pages = {} } + ctx.path = { + page = pagesPath, + src = sourcePath, + data = dataPath + } -local nErrors = 0 -local function init(...) - -- [Context] - ctx = { products = {}, theme = {}, config = {}, pages = {} } - ctx.path = { - page = sPage, - src = sSrc, - data = sData - } + -- Logger + ctx.logger = require("logger"):new({ + debugging = settings.get("kristify.debug"), + log2file = settings.get("kristify.log2file") + }) - -- Logger - ctx.logger = require("logger"):new({ debugging = settings.get("kristify.debug"), - log2file = settings.get("kristify.log2file") }) + -- Pages + local pages = fs.list(pagesPath) + for i = 1, #pages do + local f = fs.open(fs.combine(pagesPath, pages[i]), 'r') + ctx.pages[pages[i]] = f.readAll() + f.close() + end - - -- [Pages] - local pages = fs.list(sPage) - for i = 1, #pages do - local f = fs.open(fs.combine(sPage, pages[i]), 'r') - ctx.pages[pages[i]] = f.readAll() - f.close() + -- Data + local function loadStr(str, begin, env) + if not begin then begin = "" end + local success, result = pcall(loadstring(begin .. str, "t", env)) + if success and type(result) == "table" then + return result end + return false + end - -- [Data] (config,theme,products, etc.) - local function loadStr(str, begin, env) - if not begin then begin = "" end - local success, result = pcall(loadstring(begin .. str, "t", env)) - if success and type(result) == "table" then - return result - end - return false - end - - local function loadLuaFile(path, env) - if fs.exists(path) and not fs.isDir(path) then - local f = fs.open(path, 'r') - local c = f.readAll() - f.close() - local result = loadStr(c, "", env) - if not result then - ctx.logger:error("Could not load \'" .. path .. "\' properly!\n" .. tostring(result)) - sleep(1) - end - return result - else - ctx.logger:error("Could not load \'" .. path .. "\'!") - sleep(0.5) - end - return false - end - - -- theme - local col = { white = 0x1, orange = 0x2, magenta = 0x4, lightBlue = 0x8, yellow = 0x10, lime = 0x20, pink = 0x40, - grey = 0x80, lightGrey = 0x100, cyan = 0x200, purple = 0x400, blue = 0x800, brown = 0x1000, green = 0x2000, - red = 0x4000, black = 0x8000 } - local inferiorcol = col; - inferiorcol.gray = col.grey; - inferiorcol.lightGray = col.lightGrey - local result = loadLuaFile(fs.combine(sPage, "theme.lua"), { colours = col, colors = inferiorcol }) - if result then - ctx.theme = result - end - -- config - result = loadLuaFile(fs.combine(sData, "config.lua")) - if result then - ctx.config = result - end - -- products - result = loadLuaFile(fs.combine(sData, "products.lua")) - if result then - ctx.products = result - end - - -- Set debug mode - settings.define("kristify.debug", { - description = "If kristify should be debugging", - default = false, - type = "boolean" - }) - - settings.define("kristify.log2file", { - description = "If kristify should log to a file", - default = false, - type = "boolean" - }) - - -- Load Basalt - local basalt = {} - if not fs.exists(fs.combine(ctx.path.src, "lib", "basalt")) then - local authenticate = _G._GIT_API_KEY and { Authorization = "Bearer " .. _G._GIT_API_KEY } - local basaltDL, err, errCode = http.get("https://raw.githubusercontent.com/Kristify/kristify/main/src/libs/basalt.lua" - , authenticate) - if not basaltDL then - ctx.logger:error("Couldn't load Basalt into memory! Reason: \'" .. - err .. "\' (code " .. errCode.getResponseCode() .. ')') - return - end - - basalt = load(basaltDL.readAll())() - basaltDL.close() - else - basalt = require("basalt") - end - ctx.basalt = basalt - - -- Load scripts - ctx.kristly = require(fs.combine("libs", "kristly")) - ctx.utils = require("utils") - ctx.webhooks = require("webhook") - - -- Check errors - local function bAssert(condition, errormsg) - if condition then - ctx.logger:error(errormsg) - nErrors = nErrors+1 - return false + local function loadLuaFile(path, env) + if fs.exists(path) and not fs.isDir(path) then + local f = fs.open(path, 'r') + local c = f.readAll() + f.close() + local result = loadStr(c, "", env) + if not result then + error("Could not load \'" .. path .. "\' properly!\n" .. tostring(result)) + sleep(1) end - return true + return result + else + error("Could not load \'" .. path .. "\'!") + sleep(0.5) end - - local function configExpect(name, typ) - local curTyp = type(ctx.config[name]) - if curTyp ~= typ then - ctx.logger:error("Bad value for \'"..name.."\' in config; Expected \'"..typ.."\', got \'"..curTyp.."\'.") - nErrors = nErrors+1 - return false - elseif curTyp == "string" and ctx.config[name] == "" then - ctx.logger:warn("Value \'"..name.."\' in config should not be empty.") + end - end - return true - end - - configExpect("pkey", "string") - if configExpect("name", "string") then - bAssert(ctx.utils.endsWith(ctx.config.name or "", ".kst"), "Remove \'.kst\' from the name.") - end - configExpect("webhooks", "table") - configExpect("sounds", "table") + -- theme + local result = loadLuaFile(fs.combine(pagesPath, "theme.lua"), { colors }) + if result then + ctx.theme = result + end - local modem = peripheral.find("modem") - if not modem then - ctx.logger:error("Kristify is not connected to a network! (aka. wired modem)") - elseif type(ctx.config.self) == "string" and modem.getNameLocal() ~= (ctx.config.self or "") then - ctx.logger:error("Given turtle in config does not exist!") - else configExpect("self", "string") + -- config + result = loadLuaFile(fs.combine(dataPath, "config.lua")) + if result then + ctx.config = result + end + -- products + result = loadLuaFile(fs.combine(dataPath, "products.lua")) + if result then + ctx.products = result + end + + -- Set debug mode + settings.define("kristify.debug", { + description = "If kristify should be debugging", + default = false, + type = "boolean" + }) + + settings.define("kristify.log2file", { + description = "If kristify should log to a file", + default = false, + type = "boolean" + }) + + -- Load Basalt + local basalt = {} + if not fs.exists(fs.combine(ctx.path.src, "lib", "basalt")) then + local authenticate = _G._GIT_API_KEY and { Authorization = "Bearer " .. _G._GIT_API_KEY } + local basaltDL, err, errCode = http.get( + "https://raw.githubusercontent.com/Kristify/kristify/main/src/libs/basalt.lua" + , authenticate) + if not basaltDL then + ctx.logger:error("Couldn't load Basalt into memory! Reason: \'" .. + err .. "\' (code " .. errCode.getResponseCode() .. ')') + return end - if configExpect("storage", "table") then - bAssert(#ctx.config.storage==0 or ctx.config.storage[1] == "", "Storage table in config is empty or invalid!") - for _,inv in pairs(ctx.config.storage) do - if not peripheral.wrap(inv) then - ctx.logger:error("Inventory \'"..inv.."\' does not exist!") - nErrors = nErrors+1 - end - end + basalt = load(basaltDL.readAll())() + basaltDL.close() + else + basalt = require("basalt") + end + ctx.basalt = basalt + + -- Load scripts + ctx.kristly = require(fs.combine("libs", "kristly")) + ctx.utils = require("utils") + ctx.webhooks = require("webhook") + + -- Check errors + local function bAssert(condition, errormsg) + if condition then + error(errormsg) end - if configExpect("monSide", "string") then - bAssert(not peripheral.wrap(ctx.config.monSide), "Given monitor side does not exist!") + end + + local function configExpect(name, typ) + local curTyp = type(ctx.config[name]) + if curTyp ~= typ then + error("Bad value for \'" .. name .. "\' in config; Expected \'" .. typ .. "\', got \'" .. curTyp .. + "\'.") + elseif curTyp == "string" and ctx.config[name] == "" then + ctx.logger:warn("Value \'" .. name .. "\' in config should not be empty.") end - + return true + end - -- Load libs, related to peripherals - ctx.speakerLib = require("speaker") - ctx.speakerLib.config = ctx.config + configExpect("pkey", "string") + if configExpect("name", "string") then + bAssert(ctx.utils.endsWith(ctx.config.name or "", ".kst"), "Remove \'.kst\' from the name.") + end + configExpect("webhooks", "table") + configExpect("sounds", "table") - ctx.logger.debug("Loading in inv lib") - ctx.logger.debug("Configured storage: " .. textutils.serialize(ctx.config.storage)) - ctx.storage = require(fs.combine("libs", "inv"))(ctx.config.storage or {}) + if string.find(_HOST, "CraftOS-PC", 1, true) then + error("CraftOS-PC does not support turtles, and thus Kristify cannot run on it.") + end - return ctx + ctx.logger:debug("CraftOS-PC not detected") + + local modem = peripheral.find("modem") + if not modem then + error("Kristify is not connected to a network! (aka. wired modem)") + elseif type(ctx.config.self) == "string" and modem.getNameLocal() ~= (ctx.config.self or "") then + error("Given turtle in config does not exist!") + else + configExpect("self", "string") + end + + if configExpect("storage", "table") then + bAssert(#ctx.config.storage == 0 or ctx.config.storage[1] == "", "Storage table in config is empty or invalid!") + for _, inv in pairs(ctx.config.storage) do + if not peripheral.wrap(inv) then + error("Inventory \'" .. inv .. "\' does not exist!") + nErrors = nErrors + 1 + end + end + end + if configExpect("monSide", "string") then + bAssert(not peripheral.wrap(ctx.config.monSide), "Given monitor side does not exist!") + end + + + -- Load libs, related to peripherals + ctx.speakerLib = require("speaker") + ctx.speakerLib.config = ctx.config + ctx.logger:debug("Loading inventory library") + ctx.logger:debug("Configured storage: " .. textutils.serialize(ctx.config.storage)) + ctx.storage = require(fs.combine("libs", "inv"))(ctx.config.storage or {}) + ctx.logger:info("Passed initiating") + return ctx end --- INIT -term.clear() -term.setCursorPos(1, 1) -local args = table.pack(...) -xpcall(function() - init(table.unpack(args, 1, args.n)) -end, function(err) +print("Starting initiating process.") + +continue = true +local function xpcaller(toRun) + xpcall(toRun, function(err) ctx.logger:error(err) -end) - --- MAIN -local function execFile(sPath) - local script, err = loadfile(sPath, "t", _ENV) - if not script then - ctx.logger:error(err) - nErrors = nErrors+1 - return - end - local result,output = pcall(script, ctx) - if not result then - if output == "terminated" then - -- Close websockets - return - end - ctx.logger:error(output) - nErrors = nErrors+1 - end -end - -if nErrors == 0 then - parallel.waitForAny( - function() - execFile(fs.combine(sSrc, "backend.lua")) - end, - function() - execFile(fs.combine(sSrc, "frontend.lua")) - end - ) -end - -if nErrors > 0 then - ctx.logger:warn("\'"..nErrors.."\' error(s). Press any key to exit.") + ctx.logger:warn("Error detected. Press a key to exit.") sleep(0.5) + local mon = peripheral.wrap(ctx.config.monSide) + local width, height = mon.getSize() + mon.setBackgroundColor(colors.black) + mon.setTextColor(colors.white) + mon.clear() + mon.setTextScale(1) + mon.setCursorPos(math.floor(width / 2 - (#ctx.config.name + 4) / 2 + 1), math.floor(height / 2)) + mon.write(ctx.config.name .. ".kst") + mon.setCursorPos(math.floor(width / 2 - 7), math.floor(height / 2) + 1) + mon.setTextColor(colors.lightGray) + mon.write("Shop is offline") os.pullEvent("key") -end \ No newline at end of file + continue = false + end) +end + +xpcaller(init) + +local function runFile(path) + local script, err = loadfile(path, "t", _ENV) + + if not script then + error("Could not load script. " + err) + end + + -- xpcall(script, function(err) error(err) end, ctx) + -- pcall(script, ctx) + script(ctx) +end + +if continue then + err = xpcaller(function() + parallel.waitForAny( + function() + runFile(fs.combine(sourcePath, "backend.lua")) + ctx.logger:warn("Backend exited") + end, + function() + runFile(fs.combine(sourcePath, "frontend.lua")) + ctx.logger:warn("Frontend exited") + end + ) + error("Something exited.") + end) +end diff --git a/src/libs/kristly.lua b/src/libs/kristly.lua index 1505c73..3a43283 100644 --- a/src/libs/kristly.lua +++ b/src/libs/kristly.lua @@ -1,7 +1,12 @@ +-- Copyright © 2022-2023 Kristify +-- MIT License +-- WARNING: Has Bad Code TM + local expect = require "cc.expect".expect local kristly = {} local kristlyWS = { ws = nil, id = 0 } +local syncNode = settings.get("kristly.node") or "https://krist.dev/" -- ~~Secret~~ setting to change node --#region Utilities @@ -14,7 +19,7 @@ expect(1, endpoint, "string") expect(2, body, "string") - return textutils.unserializeJSON(http.post("https://krist.dev/" .. endpoint, body).readAll()) + return textutils.unserializeJSON(http.post(syncNode .. endpoint, body).readAll()) end ---A basic GET function to the krist api. @@ -24,7 +29,7 @@ local function basicGET(endpoint) expect(1, endpoint, "string") - return textutils.unserializeJSON(http.get("https://krist.dev/" .. endpoint).readAll()) + return textutils.unserializeJSON(http.get(syncNode .. endpoint).readAll()) end ---Sends a simple websocket message to the krist server @@ -155,7 +160,7 @@ function kristly.authenticate(privatekey) expect(1, privatekey, "string") - return basicJSONPOST("https://krist.dev/login", "privatekey=" .. privatekey) + return basicJSONPOST("login", "privatekey=" .. privatekey) end ---Gets information about the krist server (MOTD) diff --git a/src/version.txt b/src/version.txt index 524cb55..867e524 100644 --- a/src/version.txt +++ b/src/version.txt @@ -1 +1 @@ -1.1.1 +1.2.0 \ No newline at end of file