Logging function - replace line?

Runes of Magic/Radiant Arcana (http://www.runesofmagic.com)
Post Reply
Message
Author
noobbotter
Posts: 527
Joined: Fri Aug 31, 2012 1:15 pm

Logging function - replace line?

#1 Post by noobbotter »

I'm creating a summary log for all my bots that will display name, gold, shells, tokens, puris, etc...

I'm using the logInfo function to create each entry. I create that entry at the end of each character's daily runs so each char gets one entry per day. What I would like to know is how could I do a search in the log file for a line beginning with player.Name and delete that line prior to creating a new entry? Thanks.
User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Logging function - replace line?

#2 Post by rock5 »

The easiest way, as I understand it, is to load the whole file into a variable, modify it, then write the whole thing back. I don't believe lua provides a method to change a line only. So you could read all the lines into a table of lines then search for the line you want to change, edit it, then write all the lines back to the file.
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan
noobbotter
Posts: 527
Joined: Fri Aug 31, 2012 1:15 pm

Re: Logging function - replace line?

#3 Post by noobbotter »

well, looking at the waypoint renumbering script, i can probably figure out how to iterate through lines of a file, but i'm not sure how to dynamically create/write to a table. Can you briefly explain that? I'd sure appreciate it.

**EDIT:
Well, it turns out I figured out how to dynamically create a table on the fly and add an entry to that table. So now I just need to figure out how to read a file into a table and search for a line that starts with certain text.
User avatar
lisa
Posts: 8332
Joined: Tue Nov 09, 2010 11:46 pm
Location: Australia

Re: Logging function - replace line?

#4 Post by lisa »

noobbotter wrote:So now I just need to figure out how to read a file into a table and search for a line that starts with certain text.
http://www.lua.org/manual/5.1/manual.html#pdf-io.read

file 11.lua consists of

Code: Select all

"11111111111111111"
"22222222222222222"
"33333333333333333"
"44444444444444444"
"55555555555555555"

Code: Select all

Command> local readfile = io.open("scripts/11.lua") local file = readfile:read("*l") print(file)
"11111111111111111"

Command> local readfile = io.open("scripts/11.lua") local file = readfile:read("*a") print(file)
"11111111111111111"
"22222222222222222"
"33333333333333333"
"44444444444444444"
"55555555555555555"


notice the "*l" did just 1 line and "*a" did all lines


-------------------------------------------------------------------------------------


If you want the info to be in a table though it is much much easier.

file is like this

Code: Select all

return 
{"11111111111111111",
"22222222222222222",
"33333333333333333",
"44444444444444444",
"55555555555555555"}
and then used like this.

Code: Select all

Command> local tt = include("11.lua") table.print(tt)
table: 017C51F8
1:      11111111111111111
2:      22222222222222222
3:      33333333333333333
4:      44444444444444444
5:      55555555555555555
Notice when using include the base folder is scripts because that is why my commandline setup is, so you may need to play around with that part in your code in order to get it to include your file.


you probably want to use this though.

Code: Select all

Command> local readfile = io.open("scripts/11.lua") for line in readfile:lines() do print(line) end

return
{"11111111111111111",
"22222222222222222",
"33333333333333333",
"44444444444444444",
"55555555555555555"}
Remember no matter you do in life to always have a little fun while you are at it ;)

wiki here http://www.solarstrike.net/wiki/index.php?title=Manual
noobbotter
Posts: 527
Joined: Fri Aug 31, 2012 1:15 pm

Re: Logging function - replace line?

#5 Post by noobbotter »

