Skip to content

Commit

Permalink
Refactored the Command System so it makes use of the V-Rising AdminLe…
Browse files Browse the repository at this point in the history
…vel enum
  • Loading branch information
WhiteFang5 committed Aug 5, 2022
1 parent a093398 commit e2b1fc8
Show file tree
Hide file tree
Showing 10 changed files with 118 additions and 40 deletions.
1 change: 1 addition & 0 deletions ExperimentalMod/ExperimentalMod.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
<Compile Include="..\Shared\CommandSystem\CommandExtensions.cs" Link="Shared\CommandExtensions.cs" />
<Compile Include="..\Shared\CommandSystem\CommandSystem.cs" Link="Shared\CommandSystem.cs" />
<Compile Include="..\Shared\CommandSystem\CommandSystemConfig.cs" Link="Shared\CommandSystemConfig.cs" />
<Compile Include="..\Shared\ExtensionMethods.cs" Link="Shared\ExtensionMethods.cs" />
<Compile Include="..\Shared\Utils.cs" Link="Shared\Utils.cs" />
<Compile Include="..\Shared\VModCharacter.cs" Link="Shared\VModCharacter.cs" />
<Compile Include="..\Shared\VModStorage.cs" Link="Shared\VModStorage.cs" />
Expand Down
7 changes: 4 additions & 3 deletions PvPPunishment/Systems/PvPPunishmentSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Unity.Entities;
using VMods.Shared;
using Wetstone.API;
using AdminLevel = VMods.Shared.CommandAttribute.AdminLevel;

namespace VMods.PvPPunishment
{
Expand Down Expand Up @@ -221,7 +222,7 @@ private static void PruneOffenses()
}
}

[Command("ispunished", "ispunished [<player-name>]", "Tell you if the the given player (or yourself when no playername is given) currently has the PvP Punishment buff", true)]
[Command("ispunished", "ispunished [<player-name>]", "Tell you if the the given player (or yourself when no playername is given) currently has the PvP Punishment buff", AdminLevel.Admin)]
private static void OnIsPunishedPlayerCommand(Command command)
{
var entityManager = VWorld.Server.EntityManager;
Expand All @@ -241,7 +242,7 @@ private static void OnIsPunishedPlayerCommand(Command command)
command.Use();
}

[Command("punish", "punish [<player-name>]", "Adds (or refreshes) the PvP Punishment buff for the given player (or yourself when no playername is given)", true)]
[Command("punish", "punish [<player-name>]", "Adds (or refreshes) the PvP Punishment buff for the given player (or yourself when no playername is given)", AdminLevel.Admin)]
private static void OnPunishPlayerCommand(Command command)
{
var entityManager = VWorld.Server.EntityManager;
Expand All @@ -255,7 +256,7 @@ private static void OnPunishPlayerCommand(Command command)
command.Use();
}

