parent
3645cf53ff
commit
58bfd189d0
@ -431,7 +431,8 @@ namespace IW4MAdmin.Application
|
|||||||
{
|
{
|
||||||
Name = cmd.Name,
|
Name = cmd.Name,
|
||||||
Alias = cmd.Alias,
|
Alias = cmd.Alias,
|
||||||
MinimumPermission = cmd.Permission
|
MinimumPermission = cmd.Permission,
|
||||||
|
AllowImpersonation = cmd.AllowImpersonation
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,6 +144,7 @@ namespace IW4MAdmin
|
|||||||
catch (CommandException e)
|
catch (CommandException e)
|
||||||
{
|
{
|
||||||
Logger.WriteInfo(e.Message);
|
Logger.WriteInfo(e.Message);
|
||||||
|
E.FailReason = GameEvent.EventFailReason.Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (C != null)
|
if (C != null)
|
||||||
@ -342,7 +343,7 @@ namespace IW4MAdmin
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (E.Origin.Level > EFClient.Permission.Moderator)
|
if (E.Origin.Level > Permission.Moderator)
|
||||||
{
|
{
|
||||||
E.Origin.Tell(string.Format(loc["SERVER_REPORT_COUNT"], E.Owner.Reports.Count));
|
E.Origin.Tell(string.Format(loc["SERVER_REPORT_COUNT"], E.Owner.Reports.Count));
|
||||||
}
|
}
|
||||||
@ -371,7 +372,7 @@ namespace IW4MAdmin
|
|||||||
Expires = expires,
|
Expires = expires,
|
||||||
Offender = E.Target,
|
Offender = E.Target,
|
||||||
Offense = E.Data,
|
Offense = E.Data,
|
||||||
Punisher = E.Origin,
|
Punisher = E.ImpersonationOrigin ?? E.Origin,
|
||||||
When = DateTime.UtcNow,
|
When = DateTime.UtcNow,
|
||||||
Link = E.Target.AliasLink
|
Link = E.Target.AliasLink
|
||||||
};
|
};
|
||||||
@ -388,7 +389,7 @@ namespace IW4MAdmin
|
|||||||
Expires = DateTime.UtcNow,
|
Expires = DateTime.UtcNow,
|
||||||
Offender = E.Target,
|
Offender = E.Target,
|
||||||
Offense = E.Data,
|
Offense = E.Data,
|
||||||
Punisher = E.Origin,
|
Punisher = E.ImpersonationOrigin ?? E.Origin,
|
||||||
When = DateTime.UtcNow,
|
When = DateTime.UtcNow,
|
||||||
Link = E.Target.AliasLink
|
Link = E.Target.AliasLink
|
||||||
};
|
};
|
||||||
@ -413,7 +414,7 @@ namespace IW4MAdmin
|
|||||||
Expires = DateTime.UtcNow,
|
Expires = DateTime.UtcNow,
|
||||||
Offender = E.Target,
|
Offender = E.Target,
|
||||||
Offense = E.Message,
|
Offense = E.Message,
|
||||||
Punisher = E.Origin,
|
Punisher = E.ImpersonationOrigin ?? E.Origin,
|
||||||
Active = true,
|
Active = true,
|
||||||
When = DateTime.UtcNow,
|
When = DateTime.UtcNow,
|
||||||
Link = E.Target.AliasLink
|
Link = E.Target.AliasLink
|
||||||
@ -432,28 +433,28 @@ namespace IW4MAdmin
|
|||||||
|
|
||||||
else if (E.Type == GameEvent.EventType.TempBan)
|
else if (E.Type == GameEvent.EventType.TempBan)
|
||||||
{
|
{
|
||||||
await TempBan(E.Data, (TimeSpan)E.Extra, E.Target, E.Origin); ;
|
await TempBan(E.Data, (TimeSpan)E.Extra, E.Target, E.ImpersonationOrigin ?? E.Origin); ;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (E.Type == GameEvent.EventType.Ban)
|
else if (E.Type == GameEvent.EventType.Ban)
|
||||||
{
|
{
|
||||||
bool isEvade = E.Extra != null ? (bool)E.Extra : false;
|
bool isEvade = E.Extra != null ? (bool)E.Extra : false;
|
||||||
await Ban(E.Data, E.Target, E.Origin, isEvade);
|
await Ban(E.Data, E.Target, E.ImpersonationOrigin ?? E.Origin, isEvade);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (E.Type == GameEvent.EventType.Unban)
|
else if (E.Type == GameEvent.EventType.Unban)
|
||||||
{
|
{
|
||||||
await Unban(E.Data, E.Target, E.Origin);
|
await Unban(E.Data, E.Target, E.ImpersonationOrigin ?? E.Origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (E.Type == GameEvent.EventType.Kick)
|
else if (E.Type == GameEvent.EventType.Kick)
|
||||||
{
|
{
|
||||||
await Kick(E.Data, E.Target, E.Origin);
|
await Kick(E.Data, E.Target, E.ImpersonationOrigin ?? E.Origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (E.Type == GameEvent.EventType.Warn)
|
else if (E.Type == GameEvent.EventType.Warn)
|
||||||
{
|
{
|
||||||
await Warn(E.Data, E.Target, E.Origin);
|
await Warn(E.Data, E.Target, E.ImpersonationOrigin ?? E.Origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (E.Type == GameEvent.EventType.Disconnect)
|
else if (E.Type == GameEvent.EventType.Disconnect)
|
||||||
|
@ -19,6 +19,7 @@ namespace IW4MAdmin.Plugins.Stats.Commands
|
|||||||
Alias = "rs";
|
Alias = "rs";
|
||||||
Permission = EFClient.Permission.User;
|
Permission = EFClient.Permission.User;
|
||||||
RequiresTarget = false;
|
RequiresTarget = false;
|
||||||
|
//AllowImpersonation = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task ExecuteAsync(GameEvent E)
|
public override async Task ExecuteAsync(GameEvent E)
|
||||||
|
@ -117,5 +117,10 @@ namespace SharedLibraryCore
|
|||||||
/// Argument list for the command
|
/// Argument list for the command
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public CommandArgument[] Arguments { get; protected set; } = new CommandArgument[0];
|
public CommandArgument[] Arguments { get; protected set; } = new CommandArgument[0];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// indicates if this command allows impersonation (run as)
|
||||||
|
/// </summary>
|
||||||
|
public bool AllowImpersonation { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
13
SharedLibraryCore/Commands/CommandExtensions.cs
Normal file
13
SharedLibraryCore/Commands/CommandExtensions.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace SharedLibraryCore.Commands
|
||||||
|
{
|
||||||
|
public static class CommandExtensions
|
||||||
|
{
|
||||||
|
public static bool IsTargetingSelf(this GameEvent gameEvent) => gameEvent.Origin?.Equals(gameEvent.Target) ?? false;
|
||||||
|
|
||||||
|
public static bool CanPerformActionOnTarget(this GameEvent gameEvent) => gameEvent.Origin?.Level > gameEvent.Target?.Level;
|
||||||
|
}
|
||||||
|
}
|
@ -21,7 +21,8 @@ namespace SharedLibraryCore.Commands
|
|||||||
Command C = null;
|
Command C = null;
|
||||||
foreach (Command cmd in Manager.GetCommands())
|
foreach (Command cmd in Manager.GetCommands())
|
||||||
{
|
{
|
||||||
if (cmd.Name == CommandString.ToLower() || cmd.Alias == CommandString.ToLower())
|
if (cmd.Name.Equals(CommandString, StringComparison.OrdinalIgnoreCase) ||
|
||||||
|
(cmd.Alias ?? "").Equals(CommandString, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
C = cmd;
|
C = cmd;
|
||||||
}
|
}
|
||||||
@ -33,6 +34,12 @@ namespace SharedLibraryCore.Commands
|
|||||||
throw new CommandException($"{E.Origin} entered unknown command \"{CommandString}\"");
|
throw new CommandException($"{E.Origin} entered unknown command \"{CommandString}\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!C.AllowImpersonation && E.ImpersonationOrigin != null)
|
||||||
|
{
|
||||||
|
E.ImpersonationOrigin.Tell(loc["COMMANDS_RUN_AS_FAIL"]);
|
||||||
|
throw new CommandException($"Command {C.Name} cannot be run as another client");
|
||||||
|
}
|
||||||
|
|
||||||
E.Data = E.Data.RemoveWords(1);
|
E.Data = E.Data.RemoveWords(1);
|
||||||
String[] Args = E.Data.Trim().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
String[] Args = E.Data.Trim().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
// todo: the code below can be cleaned up
|
// todo: the code below can be cleaned up
|
||||||
|
@ -1434,6 +1434,7 @@ namespace SharedLibraryCore.Commands
|
|||||||
Alias = "sp";
|
Alias = "sp";
|
||||||
Permission = Permission.Moderator;
|
Permission = Permission.Moderator;
|
||||||
RequiresTarget = false;
|
RequiresTarget = false;
|
||||||
|
AllowImpersonation = true;
|
||||||
Arguments = new[]
|
Arguments = new[]
|
||||||
{
|
{
|
||||||
new CommandArgument()
|
new CommandArgument()
|
||||||
|
65
SharedLibraryCore/Commands/RunAsCommand.cs
Normal file
65
SharedLibraryCore/Commands/RunAsCommand.cs
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
using SharedLibraryCore.Configuration;
|
||||||
|
using SharedLibraryCore.Database.Models;
|
||||||
|
using SharedLibraryCore.Interfaces;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace SharedLibraryCore.Commands
|
||||||
|
{
|
||||||
|
public class RunAsCommand : Command
|
||||||
|
{
|
||||||
|
public RunAsCommand(CommandConfiguration config, ITranslationLookup lookup) : base(config, lookup)
|
||||||
|
{
|
||||||
|
Name = "runas";
|
||||||
|
Description = lookup["COMMANDS_RUN_AS_DESC"];
|
||||||
|
Alias = "ra";
|
||||||
|
Permission = EFClient.Permission.Moderator;
|
||||||
|
RequiresTarget = true;
|
||||||
|
Arguments = new[]
|
||||||
|
{
|
||||||
|
new CommandArgument()
|
||||||
|
{
|
||||||
|
Name = lookup["COMMANDS_ARGS_COMMANDS"],
|
||||||
|
Required = true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task ExecuteAsync(GameEvent E)
|
||||||
|
{
|
||||||
|
if (E.IsTargetingSelf())
|
||||||
|
{
|
||||||
|
E.Origin.Tell(_translationLookup["COMMANDS_RUN_AS_SELF"]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!E.CanPerformActionOnTarget())
|
||||||
|
{
|
||||||
|
E.Origin.Tell(_translationLookup["COMMANDS_RUN_AS_FAIL_PERM"]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string cmd = $"{Utilities.CommandPrefix}{E.Data}";
|
||||||
|
var impersonatedCommandEvent = new GameEvent()
|
||||||
|
{
|
||||||
|
Type = GameEvent.EventType.Command,
|
||||||
|
Origin = E.Target,
|
||||||
|
ImpersonationOrigin = E.Origin,
|
||||||
|
Message = cmd,
|
||||||
|
Data = cmd,
|
||||||
|
Owner = E.Owner
|
||||||
|
};
|
||||||
|
E.Owner.Manager.GetEventHandler().AddEvent(impersonatedCommandEvent);
|
||||||
|
|
||||||
|
var result = await impersonatedCommandEvent.WaitAsync(Utilities.DefaultCommandTimeout, E.Owner.Manager.CancellationToken);
|
||||||
|
var response = E.Owner.CommandResult.Where(c => c.ClientId == E.Target.ClientId).ToList();
|
||||||
|
|
||||||
|
// remove the added command response
|
||||||
|
for (int i = 0; i < response.Count; i++)
|
||||||
|
{
|
||||||
|
E.Origin.Tell(_translationLookup["COMMANDS_RUN_AS_SUCCESS"].FormatExt(response[i].Response));
|
||||||
|
E.Owner.CommandResult.Remove(response[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -24,5 +24,10 @@ namespace SharedLibraryCore.Configuration
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonConverter(typeof(StringEnumConverter))]
|
[JsonConverter(typeof(StringEnumConverter))]
|
||||||
public Permission MinimumPermission { get; set; }
|
public Permission MinimumPermission { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates if the command can be run by another user (impersonation)
|
||||||
|
/// </summary>
|
||||||
|
public bool AllowImpersonation { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace SharedLibraryCore.Database.Models
|
namespace SharedLibraryCore.Database.Models
|
||||||
{
|
{
|
||||||
@ -22,6 +19,7 @@ namespace SharedLibraryCore.Database.Models
|
|||||||
public int ChangeHistoryId { get; set; }
|
public int ChangeHistoryId { get; set; }
|
||||||
public int OriginEntityId { get; set; }
|
public int OriginEntityId { get; set; }
|
||||||
public int TargetEntityId { get; set; }
|
public int TargetEntityId { get; set; }
|
||||||
|
public int? ImpersonationEntityId { get; set; }
|
||||||
public ChangeType TypeOfChange { get; set; }
|
public ChangeType TypeOfChange { get; set; }
|
||||||
public DateTime TimeChanged { get; set; } = DateTime.UtcNow;
|
public DateTime TimeChanged { get; set; } = DateTime.UtcNow;
|
||||||
[MaxLength(128)]
|
[MaxLength(128)]
|
||||||
|
@ -227,6 +227,7 @@ namespace SharedLibraryCore
|
|||||||
public int? GameTime { get; set; }
|
public int? GameTime { get; set; }
|
||||||
public EFClient Origin;
|
public EFClient Origin;
|
||||||
public EFClient Target;
|
public EFClient Target;
|
||||||
|
public EFClient ImpersonationOrigin { get; set; }
|
||||||
public Server Owner;
|
public Server Owner;
|
||||||
public bool IsRemote { get; set; } = false;
|
public bool IsRemote { get; set; } = false;
|
||||||
public object Extra { get; set; }
|
public object Extra { get; set; }
|
||||||
@ -276,7 +277,7 @@ namespace SharedLibraryCore
|
|||||||
Owner?.Logger.WriteError("Waiting for event to complete timed out");
|
Owner?.Logger.WriteError("Waiting for event to complete timed out");
|
||||||
Owner?.Logger.WriteDebug($"{Id}, {Type}, {Data}, {Extra}, {FailReason.ToString()}, {Message}, {Origin}, {Target}");
|
Owner?.Logger.WriteDebug($"{Id}, {Type}, {Data}, {Extra}, {FailReason.ToString()}, {Message}, {Origin}, {Target}");
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
throw new Exception();
|
//throw new Exception();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,5 +44,10 @@ namespace SharedLibraryCore.Interfaces
|
|||||||
/// Indicates if target is required
|
/// Indicates if target is required
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool RequiresTarget { get; }
|
bool RequiresTarget { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates if the commands can be run as another client
|
||||||
|
/// </summary>
|
||||||
|
bool AllowImpersonation { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
919
SharedLibraryCore/Migrations/20200423225137_AddImpersonationIdToEFChangeHistory.Designer.cs
generated
Normal file
919
SharedLibraryCore/Migrations/20200423225137_AddImpersonationIdToEFChangeHistory.Designer.cs
generated
Normal file
@ -0,0 +1,919 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using SharedLibraryCore.Database;
|
||||||
|
|
||||||
|
namespace SharedLibraryCore.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(DatabaseContext))]
|
||||||
|
[Migration("20200423225137_AddImpersonationIdToEFChangeHistory")]
|
||||||
|
partial class AddImpersonationIdToEFChangeHistory
|
||||||
|
{
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "3.1.3");
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("SnapshotId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("Active")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("ClientId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("CurrentSessionLength")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<double>("CurrentStrain")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<int>("CurrentViewAngleId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("Deaths")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<double>("Distance")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<double>("EloRating")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<int>("HitDestinationId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("HitLocation")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("HitOriginId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("HitType")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("Hits")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("Kills")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("LastStrainAngleId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<double>("RecoilOffset")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<double>("SessionAngleOffset")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<double>("SessionAverageSnapValue")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<double>("SessionSPM")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<int>("SessionScore")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("SessionSnapHits")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<double>("StrainAngleBetween")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<int>("TimeSinceLastEvent")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("WeaponId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("When")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("SnapshotId");
|
||||||
|
|
||||||
|
b.HasIndex("ClientId");
|
||||||
|
|
||||||
|
b.HasIndex("CurrentViewAngleId");
|
||||||
|
|
||||||
|
b.HasIndex("HitDestinationId");
|
||||||
|
|
||||||
|
b.HasIndex("HitOriginId");
|
||||||
|
|
||||||
|
b.HasIndex("LastStrainAngleId");
|
||||||
|
|
||||||
|
b.ToTable("EFACSnapshot");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshotVector3", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ACSnapshotVector3Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("Active")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("SnapshotId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("Vector3Id")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("ACSnapshotVector3Id");
|
||||||
|
|
||||||
|
b.HasIndex("SnapshotId");
|
||||||
|
|
||||||
|
b.HasIndex("Vector3Id");
|
||||||
|
|
||||||
|
b.ToTable("EFACSnapshotVector3");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientKill", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("KillId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("Active")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("AttackerId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("Damage")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int?>("DeathOriginVector3Id")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("DeathType")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<double>("Fraction")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<int>("HitLoc")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("IsKill")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int?>("KillOriginVector3Id")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("Map")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<long>("ServerId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("VictimId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int?>("ViewAnglesVector3Id")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<double>("VisibilityPercentage")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<int>("Weapon")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("When")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("KillId");
|
||||||
|
|
||||||
|
b.HasIndex("AttackerId");
|
||||||
|
|
||||||
|
b.HasIndex("DeathOriginVector3Id");
|
||||||
|
|
||||||
|
b.HasIndex("KillOriginVector3Id");
|
||||||
|
|
||||||
|
b.HasIndex("ServerId");
|
||||||
|
|
||||||
|
b.HasIndex("VictimId");
|
||||||
|
|
||||||
|
b.HasIndex("ViewAnglesVector3Id");
|
||||||
|
|
||||||
|
b.ToTable("EFClientKills");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientMessage", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("MessageId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("Active")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("ClientId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Message")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<long>("ServerId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("TimeSent")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("MessageId");
|
||||||
|
|
||||||
|
b.HasIndex("ClientId");
|
||||||
|
|
||||||
|
b.HasIndex("ServerId");
|
||||||
|
|
||||||
|
b.HasIndex("TimeSent");
|
||||||
|
|
||||||
|
b.ToTable("EFClientMessages");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientRatingHistory", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("RatingHistoryId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("Active")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("ClientId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("RatingHistoryId");
|
||||||
|
|
||||||
|
b.HasIndex("ClientId");
|
||||||
|
|
||||||
|
b.ToTable("EFClientRatingHistory");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ClientId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<long>("ServerId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("Active")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<double>("AverageRecoilOffset")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<double>("AverageSnapValue")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<int>("Deaths")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<double>("EloRating")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<int>("Kills")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<double>("MaxStrain")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<double>("RollingWeightedKDR")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<double>("SPM")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<double>("Skill")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<int>("SnapHitCount")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("TimePlayed")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<double>("VisionAverage")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.HasKey("ClientId", "ServerId");
|
||||||
|
|
||||||
|
b.HasIndex("ServerId");
|
||||||
|
|
||||||
|
b.ToTable("EFClientStatistics");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFHitLocationCount", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("HitLocationCountId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("Active")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("EFClientStatisticsClientId")
|
||||||
|
.HasColumnName("EFClientStatisticsClientId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<long>("EFClientStatisticsServerId")
|
||||||
|
.HasColumnName("EFClientStatisticsServerId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("HitCount")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<float>("HitOffsetAverage")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<int>("Location")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<float>("MaxAngleDistance")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.HasKey("HitLocationCountId");
|
||||||
|
|
||||||
|
b.HasIndex("EFClientStatisticsServerId");
|
||||||
|
|
||||||
|
b.HasIndex("EFClientStatisticsClientId", "EFClientStatisticsServerId");
|
||||||
|
|
||||||
|
b.ToTable("EFHitLocationCounts");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFRating", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("RatingId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("Active")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("ActivityAmount")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("Newest")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<double>("Performance")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<int>("Ranking")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("RatingHistoryId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<long?>("ServerId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("When")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("RatingId");
|
||||||
|
|
||||||
|
b.HasIndex("RatingHistoryId");
|
||||||
|
|
||||||
|
b.HasIndex("ServerId");
|
||||||
|
|
||||||
|
b.HasIndex("Performance", "Ranking", "When");
|
||||||
|
|
||||||
|
b.ToTable("EFRating");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFServer", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("ServerId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("Active")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("EndPoint")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int?>("GameName")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("Port")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("ServerId");
|
||||||
|
|
||||||
|
b.ToTable("EFServers");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFServerStatistics", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("StatisticId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("Active")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<long>("ServerId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<long>("TotalKills")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<long>("TotalPlayTime")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("StatisticId");
|
||||||
|
|
||||||
|
b.HasIndex("ServerId");
|
||||||
|
|
||||||
|
b.ToTable("EFServerStatistics");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFAlias", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("AliasId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("Active")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("DateAdded")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int?>("IPAddress")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("LinkId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT")
|
||||||
|
.HasMaxLength(24);
|
||||||
|
|
||||||
|
b.Property<string>("SearchableName")
|
||||||
|
.HasColumnType("TEXT")
|
||||||
|
.HasMaxLength(24);
|
||||||
|
|
||||||
|
b.HasKey("AliasId");
|
||||||
|
|
||||||
|
b.HasIndex("IPAddress");
|
||||||
|
|
||||||
|
b.HasIndex("LinkId");
|
||||||
|
|
||||||
|
b.HasIndex("Name");
|
||||||
|
|
||||||
|
b.HasIndex("SearchableName");
|
||||||
|
|
||||||
|
b.HasIndex("Name", "IPAddress")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("EFAlias");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFAliasLink", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("AliasLinkId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("Active")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("AliasLinkId");
|
||||||
|
|
||||||
|
b.ToTable("EFAliasLinks");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFChangeHistory", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ChangeHistoryId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("Active")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Comment")
|
||||||
|
.HasColumnType("TEXT")
|
||||||
|
.HasMaxLength(128);
|
||||||
|
|
||||||
|
b.Property<string>("CurrentValue")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int?>("ImpersonationEntityId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("OriginEntityId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("PreviousValue")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("TargetEntityId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("TimeChanged")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("TypeOfChange")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("ChangeHistoryId");
|
||||||
|
|
||||||
|
b.ToTable("EFChangeHistory");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFClient", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("ClientId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("Active")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("AliasLinkId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("Connections")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("CurrentAliasId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("FirstConnection")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("LastConnection")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("Level")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("Masked")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<long>("NetworkId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Password")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("PasswordSalt")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("TotalConnectionTime")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("ClientId");
|
||||||
|
|
||||||
|
b.HasIndex("AliasLinkId");
|
||||||
|
|
||||||
|
b.HasIndex("CurrentAliasId");
|
||||||
|
|
||||||
|
b.HasIndex("NetworkId")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("EFClients");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFMeta", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("MetaId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("Active")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("ClientId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("Created")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Extra")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Key")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT")
|
||||||
|
.HasMaxLength(32);
|
||||||
|
|
||||||
|
b.Property<DateTime>("Updated")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Value")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("MetaId");
|
||||||
|
|
||||||
|
b.HasIndex("ClientId");
|
||||||
|
|
||||||
|
b.HasIndex("Key");
|
||||||
|
|
||||||
|
b.ToTable("EFMeta");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFPenalty", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("PenaltyId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("Active")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("AutomatedOffense")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("Expires")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("IsEvadedOffense")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("LinkId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("OffenderId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Offense")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("PunisherId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("Type")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("When")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("PenaltyId");
|
||||||
|
|
||||||
|
b.HasIndex("LinkId");
|
||||||
|
|
||||||
|
b.HasIndex("OffenderId");
|
||||||
|
|
||||||
|
b.HasIndex("PunisherId");
|
||||||
|
|
||||||
|
b.ToTable("EFPenalties");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Helpers.Vector3", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Vector3Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<float>("X")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<float>("Y")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<float>("Z")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.HasKey("Vector3Id");
|
||||||
|
|
||||||
|
b.ToTable("Vector3");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ClientId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("SharedLibraryCore.Helpers.Vector3", "CurrentViewAngle")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("CurrentViewAngleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("SharedLibraryCore.Helpers.Vector3", "HitDestination")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("HitDestinationId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("SharedLibraryCore.Helpers.Vector3", "HitOrigin")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("HitOriginId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("SharedLibraryCore.Helpers.Vector3", "LastStrainAngle")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("LastStrainAngleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshotVector3", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot", "Snapshot")
|
||||||
|
.WithMany("PredictedViewAngles")
|
||||||
|
.HasForeignKey("SnapshotId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("SharedLibraryCore.Helpers.Vector3", "Vector")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("Vector3Id")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientKill", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Attacker")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("AttackerId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("SharedLibraryCore.Helpers.Vector3", "DeathOrigin")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("DeathOriginVector3Id");
|
||||||
|
|
||||||
|
b.HasOne("SharedLibraryCore.Helpers.Vector3", "KillOrigin")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("KillOriginVector3Id");
|
||||||
|
|
||||||
|
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ServerId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Victim")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("VictimId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("SharedLibraryCore.Helpers.Vector3", "ViewAngles")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ViewAnglesVector3Id");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientMessage", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ClientId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ServerId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientRatingHistory", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ClientId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ClientId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ServerId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFHitLocationCount", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("EFClientStatisticsClientId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("EFClientStatisticsServerId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics", null)
|
||||||
|
.WithMany("HitLocations")
|
||||||
|
.HasForeignKey("EFClientStatisticsClientId", "EFClientStatisticsServerId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFRating", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFClientRatingHistory", "RatingHistory")
|
||||||
|
.WithMany("Ratings")
|
||||||
|
.HasForeignKey("RatingHistoryId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ServerId");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFServerStatistics", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("ServerId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFAlias", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFAliasLink", "Link")
|
||||||
|
.WithMany("Children")
|
||||||
|
.HasForeignKey("LinkId")
|
||||||
|
.OnDelete(DeleteBehavior.Restrict)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFClient", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFAliasLink", "AliasLink")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("AliasLinkId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFAlias", "CurrentAlias")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("CurrentAliasId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFMeta", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client")
|
||||||
|
.WithMany("Meta")
|
||||||
|
.HasForeignKey("ClientId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("SharedLibraryCore.Database.Models.EFPenalty", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFAliasLink", "Link")
|
||||||
|
.WithMany("ReceivedPenalties")
|
||||||
|
.HasForeignKey("LinkId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Offender")
|
||||||
|
.WithMany("ReceivedPenalties")
|
||||||
|
.HasForeignKey("OffenderId")
|
||||||
|
.OnDelete(DeleteBehavior.Restrict)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Punisher")
|
||||||
|
.WithMany("AdministeredPenalties")
|
||||||
|
.HasForeignKey("PunisherId")
|
||||||
|
.OnDelete(DeleteBehavior.Restrict)
|
||||||
|
.IsRequired();
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
namespace SharedLibraryCore.Migrations
|
||||||
|
{
|
||||||
|
public partial class AddImpersonationIdToEFChangeHistory : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "ImpersonationEntityId",
|
||||||
|
table: "EFChangeHistory",
|
||||||
|
nullable: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "ImpersonationEntityId",
|
||||||
|
table: "EFChangeHistory");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -14,7 +14,7 @@ namespace SharedLibraryCore.Migrations
|
|||||||
{
|
{
|
||||||
#pragma warning disable 612, 618
|
#pragma warning disable 612, 618
|
||||||
modelBuilder
|
modelBuilder
|
||||||
.HasAnnotation("ProductVersion", "3.1.0");
|
.HasAnnotation("ProductVersion", "3.1.3");
|
||||||
|
|
||||||
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot", b =>
|
modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFACSnapshot", b =>
|
||||||
{
|
{
|
||||||
@ -511,6 +511,9 @@ namespace SharedLibraryCore.Migrations
|
|||||||
b.Property<string>("CurrentValue")
|
b.Property<string>("CurrentValue")
|
||||||
.HasColumnType("TEXT");
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int?>("ImpersonationEntityId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
b.Property<int>("OriginEntityId")
|
b.Property<int>("OriginEntityId")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ namespace SharedLibraryCore.Services
|
|||||||
{
|
{
|
||||||
OriginEntityId = e.Origin.ClientId,
|
OriginEntityId = e.Origin.ClientId,
|
||||||
TargetEntityId = e.Target.ClientId,
|
TargetEntityId = e.Target.ClientId,
|
||||||
|
ImpersonationEntityId = e.ImpersonationOrigin?.ClientId,
|
||||||
TypeOfChange = EFChangeHistory.ChangeType.Ban,
|
TypeOfChange = EFChangeHistory.ChangeType.Ban,
|
||||||
Comment = e.Data
|
Comment = e.Data
|
||||||
};
|
};
|
||||||
@ -43,6 +44,7 @@ namespace SharedLibraryCore.Services
|
|||||||
{
|
{
|
||||||
OriginEntityId = e.Origin.ClientId,
|
OriginEntityId = e.Origin.ClientId,
|
||||||
TargetEntityId = e.Target?.ClientId ?? 0,
|
TargetEntityId = e.Target?.ClientId ?? 0,
|
||||||
|
ImpersonationEntityId = e.ImpersonationOrigin?.ClientId,
|
||||||
Comment = "Executed command",
|
Comment = "Executed command",
|
||||||
CurrentValue = e.Message,
|
CurrentValue = e.Message,
|
||||||
TypeOfChange = EFChangeHistory.ChangeType.Command
|
TypeOfChange = EFChangeHistory.ChangeType.Command
|
||||||
@ -53,6 +55,7 @@ namespace SharedLibraryCore.Services
|
|||||||
{
|
{
|
||||||
OriginEntityId = e.Origin.ClientId,
|
OriginEntityId = e.Origin.ClientId,
|
||||||
TargetEntityId = e.Target.ClientId,
|
TargetEntityId = e.Target.ClientId,
|
||||||
|
ImpersonationEntityId = e.ImpersonationOrigin?.ClientId,
|
||||||
Comment = "Changed permission level",
|
Comment = "Changed permission level",
|
||||||
TypeOfChange = EFChangeHistory.ChangeType.Permission,
|
TypeOfChange = EFChangeHistory.ChangeType.Permission,
|
||||||
CurrentValue = ((EFClient.Permission)e.Extra).ToString()
|
CurrentValue = ((EFClient.Permission)e.Extra).ToString()
|
||||||
|
@ -32,9 +32,9 @@ namespace SharedLibraryCore
|
|||||||
#endif
|
#endif
|
||||||
public static Encoding EncodingType;
|
public static Encoding EncodingType;
|
||||||
public static Localization.Layout CurrentLocalization = new Localization.Layout(new Dictionary<string, string>());
|
public static Localization.Layout CurrentLocalization = new Localization.Layout(new Dictionary<string, string>());
|
||||||
public static TimeSpan DefaultCommandTimeout = new TimeSpan(0, 0, 25);
|
public static TimeSpan DefaultCommandTimeout { get; set; } = new TimeSpan(0, 0, 25);
|
||||||
public static char[] DirectorySeparatorChars = new[] { '\\', '/' };
|
public static char[] DirectorySeparatorChars = new[] { '\\', '/' };
|
||||||
|
public static char CommandPrefix { get; set; } = '!';
|
||||||
public static EFClient IW4MAdminClient(Server server = null)
|
public static EFClient IW4MAdminClient(Server server = null)
|
||||||
{
|
{
|
||||||
return new EFClient()
|
return new EFClient()
|
||||||
|
178
Tests/ApplicationTests/CommandTests.cs
Normal file
178
Tests/ApplicationTests/CommandTests.cs
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
using NUnit.Framework;
|
||||||
|
using System;
|
||||||
|
using SharedLibraryCore.Interfaces;
|
||||||
|
using IW4MAdmin;
|
||||||
|
using FakeItEasy;
|
||||||
|
using IW4MAdmin.Application.EventParsers;
|
||||||
|
using System.Linq;
|
||||||
|
using IW4MAdmin.Plugins.Stats.Models;
|
||||||
|
using IW4MAdmin.Application.Helpers;
|
||||||
|
using IW4MAdmin.Plugins.Stats.Config;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using SharedLibraryCore.Database.Models;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using IW4MAdmin.Plugins.Stats.Helpers;
|
||||||
|
using ApplicationTests.Fixtures;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using SharedLibraryCore.Commands;
|
||||||
|
using SharedLibraryCore.Configuration;
|
||||||
|
using SharedLibraryCore;
|
||||||
|
using ApplicationTests.Mocks;
|
||||||
|
|
||||||
|
namespace ApplicationTests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class CommandTests
|
||||||
|
{
|
||||||
|
ILogger logger;
|
||||||
|
private IServiceProvider serviceProvider;
|
||||||
|
private ITranslationLookup transLookup;
|
||||||
|
private CommandConfiguration cmdConfig;
|
||||||
|
private MockEventHandler mockEventHandler;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
logger = A.Fake<ILogger>();
|
||||||
|
cmdConfig = new CommandConfiguration();
|
||||||
|
|
||||||
|
serviceProvider = new ServiceCollection()
|
||||||
|
.BuildBase()
|
||||||
|
.BuildServiceProvider();
|
||||||
|
|
||||||
|
mockEventHandler = new MockEventHandler(true);
|
||||||
|
A.CallTo(() => serviceProvider.GetRequiredService<IManager>().GetEventHandler())
|
||||||
|
.Returns(mockEventHandler);
|
||||||
|
|
||||||
|
var mgr = serviceProvider.GetRequiredService<IManager>();
|
||||||
|
transLookup = serviceProvider.GetRequiredService<ITranslationLookup>();
|
||||||
|
|
||||||
|
A.CallTo(() => mgr.GetCommands())
|
||||||
|
.Returns(new Command[]
|
||||||
|
{
|
||||||
|
new ImpersonatableCommand(cmdConfig, transLookup),
|
||||||
|
new NonImpersonatableCommand(cmdConfig, transLookup)
|
||||||
|
});
|
||||||
|
|
||||||
|
//Utilities.DefaultCommandTimeout = new TimeSpan(0, 0, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region RUNAS
|
||||||
|
[Test]
|
||||||
|
public async Task Test_RunAsFailsOnSelf()
|
||||||
|
{
|
||||||
|
var cmd = new RunAsCommand(cmdConfig, transLookup);
|
||||||
|
var server = serviceProvider.GetRequiredService<IW4MServer>();
|
||||||
|
var target = ClientGenerators.CreateBasicClient(server);
|
||||||
|
|
||||||
|
var gameEvent = new GameEvent()
|
||||||
|
{
|
||||||
|
Target = target,
|
||||||
|
Origin = target
|
||||||
|
};
|
||||||
|
|
||||||
|
await cmd.ExecuteAsync(gameEvent);
|
||||||
|
|
||||||
|
Assert.IsNotEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.Tell));
|
||||||
|
Assert.IsEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.Command));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Test_RunAsFailsOnHigherPrivilege()
|
||||||
|
{
|
||||||
|
var cmd = new RunAsCommand(cmdConfig, transLookup);
|
||||||
|
var server = serviceProvider.GetRequiredService<IW4MServer>();
|
||||||
|
var target = ClientGenerators.CreateBasicClient(server);
|
||||||
|
target.Level = EFClient.Permission.Administrator;
|
||||||
|
var origin = ClientGenerators.CreateBasicClient(server);
|
||||||
|
origin.NetworkId = 100;
|
||||||
|
origin.Level = EFClient.Permission.Moderator;
|
||||||
|
|
||||||
|
var gameEvent = new GameEvent()
|
||||||
|
{
|
||||||
|
Target = target,
|
||||||
|
Origin = origin
|
||||||
|
};
|
||||||
|
|
||||||
|
await cmd.ExecuteAsync(gameEvent);
|
||||||
|
|
||||||
|
Assert.IsNotEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.Tell));
|
||||||
|
Assert.IsEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.Command));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Test_RunAsFailsOnSamePrivilege()
|
||||||
|
{
|
||||||
|
var cmd = new RunAsCommand(cmdConfig, transLookup);
|
||||||
|
var server = serviceProvider.GetRequiredService<IW4MServer>();
|
||||||
|
var target = ClientGenerators.CreateBasicClient(server);
|
||||||
|
target.Level = EFClient.Permission.Administrator;
|
||||||
|
var origin = ClientGenerators.CreateBasicClient(server);
|
||||||
|
origin.NetworkId = 100;
|
||||||
|
origin.Level = EFClient.Permission.Administrator;
|
||||||
|
|
||||||
|
var gameEvent = new GameEvent()
|
||||||
|
{
|
||||||
|
Target = target,
|
||||||
|
Origin = origin
|
||||||
|
};
|
||||||
|
|
||||||
|
await cmd.ExecuteAsync(gameEvent);
|
||||||
|
|
||||||
|
Assert.IsNotEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.Tell));
|
||||||
|
Assert.IsEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.Command));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Test_RunAsFailsOnDisallowedCommand()
|
||||||
|
{
|
||||||
|
var cmd = new RunAsCommand(cmdConfig, transLookup);
|
||||||
|
var server = serviceProvider.GetRequiredService<IW4MServer>();
|
||||||
|
var target = ClientGenerators.CreateBasicClient(server);
|
||||||
|
target.Level = EFClient.Permission.Moderator;
|
||||||
|
var origin = ClientGenerators.CreateBasicClient(server);
|
||||||
|
origin.NetworkId = 100;
|
||||||
|
origin.Level = EFClient.Permission.Administrator;
|
||||||
|
|
||||||
|
var gameEvent = new GameEvent()
|
||||||
|
{
|
||||||
|
Target = target,
|
||||||
|
Origin = origin,
|
||||||
|
Owner = server,
|
||||||
|
Data = nameof(NonImpersonatableCommand)
|
||||||
|
};
|
||||||
|
|
||||||
|
await cmd.ExecuteAsync(gameEvent);
|
||||||
|
|
||||||
|
Assert.IsNotEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.Tell));
|
||||||
|
// failed when validating the command
|
||||||
|
Assert.IsNotEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.Command && _event.FailReason == GameEvent.EventFailReason.Invalid));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Test_RunAsQueuesEventAndResponse()
|
||||||
|
{
|
||||||
|
var cmd = new RunAsCommand(cmdConfig, transLookup);
|
||||||
|
var server = serviceProvider.GetRequiredService<IW4MServer>();
|
||||||
|
var target = ClientGenerators.CreateBasicClient(server);
|
||||||
|
target.Level = EFClient.Permission.Moderator;
|
||||||
|
var origin = ClientGenerators.CreateBasicClient(server);
|
||||||
|
origin.NetworkId = 100;
|
||||||
|
origin.Level = EFClient.Permission.Administrator;
|
||||||
|
|
||||||
|
var gameEvent = new GameEvent()
|
||||||
|
{
|
||||||
|
Target = target,
|
||||||
|
Origin = origin,
|
||||||
|
Data = nameof(ImpersonatableCommand),
|
||||||
|
Owner = server
|
||||||
|
};
|
||||||
|
|
||||||
|
await cmd.ExecuteAsync(gameEvent);
|
||||||
|
|
||||||
|
Assert.IsNotEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.Tell /*&& _event.Target == origin todo: fake the command result*/ ));
|
||||||
|
Assert.IsNotEmpty(mockEventHandler.Events.Where(_event => _event.Type == GameEvent.EventType.Command && !_event.Failed));
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
36
Tests/ApplicationTests/Mocks/Commands.cs
Normal file
36
Tests/ApplicationTests/Mocks/Commands.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using SharedLibraryCore;
|
||||||
|
using SharedLibraryCore.Configuration;
|
||||||
|
using SharedLibraryCore.Interfaces;
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace ApplicationTests.Mocks
|
||||||
|
{
|
||||||
|
class ImpersonatableCommand : Command
|
||||||
|
{
|
||||||
|
public ImpersonatableCommand(CommandConfiguration config, ITranslationLookup lookup) : base(config, lookup)
|
||||||
|
{
|
||||||
|
AllowImpersonation = true;
|
||||||
|
Name = nameof(ImpersonatableCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Task ExecuteAsync(GameEvent E)
|
||||||
|
{
|
||||||
|
E.Origin.Tell("test");
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class NonImpersonatableCommand : Command
|
||||||
|
{
|
||||||
|
public NonImpersonatableCommand(CommandConfiguration config, ITranslationLookup lookup) : base(config, lookup)
|
||||||
|
{
|
||||||
|
Name = nameof(NonImpersonatableCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Task ExecuteAsync(GameEvent E)
|
||||||
|
{
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,10 +7,22 @@ namespace ApplicationTests.Mocks
|
|||||||
class MockEventHandler : IEventHandler
|
class MockEventHandler : IEventHandler
|
||||||
{
|
{
|
||||||
public IList<GameEvent> Events = new List<GameEvent>();
|
public IList<GameEvent> Events = new List<GameEvent>();
|
||||||
|
private readonly bool _autoExecute;
|
||||||
|
|
||||||
|
public MockEventHandler(bool autoExecute = false)
|
||||||
|
{
|
||||||
|
_autoExecute = autoExecute;
|
||||||
|
}
|
||||||
|
|
||||||
public void AddEvent(GameEvent gameEvent)
|
public void AddEvent(GameEvent gameEvent)
|
||||||
{
|
{
|
||||||
Events.Add(gameEvent);
|
Events.Add(gameEvent);
|
||||||
|
|
||||||
|
if (_autoExecute)
|
||||||
|
{
|
||||||
|
gameEvent.Owner?.ExecuteEvent(gameEvent);
|
||||||
|
gameEvent.Complete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user