Ok, so I've got it working, for the most part. The only thing that bothers me is that it takes some time for the file I'm writing to to update. I have this in my waypoint file that is strictly used for logging the next character, so it basically will update my character log, then log next character. ( also have a bunch of formatting stuff for the log to make it prettier but still have to work on that part. But here's what I have:

Code: Select all

<onLoad>
	--=== Modified Version of Rock5's survivalnext ===--
	--===     Version 1.2      ===--

	--=== User Options ===--

	local buffer = "\t"
	cprintf(cli.yellow,"Logging Player info to Log Summary \n")
	local gold = RoMScript('GetPlayerMoney("copper");')
	local shells = getCurrency("shell")
	local tokens = inventory:itemTotalCount(203038)
	local puris = inventory:itemTotalCount("Purified Fusion Stone","itemshop")
	
	local newfile = {}
	
	function fixbuffer(myvar)
		if string.len(myvar) > 15 then
			buffer = "\t"
		elseif string.len(myvar) > 11 then
			buffer = "\t\t"
		elseif string.len(myvar) > 7 then
			buffer = "\t\t\t"
		elseif 8 > string.len(myvar) then
			buffer = "\t\t\t\t"
		end
		return buffer
	end
	
	function fixbuffershort(myvar)
		if string.len(myvar) > 6 then
			buffer = "\t"
		else 
			buffer = "\t\t"
		end
		return buffer
	end
	
	function readfilein()
		local readfile,err = io.open("scripts/rom/logs/LogSummary.txt","r")
		if err then return err end
		for line in readfile:lines() do 
			if string.match(line, player.Name) then
				table.insert(newfile,player.Name..fixbuffer(player.Name)..player.Level..fixbuffershort(player.Level)..
				maxHP..fixbuffershort(maxHP)..fgold..fixbuffer(fgold)..shells.."\t\t"..tokens.."\t\t"..puris)
			else
				table.insert(newfile, line)
			end
		end
		readfile:close()
		local writefile,err = io.open("scripts/rom/logs/LogSummary.txt","w")
		for k,v in pairs(newfile) do
			--printf("%s\n",v)
			writefile:write(v.."\n")
		end
		writefile:close()
	end
	
	function comma_value(n)
		local left,num,right = string.match(n,'^([^%d]*%d)(%d*)(.-)$')
		return left..(num:reverse():gsub('(%d%d%d)','%1,'):reverse())..right
	end
	fgold = comma_value(gold)
	maxHP = comma_value(player.MaxHP)
	readfilein()
	yrest(1000)
	When_Finished = "charlist"
		-- "end" to end script, "relog" to log next character, "charlist" to log next in 'charlist'.

	CharList = {
		{account=13 , chars={1,2,5,6}},
		{account=42 , chars={1,2,3}},
		{account=54 , chars={1,2}},
		{account=13 , chars={3}},
	}
	--SetRestartClientSettings(1, "rom4u")
	NextFileToLoad = "1Dailies-start" -- File to load after changing character.
	--====================--

	if When_Finished == "relog" then
		sendMacro("}LoginNextToon=true;a={")
		sendMacro("Logout();");
		waitForLoadingScreen();
		loadProfile()
		loadPaths(NextFileToLoad);
	elseif When_Finished == "charlist" then
		SetCharList(CharList)
		LoginNextChar()
		loadProfile()
		loadPaths(NextFileToLoad);
	elseif When_Finished == "end" then
			error("Ending script",2)
	else
		error("'When_Finished' option is invalid",0)
	end
</onLoad>
So, the readfilein function is the function that does the reading of the file, writing to table while watching for a line with matching charactername. If found, it adds the correct info for that character. Then after it's done going through the file, it closes it and re-opens it in write mode, writes the table to it, then closes it. Initially I tried to open the file jsut once for read and write but it always cleared the file empty and errored when trying to write. Now, it works right, but it takes a while for it to write. You'll see that it does this log entry right before relogging next character. I'm finding that the log file doesn't update until the next char is logged in.

By the way, here's a sample of how this logfile turns out (without the usernames), but this page makes the tabs line up worse than my NP++ does:

Code: Select all

Name				Level	HP			Gold				Shells	Tokens		Puris
charname1			80		58,687		196,029,291			340		1426		0
charname_2			61		22,725		1,383,773			960		220		1
char_3				56		8,565		1,515,562			980		280		1
char_4				55		5,436		1,360,503			980		175		2
User avatar
lisa
Posts: 8332
Joined: Tue Nov 09, 2010 11:46 pm
Location: Australia

Re: Logging function - replace line?

#6 Post by lisa »

So basically everytime you use a character you will be "editing" the line for that character in the log file, so you aren't actually using the log userfunction that just saves the info in a new line anymore?


I would rethink the whole process and save the info as an actual table, it will be faster and easier to use.

In my examples i posted I am refering to this one.

Code: Select all

return 
{"11111111111111111",
"22222222222222222",
"33333333333333333",
"44444444444444444",
"55555555555555555"}
In this case though I would make it something like this.

Code: Select all

return{
charname1={mems=990,tokens=1200,gold=800424242400},
charname2={mems=550,tokens=1500,gold=80242424240800},
charname3={mems=400,tokens=1900,gold=800080855500},
charname4={mems=700,tokens=1100,gold=80008585800},
charname5={mems=600,tokens=3200,gold=802242424800},
}
then you just do

Code: Select all

local tt = include("logsummary.lua")
local char = player.Name
tt.char = { -- use the new info here }  
-- this will just replace the existing info or create new info for that character in the tt table
-- doing tt.player.Name may work but not sure, thats why the char value.
end
then use the table tt to redo the log file, the code should take miliseconds.

Table usage would look like this as an example.

Code: Select all

Command> local tt = {lol={x=1,z=2,y=3},bah={z=6,x=7,y=8}} table.print(tt.lol)
table: 01716528
z:      2
y:      3
x:      1
Notice the charnames don't use " " so lol is actually lol and not "lol"
Remember no matter you do in life to always have a little fun while you are at it ;)

