ace/Source/ACE.Server/Command/Handlers/CharacterCommands.cs
Ty Conner d08bb47a18
Fix deletecharacter admin command (#3639)
* Fix deletecharacter

* Update CharacterCommands.cs
2021-08-08 19:01:40 -04:00

118 lines
6.5 KiB
C#

using System;
using System.Globalization;
using System.Threading;
using ACE.Common;
using ACE.Database;
using ACE.Entity.Enum;
using ACE.Server.Entity;
using ACE.Server.Entity.Actions;
using ACE.Server.Managers;
using ACE.Server.Network;
using ACE.Server.WorldObjects;
namespace ACE.Server.Command.Handlers
{
public static class CharacterCommands
{
// set-characteraccess charactername (accesslevel)
[CommandHandler("set-characteraccess", AccessLevel.Admin, CommandHandlerFlag.None, 1,
"Sets the access level for the character",
"charactername (accesslevel)\n" +
"accesslevel can be a number or enum name\n" +
"0 = Player | 1 = Advocate | 2 = Sentinel | 3 = Envoy | 4 = Developer | 5 = Admin")]
public static void HandleCharacterTokenization(Session session, params string[] parameters)
{
string characterName = parameters[0];
AccessLevel accessLevel = AccessLevel.Player;
if (parameters.Length > 1)
if (Enum.TryParse(parameters[1], true, out accessLevel))
if (!Enum.IsDefined(typeof(AccessLevel), accessLevel))
accessLevel = AccessLevel.Player;
DatabaseManager.Shard.SetCharacterAccessLevelByName(characterName.ToLower(), accessLevel, ((uint characterId) =>
{
if (characterId > 0)
{
string articleAorAN = "a";
if (accessLevel == AccessLevel.Advocate || accessLevel == AccessLevel.Admin || accessLevel == AccessLevel.Envoy)
articleAorAN = "an";
CommandHandlerHelper.WriteOutputInfo(session, "Character " + characterName + " has been made " + articleAorAN + " " + Enum.GetName(typeof(AccessLevel), accessLevel) + ".", ChatMessageType.Broadcast);
}
else
{
CommandHandlerHelper.WriteOutputInfo(session, "There is no character by the name of " + characterName + " found in the database. Has it been deleted?", ChatMessageType.Broadcast);
}
}));
}
// deletecharacter character name
[CommandHandler("deletecharacter", AccessLevel.Admin, CommandHandlerFlag.None, 1,
"Deletes a character and removes it from players restore list",
"[character name]\n" +
"Given the name of a character, this command deletes that character, booting it if in game, and removes it from character's restore list. (You can find the name for a character using the @finger command.)\n")]
public static void HandleCharacterForcedDelete(Session session, params string[] parameters)
{
var characterName = string.Join(" ", parameters);
var foundPlayer = PlayerManager.FindByName(characterName, out var isOnline);
if (foundPlayer == null)
{
CommandHandlerHelper.WriteOutputInfo(session, $"There is no character named {characterName} in the database.", ChatMessageType.Broadcast);
return;
}
if (isOnline && foundPlayer is Player player)
{
player.Character.DeleteTime = (ulong)Time.GetUnixTime();
player.Character.IsDeleted = true;
player.CharacterChangesDetected = true;
player.Session.LogOffPlayer(true);
PlayerManager.HandlePlayerDelete(player.Character.Id);
var success = PlayerManager.ProcessDeletedPlayer(player.Character.Id);
if (success)
CommandHandlerHelper.WriteOutputInfo(session, $"Successfully {(isOnline ? "booted and " : "")}deleted character {foundPlayer.Name} (0x{foundPlayer.Guid}).", ChatMessageType.Broadcast);
else
CommandHandlerHelper.WriteOutputInfo(session, $"Unable to {(isOnline ? "boot and " : "")}delete character {foundPlayer.Name} (0x{foundPlayer.Guid}) due to PlayerManager failure.", ChatMessageType.Broadcast);
}
else
{
var existingCharId = foundPlayer.Guid.Full; //DatabaseManager.Shard.BaseDatabase.GetCharacterStubByName(foundPlayer.Name).Id;
DatabaseManager.Shard.GetCharacter(existingCharId, character =>
{
if (character != null)
{
character.DeleteTime = (ulong)Time.GetUnixTime();
character.IsDeleted = true;
DatabaseManager.Shard.SaveCharacter(character, new ReaderWriterLockSlim(), result =>
{
if (result)
{
var deleteOfflineChain = new ActionChain();
deleteOfflineChain.AddAction(WorldManager.ActionQueue, () => PlayerManager.HandlePlayerDelete(character.Id));
deleteOfflineChain.AddDelayForOneTick();
deleteOfflineChain.AddAction(WorldManager.ActionQueue, () =>
{
var success = PlayerManager.ProcessDeletedPlayer(character.Id);
if (success)
CommandHandlerHelper.WriteOutputInfo(session, $"Successfully {(isOnline ? "booted and " : "")}deleted character {foundPlayer.Name} (0x{foundPlayer.Guid}).", ChatMessageType.Broadcast);
else
CommandHandlerHelper.WriteOutputInfo(session, $"Unable to {(isOnline ? "boot and " : "")}delete character {foundPlayer.Name} (0x{foundPlayer.Guid}) due to PlayerManager failure.", ChatMessageType.Broadcast);
});
deleteOfflineChain.EnqueueChain();
}
else
CommandHandlerHelper.WriteOutputInfo(session, $"Unable to {(isOnline ? "boot and " : "")}delete character {foundPlayer.Name} (0x{foundPlayer.Guid}) due to shard database SaveCharacter failure.", ChatMessageType.Broadcast);
});
}
else
CommandHandlerHelper.WriteOutputInfo(session, $"Unable to {(isOnline ? "boot and " : "")}delete character {foundPlayer.Name} (0x{foundPlayer.Guid}) due to shard database GetCharacter failure.", ChatMessageType.Broadcast);
});
}
}
}
}