Computercraft登录系统与fs API不兼容。

我正在为 Computercraft 开发一个 Windows 8 模拟操作系统,但我的登录系统无法正常工作。我已经尝试了一个小时左右,但真的很沮丧。

以下是登录代码:

    -- 登录和用户定义服务

    --- 变量

    userExists = fs.exists("/Users/.config/userConfig.cfg")
    termx, termy = term.getSize()
    halfx = math.floor(termx*0.5)
    halfy = math.floor(termy*0.5)

    prompt = "欢迎"
    uprompt = "用户名:"
    pprompt = "密码:"

    userConfig = fs.open("/Users/.config/userConfig.cfg", "r")
    edituserConfig = fs.open("/Users/.config/userConfig.cfg", "w")
    --- 函数

    function login(user)
      if user == "admin" then
        term.setCursorPos(1,1)
        term.setTextColor(256)
        print (user)

      elseif user == "guest" then
        print (user)

      else
        print ("nil")

      end
    end

    function userCheck()
      if userExists == true then
        term.clear()
        term.setBackgroundColor(8)
        term.setCursorPos(halfx-0.5*#prompt, halfy - 4)
        term.clear()

        print (prompt)

        term.setCursorPos((halfx-#uprompt), (halfy - 2))
        write (uprompt)
        term.setCursorPos((halfx-#uprompt), (halfy - 1))
        write (pprompt)
        term.setCursorPos((halfx), (halfy - 2))
        upin = read()
        term.setCursorPos((halfx), (halfy - 1))
        ppin = read("*")

        if upin == userConfig.readLine(21) and ppin == userConfig.readLine(24) then
          print ("管理员")

        elseif upin == userConfig.readLine(33) and ppin == userConfig.readLine(36) then
          login("guest")

        end

      elseif userExists == false then

      elseif userExists == nil then

      end
    end

    --- 主程序

    userCheck()

userConfig.cfg:

    -- 格式如下:
    --
    --  (名称):
    --
    --    (属性):
    --    "(值)"
    --
    --    (属性):
    --    "(值)"
    --
    --    (属性):
    --    "(值)"
    --
    --
    --  (名称):
    --    [等等]

    管理员:

      用户:
      "Admin"

      密码:
      "admin"

      授权:
      "1"

    访客:

      用户:
      "Admin"

      密码:
      nil

      授权:
      "0"

    根:

      用户:
      nil

      密码:
      nil

      授权:
      "2"
点赞
用户4119537
用户4119537

readLine 不接收参数,只读取下一行。最好的办法是使用表格和 textutils.serialize 将其全部写入文件,然后在读取时使用 textutils.unserialize 将其封装在一个表格中。

管理员:

  user:
  "Admin"

  pass:
  "admin"

  auth:
  "1"

可以写成表格形式,例如:

{
  Admin = {
            user = "Admin"

            pass = "admin"

            auth = "1"
          }

  Guest = {
            user = "Admin"

            pass = nil

            auth = "0"
          }
}

这样做可以按您的方式工作,也允许更多的变化和扩展。当然,要阅读它是另一回事,我会使用一个函数来查找并发送授权代码或 nil 如果没有起作用的话。

例如:

local function findUsers(username,password)

    --这将读取文件并将所有数据放入表格中,然后关闭它。
    local file = fs.open("userConfig.cfg","r")
    local userRanks = textutils.unserialize(file.readAll())
    file.close()

    --读取表格中的所有数据,我要这样做。
    for a,v in pairs(userRanks) do
        if type(v) == "table" then
            if userRanks[a].user == username and userRanks[a].pass == password then
                return userRanks[a].auth
            end
        end
    end

    --[[如果我们浏览整个文件表格,并且用户名和密码与文件上的不同,
        那么我们说我们找不到它,通过返回 nil]]--
    return nil
end

现在,对于您的输入区域,您只需要在输入用户名和密码后调用此函数即可,还允许您拥有授权码

local auth = findUsers(upin,ppin)

--如果他们输入了真实的用户名和密码
if auth ~= nil then

    --如果积分的授权码为“1”
    if auth == "1" then
       --做任何你想做的事情
    elseif auth == "2" then
       --为此积分代码执行其他操作
    end
elseif auth == nil then
    print("哦,不,您输入了无效的用户名和/或密码,请重试!"
end
2014-10-08 02:40:56
用户2817634
用户2817634

为了扩展Dragon53535的回答:

这是我编写的一个快速程序,可以将文件读入表格中:

local function fileToTable(path)
  -- first we make sure that the path can be opened
  assert(fs.exists(path), path..' does not exist!')
  assert(not fs.isDir(path), path..' is a directory!')

  local tSrc = {}
  local inFile = fs.open(path, 'r')

  -- we set line to a non-nil value
  local line = ''

  -- we continue the loop until line is nil
  while line do

    -- we read a line from the file
    line = inFile.readLine()

    -- now we save the value of line to our table
    -- line will be nil at EOF
    tSrc[#tSrc+1] = line
  end

  inFile.close()
  return tSrc
end

运行userConfig = fileToTable('/Users/.config/userConfig.cfg')后,您可以将类似userConfig.readLine(24)的内容替换为userConfig[24]


或者,您可以查看CC的实现方法io library。这是一个标准的Lua库(虽然在CC中它是一个fs包装器),所以代码可以更容易地从CC中移出。

特别地,io.lines()在这里会很有帮助。

上面的代码重写为使用io.lines

local function fileToTable(path)
  -- first we make sure that the path can be opened
  assert(fs.exists(path), path..' does not exist!')
  assert(not fs.isDir(path), path..' is a directory!')

  local tSrc = {}

  -- iterate over file
  -- io.lines is neat, since it opens and closes the file automatically
  for line in io.lines(path) do
    tSrc[#tSrc+1] = line
  end

  return tSrc
end

正如您所看到的,这个解决方案更简洁(只有9行代码!)且更易于管理。我不喜欢在CC中使用它的原因是io位于fs的顶层,因此最好移除中间人。

希望这可以帮助您。

2014-10-12 10:04:14