ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Net-Knuddels/eg/markovd
Revision: 1.22
Committed: Sat Jan 29 10:58:50 2005 UTC (21 years, 7 months ago) by root
Branch: MAIN
Changes since 1.21: +2 -2 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 elmex 1.1 #!/usr/bin/perl
2    
3     use strict;
4 root 1.2
5 elmex 1.1 use Socket;
6     use IO::Socket::INET;
7 root 1.2
8     use YAML;
9     use Encode;
10 elmex 1.1 use Event;
11     use Net::Knuddels;
12 root 1.2 use Algorithm::MarkovChain;
13 root 1.15 use String::Similarity;
14 elmex 1.1
15     my @CHANNELS = (
16 elmex 1.3 'Flirt',
17 root 1.11 'Flirt Private',
18 root 1.10 'Singles 11-14',
19     'Singles 15-17',
20 root 1.11
21 root 1.18 'Singles 11-14 2',
22     'Singles 15-17 2',
23 root 1.11 'Flirt 2',
24 root 1.18 'Flirt Private 2',
25 root 1.11 'Singles 11-14 3',
26 root 1.18 'Singles 15-17 3',
27 root 1.11 'Flirt 3',
28 root 1.18 'Flirt Private 3',
29 root 1.11 'Singles 11-14 4',
30 root 1.18 'Singles 15-17 4',
31 root 1.11 'Flirt 4',
32 root 1.18 'Flirt Private 4',
33 root 1.11 'Singles 11-14 5',
34 root 1.18 'Singles 15-17 5',
35 root 1.11 'Flirt 5',
36 root 1.18 'Flirt Private 5',
37 root 1.11 'Singles 11-14 6',
38 root 1.18 'Singles 15-17 6',
39 root 1.11 'Flirt 6',
40 root 1.18 'Flirt Private 6',
41 root 1.11 'Singles 11-14 7',
42 root 1.18 'Singles 15-17 7',
43 root 1.11 'Flirt 7',
44 root 1.18 'Flirt Private 7',
45 root 1.11 'Singles 11-14 8',
46 root 1.18 'Singles 15-17 8',
47 root 1.11 'Flirt 8',
48 root 1.18 'Flirt Private 8',
49 elmex 1.1 );
50    
51 root 1.14 my $logdir = "logs";
52 elmex 1.4
53 root 1.18 my $Knick = "ich bin suess";
54 root 1.15 my $Kpass = "qwerty";
55 elmex 1.1
56     my $client;
57    
58 root 1.11 my $seed = Load do { open my $fh, "<", "markovbot.dat"; binmode $fh, ":utf8"; local $/; <$fh> };
59 root 1.2 $seed ||= [];
60    
61 root 1.11 my $markov = new Algorithm::MarkovChain;
62    
63     sub seed_msg {
64     my $msg = $_[0];
65 root 1.19
66 root 1.20 return if $msg =~ /leck|fick|m.se|uschi|fikkn|bumsen|wichs|wix|popp|popen|fuck|dreck|laber|saugen|pussy
67 root 1.15 |blasen
68     |hure|strich
69 root 1.18 |stengel|penis|schwanz|pimmel|steifen|ejak|sperma
70 root 1.20 |\bcs\b|\bts\b|\brs\b|\bicq\b
71 root 1.15 |cam\b|\bmsn\b|\bbot\b|\bchat.*bot\b|tanga|schlafen|sex|\bsau\b
72 root 1.18 |intim|arsch|fotze|dumm|schnauze|klappe|rasiert|fresse|maul\b|\bmaul|rosett?e
73 root 1.15 |zieh.*aus|nackt
74     |sätz|saetz|setze|\bsatz
75 root 1.20 |sc?h?wul|schwuchtel|transe|transv|schlampe|tussi
76     |mädel
77 root 1.15 |(?-i:[A-Z]{4,})
78     /xi;
79    
80 root 1.11 my @msg = $msg =~ m/(\S+)/g;
81    
82 root 1.22 $markov->seed (symbols => \@msg, longest => 9);
83 root 1.11 }
84    
85     for (@$seed) {
86     seed_msg $_;
87     }
88    
89     sub gen_reply {
90     my ($msg) = @_;
91    
92 root 1.19 #my @msg = $msg =~ /(\S+)/g;
93    
94 root 1.15 my $reply;
95     my $best = -1;
96    
97 root 1.20 for (1..30) {
98 root 1.15 my $r = join " ", $markov->spew (length => 5, stop_at_terminal => 1);
99     my $b = similarity lc $msg, lc $r, $best;
100     ($reply, $best) = ($r, $b) if $b > $best;
101     }
102    
103     $reply;
104 root 1.11 }
105    
106     Event->signal (signal => "INT", cb => sub { Event::unloop(-1) });
107 root 1.2
108 root 1.8 Event->timer (interval => 60, cb => sub {
109 root 1.11 open my $fh, ">", "markovbot.dat~"
110 root 1.2 or return;
111     print $fh Encode::encode_utf8 Dump $seed;
112     close $fh;
113 root 1.11 rename "markovbot.dat~", "markovbot.dat";
114 root 1.2 });
115    
116 elmex 1.1 sub connect_knuddels {
117     $client->login;
118     Event->io (
119     fd => $client->fh,
120     poll => 'r',
121     cb => sub {
122     my $e = shift;
123     if (not $client->ready) {
124     $e->w->cancel;
125     }
126     });
127     }
128    
129 elmex 1.4 sub logit {
130 elmex 1.6 my ($msg, $file, $src, $dst, $room) = @_;
131 elmex 1.4
132 root 1.12 mkdir $logdir;
133     my $fh;
134 elmex 1.4
135 root 1.13 unless (open $fh, ">>:utf8", Encode::encode_utf8 "$logdir/$file") {
136 elmex 1.4 warn "Couldn't open for appending $logdir/$src: $!\n";
137     return;
138     }
139    
140 root 1.12 print $fh "$room\t$src\t$dst\t$msg\n";
141 elmex 1.4 }
142    
143 elmex 1.1 ####################################################################################
144     ########################## MAIN START ##############################################
145     ####################################################################################
146    
147     $client = new Net::Knuddels::Client PeerAddr => "213.61.5.150:2710";
148    
149 root 1.11 #$client->register (ALL => sub {
150 root 1.7 # use Dumpvalue;
151     # print "---\n";
152     # Dumpvalue->new (compactDump => 1, veryCompact => 1, quoteHighBit => 1, tick => '"')->dumpValue ([@_]);
153     #});
154    
155 elmex 1.1 $client->register (login => sub {
156 root 1.15 Event->timer (after => 0, interval => 1, repeat => 0, cb => sub {
157 root 1.18 my $channel = shift @CHANNELS
158 root 1.15 or return;
159    
160     $client->enter_room ($channel, $Knick, $Kpass);
161     $_[0]->w->again;
162     });
163 elmex 1.1 });
164    
165     $client->register (msg_room => sub {
166     my ($room, $user, $msg) = @_;
167 root 1.2 });
168    
169     my @queue;
170    
171     Event->timer (interval => 1, cb => sub {
172     my $msg = shift @queue
173     or return;
174    
175 elmex 1.6 logit ($msg->[2], $msg->[0], $Knick, $msg->[0], $msg->[1]);
176 root 1.2 $client->send_priv_msg (@$msg);
177 elmex 1.1 });
178    
179 root 1.20 my $some_room;
180    
181 root 1.17 $client->register (room_info => sub {
182 root 1.20 print "JOIN ROOM: $_[0]\n";
183     $some_room = $_[0];
184     });
185    
186     Event->timer (after => 60, interval => 60, cb => sub {
187     $client->send_priv_msg ("James", $some_room, "/knuschel");
188 elmex 1.16 });
189 root 1.17
190 root 1.18 my %next_time;
191    
192 elmex 1.16 $client->register (msg_priv_nondup => sub {
193 elmex 1.1 my ($room, $src, $dst, $msg) = @_;
194    
195 root 1.7 $msg =~ s/\260[^\260]*\260//g;
196    
197 root 1.2 print "($room) $src >> $msg\n";
198 elmex 1.6 logit ($msg, $src, $src, $dst, $room);
199 root 1.2
200 root 1.18 return if $next_time{$src} > time; # do not talk unnaturally often
201    
202 root 1.21 my $reply = gen_reply $msg;
203    
204 root 1.11 push @$seed, $msg;
205 root 1.15 seed_msg $msg;
206 elmex 1.1
207 root 1.22 my $delay = 30 * (rand) ** 5 + 0.3 * length $reply;
208 root 1.18 $next_time{$src} = time + $delay;
209 root 1.9
210 root 1.8 print "($room) $src << $reply ($delay)\n";
211 elmex 1.1
212 root 1.2 Event->timer (after => $delay, cb => sub {
213     push @queue, [$src, $room, $reply];
214     });
215 elmex 1.1 });
216    
217     connect_knuddels;
218     Event::loop;
219 root 1.7