From 7eb7e034b3db073e85f63e4cd3a32d84c29f516a Mon Sep 17 00:00:00 2001 From: Jamie Cameron Date: Sat, 16 Aug 2014 14:06:11 -0700 Subject: [PATCH] Convert UUIDs to player names --- minecraft/lang/en | 1 + minecraft/minecraft-lib.pl | 68 ++++++++++++++++++++++++++++++++++++-- minecraft/view_conn.cgi | 7 ++++ 3 files changed, 73 insertions(+), 3 deletions(-) diff --git a/minecraft/lang/en b/minecraft/lang/en index 5283d12b8..fd5198bc5 100644 --- a/minecraft/lang/en +++ b/minecraft/lang/en @@ -99,6 +99,7 @@ console_edown=The Minecraft server console cannot be used unless the server is r conn_title=Manage Player conn_header=Player details and actions conn_name=Player name +conn_uuid=Player UUID conn_state=Current state conn_yes=Connected conn_no=Disconnected diff --git a/minecraft/minecraft-lib.pl b/minecraft/minecraft-lib.pl index 1e3c7cef2..5ffa1b7d3 100644 --- a/minecraft/minecraft-lib.pl +++ b/minecraft/minecraft-lib.pl @@ -13,6 +13,7 @@ our ($module_root_directory, %text, %gconfig, $root_directory, %config, our $history_file = "$module_config_directory/history.txt"; our $download_page_url = "http://minecraft.net/download"; our $playtime_dir = "$module_config_directory/playtime"; +our $uuid_cache_file = "$module_config_directory/uuids"; &foreign_require("webmin"); @@ -545,8 +546,19 @@ foreach my $dat (glob("$config{'minecraft_dir'}/*/level.dat")) { $dat =~ /^(.*\/([^\/]+))\/level.dat$/ || next; my $path = $1; my $name = $2; - my @players = map { s/^.*\///; s/\.dat$//; $_ } - glob("$path/players/*"); + my @players; + if (-d "$path/players") { + # Old format + @players = map { s/^.*\///; s/\.dat$//; $_ } + glob("$path/players/*"); + } + if (-d "$path/playerdata" && !@players) { + # New format (UUID based) + @players = map { s/^.*\///; s/\.dat$//; $_ } + glob("$path/playerdata/*"); + @players = map { my $u = $_; + &uuid_to_username($u) || $u } @players; + } push(@rv, { 'path' => $path, 'name' => $name, 'size' => &disk_usage_kb($path)*1024, @@ -556,6 +568,48 @@ foreach my $dat (glob("$config{'minecraft_dir'}/*/level.dat")) { return @rv; } +# uuid_to_username(uuid) +# Returns the username with some UUID, by searching logs if needed +sub uuid_to_username +{ +my ($uuid) = @_; +my %cache; +&read_file_cached($uuid_cache_file, \%cache); +return $cache{$uuid} if ($cache{$uuid}); +my $found = 0; +foreach my $file (&get_minecraft_log_file(), + sort { $b cmp $a } + glob("$config{'minecraft_dir'}/logs/*.log.gz")) { + if ($file =~ /\.gz$/) { + open(LOG, "gunzip -c ".quotemeta($file)." |"); + } + else { + open(LOG, $file); + } + while() { + if (/UUID\s+of\s+player\s+(\S+)\s+is\s+(\S+)/) { + my ($lp, $lu) = ($1, $2); + if ($lu =~ /^([0-9a-f]{8})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{12})$/) { + # Convert to new UUID format + $lu = "$1-$2-$3-$4-$5"; + } + $cache{$lp} = $lu; + $cache{$lu} = $lp; + if ($cache{$uuid}) { + $found = 1; + last; + } + } + } + close(LOG); + if ($found) { + &write_file($uuid_cache_file, \%cache); + last; + } + } +return $cache{$uuid}; +} + # list_banned_ips() # Returns an array of banned addresses sub list_banned_ips @@ -1037,6 +1091,14 @@ my ($job) = grep { $_->{'module'} eq $module_name && return $job; } - +# get_player_stats(name|uuid) +# Returns all stats available for a player, in the format of the JSON file +sub get_player_stats +{ +my ($uuid) = @_; +if ($uuid !~ /^[0-9a-f]+\-[0-9a-f]+\-[0-9a-f]+\-[0-9a-f]+\-[0-9a-f]+$/) { + $uuid = &uuid_to_name($uuid); + } +} 1; diff --git a/minecraft/view_conn.cgi b/minecraft/view_conn.cgi index c3e26715f..729b46e50 100755 --- a/minecraft/view_conn.cgi +++ b/minecraft/view_conn.cgi @@ -24,6 +24,13 @@ print &ui_table_start($text{'conn_header'}, undef, 2); print &ui_table_row($text{'conn_name'}, &html_escape($in{'name'})); +# Player UUID +my $uuid = &uuid_to_username($in{'name'}); +if ($uuid) { + print &ui_table_row($text{'conn_uuid'}, + &html_escape($uuid)); + } + # Current state my @conns = &list_connected_players(); my ($c) = grep { $_ eq $in{'name'} } @conns;