Create and read from logfile?

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

Create and read from logfile?

#1 Post by noobbotter » Mon Feb 18, 2013 10:32 am

I was wondering if there is a way to create a log file with some basic info in it, and then be able to read the info from that text file later. I'm wanting to use a logfile for a bot to keep track of the bot's current quest and completion state so when I later load my questing script, it can read the file to know what the last quest was that it was working on and whether it had completed it or not, that way I can make it automatically go to the waypoint it needs to in order to continue where it left off.

I was thinking maybe doing it as an XML file, but wasn't sure if there was an easy way to read and interpret the contents of a text file versus an XML file.

I was thinking something along the lines of this:

Filename would be charactername\charactername_status.xml

contents of the file would look something like:

Code: Select all

<log>
	<quest name="Frightening Giant Mosquitoes" status="accepted" />
</log>
When the bot accepts a quest in my code, I would basically overwrite this file with the new quest name and a status of accepted.
When the bot completes a quest, it would update the status of that quest to "completed."

When I start my bot, I would want to read the log file to see what the last quest it was working on and whether it still needs to be completed (in which case it would go to that quests waypoint) or if it already completed it (in which case I would have it go to the next quest). Of course I woudl still need to figure out how to store all that information to tell it where to go.

So anyway, with an XML file set up like the above one, how would I read that? Also how would I go about making the bot program write a log file in the form of an XML? is there an easy way?


Unless, of course, someone else has already figured out a good way to keep track of where a questing bot has left off. Thanks.

User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Create and read from logfile?

#2 Post by rock5 » Mon Feb 18, 2013 12:10 pm

Writing and reading in xml is a bit complicated. It would be simpler, especially for just one bit of information, to just write the info to a file in a way that would be easy to parse and read it again. Something like

Code: Select all

local questname = "Frightening Giant Mosquitoes"
local status = "accepted"

local filename = getExecutionPath() .. "/logs/"..player.Name..".log"
local file, err = io.open(filename, "w+");
if( not file ) then
	error(err, 0);
end
file:write(questname..";"..status)
file:close()
That will write
  • Frightening Giant Mosquitoes;accepted
in the file.

Then you read it with

Code: Select all

local filename = getExecutionPath() .. "/logs/"..player.Name..".log"
local file, err = io.open(filename, "r");
if( not file ) then
	error(err, 0);
end
local raw=file:read()
file:close()
local questname,status = string.match(raw,"(.*);(.*)")
  • 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: Create and read from logfile?

#3 Post by noobbotter » Mon Feb 18, 2013 1:43 pm

Thanks, Rock. That's perfect.

I'll use that method. However, I've decided to change the way it's going to keep track of where the bot was at. I'm instead going to track it by which waypoint file he was running, and what the last major waypoint was. Of course, with that, I'm also going to have to track some other things as well, so it'll take me a while to figure out what all I need to track and how to implement all of it using variables. I'll let you know how it goes.

--Edit:
Just thought of a quick question. Is there a way to get Tag for current waypoint if it has one?

User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Create and read from logfile?

#4 Post by rock5 » Mon Feb 18, 2013 3:19 pm

Code: Select all

__WPL:getNextWaypoint(-1).Tag
should work.
  • 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: Create and read from logfile?

#5 Post by noobbotter » Mon Feb 18, 2013 4:17 pm

That was easy. Ok Rock, one final question on this topic. Variable type manipulation... If I wanted to store a number in that log, if a variable was a number would it write that number to the log just as it does text? I know when I go to read that number out from the log, it will store it into whatever variable as text. To change it to a number, would I use tonumber(variablename) ? So if I stored settings.COMBAT_DISTANCE in the log file, when I read it out into a variable named combatdist, I could reset the bot's combat distance by using

Code: Select all

settings.COMBAT_DISTANCE = tonumber(combatdist)
Does that sound right?

Thanks.

User avatar
lisa
Posts: 8332
Joined: Tue Nov 09, 2010 11:46 pm
Location: Australia

Re: Create and read from logfile?

#6 Post by lisa » Mon Feb 18, 2013 6:26 pm

aslong as the string is made up of numbers that would work fine.
"43543243" is a string
43543243 is a number

tonumber("43543243") would be 43543243

tonumber("a43543243") would be nil

Personally I would just use a table to keep the log info, just make up a little userfunction which adds the info you want to a table and then saves that table to file.

Code: Select all

return{ 
--table info here
}
if the file looks like that you can then just do
local somename = include("filename.lua")

if you did it correct then somename will be a table of what was in the file.

Ok so that should answer your questions, now my questions.

How many quests are going to be in the file?
I personally think it would be much easier to just check the quests to see where you are up to, assuming you don't have hundreds in the WP database.

RoMScript("CheckQuest(420661)")

the number is the quest Id, the value will be 0,1,2
0 is not accepted,
1 is accepted,
2 is completed.

Mind you the Id of the quest isn't something people usually have.
This simple commandline would print all 30 quests in your log, even if you have just 1 quest lol

Code: Select all

questlog:update() table.print(questlog)
print will look something like this.

