From 7ab92557425a4f1fd45cc3e6b6187fdd9bc77aab Mon Sep 17 00:00:00 2001 From: Jamie Cameron Date: Tue, 21 May 2013 23:00:16 -0700 Subject: [PATCH] Work on play time limits --- minecraft/images/playtime.gif | Bin 0 -> 5038 bytes minecraft/lang/en | 20 +++++++++ minecraft/list_playtime.cgi | 69 ++++++++++++++++++++++++++++++ minecraft/minecraft-lib.pl | 78 ++++++++++++++++++++++++++++++++++ 4 files changed, 167 insertions(+) create mode 100644 minecraft/images/playtime.gif create mode 100644 minecraft/list_playtime.cgi diff --git a/minecraft/images/playtime.gif b/minecraft/images/playtime.gif new file mode 100644 index 0000000000000000000000000000000000000000..2ca3de4939ca37b1967fd74595472ce14d42cc6e GIT binary patch literal 5038 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 <=> $playtime->{$a} } + keys %$playtime) { + print &ui_columns_row([ + "". + &html_escape($u)."", + &nice_seconds($playtime->{$u}), + &indexof($u, @conns) >= 0 ? + "$text{'playtime_on'}" : + $text{'playtime_off'}, + ]); + } + print &ui_columns_end(); + } +else { + print "$text{'playtime_none'}

\n"; + } + +print &ui_hr(); + +# Show form for setting up play time limits +print &ui_form_start("save_playtime.cgi"); +print &ui_table_start($text{'playtime_header'}, undef, 2); + +# Cron job enabled? +print &ui_table_row($text{'playtime_enabled'}, + &ui_yesno_radio("enabled", $config{'playtime_enabled'})); + +# Max time per day +print &ui_table_row($text{'playtime_max'}, + &ui_opt_textbox("max", $config{'playtime_max'}, 6, + $text{'playtime_unlimited'})." ".$text{'playtime_mins'}); + +# Apply to users +print &ui_table_row($text{'playtime_users'}, + &ui_opt_textbox("users", $config{'playtime_users'}, 40, + $text{'playtime_all'}, $text{'playtime_sel'})); + +# Days of the week +my @days = split(/\s+/, $config{'playtime_days'}); +@days = (0 .. 6) if (!@days); +print &ui_table_row($text{'playtime_days'}, + join(" ", map { &ui_checkbox("days", $_, $text{'day_'.$_}, + &indexof($_, @days) >= 0) } (0 .. 6))); + +# For connections from IPs +print &ui_table_row($text{'playtime_ips'}, + &ui_opt_textbox("ips", $config{'playtime_ips'}, 40, + $text{'playtime_all2'}, $text{'playtime_sel2'})); + +print &ui_form_end([ [ undef, $text{'save'} ] ]); + +&ui_print_footer("", $text{'index_return'}); diff --git a/minecraft/minecraft-lib.pl b/minecraft/minecraft-lib.pl index 31ff90a6d..703c60f07 100644 --- a/minecraft/minecraft-lib.pl +++ b/minecraft/minecraft-lib.pl @@ -755,4 +755,82 @@ if (time() - $config{'last_check'} > 6*60*60) { } } +# get_current_day_usage() +# Returns a hash ref from usernames to usage over the last day +sub get_current_day_usage +{ +my $logfile = $config{'minecraft_dir'}."/server.log"; + +# Seek back till we find a day line from a previous day +my @st = stat($logfile); +return { } if (!@st); +my $pos = $st[7]; +open(LOGFILE, $logfile); +my @tm = localtime(time()); +my $wantday = sprintf("%4.4d-%2.2d-%2.2d", $tm[5]+1900, $tm[4]+1, $tm[3]); +while(1) { + $pos -= 4096; + $pos = 0 if ($pos < 0); + seek(LOGFILE, $pos, 0); + last if ($pos == 0); + my $dummy = ; # Skip partial line + my $line = ; + $line =~ /^((\d+)\-(\d+)\-(\d+))/ || next; + if ($1 ne $wantday) { + # Found a line for another day + last; + } + } + +# Read forwards, looking for logins and logouts for today +my %rv; +my %lastlogin; +while(my $line = ) { + $line =~ /^((\d+)\-(\d+)\-(\d+))\s+(\d+):(\d+):(\d+)/ || next; + $1 eq $wantday || next; + my $secs = $5*60*60 + $6*60 + $7; + if ($line =~ /\s(\S+)\s*\[[^\]]+\]\s+logged\s+in\s/) { + # Login by a user + $lastlogin{$1} = $secs; + } + elsif ($line =~ /\s(\S+)(\s*\[[^\]]+\])?\s+lost\s+connection/) { + # Logout .. count time + if (defined($lastlogin{$1})) { + # Add time from last login + $rv{$1} += $secs - $lastlogin{$1}; + delete($lastlogin{$1}); + } + } + } +close(LOGFILE); + +# Add any active sessions +my $now = $tm[2]*60*60 + $tm[1]*60 + $tm[0]; +foreach my $u (keys %lastlogin) { + $rv{$u} += $now - $lastlogin{$u}; + } + +return \%rv; +} + +# nice_seconds(secs) +# Converts a number of seconds into HH:MM format +sub nice_seconds +{ +my ($time) = @_; +my $days = int($time / (24*60*60)); +my $hours = int($time / (60*60)) % 24; +my $mins = sprintf("%d", int($time / 60) % 60); +my $secs = sprintf("%d", int($time) % 60); +if ($days) { + return "$days days, $hours hours, $mins mins"; + } +elsif ($hours) { + return "$hours hours, $mins mins"; + } +else { + return "$mins mins"; + } +} + 1;