This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Waitdev_'s profile picture

2 problems in Synergy

Started by Waitdev_, 09 June 2016 - 06:33 AM
Waitdev_ #1
Posted 09 June 2016 - 08:33 AM
The first problem:
Problem 1This code doesn't work:

file = fs.open("whateverfile","r") -- returns with file
data = file.readAll() -- returns file file data
info = textutils.unserialise(data) -- returns with nothing (nil)
And for "whateverfile" (for example):

{
  data = {
	randomstring = "test";
  };
}
(I've also tried using "," instead of ";" but still doesn't work.)
2nd problem:
Problem 2An API to draw screens seems to have a problem when setting the text colour:
window:233: bad argument: double expected, got nil
Code:

w,h = term.getSize()
--[[ Currently not working
function getStyle(name)
  file = fs.open("os/synergy/styles/"..name,"r")
  data = file.readAll()
  style = textutils.unserialise(data)
  return style
end
--]]
function getStyle()
  style = {
	bg = colors.white,
	fg = colors.black,
	bar = {
	  col = colors.blue,
	  txtcol = colors.black,
	  text = "Unset bar title",
	  exit = true,
	},
	btncol = colors.lightGrey,
	btntxt = colors.black,
	btndis = colors.grey,
  }
  return style
end
function centerInLine(x1,x2,y,txt)
  term.setCursorPos(((x2-x1)/2)-(#txt/2),y1)
  write(txt)
end
function setStyle(style)
  if not type(style)=="table" then
	error("Invalid style!")
  end
  term.setBackgroundColor(style.bg)
  term.clear()
  term.setCursorPos(1,1)
  term.setBackgroundColor(style.bar.col)
  term.clearLine()
  term.setTextColor(style.bar.txtcol) -- Problem seems to occur here
  write(style.bar.text)
  if style.bar.exit then
	local w,h = term.getSize()
	term.setCursorPos(w,1)
	term.blit("x","f","e")
  end
  term.setBackgroundColor(style.bg)
  term.setTextColor(style.fg)
  term.setCursorPos(2,2)
end
function drawTextBox(x,y,l,t,c)
  term.setCursorPos(x,y)
  str = string.rep(" ",l-#t)
  str = t..str
  sp = string.rep(" ",l)
  if c then
	term.setBackgroundColor(colors.white)
	term.setTextColor(colors.lightGrey)
	write(str)
  else
	term.setBackgroundColor(colors.white)
	term.setTextColor(colors.black)
	write(sp)
  end
end
function drawButton(style,x,y,l,t,c,d)
  term.setCursorPos(x,y)
  sp = string.rep(" ",l)
  if d then
	term.setBackgroundColor(style.btndis)
  else
	term.setBackgroundColor(style.btncol)
  end
  term.setTextColor(style.btntxt)
  write(sp)
  if c then
	centerInLine(x,x+l,y,t)
  else
	write(t)
  end
end
function testButton(buttons)
  e,b,x,y = os.pullEvent("mouse_click")
  for i = 1,#buttons do
	if x>=buttons[i][1] and x<=buttons[i][3] and y>=buttons[i][2] and y<=buttons[i][4] then
	  return i
	end
  end
end
function write(txt,x,y,txtcol,bgcol)
  term.setCursorPos(x,y)
  term.setTextColor(colors[txtcol])
  term.setBackgroundColor(colors[bgcol])
  write(txt)
end
Bomb Bloke #2
Posted 09 June 2016 - 08:45 AM
Problem 1: Your code works for me, as written. I'd recommend closing the "file" handle, though. I suspect "info" isn't ending up as nil (and you're indexing into it incorrectly), or you're getting some other error which you're not quoting.

Problem 2: There's no "colors.grey". Use "colours.grey" or "colors.gray". Ditto for your other colours - use either normal or American English, but don't mix.
Waitdev_ #3
Posted 09 June 2016 - 08:53 AM
I've tried doing both, but neither of them are working. :/

Though you're right about the colors.gray part, I'll try to look out for that again later if I ever get a bug like that. Though in the 2nd problem, notice that it's saying colors.black is nil? I'm confused about that mainly.
Bomb Bloke #4
Posted 09 June 2016 - 09:19 AM
I've tried doing both, but neither of them are working. :/

Output of this, please:

Spoiler
local log = fs.open("log.txt", "w")

local file = fs.open("whateverfile","r") -- returns with file

if not file then
	log.writeLine("Error opening file. May not exist, or may be locked.")
	log.close()
	error()
end

local data = file.readAll() -- returns file file data
file.close()

if not data then
	log.writeLine("Error reading file content.")
	log.close()
	error()
end

log.writeLine("Got "..#data.." bytes from file:\n")
log.writeLine(data.."\n")

local info = textutils.unserialise(data)

log.writeLine("Content deserialised to type "..type(info))
log.close()

if type(info) == "table" and type(info.data) == "table" and info.data.randomstring then print(info.data.randomstring) end

Though you're right about the colors.gray part, I'll try to look out for that again later if I ever get a bug like that. Though in the 2nd problem, notice that it's saying colors.black is nil? I'm confused about that mainly.

I'm doubting the window API is erroring when you call term.setTextColour(). Difficult to comment without knowing the version of CC you're using.
Edited on 09 June 2016 - 07:20 AM
Waitdev_ #5
Posted 09 June 2016 - 09:25 AM
I've tried doing both, but neither of them are working. :/

Output of this, please:

Spoilerlocal log = fs.open("log.txt", "w")

local file = fs.open("whateverfile","r") – returns with file

if not file then
log.writeLine("Error opening file. May not exist, or may be locked.")
log.close()
error()
end

local data = file.readAll() – returns file file data
file.close()

if not data then
log.writeLine("Error reading file content.")
error()
end

log.writeLine("Got "..#data.." bytes from file:\n")
log.writeLine(data.."\n")

local info = textutils.unserialise(data)

log.writeLine("Content deserialised to type "..type(info))
log.close()

if type(info) == "table" and type(info.data) == "table" and info.data.randomstring then print(info.data.randomstring) end

Though you're right about the colors.gray part, I'll try to look out for that again later if I ever get a bug like that. Though in the 2nd problem, notice that it's saying colors.black is nil? I'm confused about that mainly.

I'm doubting the window API is erroring when you call term.setTextColour(). Difficult to comment without knowing the version of CC you're using.

(This time I'm using what should be loaded.)

I'm using CCEmuRedux with CC 1.79, here's the log.txt file:

Edited on 09 June 2016 - 07:26 AM
Bomb Bloke #6
Posted 09 June 2016 - 10:05 AM
When you call textutils.unserialise(), it generates a custom function out of the string "return "..input, and returns what that returns. It gives this function an empty environment table - it doesn't have access to _G. On the string you've got there, the function will attempt to index nil (because it has no access to the "colors" table) and so textutils.unserialise() will return nil.

That is to say, if you want to load in colour values like that, use the actual numbers. bg = 1, fg = 32768, etc.

Within the window API for CC 1.79, the line erroring is here, indicating you're calling term.setCursorPos() with invalid values. And indeed, I see your write function always attempts to move the cursor, even when you call it without anything but a single string as the parameter.
Waitdev_ #7
Posted 09 June 2016 - 10:41 AM
When you call textutils.unserialise(), it generates a custom function out of the string "return "..input, and returns what that returns. It gives this function an empty environment table - it doesn't have access to _G. On the string you've got there, the function will attempt to index nil (because it has no access to the "colors" table) and so textutils.unserialise() will return nil.

That is to say, if you want to load in colour values like that, use the actual numbers. bg = 1, fg = 32768, etc.

Within the window API for CC 1.79, the line erroring is here, indicating you're calling term.setCursorPos() with invalid values. And indeed, I see your write function always attempts to move the cursor, even when you call it without anything but a single string as the parameter.

The 2nd problem has been fixed, and thanks for that! Though still the 1st problem remains. Even when I'm not loading something like what I did with your code, it will still error.



packdl code

os.loadAPI("os/synergy/api/osload")
osload.api("osui")
osload.api("osfiles")
osload.api("oslanguage")
lang = osload.getLang()
style = osui.getStyle("default")
style.bar.text = "Choose a server"
osui.setStyle(style)
settings = osload.getSettingsGlobal()
for i = 1,8 do
  if settings.packdl.bookmarks[i]==nil then
    osui.drawButton(style,3,1+i*2,22," ",false,true)
  else
    osui.drawButton(style,3,1+i*2,22,settings.packdl.bookmarks[i][1],true,false)
  end
end
for i = 1,8 do
  if settings.packdl.bookmarks[i]==nil then
    osui.drawButton(style,26,1+i*2,22," ",false,true)
  else
    osui.drawButton(style,26,1+i*2,22,settings.packdl.bookmarks[i][1],true,false)
  end
end

osload code

function api(name)
  os.loadAPI("os/synergy/api/"..name)
end
function image(name)
end
function getLoggedInUser()
end
function open(path)
  file = fs.open(path,"r")
  data = file.readAll()
  return textutils.unserialise(data)
end
function getSettingsGlobal()
  open("data/user/global/settings")
  return settings
end
function getLang()
  settings = getSettingsGlobal()
  file = fs.open("os/synergy/language/"..settings.lang,"r")
  data = file.readAll()
  return textutils.unserialise(data)
end
function readPackageServer(server)
  dataFile = http.get(server.."info.txt")
  serverInfo = dataFile.readAll()
  serverInfo = textutils.unserialise(serverInfo)
  info = serverInfo.info
  packs = serverInfo.packs
  dataFile.close()
  return info,packs
end
function readFilesInPack(server,pack)
  packInfoFile = http.get(server..pack.."/info.txt")
  packInfo = packInfoFile.readAll()
  tPackInfo = textutils.unserialise(packInfo)
  info = tPackInfo.info
  files = tPackInfo.files
  packInfoFile.close()
  return info,files
end
function downloadFilesFromPack(server,pack,files)
  for i = 1,#files do
    file = http.get(server..pack.."/"..files)
    downloaded = fs.open()
  end
end
Edited on 09 June 2016 - 08:53 AM
Bomb Bloke #8
Posted 09 June 2016 - 11:04 AM
Are you sure you've got all the relevant line breaks included in what you've pasted there? 'cause getSettingsGlobal() doesn't appear to be doing what you'd want it to be doing…
Waitdev_ #9
Posted 09 June 2016 - 12:38 PM
Are you sure you've got all the relevant line breaks included in what you've pasted there? 'cause getSettingsGlobal() doesn't appear to be doing what you'd want it to be doing…

What do you mean by that? This is exactly the code by the way..
Bomb Bloke #10
Posted 09 June 2016 - 12:47 PM
function getSettingsGlobal()
  open("data/user/global/settings")  --# Gets some data, but doesn't assign it to anything.
  return settings                    --# Returns nil.
end
Waitdev_ #11
Posted 09 June 2016 - 01:04 PM
I've fixed that now, though I'm still getting the same error.
Bomb Bloke #12
Posted 09 June 2016 - 01:33 PM
Surely the line number would've changed. Given that it never matched up in the first place, I'm inclined to think that either your main script is loading the wrong API file, or it's failing to load the API file and hence just using the "last copy which loaded".

Now might be a good time to reboot the computer.
Waitdev_ #13
Posted 09 June 2016 - 01:55 PM
Even with that, I have tried rebooting, idk really anymore. Maybe I could just use an alternate way to load files to tables?
Bomb Bloke #14
Posted 09 June 2016 - 02:13 PM
Checking the files in your Github, I can see that the line numbers indeed fail to line up with what you've posted here. This is the line generating the "attempt to concatenate string and nil" error:

file = fs.open("os/synergy/language/"..settings.lang,"r")

Adding this line above it:

for key,value in pairs(settings) do print(key..": "..type(value)) end

… I get:

accounts: table
packdl: table

Checking the content of "data/user/global/settings" I see:

{
  packdl = {
    bookmarks = {
      {"Official package server","http://waitcc.net78.net/synergy/packages/ops/"};
    };
  };
  accounts = {
    database = {
      {"username","default","pass",""};
    };
  };
  lang = en;
}

… and "en" is nil, so…