ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/ext/schmorplog.ext
(Generate patch)

Comparing deliantra/server/ext/schmorplog.ext (file contents):
Revision 1.26 by root, Sun Apr 11 21:26:36 2010 UTC vs.
Revision 1.33 by root, Sat Feb 4 00:43:39 2012 UTC

3# statistics-package 3# statistics-package
4 4
5use Fcntl; 5use Fcntl;
6use Coro::AIO; 6use Coro::AIO;
7 7
8CONF EXPORT_RECENTLOG = undef
9CONF EXPORT_RECENTLOG_INTERVAL = 300
10
11#############################################################################
12# stuffs
13
8our %PLAYERSEEN; 14our %PLAYERSEEN;
9 15
16# EV, because we call ->start
10our $UPDATE_LOGINS = AE::idle sub { 17our $UPDATE_LOGINS = EV::idle sub {
11 $_[0]->stop; 18 $_[0]->stop;
12 19
13 cf::async { 20 cf::async {
14 my ($status, @pl) = ext::commands::who_listing; 21 my ($status, @pl) = ext::commands::who_listing;
15 22
60 ext::irc::do_notice $name . " logged in"; 67 ext::irc::do_notice $name . " logged in";
61 68
62 undef $PLAYERSEEN{$name}; 69 undef $PLAYERSEEN{$name};
63 $UPDATE_LOGINS->start; 70 $UPDATE_LOGINS->start;
64 71
65 warn "LOGIN: ", $pl->ob->name, " from ", $pl->ns->host; 72 cf::trace "LOGIN: ", $pl->ob->name, " from ", $pl->ns->host;
66 }, 73 },
67 on_logout => sub { 74 on_logout => sub {
68 my ($pl, $cleanly) = @_; 75 my ($pl, $cleanly) = @_;
69 $pl->ob->kv_set (schmorplog_last_logout => time); 76 $pl->ob->kv_set (schmorplog_last_logout => time);
70 ext::irc::do_notice $pl->ob->name . " left"; 77 ext::irc::do_notice $pl->ob->name . " left";
71 78
72 $UPDATE_LOGINS->start; 79 $UPDATE_LOGINS->start;
73 80
74 warn "LOGOUT: ", $pl->ob->name, " from ", $pl->ns->host, " ($cleanly)"; 81 cf::trace "LOGOUT: ", $pl->ob->name, " from ", $pl->ns->host, " ($cleanly)";
75 }, 82 },
76 on_birth => sub { 83 on_birth => sub {
77 my ($pl) = @_; 84 my ($pl) = @_;
78 $pl->ob->kv_set (schmorplog_birthdate => time); 85 $pl->ob->kv_set (schmorplog_birthdate => time);
79 ext::irc::do_notice $pl->ob->name . " was just born"; 86 ext::irc::do_notice $pl->ob->name . " was just born";
80 87
81 warn "BIRTH: ", $pl->ob->name, " from ", $pl->ns->host; 88 cf::trace "BIRTH: ", $pl->ob->name, " from ", $pl->ns->host;
82 }, 89 },
83 on_quit => sub { 90 on_quit => sub {
84 my ($pl) = @_; 91 my ($pl) = @_;
85 ext::irc::do_notice $pl->ob->name . " quit the game"; 92 ext::irc::do_notice $pl->ob->name . " quit the game";
86 93
87 warn "QUIT: ", $pl->ob->name, " from ", $pl->ns->host; 94 cf::trace "QUIT: ", $pl->ob->name, " from ", $pl->ns->host;
88 }, 95 },
89 on_death => sub { 96 on_death => sub {
90 my ($pl) = @_; 97 my ($pl) = @_;
91 98
92 my $msg = $pl->expand_cfpod ($pl->ob->name . " was killed by " . $pl->killer_name . "."); 99 my $msg = $pl->expand_cfpod ($pl->ob->name . " was killed by " . $pl->killer_name . ".");
167 my $name = $ns->pl && $ns->pl->ob ? $ns->pl->ob->name : "<unknown>"; 174 my $name = $ns->pl && $ns->pl->ob ? $ns->pl->ob->name : "<unknown>";
168 175
169 $msg =~ y/\x0a\x20-\x7f//cd; 176 $msg =~ y/\x0a\x20-\x7f//cd;
170 $msg =~ s/\s+$//; 177 $msg =~ s/\s+$//;
171 178
172 warn sprintf "clientlog [%s/%s]: %s\n", $ns->host, $name, $msg; 179 cf::error sprintf "clientlog [%s/%s]: %s\n", $ns->host, $name, $msg;
173 180
174 () 181 ()
175}; 182};
176 183
184#############################################################################
177# log max playercount every minute 185# log max playercount every minute
178#############################################################################
179 186
180our $STATSDIR = "$LOCALDIR/maxplayers"; 187our $STATSDIR = "$LOCALDIR/maxplayers";
181 188
182mkdir $STATSDIR; 189mkdir $STATSDIR;
183 190
198 205
199 IO::AIO::aio_open $path, O_WRONLY | O_CREAT, 0666, sub { 206 IO::AIO::aio_open $path, O_WRONLY | O_CREAT, 0666, sub {
200 my $fh = shift 207 my $fh = shift
201 or return; 208 or return;
202 209
210 # the truncate is 1440 extra syscalls, but saves 1439
211 # slow metadata updates.
212 IO::AIO::aio_truncate $fh, 1440, sub {
203 IO::AIO::aio_write $fh, $offs, 1, $cnt, 0, sub { 213 IO::AIO::aio_write $fh, $offs, 1, $cnt, 0, sub {
204 IO::AIO::aio_close $fh; 214 IO::AIO::aio_close $fh;
215 };
205 }; 216 };
206 }; 217 };
207}; 218};
208 219
220#############################################################################
221# export recentlog
209 222
223our %RECENT;
224
225our $update_w;
226our %need_update;
227
228sub _update_login {
229 my ($login) = @_;
230
231 my $path = (cf::player::playerdir $login) . "/playerdata";
232
233 if (0 >= aio_load $path, my $data) {
234 delete $RECENT{$login};
235 } else {
236 local $_ = $data;
237
238 my $birthdate = /^schmorplog_birthdate (\S+)$/m ? $1 : undef;
239 my $login_count = /^schmorplog_login_count (\S+)$/m ? $1 : 0;
240 my $death_count = /^schmorplog_death_count (\S+)$/m ? $1 : 0;
241 my $last_save = /^schmorplog_last_save (\S+)$/m ? $1 : undef;
242 my $last_login = /^schmorplog_last_login (\S+)$/m ? $1 : undef;
243 my $last_logout = /^schmorplog_last_logout (\S+)$/m ? $1 : undef;
244 my $client = /^schmorplog_client (.*)$/m ? $1 : "?";
245 my $map = /^map (.*)$/m ? $1 : "?";
246
247 return unless $last_login;
248
249 $last_logout = $last_save if $last_save > $last_logout && $last_login > $last_logout && $last_save < $NOW - 10 * 60;
250 $last_logout = undef if $last_logout < $last_login;
251
252 return unless $last_login > $NOW - 86400 * ($login_count * 7 + 10);
253
254# next if $count < 3 && $login < $NOW - 86400*2;
255 $RECENT{$login} = [$login, $birthdate, $last_login, $login_count, $last_logout, $client, $death_count, $map];
256 }
257}
258
259sub _update {
260 cf::async_ext {
261 $Coro::current->nice (1);
262 $Coro::current->{desc} = "recentlog updater";
263
264 Coro::AnyEvent::sleep 5; # grace time to allow file-saves
265
266 my $lock = cf::lock_acquire "export_recentlog";
267
268 my $t0 = EV::now;
269
270 while (%need_update) {
271 for (keys %need_update) {
272 delete $need_update{$_};
273
274 _update_login $_;
275 }
276 }
277
278 undef $update_w;
279
280 cf::get_slot 0.1, 0, "recentlog serialise";
281
282 my $NOW = $cf::NOW;
283
284 cf::replace_file $EXPORT_RECENTLOG, cf::encode_json {
285 version => 1,
286 date => $NOW,
287 data => [
288 sort { ($b->[4] || $NOW) <=> ($a->[4] || $NOW) }
289 values %RECENT
290 ],
291 } or warn "$EXPORT_RECENTLOG: $!";
292
293 cf::trace "recentlog updated (", EV::now - $t0, "s).\n";
294 };
295}
296
297sub update {
298 return unless defined $EXPORT_RECENTLOG;
299
300 $update_w ||= AE::timer $EXPORT_RECENTLOG_INTERVAL, 0, \&_update;
301}
302
303sub reload {
304 return unless defined $EXPORT_RECENTLOG;
305
306 my $lock = cf::lock_acquire "export_recentlog";
307
308 cf::async_ext {
309 $lock;
310
311 $Coro::current->{desc} = "recentlog reloader";
312
313 undef $need_update{$_}
314 for @{ +cf::player::list_logins };
315
316 _update;
317 };
318}
319
320cf::player->attach (
321 on_login => sub { undef $need_update{$_[0]->ob->name}; update },
322 on_logout => sub { undef $need_update{$_[0]->ob->name}; update },
323 on_birth => sub { undef $need_update{$_[0]->ob->name}; update },
324 on_death => sub { undef $need_update{$_[0]->ob->name}; update },
325# on_load => sub { undef $need_update{$_[0]->ob->name}; update },
326# on_save => sub { undef $need_update{$_[0]->ob->name}; update },
327);
328
329cf::post_init {
330 reload;
331};
332

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines