This is the new home of the egghelp.org community forum.
All data has been migrated (including user logins/passwords) to a new phpBB version.


For more information, see this announcement post. Click the X in the top right-corner of this box to dismiss this message.

Working with INI Files

Old posts that have not been replied to for several years.
D
Darkj
Halfop
Posts: 86
Joined: Sun Jul 06, 2003 9:58 pm

Working with INI Files

Post by Darkj »

I'm using INI Database v0.4.2 by mamaKIN, and basically, the way it works is three ways:

ini_read <inifile> <section> <item>
ini_write <inifile> <section> <item> [value]
ini_remove <inifile> <section> <item>

What I want to do is set up a bots listing service, for macro bots in games etc.

I've got the list to work with files, been good for some time, but I wanna covert it to INI files, just to clean things up a bit. Right now, I can !addbot <nickname> and it will add it to a file and set the line to None Nowhere None.

Which looks like this in the file:
BotName None Nowhere None

Now if it were in an INI file, it would look like this:
[botname]
charname=None
location=Nowhere
action=None

[botname1]
charname=None
location=Nowhere
action=None

Now when a user types !bots, I want it to list all the bots in the ini file, this is where I get stuck, I have no idea how to get an undetermined amount of bots out of an INI file. If anyone can give me some help, would be greatly appreaciated.
D
Darkj
Halfop
Posts: 86
Joined: Sun Jul 06, 2003 9:58 pm

Post by Darkj »

Anyone that could provide a little help here would be greatly appreciated, I'm very stuck.
User avatar
user
&nbsp;
Posts: 1452
Joined: Tue Mar 18, 2003 9:58 pm
Location: Norway

Post by user »

Code: Select all

proc parseIni {file} {
	array set arr {}
	set f [open $file]
	while {[gets $f l]>-1} {
		set l [string trim $l]
		if {[string match {\[*\]} $l]} {
			set e [string range $l 1 end-1]
		} elseif {[info exists e]&&[string match *?=?* $l]} {
			regexp {^([^=]+)=(.+)$} $l a a b
			lappend arr($e) [string trim $a] [string trim $b]
		} else {
			# what to do? (invalid/empty line)
		}
	}
	close $f
	array get arr
}
# The list returned by this proc is really a multidimensional array
# Access settings like this:
array set myIni [parseIni your.ini]
array set tmpBot $myIni(botname)
# Now tmpBot is a array with element names like the ones in your ini file :)
# eg $tmpBot(charname)
D
Darkj
Halfop
Posts: 86
Joined: Sun Jul 06, 2003 9:58 pm

Post by Darkj »

Awesome, that'll be a great help, thanks.
D
Darkj
Halfop
Posts: 86
Joined: Sun Jul 06, 2003 9:58 pm

Post by Darkj »

proc parseIni {file} {
array set arr {}
set f [open $file]
while {[gets $f l]>-1} {
set l [string trim $l]
if {[string match {\[*\]} $l]} {
set e [string range $l 1 end-1]
} elseif {[info exists e]&&[string match *?=?* $l]} {
regexp {^([^=]+)=(.+)$} $l a a b
lappend arr($e) [string trim $a] [string trim $b]
} else {

#I'm stuck here, not exatly sure what needs to go here

}
}
close $f
array get arr
}

bind pub n "!test" mytestproc
proc mytestproc {nick uhost hand chan args} {
array set myIni [parseIni bots.ini]

## Don't know how to set all this up

array set tmpBot $myIni(botname)
putserv "PRIVMSG $chan :dunno what to put here"
return 0
}
D
Darkj
Halfop
Posts: 86
Joined: Sun Jul 06, 2003 9:58 pm

Post by Darkj »

Anyway I try and do it, I just get this error:

Tcl error [mytestproc]: list must have an even number of elements
D
Darkj
Halfop
Posts: 86
Joined: Sun Jul 06, 2003 9:58 pm

Post by Darkj »

Oh, and the INI file looks like this

[testbot1]
charname=testchar1
location=testloc1
action=testact1

