Posted 30 October 2013 - 04:28 PM
http://pastebin.com/LcqtDt0B
So I ran into a weird problem, I don't get it. Maybe I just looked at it for too long. So the program is mostly done but somehow the saving is broken.
The program needs to save three tables. While I was working on the code for the sorting it seemed to work (not sure if it did). Then in a testing round I got a problem with the saveFile/loadFIle (I think). The program runs normally, I can add some fake players with messagecoun() and myself with the player detector. The program saves the tables and everything works fine. When I terminate the program and "edit" the files to see if everything worked fine, there's always "nil" written in the file. So I'm a little bit confused, because the tables weren't nil when the program saved them (at this moment the players and their stats were in the tables).
I hope someone can help me :D/> thanking you in anticipation.
Spoiler
--Info Board by Southp0le
--adjusted for 6x8 Advanced Monitor
--__work in progress
--Main Monitor Coordinates:
----x:=[1,55]
----y:=[1,27]
--Touch Monitor Coordinates:
----x:=[1,80]
----y:=[1,5]
---------------------
-------Options-------
---------------------
os.loadAPI("buttonAPI")
local serverAdmin = "Guracao"
local boardAdmin = "Southp0le"
local mon = peripheral.wrap("monitor_0")
local mon2 = peripheral.wrap("top")
local chat = peripheral.wrap("bottom")
local mod = peripheral.wrap("back")
local det = peripheral.wrap("playerDetector_0")
local filled
local page = 1
local pages = 1
local showed
backgroundColor = colors.lightBlue
textColor = colors.black
textSize = 1.5
mon.setTextColor(textColor)
mon.setBackgroundColor(backgroundColor)
mon.setTextScale(textSize)
mon2.setTextColor(textColor)
mon2.setBackgroundColor(backgroundColor)
mon2.setTextScale(textSize-0.5)
-----------------------
-------Functions-------
-----------------------
----------------
--file control--
----------------
--saves the file
function saveFile(filename)
local file = fs.open(filename,"w")
if filename == "list1" then
file.write(textutils.serialize(list))
print(textutils.serialize(list))
file.close()
print("File '"..filename.."' saved.")
refresh()
return true
elseif filename == "numbers" then
file.write(textutils.serialize(numbers))
file.close()
print("File '"..filename.."' saved.")
refresh()
return true
elseif filename == "deathReasons" then
file.write(textutils.serialize(deathReasons))
file.close()
print("File '"..filename.."' saved.")
refresh()
return true
else
return false
end
end
--loads the file and returns the file
function loadFile(filename)
local file = fs.open(filename,"r")
local data = file.readAll()
file.close()
if string.len(data) > 0 then
print("File '"..filename.."' loaded.")
return textutils.unserialize(data)
else
return {}
end
end
--checks if theres a file, creates one if not
function checkFile(file)
if fs.exists(file) == false then
if saveFile(file) then
print("Created a new file: " ..file..".")
end
else
print("Everything fine, file '" ..file.."' exists already.")
end
end
----------
--Tables--
----------
local list = {}
local numbers = {}
local deathReasons = {}
--creates table "list" with all infomation (overloaded)
function setTable(...)
local n = length()+1
local arguments = {select(1,...)}
local player = arguments[1]
numbers[n] = player
deathReasons[getNumber(player)] = {}
if table.getn(arguments) == 1 then
list[n] = {}
list[n]["player"] = arguments[1]
list[n]["deaths"] = 0
list[n]["kills"] = 0
list[n]["ratio"] = "-"
list[n]["logins"] = 0
list[n]["messages"] = 0
list[n]["average"] = 0
print("Player '" ..player.. "' successfully created.")
elseif table.getn(arguments) == 7 then
list[n] = {}
list[n]["player"] = arguments[1]
list[n]["deaths"] = arguments[2]
list[n]["kills"] = arguments[3]
list[n]["ratio"] = arguments[4]
list[n]["logins"] = arguments[5]
list[n]["messages"] = arguments[6]
list[n]["average"] = arguments[7]
print("Player '" ..player.. "' successfully created.")
else
print("Error: setTable: Wrong parameter passed to function 'setTable'!")
end
end
--returns lenght of list
function length()
local n = 0
if list ~= nil then
for k in pairs(list) do
n = n +1
end
end
return n
end
--returns related number from player
function getNumber(player)
if numbers ~= nil then
for k in ipairs(numbers) do
if numbers[k] == player then
return k
end
end
else
print("Error: getNumber: No players!")
end
end
--checks if player exists
function checkPlayer(player)
local x = 0
if numbers ~= nil then
for k in pairs(numbers) do
if numbers[k] == player then
x=x+1
end
end
end
if x > 0 then
return true
else
return false
end
end
--removes table-entry
function table.removePlayer(player)
local key = getNumber(player)
if checkPlayer(player) then
table.remove(list, key)
table.remove(numbers, key)
if deathReasons[key] ~= nil then
table.remove(deathReasons, key)
end
saveFile("list1")
saveFile("numbers")
saveFile("deathReasons")
print("Player " ..player.. " successfully removed.")
else
print("Error: removePlayer: Player '" ..player.. "' could not be removed. Is the name written correctly?")
end
end
--creates a dummy-player for comparative
--removes it if no longer needed
function dummy()
local number = length()
--setTable("dummy")
print("Players:")
if number == 0 then
setTable("dummy")
end
if list ~= nil then
for k in ipairs(list) do
print(list[k]["player"])
end
else
print(" ")
end
if number>1 and checkPlayer("dummy") then
table.removePlayer("dummy")
end
print("There're " ..number.. " Players on the server.")
end
--adds a new player to the list
function addPlayer()
while true do
event,newcomer = os.pullEvent("player")
local x = 0
if checkPlayer(newcomer) then
chat.tell(newcomer,"Error: "..newcomer..", you're already listed in the database. Don't you remember, Idiot?")
elseif checkPlayer(newcomer) == false then
chat.tell(newcomer,"Congratulations! Welcome to this great server, now you're listed in the database. Have fun, "..newcomer..".")
setTable(newcomer)
saveFile("numbers")
saveFile("list1")
else
chat.say("Well this shouldn't happen, please report this error to "..serverAdmin.." or " ..infoboardAdmin..".")
chat.say("No joke!")
end
end
end
--calculates kill/death ratio
function ratio(player)
if list[player]["deaths"] == 0 then
list[player]["ratio"] = "-"
else
list[player]["ratio"] = tonumber(list[player]["kills"])/tonumber(list[player]["deaths"])
end
end
--calculates average messagelenght
function average(player, message)
list[player]["average"] = (tonumber(list[player]["average"]))*(tonumber(list[player]["messages"])-1)
list[player]["average"] = (tonumber(list[player]["average"]) + string.len(message)) / (tonumber(list[player]["messages"]))
end
function sortByDeathsH(x, y)
return x.deaths > y.deaths
end
function sortByKillsH(x, y)
return x.kills > y.kills
end
function sortByLoginsH(x, y)
return x.logins > y.logins
end
function sortByMessagesH(x, y)
return x.messages > y.messages
end
function sortByAverageH(x, y)
return x.average > y.average
end
function sortByRatioH(x,y)
return x.ratio > y.ratio
end
function sortByDeathsL(x, y)
return x.deaths < y.deaths
end
function sortByKillsL(x, y)
return x.kills < y.kills
end
function sortByLoginsL(x, y)
return x.logins < y.logins
end
function sortByMessagesL(x, y)
return x.messages < y.messages
end
function sortByAverageL(x, y)
return x.average < y.average
end
function sortByRatioL(x,y)
return x.ratio < y.ratio
end
function sortByReasons(x, y)
return x.k > y.k
end
function sortAll (state)
if state == "max1" then
table.sort(list,sortByKillsH)
buttonAPI.toggleAll(" Max ")
elseif state == "min1" then
table.sort(list,sortByKillsL)
buttonAPI.toggleAll(" Min ")
elseif state == "max2" then
table.sort(list,sortByDeathsH)
buttonAPI.toggleAll("Max ")
elseif state == "min2" then
table.sort(list,sortByDeathsL)
buttonAPI.toggleAll("Min ")
elseif state == "max3" then
table.sort(list,sortByRatioH)
buttonAPI.toggleAll(" Max ")
elseif state == "min3" then
table.sort(list,sortByRatioL)
buttonAPI.toggleAll(" Min ")
elseif state == "max4" then
table.sort(list,sortByMessagesH)
buttonAPI.toggleAll("Max")
elseif state == "min4" then
table.sort(list,sortByMessagesL)
buttonAPI.toggleAll("Min")
elseif state == "max5" then
table.sort(list,sortByMessagesH)
buttonAPI.toggleAll("Max ")
elseif state == "min5" then
table.sort(list,sortByMessagesL)
buttonAPI.toggleAll("Min ")
elseif state == "max6" then
table.sort(list,sortByLoginsH)
buttonAPI.toggleAll("Max")
elseif state == "min6" then
table.sort(list,sortByLoginsL)
buttonAPI.toggleAll("Min")
end
saveFile("list1")
refresh()
end
-----------
--Monitor--
-----------
function firstToUpper(str)
return (str:gsub("^%l", string.upper))
end
function refresh()
mon.clear()
mon2.clear()
screen()
buttonAPI.screen()
end
--creates labels
function label(xpos,ypos, text)
mon.setCursorPos(xpos, ypos)
mon.write(text)
end
--prints everything on the monitor
function printAll()
mon2.clear()
local y = 4
if filled == "login" then
label(2,2,"Player:")
label(27,2, "Logins:")
for k in pairs(list) do
mon.setCursorPos(3,y)
mon.write(list[k]["player"])
mon.setCursorPos(29,y)
mon.write(tostring(list[k]["logins"]))
y=y+1
end
elseif filled == "sortKill" then
label(2,2,"Player:")
label(15,2, "Kills:")
label(30,2, "Deaths:")
label(45,2, "Ratio:")
for k in pairs(list) do
mon.setCursorPos(3,y)
mon.write(list[k]["player"])
mon.setCursorPos(16,y)
mon.write(tostring(list[k]["kills"]))
mon.setCursorPos(31,y)
mon.write(tostring(list[k]["deaths"]))
mon.setCursorPos(46,y)
mon.write(tostring(list[k]["ratio"]))
y=y+1
end
elseif filled == "sortMessage" then
label(2,2,"Player:")
label(22,2, "Messages:")
label(37,2, "average Length:")
for k in pairs(list) do
mon.setCursorPos(3,y)
mon.write(list[k]["player"])
mon.setCursorPos(23,y)
mon.write(tostring(list[k]["messages"]))
mon.setCursorPos(38,y)
mon.write(tostring(list[k]["average"]))
y=y+1
end
elseif filled == "sortReasons" then
n = getNumber(showed)
label(2,2, tostring(showed))
label(20,4, "Reasons:")
label(45,4, "Deaths:")
y=y+2
if deathReasons[n] ~= nil then
if #deathReasons[n] > 0 then
for k in pairs(deathReasons) do
mon.setCursorPos(3,y)
mon.write(tostring(deathReasons[n][k]))
mon.setCursorPos(21,y)
k=k+1
mon.write(tostring(deathReasons[n][k]))
y=y+1
end
end
end
end
label(55,27,"by Southp0le")
end
function screen()
if filled ~= "button" then
printAll()
end
end
function toggleScreen(change)
buttonAPI.toggleAll(change)
refresh()
end
function nextPage()
if page+1 <= pages then
page = page+1
end
fillReasons()
end
function prevPage()
if page-1 >= 1 then
page = page-1
end
fillReasons()
end
function goBack()
fillReasons()
end
function fillButton()
buttonAPI.clearTable()
buttonAPI.setTable("Kill/Death", fillSortKill,"", 2, 15, 2, 4)
buttonAPI.setTable("Death Reasons", fillReasons,"", 18, 34, 2, 4)
buttonAPI.setTable("Messages", fillSortMessages,"", 37, 48, 2, 4)
buttonAPI.setTable("Time", time,"", 70,79,2,4)
filled = "button"
refresh()
end
function fillReasons()
buttonAPI.clearTable()
players = length(numbers)
local npp = 3 --names per page
local x = 0
pages = math.ceil(players/npp)
local currName = 0
for k in pairs(numbers) do
currName = currName + 1
if currName > npp*(page-1) and currName < npp*page+1 then
buttonAPI.setTable(numbers[k], fillSortReasons, numbers[k], 28+x, 38+x ,2 ,4)
x=x+10
end
end
buttonAPI.setTable("Home", fillButton, "", 2, 7, 2, 4)
buttonAPI.setTable("Next Page", nextPage, "", 10, 20, 1, 2)
buttonAPI.setTable("Prev Page", prevPage, "", 10, 20, 4, 5)
buttonAPI.label(70,3, "Page: ")
filled = "reasons"
refresh()
end
function fillSortKill()
buttonAPI.clearTable()
buttonAPI.setTable(" Min ", sortAll, "min1", 22, 28, 4, 5)
buttonAPI.setTable(" Max ", sortAll, "max1", 22, 28, 1, 2)
buttonAPI.setTable("Min ", sortAll, "min2", 44, 50, 4, 5)
buttonAPI.setTable("Max ", sortAll, "max2", 44, 50, 1, 2)
buttonAPI.setTable(" Min ", sortAll, "min3", 66, 72, 4, 5)
buttonAPI.setTable(" Max ", sortAll, "max3", 66, 72, 1, 2)
buttonAPI.setTable("Home", fillButton, "", 2, 7, 2, 4)
filled = "sortKill"
refresh()
end
function fillSortReasons(display)
buttonAPI.clearTable()
showed = display
buttonAPI.setTable("Back", goBack, "", 9, 14, 2, 4)
buttonAPI.setTable("Home", fillButton, "", 2, 7, 2, 4)
filled = "sortReasons"
refresh()
end
function fillSortMessages()
buttonAPI.clearTable()
buttonAPI.setTable("Min",sortAll, "min4", 35, 41, 4, 5)
buttonAPI.setTable("Max",sortAll, "max4", 35, 41, 1, 2)
buttonAPI.setTable("Min ",sortAll, "min5", 60, 66, 4, 5)
buttonAPI.setTable("Max ",sortAll, "max5", 60, 66, 1, 2)
buttonAPI.setTable("Home", fillButton, "", 2, 7, 2, 4)
filled = "sortMessage"
refresh()
end
function fillSortLogins()
buttonAPI.clearTable()
buttonAPI.setTable("Min",sortAll, "min6", 26, 32, 4, 5)
buttonAPI.setTable("Max",sortAll, "max6", 26, 32, 1, 2)
buttonAPI.setTable("Home", fillButton, "", 2, 7, 2, 4)
filled = "sortLogins"
refresh()
end
------------------------
--while true functions--
------------------------
--counts deaths, kills and deathreasons
function deathcount()
while true do
event,dead,killer,cause = os.pullEvent("chat_death")
number1 = getNumber(dead)
number2 = getNumber(killer)
list[number1]["deaths"] = tonumber(list[number1]["deaths"])+1
ratio(number1)
if killer~=nil then
for k in pairs(list) do
if killer == list[k]["player"] then
list[number2]["kills"] = tonumber(list[number2]["kills"])+1
ratio(number2)
end
end
local x = 0
local i
for i=1, table.getn(deathReasons), 1 do
for j=1, table.getn(deathReasons[number1]), 1 do
if deathReasons[i][j] == killer then
deathReasons[i][j+1] = deathReasons[i][j] + 1
x = x+1
end
end
end
if x == 0 then
number = getNumber(dead)
deathReasons[number1][table.getn(deathReasons[number1])+1] = killer
deathReasons[number1][table.getn(deathReasons[number1])+1] = 1
end
end
chat.tell(dead, "You died " ..list[number1]["deaths"].. " times.")
table.sort(deathReasons[number1], sortByReasons)
saveFile("deathReasons")
saveFile("list1")
end
end
--counts numbers of messages
--includes maintenance-options
function messagecount()
while true do
event, player, message = os.pullEvent("chat")
local number = getNumber(player)
list[number]["messages"] = tonumber(list[number]["messages"])+1
average(number,tostring(message))
saveFile("list1")
if player == boardAdmin and message == "createPlayer" then
chat.tell(boardAdmin,"Waiting for information to create player: Name, Kills, Deaths, Ratio, Logins, Messages, Average")
print("Waiting for information to create player: Name, Kills, Deaths, Ratio, Logins, Messages, Average")
event, player, message = os.pullEvent("chat")
if player == boardAdmin then
local string = message
local x = 0
for word in string.gmatch(string, "%w+") do
if x == 0 then
name = word
print("Player: " ..word)
elseif x == 1 then
kills = tonumber(word)
print("Kills: " ..word)
elseif x == 2 then
deaths = tonumber(word)
print("Deaths: " ..word)
elseif x == 3 then
ratio = tonumber(word)
print("Ratio: "..word)
elseif x == 4 then
logins = tonumber(word)
print("Logins: " ..word)
elseif x == 5 then
messages = tonumber(word)
print("Messages: " ..word)
elseif x == 6 then
average = tonumber(word)
print("Average Lenght: " ..word)
else
print("Error: messagecount: createPlayer: String-message not matching")
end
x=x+1
end
end
setTable(name,deaths,kills,ratio,logins,messages,average)
saveFile("list1")
saveFile("numbers")
saveFile("deathReasons")
elseif player == boardAdmin and message == "deletePlayer"then
chat.tell(boardAdmin,"Waiting for information to delete player: Name")
print("Waiting for information to delete player: Name")
event, player, message = os.pullEvent("chat")
table.removePlayer(tostring(message))
saveFile("list1")
saveFile("numbers")
saveFile("deathReasons")
end
end
end
--checks for monitortouch
function getClick()
while true do
event,side,x,y = os.pullEvent("monitor_touch")
if side == "top" then
buttonAPI.checkxy(x,y)
end
end
end
--function with all pullEvents
function mainProcess()
parallel.waitForAny(deathcount, messagecount, addPlayer, getClick)
end
-----------
--Process--
-----------
--lifeControl()
checkFile("list1")
checkFile("numbers")
checkFile("deathReasons")
if loadFile("list1") == nil then
list = {}
else
list = loadFile("list1")
end
if loadFile("numbers") == nil then
numbers = {}
else
numbers = loadFile("numbers")
end
if loadFile("deathReasons") == nil then
deathReasons = {}
else
deathReasons = loadFile("deathReasons")
end
fillButton()
dummy()
refresh()
mainProcess()
So I ran into a weird problem, I don't get it. Maybe I just looked at it for too long. So the program is mostly done but somehow the saving is broken.
The program needs to save three tables. While I was working on the code for the sorting it seemed to work (not sure if it did). Then in a testing round I got a problem with the saveFile/loadFIle (I think). The program runs normally, I can add some fake players with messagecoun() and myself with the player detector. The program saves the tables and everything works fine. When I terminate the program and "edit" the files to see if everything worked fine, there's always "nil" written in the file. So I'm a little bit confused, because the tables weren't nil when the program saved them (at this moment the players and their stats were in the tables).
I hope someone can help me :D/> thanking you in anticipation.