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.

storing multiple variables (counters + names) in 1 file

Help for those learning Tcl or writing their own scripts.
Post Reply
B
BCyo+8C4
Voice
Posts: 24
Joined: Sun Sep 03, 2006 11:11 am

storing multiple variables (counters + names) in 1 file

Post by BCyo+8C4 »

Hi,
is it possible to store counters for multiple persons in one file?
I know how to do it for one file per person, but having just one file would be somewhat nicer. I imagine the file looking like this:

nick 123
anothernick 456
...

Would be nice if someone could help me
B
BCyo+8C4
Voice
Posts: 24
Joined: Sun Sep 03, 2006 11:11 am

Post by BCyo+8C4 »

just had the idea of writing and deleting the lines like this, but i'd still need a way to read a) certain entries (to get the old value) and b) all values (to print stats like "nick: 123, anothernick: 456" to channel. if someone could please give me a hint on how to do that.. :)


exec echo -e "$nick: $number" >> counter.txt

exec awk -f alfa.awk -v was=$nick counter.txt
User avatar
demond
Revered One
Posts: 3073
Joined: Sat Jun 12, 2004 9:58 am
Location: San Francisco, CA
Contact:

Post by demond »

as it's been pointed out countless times already, you should read the entire file, once only, on script's startup, into a list; then manipulate that list as you wish, typically on events that your script handles; save the list periodically into a file
connection, sharing, dcc problems? click <here>
before asking for scripting help, read <this>
use

Code: Select all

 tag when posting logs, code
B
BCyo+8C4
Voice
Posts: 24
Joined: Sun Sep 03, 2006 11:11 am

Post by BCyo+8C4 »

I used search but couldn't find anything. Could you please point me to a thread with instructions/examples?
User avatar
rosc2112
Revered One
Posts: 1454
Joined: Sun Feb 19, 2006 8:36 pm
Location: Northeast Pennsylvania

Post by rosc2112 »

Plenty of examples of reading/writing files, there's even a FAQ about it under "basic file operations" http://forum.egghelp.org/viewtopic.php?t=6885

.. Also look at the lindex command.
User avatar
demond
Revered One
Posts: 3073
Joined: Sat Jun 12, 2004 9:58 am
Location: San Francisco, CA
Contact:

Post by demond »

BCyo+8C4 wrote:I used search but couldn't find anything. Could you please point me to a thread with instructions/examples?
http://forum.egghelp.org/viewtopic.php?t=11184
connection, sharing, dcc problems? click <here>
before asking for scripting help, read <this>
use

Code: Select all

 tag when posting logs, code
User avatar
user
&nbsp;
Posts: 1452
Joined: Tue Mar 18, 2003 9:58 pm
Location: Norway

Post by user »

I think an array is well suited for the type of data you want to store...

Code: Select all

# this proc will save an array as tcl code that will create the array when executed
proc savearray {array file {mode w}} {
	upvar 1 $array var
	set f [open $file $mode]
	# the file will be empty if no array by that name exists.
	if {[array exists var]} {
		puts $f [list array set $array [array get var]]
	}
	close $f
}

# create some elements
set counter(nick) 123 
set counter(anothernick) 456

# save them:
savearray counter counterdata.tcl

# load them back in:
source counterdata.tcl
The concept is identical to the code demond provided, except the array is stored as tcl code instead of storing list elements as lines in the file.
Have you ever read "The Manual"?
B
BCyo+8C4
Voice
Posts: 24
Joined: Sun Sep 03, 2006 11:11 am

Post by BCyo+8C4 »

i tried you tcl array solution, but i don't really get it

counterdata.tcl:

Code: Select all

array set counter {nick 123 anothernick 456}
the normal tcl:

Code: Select all

bind msg n !trigger		increasecounter

proc increasecounter {nick uhost hand text} {
	source counterdata.tcl
	
	foreach counter nickn {
	        set counter($nickn)
	}
	
	savearray counter counterdata.tcl
	# debug line
	putserv "PRIVMSG $nick :$counter(nick)"
}

proc savearray {array file {mode w}} { 
   upvar 1 $array var 
   set f [open $file $mode] 
   # the file will be empty if no array by that name exists. 
   if {[array exists var]} { 
      puts $f [list array set $array [array get var]] 
   } 
   close $f 
} 
I just don't get how/where to put the array data in normal strings and increase one of them. Would be nice if you could point out what I have to do.
User avatar
user
&nbsp;
Posts: 1452
Joined: Tue Mar 18, 2003 9:58 pm
Location: Norway

Post by user »

BCyo+8C4 wrote:I just don't get how/where to put the array data in normal strings and increase one of them. Would be nice if you could point out what I have to do.
There is (like demond said) no need to read/parse the file every time you want to access the data. Just load it ONCE on startup and keep the data in a global variable. Then, on a regular interval OR when you make changes (if you need the file to match the actual data at all times) save it.

Eg:

Code: Select all

# load the data if it exists
if {[file exists counterdata.tcl]} {
	source counterdata.tcl
}
# saving it when ever the userfile/channel file is saved:
bind evnt - save saveCounters
proc saveCounters x {
	global counter
	savearray counter counterdata.tcl
}
# /msg bot !incall will increase ALL counters by 3
bind msg - !incall incallcounters
proc incallcounters {nick uhost hand text} {
	global counter
	foreach cnick [array names counter] {
		incr counter($cnick) 3
	}
}
# /msg bot !incme will increase YOUR counter by 1 and display the new value
bind msg - !incme incyourcounter
proc incyourcounter {nick uhost hand text} {
	global counter
	# first, make sure there is a counter element for that nick...
	if {[info exists counter($nick)]} {
		incr counter($nick)
	} else {
		# if it doesn't exist, create it...
		set counter($nick) 1
	}
	puthelp "PRIVMSG $nick :Your new count is $counter($nick)"
}
Have you ever read "The Manual"?
B
BCyo+8C4
Voice
Posts: 24
Joined: Sun Sep 03, 2006 11:11 am

Post by BCyo+8C4 »

thank you very much, i made it work :-) wouldn't have been able to do so without your help
User avatar
user
&nbsp;
Posts: 1452
Joined: Tue Mar 18, 2003 9:58 pm
Location: Norway

Post by user »

You should add

Code: Select all

bind evnt - prerehash saveCounters
to make sure you don't load old data if you .rehash ...or you could prevent it from loading the file if the counter array exists...

Code: Select all

if {[file exists counterdata.tcl]&&![info exists counter]} {
	source counterdata.tcl 
}
Have you ever read "The Manual"?
Post Reply