[testbot2]
charname=testchar2
location=testloc2
action=testact2

[testbot3]
charname=testchar3
location=testloc3
action=testact3

So i don't get how $tmpBot(botname) would work
User avatar
user
&nbsp;
Posts: 1452
Joined: Tue Mar 18, 2003 9:58 pm
Location: Norway

Post by user »

Show us the code producing that error and please use code tags around it to make it readable.
D
Darkj
Halfop
Posts: 86
Joined: Sun Jul 06, 2003 9:58 pm

Post by Darkj »

Code: Select all

bind pub n "!test" mytestproc
proc mytestproc {nick uhost hand chan args} {
  array set myIni [parseIni bots.ini]
  array set tmpBot $myIni(charname)
  putserv "PRIVMSG $chan :$tmpBot"
  return 0
}
I know I probably look like a complete moron right now, but this is the first time I've ever used an array.
D
Darkj
Halfop
Posts: 86
Joined: Sun Jul 06, 2003 9:58 pm

Post by Darkj »

Code: Select all

         lappend arr($e) [string trim $a] [string trim $b] 
      } else { 
         # what to do? (invalid/empty line) 
      } 
   } 
   close $f 
   array get arr 
And i'm stuck on that invalid/empty line stuff.
User avatar
user
&nbsp;
Posts: 1452
Joined: Tue Mar 18, 2003 9:58 pm
Location: Norway

Post by user »

If your .ini contains what you pasted, that code will not produce the error you pasted.

Let me explain what's happening in the code... The proc returns a list of lists...when you use 'array set' you create an array with element names being the botnames from the ini and the elements will contain the sublists with the botsettings. To retrieve the settings for a particular bot, just fetch the element with the name of that bot. If you want to list the botnicks from the ini, use [array names theArray]. To give you a better example I need to know what you want to do.
Darkj wrote:And i'm stuck on that invalid/empty line stuff.
You don't need to care about that part if you don't want error handling (you can remove the entire "else" part of that if statement. I only included it in case you needed/wanted something like that :))
D
Darkj
Halfop
Posts: 86
Joined: Sun Jul 06, 2003 9:58 pm

Post by Darkj »

Basically I am trying to do this

I want to get the stuff from the INI File:

[testbot1]
charname=testchar1
location=testloc1
action=testact1

[testbot2]
charname=testchar2
location=testloc2
action=testact2

And make it appear on IRC in the channel when the !bots command is used

Format: (Charname) Location (Action)
eg, Testbot1: (testchar1) testloc1 (testact1) Testbot2: (testchar2) testloc2 (testact2)
D
Darkj
Halfop
Posts: 86
Joined: Sun Jul 06, 2003 9:58 pm

Post by Darkj »

Doing some !tcl tests, and the parseIni stuff is working properly, and it is returning this:

result: testbot3 {charname testchar3 location testloc3 action testact3} testbot1 {charname testchar1 location testloc1 action testact1} testbot2 {charname testchar2 location testloc2 action testact2}

Now i just need to get that formatted decently, hopefully 2 bots per line, and it would be perfect.
User avatar
user
&nbsp;
Posts: 1452
Joined: Tue Mar 18, 2003 9:58 pm
Location: Norway

Post by user »

If you don't need the setting names at any point I suggest removing them from the parseIni proc (lappend only [string trim $b])

then

Code: Select all

foreach {nick1 vars1 nick2 vars2} [parseIni bots.ini] {
  #output [join [list $nick1 $vars1 $nick2 $vars2]]
}
...i'll leave the fun part, inserting ()'s and checking if there's no bot2 (if the number of bots is not even), to you :P

EDIT: there was an error in the output example.
Last edited by user on Sun Aug 31, 2003 6:28 pm, edited 1 time in total.
D
Darkj
Halfop
Posts: 86
Joined: Sun Jul 06, 2003 9:58 pm

Post by Darkj »

Ok i lost you, that doesn't look for cutomizable, it looks like I'll have to edit code everytime I add more bots, I was trying to avoid that.
Locked