[Command("unpunish", "unpunish [<player-name>]", "Removes the PvP Punishment buff for the given player (or yourself when no playername is given)", true)]
[Command("unpunish", "unpunish [<player-name>]", "Removes the PvP Punishment buff for the given player (or yourself when no playername is given)", AdminLevel.Admin)]
private static void OnUnPunishPlayerCommand(Command command)
{
var entityManager = VWorld.Server.EntityManager;
Expand Down
24 changes: 19 additions & 5 deletions Shared/CommandSystem/CommandAttribute.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using ProjectM;
using System;
using System.Collections.Generic;
using System.Linq;

Expand All @@ -12,18 +13,31 @@ public class CommandAttribute : Attribute
public IReadOnlyList<string> Names { get; }
public string Usage { get; }
public string Description { get; }
public bool ReqAdmin { get; }
public AdminLevel ReqAdminLevel { get; }

#endregion

#region Livecycle
#region Lifecycle

public CommandAttribute(string name, string usage = "", string description = "", bool reqAdmin = false)
public CommandAttribute(string name, string usage = "", string description = "", AdminLevel reqAdminLevel = AdminLevel.None)
{
Names = name.Split(',').Select(x => x.Trim()).ToList();
Usage = usage;
Description = description;
ReqAdmin = reqAdmin;
ReqAdminLevel = reqAdminLevel;
}

#endregion

#region Nested

/// Exact copy of <see cref="ProjectM.AdminLevel"/>
public enum AdminLevel
{
None = 0,
Moderator = 1,
Admin = 2,
SuperAdmin = 3
}

#endregion
Expand Down
2 changes: 1 addition & 1 deletion Shared/CommandSystem/CommandExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public static (string searchUsername, VModCharacter? vmodCharacter) FindVModChar

if(argIdx >= 0 && command.Args.Length >= (argIdx + 1))
{
searchUsername = command.Args[0];
searchUsername = command.Args[argIdx];
fromCharacter = VModCharacter.GetVModCharacter(searchUsername, entityManager);
}
else
Expand Down
37 changes: 25 additions & 12 deletions Shared/CommandSystem/CommandSystem.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
using ProjectM.Network;
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Wetstone.API;
using Wetstone.Hooks;
using static VMods.Shared.CommandAttribute;

namespace VMods.Shared
{
Expand All @@ -21,7 +21,7 @@ public static class CommandSystem
private static readonly Dictionary<ulong, DateTime> _lastUsedCommandTimes = new();

private static List<(MethodInfo method, CommandAttribute attribute)> _commandReflectionMethods;
private static readonly List<(Action<Command> method, CommandAttribute attribute)> _commandMethods = new();
private static readonly List<(string id, Action<Command> method, CommandAttribute attribute)> _commandMethods = new();

#endregion

Expand All @@ -47,9 +47,14 @@ public static void Deinitialize()
_commandMethods.Clear();
}

public static void RegisterCommand(Action<Command> commandMethod, CommandAttribute commandAttribute)
public static void RegisterCommand(string uniqueId, Action<Command> commandMethod, CommandAttribute commandAttribute)
{
_commandMethods.Add((commandMethod, commandAttribute));
_commandMethods.Add((uniqueId, commandMethod, commandAttribute));
}

public static void UnregisterCommand(string uniqueId)
{
_commandMethods.RemoveAll(x => x.id == uniqueId);
}

public static void UnregisterCommand(Action<Command> commandMethod, CommandAttribute commandAttribute)
Expand Down Expand Up @@ -126,9 +131,9 @@ private static void OnChatMessage(VChatEvent chatEvent)
// Fire the command (so an event handler can actually handle/execute it)
Command command = new(new VModCharacter(chatEvent.SenderUserEntity, chatEvent.SenderCharacterEntity), name, args);

foreach((var method, var attribute) in _commandMethods)
foreach((_, var method, var attribute) in _commandMethods)
{
if(!attribute.Names.Contains(command.Name) || (attribute.ReqAdmin && !user.IsAdmin))
if(!attribute.Names.Contains(command.Name) || !command.VModCharacter.AdminLevel.HasReqLevel(attribute.ReqAdminLevel))
{
continue;
}
Expand All @@ -151,7 +156,7 @@ private static void OnChatMessage(VChatEvent chatEvent)
{
foreach((var method, var attribute) in _commandReflectionMethods)
{
if(!attribute.Names.Contains(command.Name) || (attribute.ReqAdmin && !user.IsAdmin))
if(!attribute.Names.Contains(command.Name) || !command.VModCharacter.AdminLevel.HasReqLevel(attribute.ReqAdminLevel))
{
continue;
}
Expand Down Expand Up @@ -208,14 +213,22 @@ private static void OnHelpCommand(Command command)
// Nested Method(s)
void SendCommandInfo(CommandAttribute attribute)
{
if(attribute.ReqAdmin && !vmodCharacter.IsAdmin)
if(!vmodCharacter.AdminLevel.HasReqLevel(attribute.ReqAdminLevel))
{
return;
}
string message = $"<color=#00ff00>{string.Join(", ", attribute.Names.Select(x => $"{commandPrefix}{x}"))}</color>";
if(attribute.ReqAdmin)
switch(attribute.ReqAdminLevel)
{
message += " - <color=#ff0000>[ADMIN]</color>";
case AdminLevel.Moderator:
message += " - <color=#FFA500>[MOD]</color>";
break;
case AdminLevel.Admin:
message += " - <color=#ff0000>[ADMIN]</color>";
break;
case AdminLevel.SuperAdmin:
message += " - <color=#ff0000>[SUPER-ADMIN]</color>";
break;
}
message += $" - <color=#ffffff>{attribute.Description}</color>";
vmodCharacter.SendSystemMessage(message);
Expand All @@ -239,7 +252,7 @@ void SendCommandInfo(CommandAttribute attribute)
}

// Check the found info
if(attribute == null || attribute.ReqAdmin && !vmodCharacter.IsAdmin)
if(attribute == null || !vmodCharacter.AdminLevel.HasReqLevel(attribute.ReqAdminLevel))
{
return;
}
Expand Down
10 changes: 10 additions & 0 deletions Shared/ExtensionMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,15 @@ public static string ToAgoString(this TimeSpan timeSpan)
}
return $"{timeSpan.Milliseconds}ms";
}

public static bool HasReqLevel(this ProjectM.AdminLevel adminLevel, ProjectM.AdminLevel reqAdminLevel) => (int)adminLevel >= (int)reqAdminLevel;

public static bool HasReqLevel(this ProjectM.AdminLevel adminLevel, CommandAttribute.AdminLevel reqAdminLevel) => (int)adminLevel >= (int)reqAdminLevel;

public static bool HasReqLevel(this CommandAttribute.AdminLevel adminLevel, ProjectM.AdminLevel reqAdminLevel) => (int)adminLevel >= (int)reqAdminLevel;

public static ProjectM.AdminLevel ToAdminLevel(this CommandAttribute.AdminLevel adminLevel) => (ProjectM.AdminLevel)(int)adminLevel;

public static CommandAttribute.AdminLevel ToAdminLevel(this ProjectM.AdminLevel adminLevel) => (CommandAttribute.AdminLevel)(int)adminLevel;
}
}
5 changes: 3 additions & 2 deletions Shared/HighestGearScoreSystem/HighestGearScoreSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Linq;
using Unity.Entities;
using Wetstone.API;
using AdminLevel = VMods.Shared.CommandAttribute.AdminLevel;

