change table design for rating history
This commit is contained in:
parent
bf68e5672f
commit
696e2d12c9
@ -51,83 +51,78 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||
context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
|
||||
|
||||
var thirtyDaysAgo = DateTime.UtcNow.AddMonths(-1);
|
||||
var iqClientIds = (from stat in context.Set<EFClientStatistics>()
|
||||
var iqClientRatings = (from rating in context.Set<EFRating>()
|
||||
#if !DEBUG
|
||||
.Where(s => s.TimePlayed > 3600)
|
||||
.Where(s => s.EloRating > 60.0)
|
||||
where rating.RatingHistory.Client.TotalConnectionTime > 3600
|
||||
#endif
|
||||
where stat.Client.Level != Player.Permission.Banned
|
||||
where stat.Client.LastConnection >= thirtyDaysAgo
|
||||
|
||||
group stat by stat.ClientId into sj
|
||||
let performance = sj.Sum(s => (s.EloRating + s.Skill) * s.TimePlayed) / sj.Sum(st => st.TimePlayed)
|
||||
orderby performance
|
||||
select new
|
||||
{
|
||||
// sj.First().Client.CurrentAlias.Name,
|
||||
sj.First().Client.ClientId,
|
||||
Skill = sj.Select(s => s.Skill)
|
||||
})
|
||||
/*
|
||||
join averageStats in context.Set<EFClientAverageStatHistory>().Include(c => c.Ratings)
|
||||
on stat.ClientId equals averageStats.ClientId
|
||||
where averageStats.Ratings.Count > 0
|
||||
group new { stat, averageStats } by averageStats.ClientId into avg
|
||||
orderby avg.Select(c => c.averageStats.Ratings.OrderByDescending(r => r.RatingId).First().Performance).First()
|
||||
select new
|
||||
{
|
||||
avg.First().stat.Client.CurrentAlias.Name,//sj.Select(c => c.Client.CurrentAlias.Name),
|
||||
avg.First().stat.ClientId,//sj.First().ClientId,
|
||||
avg.First().stat.Kills,//Kills = sj.Select(s => s.Kills),
|
||||
avg.First().stat.Deaths,//Deaths = sj.Select(s => s.Deaths),
|
||||
avg.First().stat.Performance,//Performance = sj.Select(c => new { c.Performance, c.TimePlayed }),
|
||||
// KDR = stat.Kills / stat.Deaths,//KDR = sj.Select(c => new { KDR = c.Kills / (double)c.Deaths, c.TimePlayed }),
|
||||
//TotalPlayTime = sj.Select(c => c.TimePlayed),
|
||||
avg.First().stat.Client.LastConnection,//sj.First().Client.LastConnection,
|
||||
avg.First().stat.Client.TotalConnectionTime,//sj.First().Client.TotalConnectionTime,
|
||||
avg.First().stat.TimePlayed,
|
||||
RatingId = 0
|
||||
// todo: eventually replace this in favor of joining
|
||||
//AverageHistory = context.Set<EFClientAverageStatHistory>().SingleOrDefault(r => r.ClientId == stat.ClientId)
|
||||
})*/
|
||||
where rating.RatingHistory.Client.Level != Player.Permission.Banned
|
||||
where rating.RatingHistory.Client.LastConnection > thirtyDaysAgo
|
||||
where rating.Newest
|
||||
where rating.ServerId == null
|
||||
orderby rating.Performance descending
|
||||
select new
|
||||
{
|
||||
Ratings = rating.RatingHistory.Ratings.Where(r => r.ServerId == null),
|
||||
rating.RatingHistory.ClientId,
|
||||
rating.RatingHistory.Client.CurrentAlias.Name,
|
||||
rating.RatingHistory.Client.LastConnection,
|
||||
rating.RatingHistory.Client.TotalConnectionTime,
|
||||
rating.Performance,
|
||||
})
|
||||
.Skip(start)
|
||||
.Take(count);
|
||||
|
||||
var stats = await iqClientIds.ToListAsync();
|
||||
var clientRatings = await iqClientRatings.ToListAsync();
|
||||
|
||||
var groupedSelection = stats.GroupBy(c => c.ClientId).Select(s =>
|
||||
new TopStatsInfo()
|
||||
var clientIds = clientRatings.GroupBy(r => r.ClientId).Select(r => r.First().ClientId).ToList();
|
||||
|
||||
var iqStatsInfo = (from stat in context.Set<EFClientStatistics>()
|
||||
where clientIds.Contains(stat.ClientId)
|
||||
select new
|
||||
{
|
||||
stat.ClientId,
|
||||
stat.Kills,
|
||||
stat.Deaths,
|
||||
stat.TimePlayed,
|
||||
});
|
||||
|
||||
var statList = await iqStatsInfo.ToListAsync();
|
||||
var topPlayers = statList.GroupBy(s => s.ClientId)
|
||||
.Select(s => new
|
||||
{
|
||||
/* Name = s.First().Name,
|
||||
// weighted based on time played
|
||||
Performance = s.OrderByDescending(r => r.RatingId).First().Performance,
|
||||
// ditto
|
||||
KDR = s.First().Deaths == 0 ? s.First().Kills : (double)s.First().Kills / s.First().Deaths,
|
||||
ClientId = s.First().ClientId,
|
||||
Deaths = s.First().Deaths,
|
||||
Kills = s.First().Kills,
|
||||
LastSeen = Utilities.GetTimePassed(s.First().LastConnection, false),
|
||||
TimePlayed = Math.Round(s.First().TotalConnectionTime / 3600.0, 1).ToString("#,##0"),
|
||||
/ PerformanceHistory = s.AverageHistory == null || s.AverageHistory?.Ratings.Count < 2 ?
|
||||
new List<double>()
|
||||
{
|
||||
s.Performance,
|
||||
s.Performance
|
||||
} :
|
||||
s.AverageHistory.Ratings.Select(r => Math.Round(r.Performance, 1)).ToList()*/
|
||||
s.First().ClientId,
|
||||
Kills = s.Sum(c => c.Kills),
|
||||
Deaths = s.Sum(c => c.Deaths),
|
||||
KDR = s.Sum(c => (c.Kills / (double)(c.Deaths == 0 ? 1 : c.Deaths)) * c.TimePlayed) / s.Sum(c => c.TimePlayed)
|
||||
});
|
||||
|
||||
var statList = groupedSelection.OrderByDescending(s => s.Performance).ToList();
|
||||
var clientRatingsDict = clientRatings.ToDictionary(r => r.ClientId);
|
||||
var finished = topPlayers.Select(s => new TopStatsInfo()
|
||||
{
|
||||
ClientId = s.ClientId,
|
||||
Deaths = s.Deaths,
|
||||
Kills = s.Kills,
|
||||
KDR = Math.Round(s.KDR, 2),
|
||||
LastSeen = Utilities.GetTimePassed(clientRatingsDict[s.ClientId].LastConnection, false),
|
||||
Name = clientRatingsDict[s.ClientId].Name,
|
||||
Performance = Math.Round(clientRatingsDict[s.ClientId].Performance, 2),
|
||||
PerformanceHistory = clientRatingsDict[s.ClientId].Ratings.Count() > 1 ?
|
||||
clientRatingsDict[s.ClientId].Ratings.Select(r => r.Performance).ToList() :
|
||||
new List<double>() { clientRatingsDict[s.ClientId].Performance, clientRatingsDict[s.ClientId].Performance },
|
||||
TimePlayed = Math.Round(clientRatingsDict[s.ClientId].TotalConnectionTime / 3600.0, 1).ToString("#,##0"),
|
||||
})
|
||||
.OrderByDescending(r => r.Performance)
|
||||
.ToList();
|
||||
|
||||
// set the ranking numerically
|
||||
int i = start + 1;
|
||||
foreach (var stat in statList)
|
||||
foreach (var stat in finished)
|
||||
{
|
||||
stat.Ranking = i;
|
||||
i++;
|
||||
}
|
||||
|
||||
return statList;
|
||||
return finished;
|
||||
}
|
||||
}
|
||||
|
||||
@ -590,18 +585,13 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||
|
||||
using (var ctx = new DatabaseContext())
|
||||
{
|
||||
// select the individual history for current server
|
||||
var iqIndividualStatHistory = from statHistory in ctx.Set<EFClientStatHistory>()
|
||||
where statHistory.ClientId == client.ClientId
|
||||
where statHistory.ServerId == clientStats.ServerId
|
||||
select statHistory;
|
||||
// select the rating history for client
|
||||
var iqClientHistory = from history in ctx.Set<EFClientRatingHistory>()
|
||||
.Include(h => h.Ratings)
|
||||
where history.ClientId == client.ClientId
|
||||
select history;
|
||||
|
||||
// select the average history for current client
|
||||
var iqAverageHistory = from stat in ctx.Set<EFClientAverageStatHistory>()
|
||||
where stat.ClientId == client.ClientId
|
||||
select stat;
|
||||
|
||||
// select all stats for current client
|
||||
// select all performance & time played for current client
|
||||
var iqClientStats = from stats in ctx.Set<EFClientStatistics>()
|
||||
where stats.ClientId == client.ClientId
|
||||
where stats.ServerId != clientStats.ServerId
|
||||
@ -611,93 +601,107 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
||||
stats.TimePlayed
|
||||
};
|
||||
|
||||
// get the client ratings
|
||||
var clientHistory = await iqClientHistory
|
||||
.FirstOrDefaultAsync() ?? new EFClientRatingHistory()
|
||||
{
|
||||
Active = true,
|
||||
ClientId = client.ClientId,
|
||||
Ratings = new List<EFRating>()
|
||||
};
|
||||
|
||||
if (clientHistory.RatingHistoryId == 0)
|
||||
{
|
||||
ctx.Add(clientHistory);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
ctx.Update(clientHistory);
|
||||
}
|
||||
|
||||
// get the client ranking for the current server
|
||||
int individualClientRanking = await ctx.Set<EFClientStatHistory>()
|
||||
.Where(c => c.ClientId != client.ClientId)
|
||||
int individualClientRanking = await ctx.Set<EFRating>()
|
||||
.Where(c => c.ServerId == clientStats.ServerId)
|
||||
.Where(c => c.Ratings.OrderByDescending(r => r.RatingId).FirstOrDefault().Performance > clientStats.Performance)
|
||||
.Where(c => c.RatingHistory.ClientId != client.ClientId)
|
||||
.Where(r => r.Newest)
|
||||
.Where(c => c.Performance > clientStats.Performance)
|
||||
.CountAsync() + 1;
|
||||
|
||||
var currentServerHistory = await iqIndividualStatHistory
|
||||
.Include(r => r.Ratings)
|
||||
.FirstOrDefaultAsync() ?? new EFClientStatHistory()
|
||||
{
|
||||
Active = true,
|
||||
ClientId = client.ClientId,
|
||||
Ratings = new List<EFRating>(),
|
||||
ServerId = clientStats.ServerId
|
||||
};
|
||||
|
||||
var averageHistory = await iqAverageHistory
|
||||
.Include(r => r.Ratings)
|
||||
.FirstOrDefaultAsync() ?? new EFClientAverageStatHistory()
|
||||
{
|
||||
ClientId = client.ClientId,
|
||||
Ratings = new List<EFRating>(),
|
||||
Active = true,
|
||||
};
|
||||
|
||||
if (currentServerHistory.StatHistoryId == 0)
|
||||
// limit max history per server to 30
|
||||
if (clientHistory.Ratings.Count(r => r.ServerId == clientStats.ServerId) >= 30)
|
||||
{
|
||||
ctx.Add(currentServerHistory);
|
||||
var ratingToRemove = clientHistory.Ratings.First(r => r.ServerId == clientStats.ServerId);
|
||||
ctx.Entry(ratingToRemove).State = EntityState.Deleted;
|
||||
clientHistory.Ratings.Remove(ratingToRemove);
|
||||
}
|
||||
|
||||
else
|
||||
// set the previous newest to false
|
||||
var ratingToUnsetNewest = clientHistory.Ratings.LastOrDefault(r => r.ServerId == clientStats.ServerId);
|
||||
if (ratingToUnsetNewest != null)
|
||||
{
|
||||
ctx.Update(currentServerHistory);
|
||||
ctx.Entry(ratingToUnsetNewest).State = EntityState.Modified;
|
||||
ratingToUnsetNewest.Newest = false;
|
||||
}
|
||||
|
||||
if (averageHistory.Ratings.Count == 0)
|
||||
{
|
||||
ctx.Add(averageHistory);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
ctx.Update(averageHistory);
|
||||
}
|
||||
|
||||
if (currentServerHistory.Ratings.Count > 30)
|
||||
{
|
||||
ctx.Entry(currentServerHistory.Ratings.First()).State = EntityState.Deleted;
|
||||
currentServerHistory.Ratings.Remove(currentServerHistory.Ratings.First());
|
||||
}
|
||||
|
||||
currentServerHistory.Ratings.Add(new EFRating()
|
||||
// add new rating for current server
|
||||
clientHistory.Ratings.Add(new EFRating()
|
||||
{
|
||||
Performance = clientStats.Performance,
|
||||
Ranking = individualClientRanking,
|
||||
Active = true,
|
||||
ClientId = client.ClientId,
|
||||
Newest = true,
|
||||
ServerId = clientStats.ServerId,
|
||||
RatingHistoryId = clientHistory.RatingHistoryId,
|
||||
});
|
||||
|
||||
// get other server stats
|
||||
var clientStatsList = await iqClientStats.ToListAsync();
|
||||
|
||||
clientStatsList.Add(new
|
||||
{
|
||||
clientStats.Performance,
|
||||
TimePlayed = currentServerTotalPlaytime
|
||||
});
|
||||
|
||||
// weight the performance based on play time
|
||||
// weight the overall performance based on play time
|
||||
var performanceAverage = clientStatsList.Sum(p => (p.Performance * p.TimePlayed)) / clientStatsList.Sum(p => p.TimePlayed);
|
||||
|
||||
int overallClientRanking = await ctx.Set<EFClientAverageStatHistory>()
|
||||
.Where(c => c.ClientId != client.ClientId)
|
||||
.Where(c => c.Ratings.OrderByDescending(r => r.RatingId).FirstOrDefault().Performance > performanceAverage)
|
||||
var thirtyDaysAgo = DateTime.UtcNow.AddMonths(-1);
|
||||
int overallClientRanking = await ctx.Set<EFRating>()
|
||||
.Where(r => r.RatingHistory.Client.Level != Player.Permission.Banned)
|
||||
.Where(r => r.RatingHistory.Client.TotalConnectionTime > 3600)
|
||||
.Where(r => r.RatingHistory.Client.LastConnection > thirtyDaysAgo)
|
||||
.Where(r => r.RatingHistory.ClientId != client.ClientId)
|
||||
.Where(r => r.ServerId == null)
|
||||
.Where(r => r.Newest)
|
||||
.CountAsync() + 1;
|
||||
|
||||
if (averageHistory.Ratings.Count > 30)
|
||||
// limit max average history to 30
|
||||
if (clientHistory.Ratings.Count(r => r.ServerId == null) >= 30)
|
||||
{
|
||||
ctx.Entry(averageHistory.Ratings.First()).State = EntityState.Deleted;
|
||||
averageHistory.Ratings.Remove(averageHistory.Ratings.First());
|
||||
var ratingToRemove = clientHistory.Ratings.First(r => r.ServerId == null);
|
||||
ctx.Entry(ratingToRemove).State = EntityState.Deleted;
|
||||
clientHistory.Ratings.Remove(ratingToRemove);
|
||||
}
|
||||
|
||||
averageHistory.Ratings.Add(new EFRating()
|
||||
// set the previous average newest to false
|
||||
ratingToUnsetNewest = clientHistory.Ratings.LastOrDefault(r => r.ServerId == null);
|
||||
if (ratingToUnsetNewest != null)
|
||||
{
|
||||
ctx.Entry(ratingToUnsetNewest).State = EntityState.Modified;
|
||||
ratingToUnsetNewest.Newest = false;
|
||||
}
|
||||
|
||||
// add new average rating
|
||||
clientHistory.Ratings.Add(new EFRating()
|
||||
{
|
||||
Active = true,
|
||||
Newest = true,
|
||||
Performance = performanceAverage,
|
||||
Ranking = overallClientRanking,
|
||||
Active = true,
|
||||
ClientId = client.ClientId,
|
||||
ServerId = null,
|
||||
RatingHistoryId = clientHistory.RatingHistoryId
|
||||
});
|
||||
|
||||
await ctx.SaveChangesAsync();
|
||||
|
@ -1,22 +0,0 @@
|
||||
using SharedLibraryCore.Database.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text;
|
||||
|
||||
namespace IW4MAdmin.Plugins.Stats.Models
|
||||
{
|
||||
public class EFClientAverageStatHistory : SharedEntity
|
||||
{
|
||||
[Key]
|
||||
public int ClientId { get; set; }
|
||||
[ForeignKey("ClientId")]
|
||||
public virtual EFClient Client { get; set; }
|
||||
public virtual ICollection<EFRating> Ratings { get; set; }
|
||||
[Required]
|
||||
public int LastRatingId { get; set; }
|
||||
[ForeignKey("LastRatingId")]
|
||||
public virtual EFRating LastRating { get; set; }
|
||||
}
|
||||
}
|
@ -8,16 +8,13 @@ using System.Text;
|
||||
|
||||
namespace IW4MAdmin.Plugins.Stats.Models
|
||||
{
|
||||
public class EFClientStatHistory : SharedEntity
|
||||
public class EFClientRatingHistory : SharedEntity
|
||||
{
|
||||
[Key]
|
||||
public int StatHistoryId { get; set; }
|
||||
public int RatingHistoryId { get; set; }
|
||||
public int ClientId { get; set; }
|
||||
[ForeignKey("ClientId")]
|
||||
public virtual EFClient Client { get; set; }
|
||||
public int ServerId { get; set; }
|
||||
[ForeignKey("ServerId")]
|
||||
public virtual EFServer Server { get; set; }
|
||||
public virtual ICollection<EFRating> Ratings { get; set; }
|
||||
}
|
||||
}
|
@ -11,12 +11,19 @@ namespace IW4MAdmin.Plugins.Stats.Models
|
||||
{
|
||||
[Key]
|
||||
public int RatingId { get; set; }
|
||||
public int ClientId { get; set; }
|
||||
[ForeignKey("ClientId")]
|
||||
public EFClient Client { get; set; }
|
||||
public int RatingHistoryId { get; set; }
|
||||
[ForeignKey("RatingHistoryId")]
|
||||
public virtual EFClientRatingHistory RatingHistory { get; set; }
|
||||
// if null, indicates that the rating is an average rating
|
||||
public int? ServerId { get; set; }
|
||||
// [ForeignKey("ServerId")] can't make this nullable if this annotation is set
|
||||
public virtual EFServer Server { get; set; }
|
||||
[Required]
|
||||
public double Performance { get; set; }
|
||||
[Required]
|
||||
public int Ranking { get; set; }
|
||||
[Required]
|
||||
// indicates if the rating is the latest
|
||||
public bool Newest { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -1,139 +0,0 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SharedLibraryCore.Migrations
|
||||
{
|
||||
public partial class AddAutomatedOffenseAndRatingHistory : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "AutomatedOffense",
|
||||
table: "EFPenalties",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "EFClientAverageStatHistory",
|
||||
columns: table => new
|
||||
{
|
||||
ClientId = table.Column<int>(nullable: false),
|
||||
Active = table.Column<bool>(nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_EFClientAverageStatHistory", x => x.ClientId);
|
||||
table.ForeignKey(
|
||||
name: "FK_EFClientAverageStatHistory_EFClients_ClientId",
|
||||
column: x => x.ClientId,
|
||||
principalTable: "EFClients",
|
||||
principalColumn: "ClientId",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "EFClientStatHistory",
|
||||
columns: table => new
|
||||
{
|
||||
StatHistoryId = table.Column<int>(nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
Active = table.Column<bool>(nullable: false),
|
||||
ClientId = table.Column<int>(nullable: false),
|
||||
ServerId = table.Column<int>(nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_EFClientStatHistory", x => x.StatHistoryId);
|
||||
table.ForeignKey(
|
||||
name: "FK_EFClientStatHistory_EFClients_ClientId",
|
||||
column: x => x.ClientId,
|
||||
principalTable: "EFClients",
|
||||
principalColumn: "ClientId",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_EFClientStatHistory_EFServers_ServerId",
|
||||
column: x => x.ServerId,
|
||||
principalTable: "EFServers",
|
||||
principalColumn: "ServerId",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "EFRating",
|
||||
columns: table => new
|
||||
{
|
||||
RatingId = table.Column<int>(nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
Active = table.Column<bool>(nullable: false),
|
||||
ClientId = table.Column<int>(nullable: false),
|
||||
EFClientAverageStatHistoryClientId = table.Column<int>(nullable: true),
|
||||
EFClientStatHistoryStatHistoryId = table.Column<int>(nullable: true),
|
||||
Performance = table.Column<double>(nullable: false),
|
||||
Ranking = table.Column<int>(nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_EFRating", x => x.RatingId);
|
||||
table.ForeignKey(
|
||||
name: "FK_EFRating_EFClients_ClientId",
|
||||
column: x => x.ClientId,
|
||||
principalTable: "EFClients",
|
||||
principalColumn: "ClientId",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_EFRating_EFClientAverageStatHistory_EFClientAverageStatHistoryClientId",
|
||||
column: x => x.EFClientAverageStatHistoryClientId,
|
||||
principalTable: "EFClientAverageStatHistory",
|
||||
principalColumn: "ClientId",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
table.ForeignKey(
|
||||
name: "FK_EFRating_EFClientStatHistory_EFClientStatHistoryStatHistoryId",
|
||||
column: x => x.EFClientStatHistoryStatHistoryId,
|
||||
principalTable: "EFClientStatHistory",
|
||||
principalColumn: "StatHistoryId",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_EFClientStatHistory_ClientId",
|
||||
table: "EFClientStatHistory",
|
||||
column: "ClientId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_EFClientStatHistory_ServerId",
|
||||
table: "EFClientStatHistory",
|
||||
column: "ServerId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_EFRating_ClientId",
|
||||
table: "EFRating",
|
||||
column: "ClientId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_EFRating_EFClientAverageStatHistoryClientId",
|
||||
table: "EFRating",
|
||||
column: "EFClientAverageStatHistoryClientId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_EFRating_EFClientStatHistoryStatHistoryId",
|
||||
table: "EFRating",
|
||||
column: "EFClientStatHistoryStatHistoryId");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "EFRating");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "EFClientAverageStatHistory");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "EFClientStatHistory");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "AutomatedOffense",
|
||||
table: "EFPenalties");
|
||||
}
|
||||
}
|
||||
}
|
@ -12,7 +12,7 @@ using System;
|
||||
namespace SharedLibraryCore.Migrations
|
||||
{
|
||||
[DbContext(typeof(DatabaseContext))]
|
||||
[Migration("20180529233328_AddAutomatedOffenseAndRatingHistory")]
|
||||
[Migration("20180531212903_AddAutomatedOffenseAndRatingHistory")]
|
||||
partial class AddAutomatedOffenseAndRatingHistory
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
@ -21,17 +21,6 @@ namespace SharedLibraryCore.Migrations
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "2.0.2-rtm-10011");
|
||||
|
||||
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientAverageStatHistory", b =>
|
||||
{
|
||||
b.Property<int>("ClientId");
|
||||
|
||||
b.Property<bool>("Active");
|
||||
|
||||
b.HasKey("ClientId");
|
||||
|
||||
b.ToTable("EFClientAverageStatHistory");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientKill", b =>
|
||||
{
|
||||
b.Property<long>("KillId")
|
||||
@ -104,24 +93,20 @@ namespace SharedLibraryCore.Migrations
|
||||
b.ToTable("EFClientMessages");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientStatHistory", b =>
|
||||
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientRatingHistory", b =>
|
||||
{
|
||||
b.Property<int>("StatHistoryId")
|
||||
b.Property<int>("RatingHistoryId")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<bool>("Active");
|
||||
|
||||
b.Property<int>("ClientId");
|
||||
|
||||
b.Property<int>("ServerId");
|
||||
|
||||
b.HasKey("StatHistoryId");
|
||||
b.HasKey("RatingHistoryId");
|
||||
|
||||
b.HasIndex("ClientId");
|
||||
|
||||
b.HasIndex("ServerId");
|
||||
|
||||
b.ToTable("EFClientStatHistory");
|
||||
b.ToTable("EFClientRatingHistory");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics", b =>
|
||||
@ -192,23 +177,21 @@ namespace SharedLibraryCore.Migrations
|
||||
|
||||
b.Property<bool>("Active");
|
||||
|
||||
b.Property<int>("ClientId");
|
||||
|
||||
b.Property<int?>("EFClientAverageStatHistoryClientId");
|
||||
|
||||
b.Property<int?>("EFClientStatHistoryStatHistoryId");
|
||||
b.Property<bool>("Newest");
|
||||
|
||||
b.Property<double>("Performance");
|
||||
|
||||
b.Property<int>("Ranking");
|
||||
|
||||
b.Property<int>("RatingHistoryId");
|
||||
|
||||
b.Property<int?>("ServerId");
|
||||
|
||||
b.HasKey("RatingId");
|
||||
|
||||
b.HasIndex("ClientId");
|
||||
b.HasIndex("RatingHistoryId");
|
||||
|
||||
b.HasIndex("EFClientAverageStatHistoryClientId");
|
||||
|
||||
b.HasIndex("EFClientStatHistoryStatHistoryId");
|
||||
b.HasIndex("ServerId");
|
||||
|
||||
b.ToTable("EFRating");
|
||||
});
|
||||
@ -373,14 +356,6 @@ namespace SharedLibraryCore.Migrations
|
||||
b.ToTable("Vector3");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientAverageStatHistory", b =>
|
||||
{
|
||||
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
|
||||
.WithMany()
|
||||
.HasForeignKey("ClientId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientKill", b =>
|
||||
{
|
||||
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Attacker")
|
||||
@ -424,17 +399,12 @@ namespace SharedLibraryCore.Migrations
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientStatHistory", b =>
|
||||
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientRatingHistory", b =>
|
||||
{
|
||||
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
|
||||
.WithMany()
|
||||
.HasForeignKey("ClientId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server")
|
||||
.WithMany()
|
||||
.HasForeignKey("ServerId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics", b =>
|
||||
@ -470,18 +440,14 @@ namespace SharedLibraryCore.Migrations
|
||||
|
||||
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFRating", b =>
|
||||
{
|
||||
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
|
||||
.WithMany()
|
||||
.HasForeignKey("ClientId")
|
||||
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFClientRatingHistory", "RatingHistory")
|
||||
.WithMany("Ratings")
|
||||
.HasForeignKey("RatingHistoryId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFClientAverageStatHistory")
|
||||
.WithMany("Ratings")
|
||||
.HasForeignKey("EFClientAverageStatHistoryClientId");
|
||||
|
||||
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFClientStatHistory")
|
||||
.WithMany("Ratings")
|
||||
.HasForeignKey("EFClientStatHistoryStatHistoryId");
|
||||
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server")
|
||||
.WithMany()
|
||||
.HasForeignKey("ServerId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFServerStatistics", b =>
|
@ -0,0 +1,95 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SharedLibraryCore.Migrations
|
||||
{
|
||||
public partial class AddAutomatedOffenseAndRatingHistory : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "AutomatedOffense",
|
||||
table: "EFPenalties",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "EFClientRatingHistory",
|
||||
columns: table => new
|
||||
{
|
||||
RatingHistoryId = table.Column<int>(nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
Active = table.Column<bool>(nullable: false),
|
||||
ClientId = table.Column<int>(nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_EFClientRatingHistory", x => x.RatingHistoryId);
|
||||
table.ForeignKey(
|
||||
name: "FK_EFClientRatingHistory_EFClients_ClientId",
|
||||
column: x => x.ClientId,
|
||||
principalTable: "EFClients",
|
||||
principalColumn: "ClientId",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "EFRating",
|
||||
columns: table => new
|
||||
{
|
||||
RatingId = table.Column<int>(nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
Active = table.Column<bool>(nullable: false),
|
||||
Newest = table.Column<bool>(nullable: false),
|
||||
Performance = table.Column<double>(nullable: false),
|
||||
Ranking = table.Column<int>(nullable: false),
|
||||
RatingHistoryId = table.Column<int>(nullable: false),
|
||||
ServerId = table.Column<int>(nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_EFRating", x => x.RatingId);
|
||||
table.ForeignKey(
|
||||
name: "FK_EFRating_EFClientRatingHistory_RatingHistoryId",
|
||||
column: x => x.RatingHistoryId,
|
||||
principalTable: "EFClientRatingHistory",
|
||||
principalColumn: "RatingHistoryId",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_EFRating_EFServers_ServerId",
|
||||
column: x => x.ServerId,
|
||||
principalTable: "EFServers",
|
||||
principalColumn: "ServerId",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_EFClientRatingHistory_ClientId",
|
||||
table: "EFClientRatingHistory",
|
||||
column: "ClientId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_EFRating_RatingHistoryId",
|
||||
table: "EFRating",
|
||||
column: "RatingHistoryId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_EFRating_ServerId",
|
||||
table: "EFRating",
|
||||
column: "ServerId");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "EFRating");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "EFClientRatingHistory");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "AutomatedOffense",
|
||||
table: "EFPenalties");
|
||||
}
|
||||
}
|
||||
}
|
@ -20,17 +20,6 @@ namespace SharedLibraryCore.Migrations
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "2.0.2-rtm-10011");
|
||||
|
||||
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientAverageStatHistory", b =>
|
||||
{
|
||||
b.Property<int>("ClientId");
|
||||
|
||||
b.Property<bool>("Active");
|
||||
|
||||
b.HasKey("ClientId");
|
||||
|
||||
b.ToTable("EFClientAverageStatHistory");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientKill", b =>
|
||||
{
|
||||
b.Property<long>("KillId")
|
||||
@ -103,24 +92,20 @@ namespace SharedLibraryCore.Migrations
|
||||
b.ToTable("EFClientMessages");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientStatHistory", b =>
|
||||
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientRatingHistory", b =>
|
||||
{
|
||||
b.Property<int>("StatHistoryId")
|
||||
b.Property<int>("RatingHistoryId")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<bool>("Active");
|
||||
|
||||
b.Property<int>("ClientId");
|
||||
|
||||
b.Property<int>("ServerId");
|
||||
|
||||
b.HasKey("StatHistoryId");
|
||||
b.HasKey("RatingHistoryId");
|
||||
|
||||
b.HasIndex("ClientId");
|
||||
|
||||
b.HasIndex("ServerId");
|
||||
|
||||
b.ToTable("EFClientStatHistory");
|
||||
b.ToTable("EFClientRatingHistory");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics", b =>
|
||||
@ -191,23 +176,21 @@ namespace SharedLibraryCore.Migrations
|
||||
|
||||
b.Property<bool>("Active");
|
||||
|
||||
b.Property<int>("ClientId");
|
||||
|
||||
b.Property<int?>("EFClientAverageStatHistoryClientId");
|
||||
|
||||
b.Property<int?>("EFClientStatHistoryStatHistoryId");
|
||||
b.Property<bool>("Newest");
|
||||
|
||||
b.Property<double>("Performance");
|
||||
|
||||
b.Property<int>("Ranking");
|
||||
|
||||
b.Property<int>("RatingHistoryId");
|
||||
|
||||
b.Property<int?>("ServerId");
|
||||
|
||||
b.HasKey("RatingId");
|
||||
|
||||
b.HasIndex("ClientId");
|
||||
b.HasIndex("RatingHistoryId");
|
||||
|
||||
b.HasIndex("EFClientAverageStatHistoryClientId");
|
||||
|
||||
b.HasIndex("EFClientStatHistoryStatHistoryId");
|
||||
b.HasIndex("ServerId");
|
||||
|
||||
b.ToTable("EFRating");
|
||||
});
|
||||
@ -372,14 +355,6 @@ namespace SharedLibraryCore.Migrations
|
||||
b.ToTable("Vector3");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientAverageStatHistory", b =>
|
||||
{
|
||||
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
|
||||
.WithMany()
|
||||
.HasForeignKey("ClientId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientKill", b =>
|
||||
{
|
||||
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Attacker")
|
||||
@ -423,17 +398,12 @@ namespace SharedLibraryCore.Migrations
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientStatHistory", b =>
|
||||
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientRatingHistory", b =>
|
||||
{
|
||||
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
|
||||
.WithMany()
|
||||
.HasForeignKey("ClientId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server")
|
||||
.WithMany()
|
||||
.HasForeignKey("ServerId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics", b =>
|
||||
@ -469,18 +439,14 @@ namespace SharedLibraryCore.Migrations
|
||||
|
||||
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFRating", b =>
|
||||
{
|
||||
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
|
||||
.WithMany()
|
||||
.HasForeignKey("ClientId")
|
||||
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFClientRatingHistory", "RatingHistory")
|
||||
.WithMany("Ratings")
|
||||
.HasForeignKey("RatingHistoryId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFClientAverageStatHistory")
|
||||
.WithMany("Ratings")
|
||||
.HasForeignKey("EFClientAverageStatHistoryClientId");
|
||||
|
||||
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFClientStatHistory")
|
||||
.WithMany("Ratings")
|
||||
.HasForeignKey("EFClientStatHistoryStatHistoryId");
|
||||
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server")
|
||||
.WithMany()
|
||||
.HasForeignKey("ServerId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFServerStatistics", b =>
|
||||
|
@ -23,6 +23,7 @@ function loadMoreItems() {
|
||||
if (response.trim().length === 0) {
|
||||
staleLoader();
|
||||
}
|
||||
$(document).trigger("loaderFinished", response);
|
||||
hideLoader();
|
||||
isLoaderLoading = false;
|
||||
})
|
||||
|
@ -27,8 +27,8 @@
|
||||
gridThickness: 0,
|
||||
lineThickness: 0,
|
||||
tickThickness: 0,
|
||||
minimum: Math.min(...data) - 15,
|
||||
maximum: Math.max(...data) + 15,
|
||||
minimum: Math.min(...data) - Math.min(...data) * 0.075,
|
||||
maximum: Math.max(...data) + Math.max(...data) * 0.075,
|
||||
margin: 0,
|
||||
valueFormatString: " ",
|
||||
labelMaxWidth: 0
|
||||
@ -59,3 +59,10 @@ $(document).ready(function () {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
$(document).on("loaderFinished", function (event, response) {
|
||||
const ids = $.map($(response).find('.client-rating-graph'), function (elem) { return $(elem).attr('id'); });
|
||||
ids.forEach(function (item, index) {
|
||||
getStatsChart(item, $(item).width(), $(item).height()).render();
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user