fixed broken broadcast events
events don't get out of order when a invalid event line throws exception handle the stats history update with no change throwing DBConcurrencyException
This commit is contained in:
parent
46bdc2ac33
commit
cc7628d058
@ -18,29 +18,15 @@ namespace IW4MAdmin.Application.EventParsers
|
|||||||
string[] lineSplit = logLine.Split(';');
|
string[] lineSplit = logLine.Split(';');
|
||||||
string eventType = lineSplit[0];
|
string eventType = lineSplit[0];
|
||||||
|
|
||||||
// kill
|
|
||||||
if (eventType == "K")
|
|
||||||
{
|
|
||||||
if (!server.CustomCallback)
|
|
||||||
{
|
|
||||||
return new GameEvent()
|
|
||||||
{
|
|
||||||
Type = GameEvent.EventType.Kill,
|
|
||||||
Data = logLine,
|
|
||||||
Origin = server.GetPlayersAsList().First(c => c.ClientNumber == Utilities.ClientIdFromString(lineSplit, 6)),
|
|
||||||
Target = server.GetPlayersAsList().First(c => c.ClientNumber == Utilities.ClientIdFromString(lineSplit, 2)),
|
|
||||||
Owner = server
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (eventType == "JoinTeam")
|
if (eventType == "JoinTeam")
|
||||||
{
|
{
|
||||||
|
var origin = server.GetPlayersAsList().FirstOrDefault(c => c.NetworkId == lineSplit[1].ConvertLong());
|
||||||
|
|
||||||
return new GameEvent()
|
return new GameEvent()
|
||||||
{
|
{
|
||||||
Type = GameEvent.EventType.JoinTeam,
|
Type = GameEvent.EventType.JoinTeam,
|
||||||
Data = eventType,
|
Data = eventType,
|
||||||
Origin = server.GetPlayersAsList().FirstOrDefault(c => c.NetworkId == lineSplit[1].ConvertLong()),
|
Origin = origin,
|
||||||
Owner = server
|
Owner = server
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -55,13 +41,15 @@ namespace IW4MAdmin.Application.EventParsers
|
|||||||
.Replace("\x15", "")
|
.Replace("\x15", "")
|
||||||
.Trim();
|
.Trim();
|
||||||
|
|
||||||
|
var origin = server.GetPlayersAsList().First(c => c.ClientNumber == Utilities.ClientIdFromString(lineSplit, 2));
|
||||||
|
|
||||||
if (message[0] == '!' || message[0] == '@')
|
if (message[0] == '!' || message[0] == '@')
|
||||||
{
|
{
|
||||||
return new GameEvent()
|
return new GameEvent()
|
||||||
{
|
{
|
||||||
Type = GameEvent.EventType.Command,
|
Type = GameEvent.EventType.Command,
|
||||||
Data = message,
|
Data = message,
|
||||||
Origin = server.GetPlayersAsList().First(c => c.ClientNumber == Utilities.ClientIdFromString(lineSplit, 2)),
|
Origin = origin,
|
||||||
Owner = server,
|
Owner = server,
|
||||||
Message = message
|
Message = message
|
||||||
};
|
};
|
||||||
@ -71,33 +59,56 @@ namespace IW4MAdmin.Application.EventParsers
|
|||||||
{
|
{
|
||||||
Type = GameEvent.EventType.Say,
|
Type = GameEvent.EventType.Say,
|
||||||
Data = message,
|
Data = message,
|
||||||
Origin = server.GetPlayersAsList().First(c => c.ClientNumber == Utilities.ClientIdFromString(lineSplit, 2)),
|
Origin = origin,
|
||||||
Owner = server,
|
Owner = server,
|
||||||
Message = message
|
Message = message
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (eventType == "K")
|
||||||
|
{
|
||||||
|
if (!server.CustomCallback)
|
||||||
|
{
|
||||||
|
var origin = server.GetPlayersAsList().First(c => c.ClientNumber == Utilities.ClientIdFromString(lineSplit, 6));
|
||||||
|
var target = server.GetPlayersAsList().First(c => c.ClientNumber == Utilities.ClientIdFromString(lineSplit, 2));
|
||||||
|
|
||||||
|
return new GameEvent()
|
||||||
|
{
|
||||||
|
Type = GameEvent.EventType.Kill,
|
||||||
|
Data = logLine,
|
||||||
|
Origin = origin,
|
||||||
|
Owner = server
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (eventType == "ScriptKill")
|
if (eventType == "ScriptKill")
|
||||||
{
|
{
|
||||||
|
var origin = server.GetPlayersAsList().First(c => c.NetworkId == lineSplit[1].ConvertLong());
|
||||||
|
var target = server.GetPlayersAsList().First(c => c.NetworkId == lineSplit[2].ConvertLong());
|
||||||
return new GameEvent()
|
return new GameEvent()
|
||||||
{
|
{
|
||||||
Type = GameEvent.EventType.ScriptKill,
|
Type = GameEvent.EventType.ScriptKill,
|
||||||
Data = logLine,
|
Data = logLine,
|
||||||
Origin = server.GetPlayersAsList().First(c => c.NetworkId == lineSplit[1].ConvertLong()),
|
Origin = origin,
|
||||||
Target = server.GetPlayersAsList().First(c => c.NetworkId == lineSplit[2].ConvertLong()),
|
Target = target,
|
||||||
Owner = server
|
Owner = server
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eventType == "ScriptDamage")
|
if (eventType == "ScriptDamage")
|
||||||
{
|
{
|
||||||
|
var origin = server.GetPlayersAsList().First(c => c.NetworkId == lineSplit[1].ConvertLong());
|
||||||
|
var target = server.GetPlayersAsList().First(c => c.NetworkId == lineSplit[2].ConvertLong());
|
||||||
|
|
||||||
return new GameEvent()
|
return new GameEvent()
|
||||||
{
|
{
|
||||||
Type = GameEvent.EventType.ScriptDamage,
|
Type = GameEvent.EventType.ScriptDamage,
|
||||||
Data = logLine,
|
Data = logLine,
|
||||||
Origin = server.GetPlayersAsList().First(c => c.NetworkId == lineSplit[1].ConvertLong()),
|
Origin = origin,
|
||||||
Target = server.GetPlayersAsList().First(c => c.NetworkId == lineSplit[2].ConvertLong()),
|
Target = target,
|
||||||
Owner = server
|
Owner = server
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -107,12 +118,15 @@ namespace IW4MAdmin.Application.EventParsers
|
|||||||
{
|
{
|
||||||
if (Regex.Match(eventType, @"^(D);((?:bot[0-9]+)|(?:[A-Z]|[0-9])+);([0-9]+);(axis|allies);(.+);((?:[A-Z]|[0-9])+);([0-9]+);(axis|allies);(.+);((?:[0-9]+|[a-z]+|_)+);([0-9]+);((?:[A-Z]|_)+);((?:[a-z]|_)+)$").Success)
|
if (Regex.Match(eventType, @"^(D);((?:bot[0-9]+)|(?:[A-Z]|[0-9])+);([0-9]+);(axis|allies);(.+);((?:[A-Z]|[0-9])+);([0-9]+);(axis|allies);(.+);((?:[0-9]+|[a-z]+|_)+);([0-9]+);((?:[A-Z]|_)+);((?:[a-z]|_)+)$").Success)
|
||||||
{
|
{
|
||||||
|
var origin = server.GetPlayersAsList().First(c => c.NetworkId == lineSplit[5].ConvertLong());
|
||||||
|
var target = server.GetPlayersAsList().First(c => c.NetworkId == lineSplit[1].ConvertLong());
|
||||||
|
|
||||||
return new GameEvent()
|
return new GameEvent()
|
||||||
{
|
{
|
||||||
Type = GameEvent.EventType.Damage,
|
Type = GameEvent.EventType.Damage,
|
||||||
Data = eventType,
|
Data = eventType,
|
||||||
Origin = server.GetPlayersAsList().First(c => c.NetworkId == lineSplit[5].ConvertLong()),
|
Origin = origin,
|
||||||
Target = server.GetPlayersAsList().First(c => c.NetworkId == lineSplit[1].ConvertLong()),
|
Target = target,
|
||||||
Owner = server
|
Owner = server
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -15,14 +15,11 @@ namespace IW4MAdmin.Application
|
|||||||
private readonly IManager Manager;
|
private readonly IManager Manager;
|
||||||
static long NextEventId = 1;
|
static long NextEventId = 1;
|
||||||
private readonly SortedList<long, GameEvent> OutOfOrderEvents;
|
private readonly SortedList<long, GameEvent> OutOfOrderEvents;
|
||||||
private readonly SemaphoreSlim ProcessingEvent;
|
|
||||||
|
|
||||||
public GameEventHandler(IManager mgr)
|
public GameEventHandler(IManager mgr)
|
||||||
{
|
{
|
||||||
Manager = mgr;
|
Manager = mgr;
|
||||||
OutOfOrderEvents = new SortedList<long, GameEvent>();
|
OutOfOrderEvents = new SortedList<long, GameEvent>();
|
||||||
ProcessingEvent = new SemaphoreSlim(0);
|
|
||||||
ProcessingEvent.Release();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AddEvent(GameEvent gameEvent)
|
public bool AddEvent(GameEvent gameEvent)
|
||||||
@ -30,13 +27,23 @@ namespace IW4MAdmin.Application
|
|||||||
#if DEBUG
|
#if DEBUG
|
||||||
Manager.GetLogger().WriteDebug($"Got new event of type {gameEvent.Type} for {gameEvent.Owner} with id {gameEvent.Id}");
|
Manager.GetLogger().WriteDebug($"Got new event of type {gameEvent.Type} for {gameEvent.Owner} with id {gameEvent.Id}");
|
||||||
#endif
|
#endif
|
||||||
while (OutOfOrderEvents.Values.FirstOrDefault()?.Id == Interlocked.Read(ref NextEventId))
|
GameEvent sortedEvent = null;
|
||||||
|
lock (OutOfOrderEvents)
|
||||||
|
{
|
||||||
|
sortedEvent = OutOfOrderEvents.Values.FirstOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
while (sortedEvent?.Id == Interlocked.Read(ref NextEventId))
|
||||||
{
|
{
|
||||||
lock (OutOfOrderEvents)
|
lock (OutOfOrderEvents)
|
||||||
{
|
{
|
||||||
var fixedEvent = OutOfOrderEvents.Values[0];
|
|
||||||
OutOfOrderEvents.RemoveAt(0);
|
OutOfOrderEvents.RemoveAt(0);
|
||||||
AddEvent(fixedEvent);
|
}
|
||||||
|
AddEvent(sortedEvent);
|
||||||
|
|
||||||
|
lock (OutOfOrderEvents)
|
||||||
|
{
|
||||||
|
sortedEvent = OutOfOrderEvents.Values.FirstOrDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,9 +51,10 @@ namespace IW4MAdmin.Application
|
|||||||
// event occurs
|
// event occurs
|
||||||
if (gameEvent.Id == Interlocked.Read(ref NextEventId))
|
if (gameEvent.Id == Interlocked.Read(ref NextEventId))
|
||||||
{
|
{
|
||||||
Manager.GetLogger().WriteDebug($"Starting to wait for event with id {gameEvent.Id}");
|
#if DEBUG == true
|
||||||
|
Manager.GetLogger().WriteDebug($"sent event with id {gameEvent.Id} to be processed");
|
||||||
|
#endif
|
||||||
((Manager as ApplicationManager).OnServerEvent)(this, new GameEventArgs(null, false, gameEvent));
|
((Manager as ApplicationManager).OnServerEvent)(this, new GameEventArgs(null, false, gameEvent));
|
||||||
Manager.GetLogger().WriteDebug($"Finished waiting for event with id {gameEvent.Id}");
|
|
||||||
Interlocked.Increment(ref NextEventId);
|
Interlocked.Increment(ref NextEventId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,8 +62,10 @@ namespace IW4MAdmin.Application
|
|||||||
// so me must wait until the next expected one arrives
|
// so me must wait until the next expected one arrives
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
#if DEBUG == true
|
||||||
Manager.GetLogger().WriteWarning("Incoming event is out of order");
|
Manager.GetLogger().WriteWarning("Incoming event is out of order");
|
||||||
Manager.GetLogger().WriteDebug($"Expected event Id is {Interlocked.Read(ref NextEventId)}, but got {gameEvent.Id} instead");
|
Manager.GetLogger().WriteDebug($"Expected event Id is {Interlocked.Read(ref NextEventId)}, but got {gameEvent.Id} instead");
|
||||||
|
#endif
|
||||||
|
|
||||||
// this prevents multiple threads from adding simultaneously
|
// this prevents multiple threads from adding simultaneously
|
||||||
lock (OutOfOrderEvents)
|
lock (OutOfOrderEvents)
|
||||||
|
@ -2,10 +2,7 @@
|
|||||||
using SharedLibraryCore.Interfaces;
|
using SharedLibraryCore.Interfaces;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Net;
|
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace IW4MAdmin.Application.IO
|
namespace IW4MAdmin.Application.IO
|
||||||
{
|
{
|
||||||
@ -76,7 +73,6 @@ namespace IW4MAdmin.Application.IO
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// todo: catch elsewhere
|
|
||||||
var e = Parser.GetEvent(server, eventLine);
|
var e = Parser.GetEvent(server, eventLine);
|
||||||
#if DEBUG == true
|
#if DEBUG == true
|
||||||
server.Logger.WriteDebug($"Parsed event with id {e.Id} from http");
|
server.Logger.WriteDebug($"Parsed event with id {e.Id} from http");
|
||||||
|
@ -529,9 +529,9 @@ namespace IW4MAdmin
|
|||||||
if (E.Type == GameEvent.EventType.Broadcast)
|
if (E.Type == GameEvent.EventType.Broadcast)
|
||||||
{
|
{
|
||||||
// this is a little ugly but I don't want to change the abstract class
|
// this is a little ugly but I don't want to change the abstract class
|
||||||
if (E.Message != null)
|
if (E.Data != null)
|
||||||
{
|
{
|
||||||
await E.Owner.ExecuteCommandAsync(E.Message);
|
await E.Owner.ExecuteCommandAsync(E.Data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,10 +8,11 @@ import datetime
|
|||||||
class Authenticate(Resource):
|
class Authenticate(Resource):
|
||||||
def post(self):
|
def post(self):
|
||||||
instance_id = request.json['id']
|
instance_id = request.json['id']
|
||||||
if ctx.get_token(instance_id) is not False:
|
#todo: see why this is failing
|
||||||
return { 'message' : 'that id already has a token'}, 401
|
#if ctx.get_token(instance_id) is not False:
|
||||||
else:
|
# return { 'message' : 'that id already has a token'}, 401
|
||||||
expires = datetime.timedelta(days=30)
|
#else:
|
||||||
token = create_access_token(instance_id, expires_delta=expires)
|
expires = datetime.timedelta(days=30)
|
||||||
ctx.add_token(instance_id, token)
|
token = create_access_token(instance_id, expires_delta=expires)
|
||||||
return { 'access_token' : token }, 200
|
ctx.add_token(instance_id, token)
|
||||||
|
return { 'access_token' : token }, 200
|
||||||
|
@ -45,7 +45,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
|
|
||||||
var thirtyDaysAgo = DateTime.UtcNow.AddMonths(-1);
|
var thirtyDaysAgo = DateTime.UtcNow.AddMonths(-1);
|
||||||
var iqClientRatings = (from rating in context.Set<EFRating>()
|
var iqClientRatings = (from rating in context.Set<EFRating>()
|
||||||
#if !DEBUG
|
#if DEBUG == false
|
||||||
where rating.ActivityAmount >= Plugin.Config.Configuration().TopPlayersMinPlayTime
|
where rating.ActivityAmount >= Plugin.Config.Configuration().TopPlayersMinPlayTime
|
||||||
#endif
|
#endif
|
||||||
where rating.RatingHistory.Client.Level != Player.Permission.Banned
|
where rating.RatingHistory.Client.Level != Player.Permission.Banned
|
||||||
@ -561,9 +561,9 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
}
|
}
|
||||||
|
|
||||||
// update their performance
|
// update their performance
|
||||||
#if !DEBUG
|
//#if !DEBUG
|
||||||
if ((DateTime.UtcNow - attackerStats.LastStatHistoryUpdate).TotalMinutes >= 2.5)
|
if ((DateTime.UtcNow - attackerStats.LastStatHistoryUpdate).TotalMinutes >= 2.5)
|
||||||
#endif
|
//#endif
|
||||||
{
|
{
|
||||||
await UpdateStatHistory(attacker, attackerStats);
|
await UpdateStatHistory(attacker, attackerStats);
|
||||||
attackerStats.LastStatHistoryUpdate = DateTime.UtcNow;
|
attackerStats.LastStatHistoryUpdate = DateTime.UtcNow;
|
||||||
@ -718,7 +718,14 @@ namespace IW4MAdmin.Plugins.Stats.Helpers
|
|||||||
ActivityAmount = clientStatsList.Sum(s => s.TimePlayed)
|
ActivityAmount = clientStatsList.Sum(s => s.TimePlayed)
|
||||||
});
|
});
|
||||||
|
|
||||||
await ctx.SaveChangesAsync();
|
try
|
||||||
|
{
|
||||||
|
await ctx.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
catch (DbUpdateConcurrencyException e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,8 +13,6 @@ using SharedLibraryCore.Services;
|
|||||||
using IW4MAdmin.Plugins.Stats.Config;
|
using IW4MAdmin.Plugins.Stats.Config;
|
||||||
using IW4MAdmin.Plugins.Stats.Helpers;
|
using IW4MAdmin.Plugins.Stats.Helpers;
|
||||||
using IW4MAdmin.Plugins.Stats.Models;
|
using IW4MAdmin.Plugins.Stats.Models;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Microsoft.AspNetCore.Mvc.Routing;
|
|
||||||
|
|
||||||
namespace IW4MAdmin.Plugins.Stats
|
namespace IW4MAdmin.Plugins.Stats
|
||||||
{
|
{
|
||||||
@ -77,8 +75,6 @@ namespace IW4MAdmin.Plugins.Stats
|
|||||||
string[] killInfo = (E.Data != null) ? E.Data.Split(';') : new string[0];
|
string[] killInfo = (E.Data != null) ? E.Data.Split(';') : new string[0];
|
||||||
if (killInfo.Length >= 13)
|
if (killInfo.Length >= 13)
|
||||||
{
|
{
|
||||||
// todo: remove me
|
|
||||||
E.Owner.Logger.WriteDebug($"Starting Add script hit (kill) for event with id {E.Id}");
|
|
||||||
await Manager.AddScriptHit(false, E.Time, E.Origin, E.Target, S.GetHashCode(), S.CurrentMap.Name, killInfo[7], killInfo[8],
|
await Manager.AddScriptHit(false, E.Time, E.Origin, E.Target, S.GetHashCode(), S.CurrentMap.Name, killInfo[7], killInfo[8],
|
||||||
killInfo[5], killInfo[6], killInfo[3], killInfo[4], killInfo[9], killInfo[10], killInfo[11], killInfo[12], killInfo[13]);
|
killInfo[5], killInfo[6], killInfo[3], killInfo[4], killInfo[9], killInfo[10], killInfo[11], killInfo[12], killInfo[13]);
|
||||||
}
|
}
|
||||||
@ -95,8 +91,6 @@ namespace IW4MAdmin.Plugins.Stats
|
|||||||
killInfo = (E.Data != null) ? E.Data.Split(';') : new string[0];
|
killInfo = (E.Data != null) ? E.Data.Split(';') : new string[0];
|
||||||
if (killInfo.Length >= 13)
|
if (killInfo.Length >= 13)
|
||||||
{
|
{
|
||||||
// todo: remove me
|
|
||||||
E.Owner.Logger.WriteDebug($"Starting Add script hit (damage) for event with id {E.Id}");
|
|
||||||
await Manager.AddScriptHit(true, E.Time, E.Origin, E.Target, S.GetHashCode(), S.CurrentMap.Name, killInfo[7], killInfo[8],
|
await Manager.AddScriptHit(true, E.Time, E.Origin, E.Target, S.GetHashCode(), S.CurrentMap.Name, killInfo[7], killInfo[8],
|
||||||
killInfo[5], killInfo[6], killInfo[3], killInfo[4], killInfo[9], killInfo[10], killInfo[11], killInfo[12], killInfo[13]);
|
killInfo[5], killInfo[6], killInfo[3], killInfo[4], killInfo[9], killInfo[10], killInfo[11], killInfo[12], killInfo[13]);
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Query;
|
||||||
|
using Microsoft.EntityFrameworkCore.Query.Internal;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage;
|
||||||
using SharedLibraryCore;
|
using SharedLibraryCore;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using WebfrontCore.Controllers;
|
using WebfrontCore.Controllers;
|
||||||
@ -48,6 +52,7 @@ namespace IW4MAdmin.Plugins.Stats.Web.Controllers
|
|||||||
};
|
};
|
||||||
|
|
||||||
var messages = await iqMessages.ToListAsync();
|
var messages = await iqMessages.ToListAsync();
|
||||||
|
string sql = iqMessages.ToSql();
|
||||||
|
|
||||||
return View("_MessageContext", messages);
|
return View("_MessageContext", messages);
|
||||||
}
|
}
|
||||||
@ -78,4 +83,32 @@ namespace IW4MAdmin.Plugins.Stats.Web.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class IQueryableExtensions
|
||||||
|
{
|
||||||
|
private static readonly TypeInfo QueryCompilerTypeInfo = typeof(QueryCompiler).GetTypeInfo();
|
||||||
|
|
||||||
|
private static readonly FieldInfo QueryCompilerField = typeof(EntityQueryProvider).GetTypeInfo().DeclaredFields.First(x => x.Name == "_queryCompiler");
|
||||||
|
|
||||||
|
private static readonly FieldInfo QueryModelGeneratorField = QueryCompilerTypeInfo.DeclaredFields.First(x => x.Name == "_queryModelGenerator");
|
||||||
|
|
||||||
|
private static readonly FieldInfo DataBaseField = QueryCompilerTypeInfo.DeclaredFields.Single(x => x.Name == "_database");
|
||||||
|
|
||||||
|
private static readonly PropertyInfo DatabaseDependenciesField = typeof(Database).GetTypeInfo().DeclaredProperties.Single(x => x.Name == "Dependencies");
|
||||||
|
|
||||||
|
public static string ToSql<TEntity>(this IQueryable<TEntity> query) where TEntity : class
|
||||||
|
{
|
||||||
|
var queryCompiler = (QueryCompiler)QueryCompilerField.GetValue(query.Provider);
|
||||||
|
var modelGenerator = (QueryModelGenerator)QueryModelGeneratorField.GetValue(queryCompiler);
|
||||||
|
var queryModel = modelGenerator.ParseQuery(query.Expression);
|
||||||
|
var database = (IDatabase)DataBaseField.GetValue(queryCompiler);
|
||||||
|
var databaseDependencies = (DatabaseDependencies)DatabaseDependenciesField.GetValue(database);
|
||||||
|
var queryCompilationContext = databaseDependencies.QueryCompilationContextFactory.Create(false);
|
||||||
|
var modelVisitor = (RelationalQueryModelVisitor)queryCompilationContext.CreateQueryModelVisitor();
|
||||||
|
modelVisitor.CreateQueryExecutor<TEntity>(queryModel);
|
||||||
|
var sql = modelVisitor.Queries.First().ToString();
|
||||||
|
|
||||||
|
return sql;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -150,8 +150,8 @@ namespace SharedLibraryCore.RCon
|
|||||||
// will this really prevent flooding?
|
// will this really prevent flooding?
|
||||||
if ((DateTime.Now - LastQuery).TotalMilliseconds < 350)
|
if ((DateTime.Now - LastQuery).TotalMilliseconds < 350)
|
||||||
{
|
{
|
||||||
//await Task.Delay(350);
|
|
||||||
Thread.Sleep(350);
|
Thread.Sleep(350);
|
||||||
|
//await Task.Delay(350);
|
||||||
}
|
}
|
||||||
|
|
||||||
LastQuery = DateTime.Now;
|
LastQuery = DateTime.Now;
|
||||||
|
@ -116,7 +116,7 @@ namespace SharedLibraryCore
|
|||||||
/// <param name="Message">Message to be sent to all players</param>
|
/// <param name="Message">Message to be sent to all players</param>
|
||||||
public async Task Broadcast(String Message)
|
public async Task Broadcast(String Message)
|
||||||
{
|
{
|
||||||
#if !DEBUG
|
#if DEBUG == false
|
||||||
string formattedMessage = String.Format(RconParser.GetCommandPrefixes().Say, Message);
|
string formattedMessage = String.Format(RconParser.GetCommandPrefixes().Say, Message);
|
||||||
#else
|
#else
|
||||||
Logger.WriteVerbose(Message.StripColors());
|
Logger.WriteVerbose(Message.StripColors());
|
||||||
@ -124,8 +124,12 @@ namespace SharedLibraryCore
|
|||||||
var e = new GameEvent()
|
var e = new GameEvent()
|
||||||
{
|
{
|
||||||
Type = GameEvent.EventType.Broadcast,
|
Type = GameEvent.EventType.Broadcast,
|
||||||
|
#if DEBUG == true
|
||||||
Data = Message,
|
Data = Message,
|
||||||
Owner = this
|
#else
|
||||||
|
Data = formattedMessage,
|
||||||
|
#endif
|
||||||
|
Owner = this,
|
||||||
};
|
};
|
||||||
|
|
||||||
Manager.GetEventHandler().AddEvent(e);
|
Manager.GetEventHandler().AddEvent(e);
|
||||||
|
@ -65,14 +65,14 @@ $(document).ready(function () {
|
|||||||
'serverId': $(this).data('serverid'),
|
'serverId': $(this).data('serverid'),
|
||||||
'when': $(this).data('when')
|
'when': $(this).data('when')
|
||||||
})
|
})
|
||||||
.done(function (response) {
|
.done(function (response) {
|
||||||
$('.client-message-context').remove();
|
$('.client-message-context').remove();
|
||||||
location.after(response);
|
location.after(response);
|
||||||
hideLoader();
|
hideLoader();
|
||||||
})
|
})
|
||||||
.fail(function (jqxhr, textStatus, error) {
|
.fail(function (jqxhr, textStatus, error) {
|
||||||
errorLoader();
|
errorLoader();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user