mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-08-04 03:46:19 -04:00
Add /deletelvl *backup and /os delete *backup
Allows backups to be deleted from in-game.
This commit is contained in:
parent
0eba96d656
commit
3682ba5ee5
@ -103,8 +103,22 @@ namespace MCGalaxy.Commands.World {
|
|||||||
|
|
||||||
static string[] deleteHelp = new string[] {
|
static string[] deleteHelp = new string[] {
|
||||||
"&T/os delete &H- Deletes your map.",
|
"&T/os delete &H- Deletes your map.",
|
||||||
|
"&T/os delete "+CmdDeleteLvl.BACKUP_FLAG+" [backup]",
|
||||||
|
"&H -Permanently- deletes [backup] from your map.",
|
||||||
};
|
};
|
||||||
static void HandleDelete(Player p, string message) {
|
static void HandleDelete(Player p, string message) {
|
||||||
|
if (message.CaselessStarts(CmdDeleteLvl.BACKUP_FLAG)) {
|
||||||
|
string[] args = message.SplitSpaces(2); //"flag", "other args"
|
||||||
|
if (args.Length == 1) {
|
||||||
|
p.Message("You must provide a backup to delete.");
|
||||||
|
p.Message("A backup is usually a number, but may also be named.");
|
||||||
|
p.Message("See &T/{0} restore &7to display backups.", commandShortcut);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
CmdDeleteLvl.UseBackup(p, p.level.name +" "+ args[1], true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (message.Length > 0) {
|
if (message.Length > 0) {
|
||||||
p.Message("To delete your current map, type &T/{0} delete", commandShortcut);
|
p.Message("To delete your current map, type &T/{0} delete", commandShortcut);
|
||||||
return;
|
return;
|
||||||
|
@ -22,13 +22,34 @@ namespace MCGalaxy.Commands.World {
|
|||||||
public override string name { get { return "DeleteLvl"; } }
|
public override string name { get { return "DeleteLvl"; } }
|
||||||
public override string type { get { return CommandTypes.World; } }
|
public override string type { get { return CommandTypes.World; } }
|
||||||
public override LevelPermission defaultRank { get { return LevelPermission.Admin; } }
|
public override LevelPermission defaultRank { get { return LevelPermission.Admin; } }
|
||||||
|
|
||||||
|
public const string BACKUP_FLAG = "*backup";
|
||||||
|
public readonly static CommandAlias BackupAlias = new CommandAlias("DeleteBackup", BACKUP_FLAG);
|
||||||
|
|
||||||
public override CommandAlias[] Aliases {
|
public override CommandAlias[] Aliases {
|
||||||
get { return new[] { new CommandAlias("WDelete"), new CommandAlias("WorldDelete"), new CommandAlias("WRemove") }; }
|
get { return new[] {
|
||||||
|
new CommandAlias("WDelete"), new CommandAlias("WorldDelete"), new CommandAlias("WRemove"),
|
||||||
|
BackupAlias
|
||||||
|
}; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override CommandPerm[] ExtraPerms {
|
||||||
|
get { return new[] { new CommandPerm(LevelPermission.Owner, "can delete backups of levels") }; }
|
||||||
|
}
|
||||||
|
|
||||||
public override bool MessageBlockRestricted { get { return true; } }
|
public override bool MessageBlockRestricted { get { return true; } }
|
||||||
|
|
||||||
public override void Use(Player p, string message, CommandData data) {
|
public override void Use(Player p, string message, CommandData data) {
|
||||||
if (message.Length == 0 || message.SplitSpaces().Length > 1) { Help(p); return; }
|
if (message.Length == 0) { Help(p); return; }
|
||||||
|
|
||||||
|
string[] words = message.SplitSpaces(2);
|
||||||
|
if (words[0].CaselessEq(BACKUP_FLAG)) {
|
||||||
|
if (!CheckExtraPerm(p, data, 1)) return;
|
||||||
|
UseBackup(p, words.Length >= 2 ? words[1] : "", false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (words.Length > 1) { Help(p); return; }
|
||||||
string map = Matcher.FindMaps(p, message);
|
string map = Matcher.FindMaps(p, message);
|
||||||
LevelConfig cfg;
|
LevelConfig cfg;
|
||||||
|
|
||||||
@ -38,11 +59,50 @@ namespace MCGalaxy.Commands.World {
|
|||||||
if (!LevelActions.Delete(p, map)) return;
|
if (!LevelActions.Delete(p, map)) return;
|
||||||
Chat.MessageGlobal("Level {0} &Swas deleted", cfg.Color + map);
|
Chat.MessageGlobal("Level {0} &Swas deleted", cfg.Color + map);
|
||||||
}
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// os changes which confirmation text is displayed
|
||||||
|
/// </summary>
|
||||||
|
public static void UseBackup(Player p, string message, bool os) {
|
||||||
|
if (message.Length == 0) { HelpBackup(p); return; }
|
||||||
|
string[] words = message.SplitSpaces();
|
||||||
|
if (words.Length < 2) {
|
||||||
|
//Cannot be seen with os since two args guaranteed provided
|
||||||
|
p.Message("You must provide a level name and the backup to delete.");
|
||||||
|
p.Message("A backup is usually a number, but may also be named.");
|
||||||
|
p.Message("See &T/help restore &7to display backups.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bool confirmed = words.Length == 3 && words[2].CaselessEq("confirm");
|
||||||
|
|
||||||
|
string map = words[0].ToLower();
|
||||||
|
string backup = words[1].ToLower();
|
||||||
|
if (!confirmed) {
|
||||||
|
p.Message("You are about to &Wpermanently delete&S backup \"{0}\" from level \"{1}\"",
|
||||||
|
backup, map);
|
||||||
|
|
||||||
|
if (os) {
|
||||||
|
p.Message("If you are sure, type &T/os delete {0} {1} confirm", BACKUP_FLAG, backup);
|
||||||
|
} else {
|
||||||
|
// Don't use message, since they could have typed /deletebackup earth 1 derp
|
||||||
|
// and it should not tell you to type "[...] derp confirm"
|
||||||
|
p.Message("If you are sure, type &T/{0} {1} {2} confirm", BackupAlias.Trigger, map, backup);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LevelActions.DeleteBackup(p, map, backup);
|
||||||
|
}
|
||||||
|
|
||||||
public override void Help(Player p) {
|
public override void Help(Player p) {
|
||||||
p.Message("&T/DeleteLvl [level]");
|
p.Message("&T/DeleteLvl [level]");
|
||||||
p.Message("&HCompletely deletes [level] (portals, MBs, everything)");
|
p.Message("&HCompletely deletes [level] (portals, MBs, everything)");
|
||||||
p.Message("&HA backup of the level is made in the levels/deleted folder");
|
p.Message("&HA backup of the level is made in the levels/deleted folder");
|
||||||
|
HelpBackup(p);
|
||||||
}
|
}
|
||||||
|
public static void HelpBackup(Player p) {
|
||||||
|
p.Message("&T/DeleteLvl {0} [level] [backup]", BACKUP_FLAG);
|
||||||
|
p.Message("&H-Permanently- deletes [backup] of [level].");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,8 +26,7 @@ namespace MCGalaxy.Commands.World {
|
|||||||
public override string type { get { return CommandTypes.World; } }
|
public override string type { get { return CommandTypes.World; } }
|
||||||
public override bool SuperUseable { get { return false; } }
|
public override bool SuperUseable { get { return false; } }
|
||||||
|
|
||||||
const string currentFlag = "*current";
|
const string CURRENT_FLAG = "*current";
|
||||||
const string latestFlag = "*latest";
|
|
||||||
|
|
||||||
public override void Use(Player p, string message, CommandData data) {
|
public override void Use(Player p, string message, CommandData data) {
|
||||||
if (message.Length == 0) { LevelOperations.OutputBackups(p, p.level); return; }
|
if (message.Length == 0) { LevelOperations.OutputBackups(p, p.level); return; }
|
||||||
@ -37,7 +36,7 @@ namespace MCGalaxy.Commands.World {
|
|||||||
string backupArg = args.Length > 1 ? args[1] : args[0];
|
string backupArg = args.Length > 1 ? args[1] : args[0];
|
||||||
|
|
||||||
string path;
|
string path;
|
||||||
if (backupArg == currentFlag) {
|
if (backupArg == CURRENT_FLAG) {
|
||||||
path = LevelInfo.MapPath(mapArg);
|
path = LevelInfo.MapPath(mapArg);
|
||||||
if (!LevelInfo.MapExists(mapArg)) {
|
if (!LevelInfo.MapExists(mapArg)) {
|
||||||
if (Directory.Exists(LevelInfo.BackupBasePath(mapArg))) {
|
if (Directory.Exists(LevelInfo.BackupBasePath(mapArg))) {
|
||||||
@ -49,26 +48,11 @@ namespace MCGalaxy.Commands.World {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!Directory.Exists(LevelInfo.BackupBasePath(mapArg))) {
|
if (!LevelInfo.GetBackupPath(p, mapArg, backupArg, out path)) return;
|
||||||
p.Message("Level \"{0}\" has no backups.", mapArg); return;
|
|
||||||
}
|
|
||||||
if (backupArg == latestFlag) {
|
|
||||||
int latest = LevelInfo.LatestBackup(mapArg);
|
|
||||||
if (latest == 0) {
|
|
||||||
p.Message("&WLevel \"{0}\" does not have any numbered backups, " +
|
|
||||||
"so the latest backup could not be determined.", mapArg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
backupArg = latest.ToString();
|
|
||||||
}
|
|
||||||
path = LevelInfo.BackupFilePath(mapArg, backupArg);
|
|
||||||
}
|
|
||||||
if (!File.Exists(path)) {
|
|
||||||
p.Message("Backup \"{0}\" for {1} could not be found.", backupArg, mapArg); return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string formattedMuseumName;
|
string formattedMuseumName;
|
||||||
if (backupArg == currentFlag) {
|
if (backupArg == CURRENT_FLAG) {
|
||||||
formattedMuseumName = "&cMuseum &S(" + mapArg + ")";
|
formattedMuseumName = "&cMuseum &S(" + mapArg + ")";
|
||||||
} else {
|
} else {
|
||||||
formattedMuseumName = "&cMuseum &S(" + mapArg + " " + backupArg + ")";
|
formattedMuseumName = "&cMuseum &S(" + mapArg + " " + backupArg + ")";
|
||||||
@ -92,9 +76,9 @@ namespace MCGalaxy.Commands.World {
|
|||||||
public override void Help(Player p) {
|
public override void Help(Player p) {
|
||||||
p.Message("&T/Museum <level> [backup]");
|
p.Message("&T/Museum <level> [backup]");
|
||||||
p.Message("&HVisits the [backup] of <level>");
|
p.Message("&HVisits the [backup] of <level>");
|
||||||
p.Message("&T/Museum <level> *latest");
|
p.Message("&T/Museum <level> {0}", LevelInfo.LATEST_MUSEUM_FLAG);
|
||||||
p.Message("&HVisits the latest backup of <level>");
|
p.Message("&HVisits the latest backup of <level>");
|
||||||
p.Message("&T/Museum <level> *current");
|
p.Message("&T/Museum <level> {0}", CURRENT_FLAG);
|
||||||
p.Message("&HVisits <level> as it is currently stored on disk.");
|
p.Message("&HVisits <level> as it is currently stored on disk.");
|
||||||
p.Message("&HIf <level> is not given, the current level is used.");
|
p.Message("&HIf <level> is not given, the current level is used.");
|
||||||
}
|
}
|
||||||
|
@ -185,7 +185,7 @@ namespace MCGalaxy
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MovePlayersToMain() {
|
internal void MovePlayersToMain() {
|
||||||
Player[] players = PlayerInfo.Online.Items;
|
Player[] players = PlayerInfo.Online.Items;
|
||||||
foreach (Player p in players) {
|
foreach (Player p in players) {
|
||||||
if (p.level == this) {
|
if (p.level == this) {
|
||||||
|
@ -174,6 +174,31 @@ namespace MCGalaxy
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Deletes the backup of the given map, if found.
|
||||||
|
/// Supports Commands.World.CmdMuseum.LATEST_FLAG as backup number to return latest backup path.
|
||||||
|
/// </summary>
|
||||||
|
public static void DeleteBackup(Player p, string map, string backup) {
|
||||||
|
string discard;
|
||||||
|
if (!LevelInfo.GetBackupPath(p, map, backup, out discard)) return;
|
||||||
|
|
||||||
|
foreach (Player pl in PlayerInfo.Online.Items) {
|
||||||
|
//Find if any player is in a museum of the level backup being deleted
|
||||||
|
if (pl.level.MapName.CaselessEq(map) && pl.level.IsMuseum) {
|
||||||
|
//Move everyone out of that museum.
|
||||||
|
//Since Unload does not move players if it's a museum, call it manually
|
||||||
|
pl.level.MovePlayersToMain();
|
||||||
|
pl.level.Unload(true, false);
|
||||||
|
//TODO: Only move players out of the museum if the backup being deleted actually matches their museum
|
||||||
|
//It really doesn't look like the code was designed to be able to do this
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Directory.Delete(LevelInfo.BackupDirPath(map, backup), true);
|
||||||
|
p.Message("Deleted backup {0}.", backup);
|
||||||
|
}
|
||||||
|
|
||||||
static void DeleteDatabaseTables(string map) {
|
static void DeleteDatabaseTables(string map) {
|
||||||
Database.DeleteTable("Block" + map);
|
Database.DeleteTable("Block" + map);
|
||||||
|
|
||||||
|
@ -116,6 +116,38 @@ namespace MCGalaxy {
|
|||||||
return (LatestBackup(map) + 1).ToString();
|
return (LatestBackup(map) + 1).ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public const string LATEST_MUSEUM_FLAG = "*latest";
|
||||||
|
/// <summary>
|
||||||
|
/// Returns true if a file was found for the given map with the given backup number.
|
||||||
|
/// Supports LATEST_FLAG as backup number to return latest backup path.
|
||||||
|
/// </summary>
|
||||||
|
public static bool GetBackupPath(Player p, string map, string backupNumber, out string path) {
|
||||||
|
if (!Directory.Exists(BackupBasePath(map))) {
|
||||||
|
p.Message("Level \"{0}\" has no backups.", map);
|
||||||
|
path = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (backupNumber == LATEST_MUSEUM_FLAG) {
|
||||||
|
int latest = LatestBackup(map);
|
||||||
|
if (latest == 0) {
|
||||||
|
p.Message("&WLevel \"{0}\" does not have any numbered backups, " +
|
||||||
|
"so the latest backup could not be determined.", map);
|
||||||
|
path = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
backupNumber = latest.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
path = BackupFilePath(map, backupNumber);
|
||||||
|
|
||||||
|
if (!File.Exists(path)) {
|
||||||
|
p.Message("Backup \"{0}\" for {1} could not be found.", backupNumber, map);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary> Relative path of a level's property file </summary>
|
/// <summary> Relative path of a level's property file </summary>
|
||||||
public static string PropsPath(string name) {
|
public static string PropsPath(string name) {
|
||||||
return "levels/level properties/" + name + ".properties";
|
return "levels/level properties/" + name + ".properties";
|
||||||
|
@ -195,6 +195,8 @@ namespace MCGalaxy {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly string Reflexive;
|
public readonly string Reflexive;
|
||||||
|
|
||||||
|
//TODO: Third Person Singular Objective (Them/Him/Her)
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// They/them uses "plural" style verbs, so this is required for grammar that sounds correct
|
/// They/them uses "plural" style verbs, so this is required for grammar that sounds correct
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user