Command and settings changes.
Attribute for checking if command is for in-game only; Added CommandException.cs and InvalidParametersException.cs Added NecroSkeletonCount to GameServerConfig.cs, thus the amount of necro skeletons can now be set. Added new quest command: !quest set [questId] [stepId] to fast-forward to a specific quest.
This commit is contained in:
parent
aa05ae4988
commit
f72ff60965
@ -25,11 +25,17 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
/// </summary>
|
||||
public Account.UserLevels MinUserLevel { get; private set; }
|
||||
|
||||
public CommandGroupAttribute(string name, string help, Account.UserLevels minUserLevel = Account.UserLevels.Admin)
|
||||
/// <summary>
|
||||
/// For InGame commands only. If true, the command will be available only in the game.
|
||||
/// </summary>
|
||||
public bool InGameOnly { get; }
|
||||
|
||||
public CommandGroupAttribute(string name, string help, Account.UserLevels minUserLevel = Account.UserLevels.Admin, bool inGameOnly = false)
|
||||
{
|
||||
Name = name.ToLower();
|
||||
Help = help;
|
||||
MinUserLevel = minUserLevel;
|
||||
InGameOnly = inGameOnly;
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,21 +55,27 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
/// <summary>
|
||||
/// Minimum user level required to invoke the command.
|
||||
/// </summary>
|
||||
public Account.UserLevels MinUserLevel { get; private set; }
|
||||
public Account.UserLevels MinUserLevel { get; }
|
||||
|
||||
public CommandAttribute(string command, string help, Account.UserLevels minUserLevel = Account.UserLevels.User)
|
||||
/// <summary>
|
||||
/// Whether the command is only for in-game command.
|
||||
/// </summary>
|
||||
public bool InGameOnly { get; }
|
||||
|
||||
public CommandAttribute(string command, string help, Account.UserLevels minUserLevel = Account.UserLevels.User, bool inGameOnly = false)
|
||||
{
|
||||
Name = command.ToLower();
|
||||
Help = help;
|
||||
MinUserLevel = minUserLevel;
|
||||
InGameOnly = inGameOnly;
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public class DefaultCommand : CommandAttribute
|
||||
{
|
||||
public DefaultCommand(Account.UserLevels minUserLevel = Account.UserLevels.User)
|
||||
: base("", "", minUserLevel)
|
||||
public DefaultCommand(Account.UserLevels minUserLevel = Account.UserLevels.User, bool inGameOnly = false)
|
||||
: base("", "", minUserLevel, inGameOnly)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace DiIiS_NA.GameServer.CommandManager;
|
||||
|
||||
public class CommandException : Exception
|
||||
{
|
||||
public CommandException(string message) : base(message) {}
|
||||
public CommandException(string message, Exception ex) : base(message, ex) {}
|
||||
}
|
||||
@ -6,6 +6,7 @@ using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using FluentNHibernate.Utils;
|
||||
|
||||
namespace DiIiS_NA.GameServer.CommandManager
|
||||
{
|
||||
@ -13,7 +14,7 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
{
|
||||
private static readonly Logger Logger = LogManager.CreateLogger("CmdGrp");
|
||||
|
||||
public CommandGroupAttribute Attributes { get; private set; }
|
||||
private CommandGroupAttribute Attributes { get; set; }
|
||||
|
||||
private readonly Dictionary<CommandAttribute, MethodInfo> _commands = new();
|
||||
|
||||
@ -37,7 +38,7 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
if (!_commands.ContainsKey(attribute))
|
||||
_commands.Add(attribute, method);
|
||||
else
|
||||
Logger.Fatal("Command '$[underline white]${0}$[/]$' already exists.", attribute.Name);
|
||||
Logger.Fatal($"$[red]$Command$[/]$ '$[underline white]${attribute.Name.SafeAnsi()}$[/]$' already exists.");
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,6 +68,8 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
#else
|
||||
return "You don't have enough privileges to invoke that command.";
|
||||
#endif
|
||||
if (invokerClient?.InGameClient == null && Attributes.InGameOnly)
|
||||
return "You can only use this command in-game.";
|
||||
string[] @params = null;
|
||||
CommandAttribute target = null;
|
||||
|
||||
@ -77,7 +80,7 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
@params = parameters.Split(' ');
|
||||
target = GetSubcommand(@params[0]) ?? GetDefaultSubcommand();
|
||||
|
||||
if (target != GetDefaultSubcommand())
|
||||
if (!Equals(target, GetDefaultSubcommand()))
|
||||
@params = @params.Skip(1).ToArray();
|
||||
}
|
||||
|
||||
@ -88,15 +91,28 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
#else
|
||||
return "You don't have enough privileges to invoke that command.";
|
||||
#endif
|
||||
if (invokerClient?.InGameClient == null && target.InGameOnly)
|
||||
return "This command can only be invoked in-game.";
|
||||
|
||||
try
|
||||
{
|
||||
return (string)_commands[target].Invoke(this, new object[] { @params, invokerClient });
|
||||
}
|
||||
catch (CommandException commandException)
|
||||
{
|
||||
return commandException.Message;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.ErrorException(ex, "Command Handling Error");
|
||||
return "An error occurred while executing the command.";
|
||||
}
|
||||
}
|
||||
|
||||
public string GetHelp(string command)
|
||||
{
|
||||
foreach (var pair in _commands)
|
||||
foreach (var pair in _commands.Where(pair => command == pair.Key.Name))
|
||||
{
|
||||
if (command != pair.Key.Name) continue;
|
||||
return pair.Key.Help;
|
||||
}
|
||||
|
||||
@ -114,14 +130,8 @@ namespace DiIiS_NA.GameServer.CommandManager
|
||||
return output.Substring(0, output.Length - 2) + ".";
|
||||
}
|
||||
|
||||
protected CommandAttribute GetDefaultSubcommand()
|
||||
{
|
||||
return _commands.Keys.First();
|
||||
}
|
||||
protected CommandAttribute GetDefaultSubcommand() => _commands.Keys.First();
|
||||
|
||||
protected CommandAttribute GetSubcommand(string name)
|
||||
{
|
||||
return _commands.Keys.FirstOrDefault(command => command.Name == name);
|
||||
}
|
||||
protected CommandAttribute GetSubcommand(string name) => _commands.Keys.FirstOrDefault(command => command.Name == name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,25 +1,17 @@
|
||||
using System;
|
||||
using DiIiS_NA.LoginServer.AccountsSystem;
|
||||
using DiIiS_NA.LoginServer.Battle;
|
||||
using FluentNHibernate.Utils;
|
||||
|
||||
namespace DiIiS_NA.GameServer.CommandManager;
|
||||
|
||||
[CommandGroup("quest",
|
||||
"Retrieves information about quest states and manipulates quest progress.\n Usage: quest [triggers | trigger eventType eventValue | advance snoQuest]")]
|
||||
"Retrieves information about quest states and manipulates quest progress.\n" +
|
||||
"Usage: quest [triggers | trigger eventType eventValue | advance snoQuest]",
|
||||
Account.UserLevels.Tester, inGameOnly: true)]
|
||||
public class QuestCommand : CommandGroup
|
||||
{
|
||||
[DefaultCommand]
|
||||
public string Quest(string[] @params, BattleClient invokerClient)
|
||||
{
|
||||
if (invokerClient == null)
|
||||
return "You cannot invoke this command from console.";
|
||||
|
||||
if (invokerClient.InGameClient == null)
|
||||
return "You can only invoke this command while in-game.";
|
||||
|
||||
return Info(@params, invokerClient);
|
||||
}
|
||||
|
||||
[Command("advance", "Advances a quest by a single step\n Usage: advance")]
|
||||
[Command("advance", "Advances a quest by a single step\n Usage: advance", inGameOnly: true)]
|
||||
public string Advance(string[] @params, BattleClient invokerClient)
|
||||
{
|
||||
try
|
||||
@ -33,7 +25,7 @@ public class QuestCommand : CommandGroup
|
||||
}
|
||||
}
|
||||
|
||||
[Command("sideadvance", "Advances a side-quest by a single step\n Usage: sideadvance")]
|
||||
[Command("sideadvance", "Advances a side-quest by a single step\n Usage: sideadvance", inGameOnly: true)]
|
||||
public string SideAdvance(string[] @params, BattleClient invokerClient)
|
||||
{
|
||||
try
|
||||
@ -69,7 +61,7 @@ public class QuestCommand : CommandGroup
|
||||
}
|
||||
}
|
||||
|
||||
[Command("timer", "Send broadcasted text message.\n Usage: public 'message'")]
|
||||
[Command("timer", "Send broadcast text message.\n Usage: public 'message'")]
|
||||
public string Timer(string[] @params, BattleClient invokerClient)
|
||||
{
|
||||
if (@params == null)
|
||||
@ -78,20 +70,42 @@ public class QuestCommand : CommandGroup
|
||||
if (@params.Length != 2)
|
||||
return "Invalid arguments. Type 'help text public' to get help.";
|
||||
|
||||
var eventId = int.Parse(@params[0]);
|
||||
var duration = int.Parse(@params[1]);
|
||||
if (!int.TryParse(@params[0], out var eventId) || !int.TryParse(@params[1], out var duration))
|
||||
return "Invalid arguments. Type 'help text public' to get help.";
|
||||
|
||||
invokerClient.InGameClient.Game.QuestManager.LaunchQuestTimer(eventId, (float)duration,
|
||||
new Action<int>((q) => { }));
|
||||
invokerClient.InGameClient.Game.QuestManager.LaunchQuestTimer(eventId, (float)duration, (_) => { });
|
||||
|
||||
return "Message sent.";
|
||||
}
|
||||
|
||||
[Command("info", "Retrieves information about quest states.\n Usage: info")]
|
||||
[Command("set", "Advance to a specific quest step.\n Usage: quest to [questId] [step]")]
|
||||
public string Set(string[] @params, BattleClient invokerClient)
|
||||
{
|
||||
if (@params == null)
|
||||
return Fallback();
|
||||
|
||||
if (@params.Length != 2)
|
||||
return "Invalid arguments. Type 'help quest to' to get help.";
|
||||
|
||||
if (!int.TryParse(@params[0], out var questId) || !int.TryParse(@params[1], out var step))
|
||||
return "Invalid arguments. Type 'help quest to' to get help.";
|
||||
|
||||
try
|
||||
{
|
||||
invokerClient.InGameClient.Game.QuestManager.AdvanceTo(questId, step);
|
||||
return $"Advancing to quest {questId} step {step}";
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return e.Message;
|
||||
}
|
||||
}
|
||||
|
||||
[Command("info", "Retrieves information about quest states.\n Usage: info", inGameOnly: true)]
|
||||
public string Info(string[] @params, BattleClient invokerClient)
|
||||
{
|
||||
if (invokerClient?.InGameClient?.Game?.QuestManager is not {} questManager)
|
||||
return "You can only invoke this command while in-game.";
|
||||
if (invokerClient.InGameClient.Game?.QuestManager is not {} questManager)
|
||||
return "No quests found.";
|
||||
|
||||
var act = questManager.CurrentAct;
|
||||
var quest = questManager.Game.CurrentQuest;
|
||||
|
||||
@ -0,0 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace DiIiS_NA.GameServer.CommandManager;
|
||||
|
||||
public class InvalidParametersException : CommandException
|
||||
{
|
||||
public InvalidParametersException(string message) : base(message) {}
|
||||
public InvalidParametersException(string message, Exception ex) : base(message, ex) {}
|
||||
}
|
||||
@ -31,11 +31,10 @@ namespace DiIiS_NA.GameServer.GSSystem.ObjectsSystem
|
||||
|
||||
if (Contains(name))
|
||||
{
|
||||
_attributeMap[name] += action;
|
||||
_logger.Warn($"Fixed attribute {name} already exists. Action will be added.");
|
||||
return;
|
||||
_attributeMap[name] = action;
|
||||
_logger.Warn($"Overwrite attribute {name}");
|
||||
}
|
||||
|
||||
else
|
||||
_attributeMap.Add(name, action);
|
||||
}
|
||||
|
||||
|
||||
@ -3203,14 +3203,14 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
|
||||
NecroSkeletons.Clear();
|
||||
}
|
||||
while (NecroSkeletons.Count < 7)
|
||||
while (NecroSkeletons.Count < GameServerConfig.Instance.NecroSkeletonCount)
|
||||
{
|
||||
var Skeleton = new NecromancerSkeleton_A(World, ActorSno._p6_necro_commandskeletons_a, this);
|
||||
Skeleton.Brain.DeActivate();
|
||||
Skeleton.Scale = 1.2f;
|
||||
var necroSkeleton = new NecromancerSkeleton_A(World, ActorSno._p6_necro_commandskeletons_a, this);
|
||||
necroSkeleton.Brain.DeActivate();
|
||||
necroSkeleton.Scale = 1.2f;
|
||||
|
||||
Skeleton.EnterWorld(PowerContext.RandomDirection(Position, 3f, 8f));
|
||||
NecroSkeletons.Add(Skeleton);
|
||||
necroSkeleton.EnterWorld(PowerContext.RandomDirection(Position, 3f, 8f));
|
||||
NecroSkeletons.Add(necroSkeleton);
|
||||
/*this.InGameClient.SendMessage(new PetMessage()
|
||||
{
|
||||
Owner = this.PlayerIndex,
|
||||
@ -3219,7 +3219,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
Type = 70,
|
||||
});
|
||||
//*/
|
||||
Skeleton.Brain.Activate();
|
||||
necroSkeleton.Brain.Activate();
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -3540,7 +3540,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
world.Reveal(this);
|
||||
Unreveal(this);
|
||||
|
||||
if (Math.Abs(_CurrentHPValue - (-1f)) < Globals.FLOAT_TOLERANCE)
|
||||
if (Math.Abs(_CurrentHPValue - -1f) < Globals.FLOAT_TOLERANCE)
|
||||
DefaultQueryProximityRadius = 60;
|
||||
|
||||
InGameClient.SendMessage(new EnterWorldMessage()
|
||||
@ -3571,7 +3571,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
break;
|
||||
}
|
||||
|
||||
if (Math.Abs(_CurrentHPValue - (-1f)) < Globals.FLOAT_TOLERANCE)
|
||||
if (Math.Abs(_CurrentHPValue - -1f) < Globals.FLOAT_TOLERANCE)
|
||||
AddPercentageHP(100);
|
||||
|
||||
DefaultQueryProximityRadius = 100;
|
||||
@ -3741,7 +3741,7 @@ public class Player : Actor, IMessageConsumer, IUpdateable
|
||||
AllBuffs.Clear();
|
||||
BetweenWorlds = false;
|
||||
|
||||
if (Math.Abs(_CurrentHPValue - (-1)) > Globals.FLOAT_TOLERANCE)
|
||||
if (Math.Abs(_CurrentHPValue - -1) > Globals.FLOAT_TOLERANCE)
|
||||
{
|
||||
Attributes[GameAttributes.Hitpoints_Cur] = _CurrentHPValue;
|
||||
Attributes[GameAttributes.Resource_Cur, (int)Toon.HeroTable.PrimaryResource + 1] = _CurrentResourceValue;
|
||||
|
||||
@ -298,12 +298,21 @@ namespace DiIiS_NA.GameServer
|
||||
set => Set(nameof(NephalemRiftOrbsChance), value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Forces the game to reveal all the map.
|
||||
/// </summary>
|
||||
public bool ForceMinimapVisibility
|
||||
{
|
||||
get => GetBoolean(nameof(ForceMinimapVisibility), false);
|
||||
set => Set(nameof(ForceMinimapVisibility), value);
|
||||
}
|
||||
|
||||
public int NecroSkeletonCount
|
||||
{
|
||||
get => GetInt(nameof(NecroSkeletonCount), 7);
|
||||
set => Set(nameof(NecroSkeletonCount), value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
public static GameServerConfig Instance { get; } = new();
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
user.block.title