wiki here http://www.solarstrike.net/wiki/index.php?title=Manual
noobbotter
Posts: 527
Joined: Fri Aug 31, 2012 1:15 pm

Re: Logging function - replace line?

#7 Post by noobbotter »

That gets confusing real quick. Ok, so you're saying that if I read the log file into a table, then I can use the table function to update the info in the table that matches the current player name. That's kind of what I'm already doing but instead of writing it all to a file at once, I'm reading it line by line and when the line matches, I update what's being written to the table. Then afterwards, I write the table out to the log file.

So with my data I currently have in the log file:

Code: Select all

Name            Level   HP         Gold            Shells   Tokens      Puris
charname1         80      58,687      196,029,291         340      1426      0
charname_2         61      22,725      1,383,773         960      220      1
char_3            56      8,565      1,515,562         980      280      1
char_4            55      5,436      1,360,503         980      175      2
if I do a local tt = include("logsummary.txt") how would it arrange the data in the table? What sets up the table schema to make it look like this:

Code: Select all

return{
charname1={mems=990,tokens=1200,gold=800424242400},
charname2={mems=550,tokens=1500,gold=80242424240800},
charname3={mems=400,tokens=1900,gold=800080855500},
charname4={mems=700,tokens=1100,gold=80008585800},
charname5={mems=600,tokens=3200,gold=802242424800},
}
(Actually, in my case I would try to arrange the table like this:

Code: Select all

charname1={level=80,hp=58687,gold=196029291,shells=340,tokens=1426,puris=0},
charname2={level=61,hp=22725,gold=1383773,shells=960,tokens=220,puris=1},
etc...
How would I make it read the log file and arrange the data into the table that way? Or were you saying I should have the file saved with the data looking like that, as compared to having it look the way I have it? The whole purpose for this log file is so I can open the file at any time to manually see where my characters stand with shells, puris, gold, etc...

I haven't done a lot of work with tables so I'm still learning.
User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Logging function - replace line?

#8 Post by rock5 »

I would advice, if your priority is usability of the information by the bot then do it Lisas way but if you want the file to be easily understood when you open and look at it then do it your way. Most of the time log files are meant to be looked at by human eyes so your way is best.

2 points I'd like to make.
  • 1. If you want the columns nicely lined up you can look at some of my logging to see how I do it, eg. in cot_tele.
    2. I noticed a bug in your code. What if the name doesn't already exist? It wont be added. The way I would do it is if it finds it then delete that line (or don't add it to the table). Then when you have finished reading the file (and removing the entry you will be replacing) then add the new entry to the end. The benefits of this are; if the name doesn't already exist it will be added anyway and the entries in the log will be in chronological order which I think would make it more useful.
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan
noobbotter
Posts: 527
Joined: Fri Aug 31, 2012 1:15 pm