namespace VMods.Shared
{
Expand Down Expand Up @@ -140,7 +141,7 @@ private static void OnVampireDowned(Entity killer, Entity victim)
_gearScoreData.Remove(victumUser.PlatformId);
}

[Command("highestgs,hgs,higs,highgs,highestgearscore", "highestgs [<player-name>]", "Tells you what the highest gear score is for the given player (or yourself when noplayername is given)", true)]
[Command("highestgs,hgs,higs,highgs,highestgearscore", "highestgs [<player-name>]", "Tells you what the highest gear score is for the given player (or yourself when noplayername is given)", AdminLevel.Admin)]
private static void OnHighestGearScoreCommand(Command command)
{
var entityManager = VWorld.Server.EntityManager;
Expand All @@ -161,7 +162,7 @@ private static void OnHighestGearScoreCommand(Command command)
}
}

[Command("clearhgs,resethgs,clearhighestgearscore,resethighestgearscore", "clearhgs [<player-name>]", "Removes the current Highest Gear Score record for the given player (or yourself when noplayername is given)", true)]
[Command("clearhgs,resethgs,clearhighestgearscore,resethighestgearscore", "clearhgs [<player-name>]", "Removes the current Highest Gear Score record for the given player (or yourself when noplayername is given)", AdminLevel.Admin)]
private static void OnResetHighestGearScoreCommand(Command command)
{
var entityManager = VWorld.Server.EntityManager;
Expand Down
11 changes: 11 additions & 0 deletions Shared/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,17 @@ public static string GetCharacterName(ulong platformId, EntityManager? entityMan
return null;
}

public static AdminLevel GetAdminLevel(Entity userEntity, EntityManager? entityManager = null)
{
entityManager ??= CurrentWorld.EntityManager;
if(entityManager.Value.HasComponent<AdminUser>(userEntity))
{
var adminUser = entityManager.Value.GetComponentData<AdminUser>(userEntity);
return adminUser.Level;
}
return AdminLevel.None;
}

public static void LogAllComponentTypes(Entity entity, EntityManager? entityManager = null)
{
if(entity == Entity.Null)
Expand Down
57 changes: 42 additions & 15 deletions Shared/VModCharacter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,34 @@ public readonly struct VModCharacter

public bool IsAdmin => User.IsAdmin;

public AdminLevel AdminLevel { get; }

public string CharacterName => User.CharacterName.ToString();

#endregion

#region Lifecycle

public VModCharacter(User user, PlayerCharacter character) => (User, Character, FromCharacter) = (user, character, FromCharacter = new FromCharacter()
public VModCharacter(User user, PlayerCharacter character, EntityManager? entityManager = null)
{
User = character.UserEntity._Entity,
Character = user.LocalCharacter._Entity,
});
entityManager ??= Utils.CurrentWorld.EntityManager;
User = user;
Character = character;
FromCharacter = new FromCharacter()
{
User = character.UserEntity._Entity,
Character = user.LocalCharacter._Entity,
};
AdminLevel = Utils.GetAdminLevel(FromCharacter.User, entityManager);
}

public VModCharacter(FromCharacter fromCharacter, EntityManager? entityManager = null)
{
entityManager ??= Utils.CurrentWorld.EntityManager;
User = entityManager.Value.GetComponentData<User>(fromCharacter.User);
Character = entityManager.Value.GetComponentData<PlayerCharacter>(fromCharacter.Character);
FromCharacter = fromCharacter;
AdminLevel = Utils.GetAdminLevel(FromCharacter.User, entityManager);
}

public VModCharacter(Entity userEntity, Entity charEntity, EntityManager? entityManager = null)
Expand All @@ -48,23 +60,23 @@ public VModCharacter(Entity userEntity, Entity charEntity, EntityManager? entity
User = Character.UserEntity._Entity,
Character = User.LocalCharacter._Entity,
};
AdminLevel = Utils.GetAdminLevel(FromCharacter.User, entityManager);
}