Code: Select all

Quest:  table: 039FD098
        1:      table: 039FD0C0
                BaseItemAddress:        330139700
                KillGoals:      table: 03D07BE8
                QuestGiver:     table: 03D07A30
                        1:      table: 03D07A58
                                Name:   Leighton
                                Id:     110482
                Name:   Testing Your Skills
                Id:     420666
                Index:  1
                Level:  2
                QuestTaker:     table: 03D07B20
                AcceptLevel:    2
                ItemGoals:      table: 03D07B70
                        1:      table: 03D07B98
                                BaseItemAddress:        37529600
                                IdType: 2
                                Id:     201171
                                Name:   Mushroom Cap
                                NumReq: 5
                Address:        10451640
        2:      table: 039FD188
                KillGoals:      table: 039FD228
                QuestGiver:     table: 039FD1B0
                Name:
                Id:     0
                Index:  2
                Level:  0
                QuestTaker:     table: 039FD1D8
                AcceptLevel:    0
                ItemGoals:      table: 039FD200
                Address:        10451652
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: Create and read from logfile?

#7 Post by noobbotter » Mon Feb 18, 2013 6:48 pm

I've kinda changed my mind. Instead of tracking it by quest, I'm going to track the bot's progress by logging waypoints so if I need to resume, I can resume straight from the last waypoint I left off at. I'm planning on doing regular quests (not dailies unless needed to fill in missing xp to get to next level when out of regular quests) and I plan on all quests for one level in one WP file. So 30.xml would be one waypoint file, 31.xml would be another and so on.

I'm finally trying some of this but I'm getting an error "error closing parser: no element found" what exactly does that mean? Couldn't find the file?

Edit-- I figured it out. Not sure now what the problem was, but I did figure it out and worked through other issues I was having. Thanks for the help. I've got it completely controlling where it's at through 5 different quests at which point the bot will (should) be at lvl 31. I still need to build an "f not 31, then fight mobs until player level is 31) and then once at 31 and finished those 5 quests, it loads up the wp file for lvl 31. The whole time, through the major waypoints, it keeps track of where it is via a log file, and the resume seems to be working fairly well.

User avatar
lolita
Posts: 139
Joined: Thu Oct 20, 2011 5:39 am
Location: Serbia

Re: Create and read from logfile?

#8 Post by lolita » Mon Aug 05, 2013 3:57 am

im working on my tiering script, i managed to read logfile and send items to alll chars on list, and at the end file is deleted

Code: Select all

function SendItemsFromFile()
	local lines = {}
	local filename = getExecutionPath() .. "/logs/SendItems.log"
	local file, err = io.open(filename, "r");
	if( not file ) then
		print("Everyone hase items, loging off");
		player:logout()
	else
		-- read the lines in table 'lines'
		for line in io.lines(filename) do
		  table.insert(lines, line)
		end
		-- sort
		table.sort(lines)
		-- send items
		for i, l in ipairs(lines) do
			UMM_SendByNameOrId(l, Tier5_list, 9)
			if (40 > inventory:itemTotalCount(0)) then
				UMM_SendByNameOrId(l, Tier5_list, 9)
				logInfo("Tiering Log", l.." got 9 items.",true)
				--some code for deliting already used line here
			else
				RoMScript("UMMFrame:Hide()")
				UMM_TakeMail()
				if (40 > inventory:itemTotalCount(0)) then
					UMM_SendByNameOrId(l, Tier5_list, 9)
					logInfo("Tiering Log", l.." got 9 items.",true)
					--some code for deliting already used line here
				else
					printf("Not enof T5 items for "..l..".\n")
					logInfo("Tiering Log", l.." didn't got Items.",true)
					player:sleep() -- if we continue, SendItems file will be delited
				end
			end
		end
		file:close()
		yrest(1000)
		os.remove(filename) -- i wand to remove this if it's posible
		print("All done")
	end
end
now i wonder can be deleted specific line in file, after i use it, so i dont have to delete logfile,
if bot run out of items, and logfile is deleted, chars wont get items?
And is there way to count bag items of table, e.g

Code: Select all

Tier5_list = {
	227700,	227701,	227702,	227703,	227704,
	227705,	227706, 227707, 227708, 227709,
	227710,	227711,
	213783,	213791,	213794,	213795,	213796,
	213797,	213798,	213799,	213800,	213801,
	213802,	213803,	213804,	213805, 213806,
	213807, 213808, 213809, 213810, 213811,
	213812, 213813, 213814, 213815, 230696,
	230690, 230697, 230698, 230699, 230700,
	230701, 230702, 230703, 230704, 230705,
	230706, 230707, 230708, 230709, 230710,
	230711, 230712, 230713, 230714, 230715,
	230716, 230717, 230718, 230719, 230720,
	-- Other items
	231921, 231923, 231965,
}
inventory:itemTotalCount(Tier5_list)  ????
Life is a journey, not destination :D

User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Create and read from logfile?

#9 Post by rock5 » Mon Aug 05, 2013 5:19 am