Re: Logging function - replace line?

#9 Post by noobbotter »

Good point. When I add a new character to my list of characters I run, I wouldn't want to have to manually add an entry to this log file. So I took that advice and changed it to write all the lines that don't match player name, then go back and create a new entry in the table for the current player. (I also added os.date() into my log just so if a character didn't get to the end of his runs, I'll be able to see it here). Then I looked at the logging in cot_tele, did some research on string.format() and then created a formatting that should work well for my needs. Here's what I came up with:

Code: Select all

local gold = RoMScript('GetPlayerMoney("copper");')
	local shells = getCurrency("shell")
	local tokens = inventory:itemTotalCount(203038)
	local mems = RoMScript('GetPlayerMoney("mems");')
	local puris = inventory:itemTotalCount("Purified Fusion Stone","itemshop")
	
	local newfile = {}
	
	function readfilein()
		local readfile,err = io.open("scripts/rom/logs/LogSummary.txt","r")
		if err then return err end
		for line in readfile:lines() do 
			if not string.match(line, player.Name) then
				table.insert(newfile, line)
			end
		end
		readfile:close()
		-- going to use a separate one-time execution of a file to create the header using the following commented line
		--      header = string.format("%-10s  %-13s  %-5s  %-7s  %-11s  %-6s  %-6s  %-5s  %-5s", "Date/Time", "Name", "Level", "Max HP", "Gold", "Shells", "Tokens", "Mems", "Puris");
		-- that will be used to help me line up the actual data properly in the following line:
		local newentry = string.format("%-10s  %-13s  %-5s  %-7s  %-11s  %-6s  %-6s  %-5s  %-5s",os.date(), player.Name, player.Level, comma_value(player.MaxHP), comma_value(gold), shells, comma_value(tokens), comma_value(mems), puris)
		table.insert(newfile,newentry)
		local writefile,err = io.open("scripts/rom/logs/LogSummary.txt","w+")
		for k,v in pairs(newfile) do
			--printf("%s\n",v)
			writefile:write(v.."\n")
		end
		writefile:close()
	end
	
	function comma_value(n)
		local left,num,right = string.match(n,'^([^%d]*%d)(%d*)(.-)$')
		return left..(num:reverse():gsub('(%d%d%d)','%1,'):reverse())..right
	end
	readfilein()
Last edited by noobbotter on Fri Jan 24, 2014 12:27 pm, edited 1 time in total.
User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Logging function - replace line?

#10 Post by rock5 »

Sorry but I edited your posts to make those long lines into 2 lines because it's a bit annoying to have to scroll left and right to read this topic. :D Shouldn't affect the functionality of the code.
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan
noobbotter
Posts: 527
Joined: Fri Aug 31, 2012 1:15 pm

Re: Logging function - replace line?

#11 Post by noobbotter »

I just did an update on that last post while you did that. And thanks. That left-right scrolling was driving me nuts.
User avatar
lisa
Posts: 8332
Joined: Tue Nov 09, 2010 11:46 pm
Location: Australia

Re: Logging function - replace line?

#12 Post by lisa »

wow you guys over think things, k.i.s.s. (keep it simple s)

Ok so you want a file that is easy to look at but being easy to look at isn't easy for coding usage, so have 2 files.

ok the
local hh = include("filename.lua")
makes hh be the actual table, simple as that.

Now to save the table in the file format required for table do

Code: Select all

file:write("return { \n")
for k,v in pairs(hh) do
file:write(k.."={x="..v.x..",z="..v.z..",y="..v.y.."},\n") 
end
file:write("}")
file:close()
-- k will be char name, v. will be the values for that character.