public VModCharacter(Entity charEntity, EntityManager? entityManager = null)
#endregion

#region Public Methods

public static bool operator ==(VModCharacter left, VModCharacter right)
{
entityManager ??= Utils.CurrentWorld.EntityManager;
Character = entityManager.Value.GetComponentData<PlayerCharacter>(charEntity);
User = entityManager.Value.GetComponentData<User>(Character.UserEntity._Entity);
FromCharacter = new FromCharacter()
if(ReferenceEquals(left, right))
{
User = Character.UserEntity._Entity,
Character = User.LocalCharacter._Entity,
};
return true;
}
return left.User == right.User;
}

#endregion

#region Public Methods
public static bool operator !=(VModCharacter left, VModCharacter right) => !(left == right);

public static VModCharacter? GetVModCharacter(string charactername, EntityManager? entityManager = null)
{
Expand All @@ -82,6 +94,21 @@ public VModCharacter(Entity charEntity, EntityManager? entityManager = null)
return null;
}

public override bool Equals(object obj)
{
if(base.Equals(obj))
{
return true;
}
if(obj is VModCharacter vmodCharacter)
{
return this == vmodCharacter;
}
return false;
}

public override int GetHashCode() => (User, Character).GetHashCode();

public void ApplyBuff(PrefabGUID buffGUID)
{
Utils.ApplyBuff(FromCharacter, buffGUID);
Expand Down
4 changes: 2 additions & 2 deletions Shared/VModStorage.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System;
using System.IO;
using System.Text.Json;
using Wetstone.API;
using static VMods.Shared.CommandAttribute;

namespace VMods.Shared
{
Expand Down Expand Up @@ -73,7 +73,7 @@ public static T Load<T>(string filename, Func<T> getDefaultValue)

#region Private Methods

[Command("saveall", "saveall", "Saves all data of all VMod plugins", true)]
[Command("saveall", "saveall", "Saves all data of all VMod plugins", AdminLevel.Admin)]
private static void OnSaveAllCommand(Command command)
{
SaveAll();
Expand Down

0 comments on commit e2b1fc8

Please sign in to comment.