I don't think I've ever had to do it but I think deleting lines is either impossible or very difficult. I think normally the whole file is read to a variable, the contents changed, then the whole thing is written back again.

As for the item counting, you would have to create your own code. Something like,

Code: Select all

local count = 0
for k, id in pairs(Tier5_list) do
    count = count + inventory:itemTotalCount(id)
end
print("Total count of table items = "..count)
  • 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
lolita
Posts: 139
Joined: Thu Oct 20, 2011 5:39 am
Location: Serbia

Re: Create and read from logfile?

#10 Post by lolita » Mon Aug 05, 2013 5:44 am

code for counting work's, take some time but working fine. Maybe yyou should add it to your Count mobs userfunction

Code: Select all

function CountTable(_table)
	local count = 0
	for k, id in pairs(_table) do
		count = count + inventory:itemTotalCount(id)
	end
	print("Total count of table items = "..count)
	return count
end
and for deliting lines, i got another idea, can i do soething like this

Code: Select all

for i, l in ipairs(lines) do
			UMM_SendByNameOrId(l, Tier5_list, 9)
			if (40 > inventory:itemTotalCount(0)) then
				UMM_SendByNameOrId(l, Tier5_list, 9)
				logInfo("Tiering Log", l.." got 9 items.",true)
				table.remove(lines, l)
			else
				RoMScript("UMMFrame:Hide()")
				UMM_TakeMail()
				if (40 > inventory:itemTotalCount(0)) then
					UMM_SendByNameOrId(l, Tier5_list, 9)
					logInfo("Tiering Log", l.." got 9 items.",true)
					table.remove(lines, l)
				else
					printf("Not enof T5 items for "..l..".\n")
					logInfo("Tiering Log", l.." didn't got Items.",true)
					file:write(lines)
					file:close()
					player:sleep() -- if we continue, SendItems file will be delited
				end
			end
		end
to remove lines from table every time items are send, and if it comes to error, save tabe back and exit loop?
Life is a journey, not destination :D

User avatar
rock5
Posts: 12173
Joined: Tue Jan 05, 2010 3:30 am
Location: Australia

Re: Create and read from logfile?

#11 Post by rock5 » Mon Aug 05, 2013 6:57 am

If it's noticeably slow it's because it goes through the inventory for each id. It can be made faster by making a custom counting function that goes through the inventory only once. Something like this,

Code: Select all

function CountTable(_table)
    local function isInTable(_id) -- Function to check if id is in table
        for k, id in pairs(_table) do
            if id == _id then return true end
        end
        return false
    end

    local first, last = 61, 240 -- Slot number range
    local item
    local count = 0
    for slot = first, last do
        item = inventory.BagSlot[slot]
        item:update()
        if item.Available and (not item.Empty) and isInTable(item.Id) then
            count = count + item.ItemCount
        end
    end
    return count
end
If I thought this was something that was needed I'd probably just add it to itemTotalCount but I don't see a real need for it. In most cases you wouldn't want to count the total of different items.
  • 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
lolita
Posts: 139
Joined: Thu Oct 20, 2011 5:39 am
Location: Serbia

Re: Create and read from logfile?

#12 Post by lolita » Tue Aug 06, 2013 2:53 am

ty rock5, second code is much faster and working as intended.
i finally achieved what i wanted to read/write log file line by line if fail to send items
Here is template , if someone need it, for sending fusions to char' on list

Code: Select all

function SendItemsFromFile()
	local lines = {}
	local filename = getExecutionPath() .. "/logs/testing.log"
	local file, err = io.open(filename, "r");
	if( not file ) then
		print("File not found");
		player:sleep()
	else
		local newlines = {}
		-- read the lines in table 'lines'
		for line in io.lines(filename) do
		  table.insert(lines, line)
		end
		-- sort table
		table.sort(lines)
		table.concat(lines, "\n")
		cprintf(cli.blue,"We need To send to those chars:\n")
		for k,v in pairs(lines) do
			print(k,v)
		end
		cprintf(cli.green,"Start Sending Items\n")
		-- send items
		for i, l in ipairs(lines) do
			local fusion = inventory:itemTotalCount("Fusion Stone", "bags")
			-- read the lines in table 'newlines'
			if newlines[1] == nil then
				cprintf(cli.green,"Reading lines...\n")
				for line in io.lines(filename) do
					table.insert(newlines, line)
					cprintf(cli.lightblue,"Adding "..line.." to list\n")
				end
				table.sort(newlines)
			end
			if fusion > 0 then
				UMM_SendByNameOrId(l,"Fusion Stone", 1)
				--logInfo("Tiering Log", l.." got 9 items.",true)
				table.remove(newlines, 1)
			else
				cprintf(cli.red,"Not enof fusions for "..l..".\n")
				logInfo("Tiering Log", l.." didn't got Items.",true)
			end
		end
		file:close()
		local newfile, err = io.open(filename, "w+");
		newfile:write(table.concat(newlines, "\n"))
		yrest(1000)
		newfile:close()
		cprintf(cli.green,"All done\n")
	end
end
thx again rock5
Life is a journey, not destination :D

Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 2 guests