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.

[SOLVED] Bartender script (PHP)

Requests for complete scripts or modifications/fixes for scripts you didn't write. Response not guaranteed, and no thread bumping!
Post Reply
User avatar
Fire-Fox
Master
Posts: 289
Joined: Sat Sep 23, 2006 9:01 pm
Location: /dev/null

[SOLVED] Bartender script (PHP)

Post by Fire-Fox »

Hi,

I have a fun project as I don't know much tcl and would love this to work with tcl :)

Code: Select all

<?php

class serve_mod extends module {

	public $title = "iRC SerVe";
	public $author = "g2x3k";
	public $version = "0.2";

	public function init() {
		// init


		// not working atm .. *TODO
		$this->serve["settings"]["antispam"] = "1/3"; //1 trigger each 3 sec ...
		$this->serve["settings"]["spamreplies"][] = "Hey hey there dont you think its going a bit to fast there only [since] since youre last ...";
		$this->serve["settings"]["spamreplies"][] = "iam busy ...";
		$this->serve["settings"]["spamreplies"][] = "havent you just had ?";
		$this->serve["settings"]["dateformat"] = "h:i:s";
		// config of avaible stuff for serving ...
		
		$this->serve["triggers"]["bar"] = "This Bar have: !coffee !bang !cola !beer !joint !head !mix !whisky !pipe !pussy !coke !icecream";
		$this->serve["triggers"]["coke"] = "Are you stupid? We doesn't do [censored] like this... GO SLAP YOUR SELF IN THE NUTS! :P";
		
		$this->serve["triggers"]["coffee"]  = "Making a cup of coffee for [nick], [today] made today of [total] ordered wich make it the [sumtotal] time i make coffee";

		$this->serve["triggers"]["bang"][] 	= "fills a bang from stash and serves it to [nick] ([today]/[total]/[sumtotal])";
		$this->serve["triggers"]["cola"][] 	= "Serves icecold cola ([today]/[total]/[sumtotal])";
        $this->serve["triggers"]["cola"][] 	= "Serves cola that been laying in pile of [censored] ~45c ([today]/[total]/[sumtotal])";
        $this->serve["triggers"]["cola"][] 	= "Serves cola been standing close to box of dryice ~1,3c ([today]/[total]/[sumtotal])";
		$this->serve["triggers"]["cola"][] 	= "Serves cola that been standing next to comp for few hrs ([today]/[total]/[sumtotal])";
		$this->serve["triggers"]["beer"][] 	= "Serves icecold beer ([today]/[total]/[sumtotal])";
		$this->serve["triggers"]["joint"][] = "Grabs a joint to [nick] from the stash ([today]/[total]/[sumtotal])";

		$this->serve["triggers"]["head"][] 	= ".h.e.a.d. ([total])";
		$this->serve["triggers"]["head"][] 	= "head for you sir. ([total])";
		
        $this->serve["triggers"]["wine"][] 	= "pours up some fine stuff from the basement ([total])";
        $this->serve["triggers"]["wine"][] 	= "here you are, found something out back ([total])";		
        $this->serve["triggers"]["wine"][] 	= "lucky you we just got one of this left enjoy ([total])";
		$this->serve["triggers"]["wine"][] 	= "so youre hit hard, where you want it ?, dont cry";
		
		$this->serve["triggers"]["mix"][] 	= "grinding up some weed for a mix ([total])";
		$this->serve["triggers"]["mix"][] 	= "grabs some the good stuff for a mix ([total])";
		$this->serve["triggers"]["mix"][] 	= "sneaks into g2x3ks stash and steals for a mix, here you go ([total])";
		$this->serve["triggers"]["mix"][] 	= "goes strain hunting in india for some good [censored] for your mix ([total])";
		$this->serve["triggers"]["mix"][] 	= "goes strain hunting in morocco for some good [censored] for your mix ([total])";

		$this->serve["triggers"]["pipe"][] 	= "goes strain hunting in morocco for some good [censored] for your pipe ([total])";
        $this->serve["triggers"]["pipe"][] 	= "saw some [censored] in corner, fills a pipe ([total])";
        $this->serve["triggers"]["pipe"][] 	= "skunky just arrieved peace all over ([total])";
        
        $this->serve["triggers"]["whiskey"][] 	= "serves whiskey on the rocks ([total])";
        $this->serve["triggers"]["whiskey"][] 	= "found some weird looking bottle in corner, might hit gold cheers ([total])";
        $this->serve["triggers"]["whiskey"][] 	= "cola and bad whiskey for you ([total])";
        
		$this->serve["triggers"]["pussy"][]	= "slaps [nick] in face with a smelly pussy ([total])";
		$this->serve["triggers"]["pussy"][] = "Sends some pussy [nick]`s way .. ([total])";
		$this->serve["triggers"]["pussy"][] = "not enough money to suply you aswell ... ([total])";

    	$this->serve["triggers"]["icecream"][] 	= "here [nick]... one ball for you only ([today]/[total]/[sumtotal])";
        $this->serve["triggers"]["icecream"][] 	= "finds a biig icecream for [nick] eat and you get for free (50$ to use toilet) ([today]/[total]/[sumtotal])";
        $this->serve["triggers"]["icecream"][] 	= "dusts off something that look like icecream from the corner of fridge, here [nick] ([today]/[total]/[sumtotal])";
		// - docu:
		// [nick] = nick that triggered, [today] how many heads/coffee person had today
		// [total] = how many nick had it total, [last] time of last, [since] time since last
		// [sumtotal], [sumchannel], [sumnetwork] = how many all had

		// - reply syntax (random reply) :
		// $this->serve["triggers"]["coffee"]["replies"][] = "some reply here";
		// $this->serve["triggers"]["coffee"]["replies"][] = "another reply here";
		// - reply syntax - two line reply:
		// $this->serve["triggers"]["coffee"]["replies"][1] = "Line 1 of the reply 1";
		// $this->serve["triggers"]["coffee"]["replies"][1] = "Line 2 of the reply 1";
		// $this->serve["triggers"]["coffee"]["replies"][2] = "Line 1 of the reply 2";
		// $this->serve["triggers"]["coffee"]["replies"][2] = "Line 2 of the reply 2";
		// * [1/2] binds the two replies togeter must be incremented

		// - default settings syntax
		// $this->serve["settings"]["antispam"] = "1/3"; //1 trigger each 3 sec ...
		// $this->serve["settings"]["dateformat"] = "h:i:s";
		// - trigger settings syntax (overrides default settings if set)
		// $this->serve["triggers"]["coffee"]["settings"]["antispam"] = "1/60"; one a minute
		// $this->serve["triggers"]["coffee"]["settings"]["spamreplies"][] = "hey stop that iam burning my hands on this coffee ... one per minute shuld be enough";
		// set timer to clear "today" stats every 24hr

		// timer stuff
		//timerinfo for nxt day
		$args = new argClass();
		$args->timerid = strtotime(date("Y-m-d 00", time()+86400).":00:00");
		$settimer = $args->timerid-time();
		//start timers
		$this->ircClass->privMsg("#coders", "timer set to run at $args->timerid / ".date("Y-m-d H:i:s",$args->timerid));
		$this->timerClass->addTimer("serveclear" . $args->timerid, $this, "timer_serve", $args, $settimer, false);

	}

