private static void DumpPlayerGroupStats( TextWriter writer, IList<PlayerInfo> infos, string groupName )
{
RankStats stat = new RankStats();
foreach ( Rank rank2 in RankManager.Ranks ) {
stat.PreviousRank.Add( rank2, 0 );
}
int totalCount = infos.Count;
int bannedCount = infos.Count( info => info.IsBanned );
int inactiveCount = infos.Count( info => info.TimeSinceLastSeen.TotalDays >= 30 );
infos = infos.Where( info => ( info.TimeSinceLastSeen.TotalDays < 30 && !info.IsBanned ) ).ToList();
if ( infos.Count == 0 ) {
writer.WriteLine( "{0}: {1} players, {2} banned, {3} inactive",
groupName, totalCount, bannedCount, inactiveCount );
writer.WriteLine();
return;
}
foreach (PlayerInfo t in infos)
{
stat.TimeSinceFirstLogin += t.TimeSinceFirstLogin;
stat.TimeSinceLastLogin += t.TimeSinceLastLogin;
stat.TotalTime += t.TotalTime;
stat.BlocksBuilt += t.BlocksBuilt;
stat.BlocksDeleted += t.BlocksDeleted;
stat.BlocksDrawn += t.BlocksDrawn;
stat.TimesVisited += t.TimesVisited;
stat.MessagesWritten += t.MessagesWritten;
stat.TimesKicked += t.TimesKicked;
stat.TimesKickedOthers += t.TimesKickedOthers;
stat.TimesBannedOthers += t.TimesBannedOthers;
if ( t.PreviousRank != null )
stat.PreviousRank[t.PreviousRank]++;
}
stat.BlockRatio = stat.BlocksBuilt / ( double )Math.Max( stat.BlocksDeleted, 1 );
stat.BlocksChanged = stat.BlocksDeleted + stat.BlocksBuilt;
stat.TimeSinceFirstLoginMedian = DateTime.UtcNow.Subtract( infos.OrderByDescending( info => info.FirstLoginDate )
.ElementAt( infos.Count / 2 ).FirstLoginDate );
stat.TimeSinceLastLoginMedian = DateTime.UtcNow.Subtract( infos.OrderByDescending( info => info.LastLoginDate )
.ElementAt( infos.Count / 2 ).LastLoginDate );
stat.TotalTimeMedian = infos.OrderByDescending( info => info.TotalTime ).ElementAt( infos.Count / 2 ).TotalTime;
stat.BlocksBuiltMedian = infos.OrderByDescending( info => info.BlocksBuilt ).ElementAt( infos.Count / 2 ).BlocksBuilt;
stat.BlocksDeletedMedian = infos.OrderByDescending( info => info.BlocksDeleted ).ElementAt( infos.Count / 2 ).BlocksDeleted;
stat.BlocksDrawnMedian = infos.OrderByDescending( info => info.BlocksDrawn ).ElementAt( infos.Count / 2 ).BlocksDrawn;
PlayerInfo medianBlocksChangedPlayerInfo = infos.OrderByDescending( info => ( info.BlocksDeleted + info.BlocksBuilt ) ).ElementAt( infos.Count / 2 );
stat.BlocksChangedMedian = medianBlocksChangedPlayerInfo.BlocksDeleted + medianBlocksChangedPlayerInfo.BlocksBuilt;
PlayerInfo medianBlockRatioPlayerInfo = infos.OrderByDescending( info => ( info.BlocksBuilt / ( double )Math.Max( info.BlocksDeleted, 1 ) ) )
.ElementAt( infos.Count / 2 );
stat.BlockRatioMedian = medianBlockRatioPlayerInfo.BlocksBuilt / ( double )Math.Max( medianBlockRatioPlayerInfo.BlocksDeleted, 1 );
stat.TimesVisitedMedian = infos.OrderByDescending( info => info.TimesVisited ).ElementAt( infos.Count / 2 ).TimesVisited;
stat.MessagesWrittenMedian = infos.OrderByDescending( info => info.MessagesWritten ).ElementAt( infos.Count / 2 ).MessagesWritten;
stat.TimesKickedMedian = infos.OrderByDescending( info => info.TimesKicked ).ElementAt( infos.Count / 2 ).TimesKicked;
stat.TimesKickedOthersMedian = infos.OrderByDescending( info => info.TimesKickedOthers ).ElementAt( infos.Count / 2 ).TimesKickedOthers;
stat.TimesBannedOthersMedian = infos.OrderByDescending( info => info.TimesBannedOthers ).ElementAt( infos.Count / 2 ).TimesBannedOthers;
stat.TopTimeSinceFirstLogin = infos.OrderBy( info => info.FirstLoginDate ).ToArray();
stat.TopTimeSinceLastLogin = infos.OrderBy( info => info.LastLoginDate ).ToArray();
stat.TopTotalTime = infos.OrderByDescending( info => info.TotalTime ).ToArray();
stat.TopBlocksBuilt = infos.OrderByDescending( info => info.BlocksBuilt ).ToArray();
stat.TopBlocksDeleted = infos.OrderByDescending( info => info.BlocksDeleted ).ToArray();
stat.TopBlocksDrawn = infos.OrderByDescending( info => info.BlocksDrawn ).ToArray();
stat.TopBlocksChanged = infos.OrderByDescending( info => ( info.BlocksDeleted + info.BlocksBuilt ) ).ToArray();
stat.TopBlockRatio = infos.OrderByDescending( info => ( info.BlocksBuilt / ( double )Math.Max( info.BlocksDeleted, 1 ) ) ).ToArray();
stat.TopTimesVisited = infos.OrderByDescending( info => info.TimesVisited ).ToArray();
stat.TopMessagesWritten = infos.OrderByDescending( info => info.MessagesWritten ).ToArray();
stat.TopTimesKicked = infos.OrderByDescending( info => info.TimesKicked ).ToArray();
stat.TopTimesKickedOthers = infos.OrderByDescending( info => info.TimesKickedOthers ).ToArray();
stat.TopTimesBannedOthers = infos.OrderByDescending( info => info.TimesBannedOthers ).ToArray();
writer.WriteLine( "{0}: {1} players, {2} banned, {3} inactive",
groupName, totalCount, bannedCount, inactiveCount );
writer.WriteLine( " TimeSinceFirstLogin: {0} mean, {1} median, {2} total",
TimeSpan.FromTicks( stat.TimeSinceFirstLogin.Ticks / infos.Count ).ToCompactString(),
stat.TimeSinceFirstLoginMedian.ToCompactString(),
stat.TimeSinceFirstLogin.ToCompactString() );
if ( infos.Count() > TopPlayersToList * 2 + 1 ) {
foreach ( PlayerInfo info in stat.TopTimeSinceFirstLogin.Take( TopPlayersToList ) ) {
writer.WriteLine( " {0,20} {1}", info.TimeSinceFirstLogin.ToCompactString(), info.Name );
}
writer.WriteLine( " ...." );
foreach ( PlayerInfo info in stat.TopTimeSinceFirstLogin.Reverse().Take( TopPlayersToList ).Reverse() ) {
writer.WriteLine( " {0,20} {1}", info.TimeSinceFirstLogin.ToCompactString(), info.Name );
}
} else {
foreach ( PlayerInfo info in stat.TopTimeSinceFirstLogin ) {
writer.WriteLine( " {0,20} {1}", info.TimeSinceFirstLogin.ToCompactString(), info.Name );
}
}
writer.WriteLine();
writer.WriteLine( " TimeSinceLastLogin: {0} mean, {1} median, {2} total",
TimeSpan.FromTicks( stat.TimeSinceLastLogin.Ticks / infos.Count ).ToCompactString(),
stat.TimeSinceLastLoginMedian.ToCompactString(),
stat.TimeSinceLastLogin.ToCompactString() );
if ( infos.Count() > TopPlayersToList * 2 + 1 ) {
foreach ( PlayerInfo info in stat.TopTimeSinceLastLogin.Take( TopPlayersToList ) ) {
writer.WriteLine( " {0,20} {1}", info.TimeSinceLastLogin.ToCompactString(), info.Name );
}
writer.WriteLine( " ...." );
foreach ( PlayerInfo info in stat.TopTimeSinceLastLogin.Reverse().Take( TopPlayersToList ).Reverse() ) {
writer.WriteLine( " {0,20} {1}", info.TimeSinceLastLogin.ToCompactString(), info.Name );
}
} else {
foreach ( PlayerInfo info in stat.TopTimeSinceLastLogin ) {
writer.WriteLine( " {0,20} {1}", info.TimeSinceLastLogin.ToCompactString(), info.Name );
}
}
writer.WriteLine();
writer.WriteLine( " TotalTime: {0} mean, {1} median, {2} total",
TimeSpan.FromTicks( stat.TotalTime.Ticks / infos.Count ).ToCompactString(),
stat.TotalTimeMedian.ToCompactString(),
stat.TotalTime.ToCompactString() );
if ( infos.Count() > TopPlayersToList * 2 + 1 ) {
foreach ( PlayerInfo info in stat.TopTotalTime.Take( TopPlayersToList ) ) {
writer.WriteLine( " {0,20} {1}", info.TotalTime.ToCompactString(), info.Name );
}
writer.WriteLine( " ...." );
foreach ( PlayerInfo info in stat.TopTotalTime.Reverse().Take( TopPlayersToList ).Reverse() ) {
writer.WriteLine( " {0,20} {1}", info.TotalTime.ToCompactString(), info.Name );
}
} else {
foreach ( PlayerInfo info in stat.TopTotalTime ) {
writer.WriteLine( " {0,20} {1}", info.TotalTime.ToCompactString(), info.Name );
}
}
writer.WriteLine();
writer.WriteLine( " BlocksBuilt: {0} mean, {1} median, {2} total",
stat.BlocksBuilt / infos.Count,
stat.BlocksBuiltMedian,
stat.BlocksBuilt );
if ( infos.Count() > TopPlayersToList * 2 + 1 ) {
foreach ( PlayerInfo info in stat.TopBlocksBuilt.Take( TopPlayersToList ) ) {
writer.WriteLine( " {0,20} {1}", info.BlocksBuilt, info.Name );
}
writer.WriteLine( " ...." );
foreach ( PlayerInfo info in stat.TopBlocksBuilt.Reverse().Take( TopPlayersToList ).Reverse() ) {
writer.WriteLine( " {0,20} {1}", info.BlocksBuilt, info.Name );
}
} else {
foreach ( PlayerInfo info in stat.TopBlocksBuilt ) {
writer.WriteLine( " {0,20} {1}", info.BlocksBuilt, info.Name );
}
}
writer.WriteLine();
writer.WriteLine( " BlocksDeleted: {0} mean, {1} median, {2} total",
stat.BlocksDeleted / infos.Count,
stat.BlocksDeletedMedian,
stat.BlocksDeleted );
if ( infos.Count() > TopPlayersToList * 2 + 1 ) {
foreach ( PlayerInfo info in stat.TopBlocksDeleted.Take( TopPlayersToList ) ) {
writer.WriteLine( " {0,20} {1}", info.BlocksDeleted, info.Name );
}
writer.WriteLine( " ...." );
foreach ( PlayerInfo info in stat.TopBlocksDeleted.Reverse().Take( TopPlayersToList ).Reverse() ) {
writer.WriteLine( " {0,20} {1}", info.BlocksDeleted, info.Name );
}
} else {
foreach ( PlayerInfo info in stat.TopBlocksDeleted ) {
writer.WriteLine( " {0,20} {1}", info.BlocksDeleted, info.Name );
}
}
writer.WriteLine();
writer.WriteLine( " BlocksChanged: {0} mean, {1} median, {2} total",
stat.BlocksChanged / infos.Count,
stat.BlocksChangedMedian,
stat.BlocksChanged );
if ( infos.Count() > TopPlayersToList * 2 + 1 ) {
foreach ( PlayerInfo info in stat.TopBlocksChanged.Take( TopPlayersToList ) ) {
writer.WriteLine( " {0,20} {1}", ( info.BlocksDeleted + info.BlocksBuilt ), info.Name );
}
writer.WriteLine( " ...." );
foreach ( PlayerInfo info in stat.TopBlocksChanged.Reverse().Take( TopPlayersToList ).Reverse() ) {
writer.WriteLine( " {0,20} {1}", ( info.BlocksDeleted + info.BlocksBuilt ), info.Name );
}
} else {
foreach ( PlayerInfo info in stat.TopBlocksChanged ) {
writer.WriteLine( " {0,20} {1}", ( info.BlocksDeleted + info.BlocksBuilt ), info.Name );
}
}
writer.WriteLine();
writer.WriteLine( " BlocksDrawn: {0} mean, {1} median, {2} total",
stat.BlocksDrawn / infos.Count,
stat.BlocksDrawnMedian,
stat.BlocksDrawn );
if ( infos.Count() > TopPlayersToList * 2 + 1 ) {
foreach ( PlayerInfo info in stat.TopBlocksDrawn.Take( TopPlayersToList ) ) {
writer.WriteLine( " {0,20} {1}", info.BlocksDrawn, info.Name );
}
writer.WriteLine( " ...." );
foreach ( PlayerInfo info in stat.TopBlocksDrawn.Reverse().Take( TopPlayersToList ).Reverse() ) {
writer.WriteLine( " {0,20} {1}", info.BlocksDrawn, info.Name );
}
} else {
foreach ( PlayerInfo info in stat.TopBlocksDrawn ) {
writer.WriteLine( " {0,20} {1}", info.BlocksDrawn, info.Name );
}
}
writer.WriteLine( " BlockRatio: {0:0.000} mean, {1:0.000} median",
stat.BlockRatio,
stat.BlockRatioMedian );
if ( infos.Count() > TopPlayersToList * 2 + 1 ) {
foreach ( PlayerInfo info in stat.TopBlockRatio.Take( TopPlayersToList ) ) {
writer.WriteLine( " {0,20:0.000} {1}", ( info.BlocksBuilt / ( double )Math.Max( info.BlocksDeleted, 1 ) ), info.Name );
}
writer.WriteLine( " ...." );
foreach ( PlayerInfo info in stat.TopBlockRatio.Reverse().Take( TopPlayersToList ).Reverse() ) {
writer.WriteLine( " {0,20:0.000} {1}", ( info.BlocksBuilt / ( double )Math.Max( info.BlocksDeleted, 1 ) ), info.Name );
}
} else {
foreach ( PlayerInfo info in stat.TopBlockRatio ) {
writer.WriteLine( " {0,20:0.000} {1}", ( info.BlocksBuilt / ( double )Math.Max( info.BlocksDeleted, 1 ) ), info.Name );
}
}
writer.WriteLine();
writer.WriteLine( " TimesVisited: {0} mean, {1} median, {2} total",
stat.TimesVisited / infos.Count,
stat.TimesVisitedMedian,
stat.TimesVisited );
if ( infos.Count() > TopPlayersToList * 2 + 1 ) {
foreach ( PlayerInfo info in stat.TopTimesVisited.Take( TopPlayersToList ) ) {
writer.WriteLine( " {0,20} {1}", info.TimesVisited, info.Name );
}
writer.WriteLine( " ...." );
foreach ( PlayerInfo info in stat.TopTimesVisited.Reverse().Take( TopPlayersToList ).Reverse() ) {
writer.WriteLine( " {0,20} {1}", info.TimesVisited, info.Name );
}
} else {
foreach ( PlayerInfo info in stat.TopTimesVisited ) {
writer.WriteLine( " {0,20} {1}", info.TimesVisited, info.Name );
}
}
writer.WriteLine();
writer.WriteLine( " MessagesWritten: {0} mean, {1} median, {2} total",
stat.MessagesWritten / infos.Count,
stat.MessagesWrittenMedian,
stat.MessagesWritten );
if ( infos.Count() > TopPlayersToList * 2 + 1 ) {
foreach ( PlayerInfo info in stat.TopMessagesWritten.Take( TopPlayersToList ) ) {
writer.WriteLine( " {0,20} {1}", info.MessagesWritten, info.Name );
}
writer.WriteLine( " ...." );
foreach ( PlayerInfo info in stat.TopMessagesWritten.Reverse().Take( TopPlayersToList ).Reverse() ) {
writer.WriteLine( " {0,20} {1}", info.MessagesWritten, info.Name );
}
} else {
foreach ( PlayerInfo info in stat.TopMessagesWritten ) {
writer.WriteLine( " {0,20} {1}", info.MessagesWritten, info.Name );
}
}
writer.WriteLine();
writer.WriteLine( " TimesKicked: {0:0.0} mean, {1} median, {2} total",
stat.TimesKicked / ( double )infos.Count,
stat.TimesKickedMedian,
stat.TimesKicked );
if ( infos.Count() > TopPlayersToList * 2 + 1 ) {
foreach ( PlayerInfo info in stat.TopTimesKicked.Take( TopPlayersToList ) ) {
writer.WriteLine( " {0,20} {1}", info.TimesKicked, info.Name );
}
writer.WriteLine( " ...." );
foreach ( PlayerInfo info in stat.TopTimesKicked.Reverse().Take( TopPlayersToList ).Reverse() ) {
writer.WriteLine( " {0,20} {1}", info.TimesKicked, info.Name );
}
} else {
foreach ( PlayerInfo info in stat.TopTimesKicked ) {
writer.WriteLine( " {0,20} {1}", info.TimesKicked, info.Name );
}
}
writer.WriteLine();
writer.WriteLine( " TimesKickedOthers: {0:0.0} mean, {1} median, {2} total",
stat.TimesKickedOthers / ( double )infos.Count,
stat.TimesKickedOthersMedian,
stat.TimesKickedOthers );
if ( infos.Count() > TopPlayersToList * 2 + 1 ) {
foreach ( PlayerInfo info in stat.TopTimesKickedOthers.Take( TopPlayersToList ) ) {
writer.WriteLine( " {0,20} {1}", info.TimesKickedOthers, info.Name );
}
writer.WriteLine( " ...." );
foreach ( PlayerInfo info in stat.TopTimesKickedOthers.Reverse().Take( TopPlayersToList ).Reverse() ) {
writer.WriteLine( " {0,20} {1}", info.TimesKickedOthers, info.Name );
}
} else {
foreach ( PlayerInfo info in stat.TopTimesKickedOthers ) {
writer.WriteLine( " {0,20} {1}", info.TimesKickedOthers, info.Name );
}
}
writer.WriteLine();
writer.WriteLine( " TimesBannedOthers: {0:0.0} mean, {1} median, {2} total",
stat.TimesBannedOthers / ( double )infos.Count,
stat.TimesBannedOthersMedian,
stat.TimesBannedOthers );
if ( infos.Count() > TopPlayersToList * 2 + 1 ) {
foreach ( PlayerInfo info in stat.TopTimesBannedOthers.Take( TopPlayersToList ) ) {
writer.WriteLine( " {0,20} {1}", info.TimesBannedOthers, info.Name );
}
writer.WriteLine( " ...." );
foreach ( PlayerInfo info in stat.TopTimesBannedOthers.Reverse().Take( TopPlayersToList ).Reverse() ) {
writer.WriteLine( " {0,20} {1}", info.TimesBannedOthers, info.Name );
}
} else {
foreach ( PlayerInfo info in stat.TopTimesBannedOthers ) {
writer.WriteLine( " {0,20} {1}", info.TimesBannedOthers, info.Name );
}
}
writer.WriteLine();
}