Then do the format you want for the file you want to actually read, it will still only take miliseconds to do it.
Remember no matter you do in life to always have a little fun while you are at it ;)

wiki here http://www.solarstrike.net/wiki/index.php?title=Manual
User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Logging function - replace line?

#13 Post by rock5 »

Sorry Lisa but I can't see any reason to have a table of separate values unless you intend to use it somehow. I don't think I've seen the user mention anywhere that they want to use the data. I think all they wanted was a log that only had 1 entry per character.

You know, updating a log instead of adding to it, is a good idea. I wonder if you should add an option for it in your logger userfunction.
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan
User avatar
lisa
Posts: 8332
Joined: Tue Nov 09, 2010 11:46 pm
Location: Australia

Re: Logging function - replace line?

#14 Post by lisa »

I did it that way because reading each line and doing string searches for char names and and then trying to identify what values are which and so on is a major pain in the head.

Saving data as a table and using it to update single lines is extremely easy, as I showed earlier, it even adds new characters without any issues or extra code.
Remember no matter you do in life to always have a little fun while you are at it ;)

wiki here http://www.solarstrike.net/wiki/index.php?title=Manual
User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Logging function - replace line?

#15 Post by rock5 »

What do you mean by "trying to identify what values are which"? All you need to do is the string search for the character name.
  • Please consider making a small donation to me to support my continued contributions to the bot and this forum. Thank you. Donate
  • I check all posts before reading PMs. So if you want a fast reply, don't PM me but post a topic instead. PM me for private or personal topics only.
  • How to: copy and paste in micromacro
    ________________________
    Quote:
    • “They say hard work never hurt anybody, but I figure, why take the chance.”
          • Ronald Reagan
User avatar
lisa
Posts: 8332
Joined: Tue Nov 09, 2010 11:46 pm
Location: Australia

Re: Logging function - replace line?

#16 Post by lisa »

hmm true I keep thinking reading the data would be useful, well there is always the issue of finding partial name of name

"charname"

Would also find "charname1" "charname2" "charname3"

"stylo"
"stylobask"
"styloish"

but you could get around that by storing name with something after name

Chazza:
Vippy:
Astra:

string.find(line,player.Name..":")

either way, what ever you go with is all good.
Remember no matter you do in life to always have a little fun while you are at it ;)

wiki here http://www.solarstrike.net/wiki/index.php?title=Manual
noobbotter
Posts: 527
Joined: Fri Aug 31, 2012 1:15 pm

Re: Logging function - replace line?

#17 Post by noobbotter »

Well, I ran it the way I posted earlier and it's working good. I started it with just the header line in the log file and ran each character through and it created and formatted everything perfectly (on here they don't line up right but in notepad++, it looks good):

Code: Select all

Date/Time          Name           Level  Max HP   Gold         Shells  Tokens  Mems  Puris
01/24/14 19:52:23  			      62     22,803   1,426,093    960     320     0      1    
01/24/14 20:09:43  				  56     8,565    1,557,882    980     380     0      1    
01/24/14 20:29:53				  55     5,436    1,402,823    980     275     0      2    
01/24/14 20:47:17				  55     5,595    1,256,930    975     225     0      2    
01/24/14 21:03:08				  56     5,382    450,067      970     140     0      3    
01/24/14 21:25:12  				  56     7,093    1,519,623    960     510     0      2    
01/24/14 21:43:43  				  62     22,986   1,047,179    955     400     0      3    
01/24/14 22:00:24  				  56     4,806    746,899      975     470     0      1    
01/24/14 22:18:53  				  55     5,222    1,438,228    975     270     0      3    
01/24/14 22:36:48  				  55     4,575    1,320,658    1000    420     0      3    
(Of course, I removed the names and changed some values to protect myself). I think I'll keep it the way I have it. Seems to be updating the file much quicker than before... Maybe it was jsut taking a little longer before notepad++ realized the file had updated.
Post Reply