	public function timer_serve($args = false) {
		//clear daily stats
		$res = $this->db->query("UPDATE `layer13`.`servestats` SET `today` = '0'");
		$this->ircClass->privMsg("#coders", "cleared serve_today");

		//timerinfo for nxt day
		$args = new argClass();
		$args->timerid = strtotime(date("Y-m-d 00", time()+86400).":00:00");
		$settimer = $args->timerid-time();
		//start timers
		$this->ircClass->privMsg("#coders", "timer set to run at $args->timerid / ".date("Y-m-d H:i:s",$args->timerid));
		$this->timerClass->addTimer("serveclear" . $args->timerid, $this, "timer_serve", $args, $settimer, false);
	}

	public function priv_serve($line, $args) {
		$chan = strtolower($line['to']);
		$nick = $line['fromNick'];
		$address = $line["fromIdent"]."@".$line["fromHost"];
		$network = $this->ircClass->getServerConf ("NETWORK");

		// failsafes ...
		if (strpos ( $chan, "#" ) === false)
		return;
		if ($this->ircClass->getStatusRaw () != STATUS_CONNECTED_REGISTERED)
		return;
		if ($line['to'] == $this->ircClass->getNick())
		return; // dont work in private ...
      
		foreach ($this->serve["triggers"] as $trigger => $reply) {
			if (preg_match("/(!|\.)$trigger\b/i", $line["text"])) {

				// parse trigger settings and replies

				$rid = rand(0, count($reply)-1);

				if (is_array($reply)) $reply = $reply[$rid];


				// check for nick in db
				$ures = $this->db->query("SELECT * FROM servestats WHERE nick LIKE ".sqlesc($nick)." AND network LIKE '$network' AND type LIKE ".sqlesc($trigger)." LIMIT 1");
				if (mysql_num_rows($ures) >= 1) {
					$urow = mysql_fetch_assoc($ures);

					$nres = $this->db->query("UPDATE `layer13`.`servestats` SET `today` = today+1, `total` = total+1 WHERE `servestats`.`id` = $urow[id]");

				}
				else {
					// check for address in db'
					$ures = $this->db->query("SELECT * FROM servestats WHERE address LIKE ".sqlesc($address)." AND network LIKE '$network' AND type LIKE ".sqlesc($trigger)."");
					if (mysql_num_rows($ures) >= 1) {
						$urow = mysql_fetch_assoc($ures);
						//$this->ircClass->privMsg("$chan", "found in db using address .. setting nick and updateing");
						$nres = $this->db->query("UPDATE `layer13`.`servestats` SET `today` = today+1, `total` = total+1, `nick` = ".sqlesc($nick)." WHERE `servestats`.`id` = $urow[id]");
					}
					else {
						// else add
						//$this->ircClass->privMsg("$chan", "not found in db ($nick - $address) .. adding");
						$ires = $this->db->query("INSERT INTO `layer13`.`servestats` (`id`, `nick`, `address`, `type`, `last`, `today`, `total`, `channel`, `network`)
						 VALUES (NULL, ".sqlesc($nick).", ".sqlesc($address).", ".sqlesc($trigger).", UNIX_TIMESTAMP(), '1', '1', ".sqlesc($chan).", ".sqlesc($network).");");
					}
				}

				// grab info from db parse reply and return result
				$ures = $this->db->query("SELECT * FROM servestats WHERE nick LIKE ".sqlesc($nick)." AND network LIKE '$network' AND type LIKE ".sqlesc($trigger)." LIMIT 1");
				$urow = mysql_fetch_assoc($ures);
				//grap totals
				$tres = $this->db->query("SELECT sum(total) as sumtotal, sum(today) as sumtoday  FROM servestats WHERE network LIKE '$network' AND type LIKE ".sqlesc($trigger)." LIMIT 1");
				$trow = mysql_fetch_assoc($tres);

				$message = str_replace(array("[nick]", "[today]", "[total]", "[sumtotal]", "[sumtoday]"), array("$nick", $urow["today"], $urow["total"], $trow["sumtotal"],$trow["sumtoday"]), $reply);
				//lookup nick or insert, update stats and reply
				//$this->ircClass->privMsg("$chan", "trigger: $trigger - $reply @ $chan/$network");
				$this->ircClass->privMsg("$chan", "$message");
			}
		}
	}

	function addOrdinalNumberSuffix($num) {
		if (!in_array(($num % 100),array(11,12,13))){
			switch ($num % 10) {
				// Handle 1st, 2nd, 3rd
				case 1:  return $num.'st';
				case 2:  return $num.'nd';
				case 3:  return $num.'rd';
			}
		}
		return $num.'th';
	}
}
?>
SQL Shcema (If it helps)

Code: Select all

CREATE TABLE IF NOT EXISTS `servestats` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nick` varchar(32) CHARACTER SET latin1 NOT NULL,
  `address` varchar(255) CHARACTER SET latin1 NOT NULL,
  `type` varchar(255) CHARACTER SET latin1 NOT NULL,
  `last` decimal(11,0) NOT NULL,
  `today` int(11) NOT NULL,
  `total` int(11) NOT NULL,
  `channel` varchar(255) CHARACTER SET latin1 NOT NULL,
  `network` varchar(255) CHARACTER SET latin1 NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
Last edited by Fire-Fox on Sat May 27, 2023 3:41 am, edited 2 times in total.
GreatZ
Fire-Fox | Denmark

Scripts: Relay | Store Text | TvMaze
User avatar
Fire-Fox
Master
Posts: 289
Joined: Sat Sep 23, 2006 9:01 pm
Location: /dev/null

Post by Fire-Fox »

No one what can help with it :)
GreatZ
Fire-Fox | Denmark

Scripts: Relay | Store Text | TvMaze
s
simo
Revered One
Posts: 1069
Joined: Sun Mar 22, 2015 2:41 pm

Post by simo »

It helps if u provide a detailed description of what it does
User avatar
Fire-Fox
Master
Posts: 289
Joined: Sat Sep 23, 2006 9:01 pm
Location: /dev/null

Post by Fire-Fox »

simo wrote:It helps if u provide a detailed description of what it does
What the script does is servering things to users :-)

Code: Select all

 - docu:
[nick] = nick that triggered, [today] how many heads/coffee person had today
[total] = how many nick had it total, [last] time of last, [since] time since last
[sumtotal], [sumchannel], [sumnetwork] = how many all had
Triggers:

Code: Select all

$this->serve["triggers"]["bar"] = "This Bar have: !coffee !bang !cola !beer !joint !head !mix !whisky !pipe !pussy !coke !icecream";
EX 1:

Code: Select all

!coffee
Output:

Code: Select all

 $this->serve["triggers"]["coffee"]  = "Making a cup of coffee for [nick], [today] made today of [total] ordered wich make it the [sumtotal] time i make coffee";
And it stores it in a mysql database[/quote]
GreatZ
Fire-Fox | Denmark

Scripts: Relay | Store Text | TvMaze
s
simo
Revered One
Posts: 1069
Joined: Sun Mar 22, 2015 2:41 pm

Post by simo »

you can find a lot of script for that on

https://tclarchive.org/search.php?str=b ... =0&sub.y=0
User avatar
Fire-Fox
Master
Posts: 289
Joined: Sat Sep 23, 2006 9:01 pm
Location: /dev/null

Post by Fire-Fox »

I have been there, and non of them do what I need
GreatZ
Fire-Fox | Denmark

Scripts: Relay | Store Text | TvMaze
User avatar
SpiKe^^
Owner
Posts: 831
Joined: Fri May 12, 2006 10:20 pm
Location: Tennessee, USA
Contact:

Post by SpiKe^^ »

SpiKe^^

Get BogusTrivia 2.06.4.7 at www.mytclscripts.com
or visit the New Tcl Acrhive at www.tclarchive.org
.
User avatar
Fire-Fox
Master
Posts: 289
Joined: Sat Sep 23, 2006 9:01 pm
Location: /dev/null

Post by Fire-Fox »

Thanks, but as I can see there is no total/sumtotal = have many drinks a user have had, in total today. and grand total all time :)

Like:

Code: Select all

(Today: 1, Your Total: 406, Grand Total all users: 967)
GreatZ
Fire-Fox | Denmark

Scripts: Relay | Store Text | TvMaze
User avatar
CrazyCat
Revered One
Posts: 1215
Joined: Sun Jan 13, 2002 8:00 pm
Location: France
Contact:

Post by CrazyCat »

User avatar
caesar
Mint Rubber
Posts: 3776
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

Saw your code and added the 'nick change' he asked, made a few changes here and there. To name a few..

1. Replaced [list ... ] with { .. }. From the point of view of the compiler it makes no difference, but for user it's easier to see a difference between:

Code: Select all

 set replies(cola) [list "Serves icecold cola (%utoday/%utotal/%ctotal)" \
      "Serves cola that been laying in pile of [censored] ~45c (%utoday/%utotal/%ctotal)" \
      "Serves cola been standing close to box of dryice ~1,3c (%utoday/%utotal/%ctotal)" \
      "Serves cola that been standing next to comp for few hrs (%utoday/%utotal/%ctotal)"]
and this:

Code: Select all

	set replies(cola) {
		"Serves icecold cola (%utoday/%utotal/%ctotal)"
		"Serves cola that been laying in pile of [censored] ~45c (%utoday/%utotal/%ctotal)"
		"Serves cola been standing close to box of dryice ~1,3c (%utoday/%utotal/%ctotal)"
		"Serves cola that been standing next to comp for few hrs (%utoday/%utotal/%ctotal)"
	}
2. string map is your friend, 'regsub -all --' isn't. :)

3. Removed formatmsg function, rebuilt the help one, and some other things I don't remember right now... oh.. and made the stats record stuff in lower case to make it work case in-sensitive.

Anyway, here's the updated code that he says is working as intended.

Code: Select all

# Bartender v0.2b
# By CrazyCat <https://www.eggdrop.fr>
#
# type .chanset #channel +bar to activate on #channel
# help command is !bar (public command on channel)

namespace eval bartender {

	# List of replies
	# Variables:
	# - %nick : nick of the user
	# - %utoday, %utotal : user count for today and total
	# - %ctoday, %ctotal : channel count for today and total
   
	set replies(coke) {
		"Are you stupid? We doesn't do [censored] like this... GO SLAP YOUR SELF IN THE NUTS! :P"
	}
	
	set replies(coffee) {
		"Making a cup of coffee for %nick, %utoday made today of %utotal ordered wich make it the %ctotal time i make coffee"
	}
	
	set replies(bang) {
		"fills a bang from stash and serves it to %nick (%utoday/%utotal/%ctotal)"
	}
	
	set replies(cola) {
		"Serves icecold cola (%utoday/%utotal/%ctotal)"
		"Serves cola that been laying in pile of [censored] ~45c (%utoday/%utotal/%ctotal)"
		"Serves cola been standing close to box of dryice ~1,3c (%utoday/%utotal/%ctotal)"
		"Serves cola that been standing next to comp for few hrs (%utoday/%utotal/%ctotal)"
	}
	
	set replies(beer) {
		"Serves icecold beer (%utoday/%utotal/%ctotal)"
	}
	set replies(joint) {
		"Grabs a joint to %nick from the stash (%utoday/%utotal/%ctotal)"
	}

	# and so on.. you should get the idea.. I'm lazy.
   
	# antiflood delay (in seconds)
	variable delay 10
   
	###############################
	## DO NOT EDIT BELOW
	###############################

	variable wait
 	variable author "CrazyCat"
	variable version "0.2b"
	setudef flag bar
	setudef str bardb
   
	# Running command
	proc process {nick uhost handle chan text} {
		if {![channel get $chan bar]} { return }
		set now [clock seconds]
		set cmd [string range $::lastbind 1 end]
		set chan [string tolower $chan]
		if {![info exists ::bartender::wait($chan)] || $::bartender::wait($chan)<$now} {
			set ::bartender::wait($chan) [expr $now +3]
		} else {
			set since [expr $::bartender::wait($chan) - $now]
			set answer [lindex $::bartender::spam [rand [llength $::bartender::spam]]]
			puthelp "PRIVMSG $chan :[string map [list %since $since] $answer]"
			return
		}
		if {![info exists ::bartender::replies($cmd)]} {
			putserv "PRIVMSG $chan :The bar have [join $::bartender::cmds]"
			return
		}
		set lowerNick [string tolower $nick]
		statadd $chan $lowerNick $cmd
		set answer [lindex $::bartender::replies($cmd) [rand [llength $::bartender::replies($cmd)]]]
		set bar [channel get $chan bardb]
		set ctoday [dict get $bar today]
		set ctotal [dict get $bar total]
		set utoday [dict get $bar nicks $lowerNick today]
		set utotal [dict get $bar nicks $lowerNick total]
		if {[scan $text {%s} guest] < 0} {
			set reply [string map [list %nick $lowerNick] $answer]
		} else {
			set reply [string map [list %nick $guest] $answer]
		}
		putserv "PRIVMSG $chan :[string map [list %chan $chan %ctoday $ctoday %ctotal $ctotal %utotal $utotal %utoday $utoday] $reply]"
	}

	# Add stats in bardb 
	proc statadd {chan nick cmd} {
		if {[channel get $chan bardb] eq ""} {
			dict set bar total 1
			dict set bar today 1
			dict set bar nicks $nick today 1
			dict set bar nicks $nick total 1
			channel set $chan bardb $bar
			return
		}
		set bar [channel get $chan bardb]
		dict incr bar total
		dict incr bar today
		if {![dict exists $bar nicks $nick]} {
			dict set bar nicks $nick today 1
			dict set bar nicks $nick total 1
		} else {
			set bn [dict get $bar nicks $nick]
			dict incr bn total
			dict incr bn today
			dict set bar nicks $nick $bn
		}
		channel set $chan bardb $bar
		return
	}
   
	# Creates associated binds
	foreach ele [binds [namespace current]::*] {
		if {[scan $ele {%s%s%s%d%s} type flags cmd hits func] != 5} continue
		if {$type ne "pub"} continue
		unbind $type $flags $cmd $func
	}

	foreach trigger [array names ::bartender::replies] {
		bind pub - !$trigger ::bartender::process
		lappend ::bartender::cmds "!$trigger"
	}
   
	# Small help: list all commands
	bind pub - !bar ::bartender::help
	
	proc help {nick uhost handle chan text} {
		if {![channel get $chan bar]} { return }
		foreach ele [array names ::bartender::replies] {
			lappend menu !$ele
		}
		putserv "PRIVMSG $chan :Today's menu: [join $menu ", "]"	
	}
   
	# Reset "Today" stats
	bind time - "00 00 * *" ::bartender::restoday
	
	proc restoday {mi ho dm mo} {
		foreach chan [channels] {
		if {![channel get $chan bar]} {
			channel set $chan bardb {}
			continue
		}
		set bar [channel get $chan bardb]
		if {$bar ne ""} {
			dict set bar today 0
			foreach nick [dict keys [dict get $bar nicks]] {
				dict set bar nicks $nick today 0
			}
		}
		channel set $chan bardb $bar
	}

	putlog "Bartender v${::bartender::version} by ${::bartender::author} loaded"
}
Once the game is over, the king and the pawn go back in the same box.
User avatar
CrazyCat
Revered One
Posts: 1215
Joined: Sun Jan 13, 2002 8:00 pm
Location: France
Contact:

Post by CrazyCat »

1. I used list rather than simplified writing because the script was also a kind of tutorial, but I usually use {}

2. True, but regsub (and regexp) is my friend. I've a friend, yeah ! :)

3. Can't remind why I made a proc formatmsg, probably I started on a more complex script

3.1. I forget my usual set nick [string tolower $nick] :)
3.2. You added an unbind onload... Usefull to remove deleted replies key on rehash / source
3.3. you recreate the help string on the fly rather than use $::bartender::cmds variable... impact on performances ?

And you don't check if "guest" is on chan :) Could be interresting (was my idea, but I'll do that tomorrow)
User avatar
CrazyCat
Revered One
Posts: 1215
Joined: Sun Jan 13, 2002 8:00 pm
Location: France
Contact:

Post by CrazyCat »

I've updated my source. And kept my formatmsg proc :)
User avatar
Fire-Fox
Master
Posts: 289
Joined: Sat Sep 23, 2006 9:01 pm
Location: /dev/null

Post by Fire-Fox »

All working as intended :)
GreatZ
Fire-Fox | Denmark

Scripts: Relay | Store Text | TvMaze
User avatar
caesar
Mint Rubber
Posts: 3776
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

I copied the restoday as it was and didn't pay much attention to it. Today Fire asked me to have a look at an error he was getting and noticed that the time function had 4 arguments, while it expects 5 space separated integers of the form of "minute hour day month year".

To fix this replace:

Code: Select all

proc restoday {mi ho dm mo} { 
with:

Code: Select all

proc restoday {minute hour day month year} {
or use the args trick since any of the arguments isn't used in the function:

Code: Select all

proc restoday args {
Once the game is over, the king and the pawn go back in the same box.
User avatar
CrazyCat
Revered One
Posts: 1215
Joined: Sun Jan 13, 2002 8:00 pm
Location: France
Contact:

Post by CrazyCat »

You're right, didn't seen my version on gitlab was false.
Source corrected.

Nota: you can do PR on it rather than let me editing to add your corrections :)
Post Reply