mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-24 05:03:34 -04:00
Add /os list, sort lists of displayed levels a bit more nicely
This commit is contained in:
parent
aeda35c708
commit
5ce514187f
@ -16,7 +16,6 @@
|
|||||||
permissions and limitations under the Licenses.
|
permissions and limitations under the Licenses.
|
||||||
*/
|
*/
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace MCGalaxy.Commands.Info
|
namespace MCGalaxy.Commands.Info
|
||||||
{
|
{
|
||||||
@ -31,55 +30,11 @@ namespace MCGalaxy.Commands.Info
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override void Use(Player p, string message, CommandData data) {
|
public override void Use(Player p, string message, CommandData data) {
|
||||||
string[] files = LevelInfo.AllMapFiles();
|
string[] files = LevelInfo.AllMapNames();
|
||||||
// Files list is not guaranteed to be in alphabetical order
|
// Files list is not guaranteed to be in alphabetical order
|
||||||
Array.Sort(files);
|
Array.Sort(files, new AlphanumComparator());
|
||||||
|
LevelInfo.ListMaps(p, files, "Levels", "Levels", "levels", message);
|
||||||
p.Message("Levels (&c[no] &Sif not visitable):");
|
|
||||||
Paginator.Output(p, files, (file) => FormatMap(p, file),
|
|
||||||
"Levels", "levels", message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static string FormatMap(Player p, string file) {
|
|
||||||
LevelPermission visitP, buildP;
|
|
||||||
bool loadOnGoto;
|
|
||||||
string map = Path.GetFileNameWithoutExtension(file);
|
|
||||||
RetrieveProps(map, out visitP, out buildP, out loadOnGoto);
|
|
||||||
|
|
||||||
LevelPermission maxPerm = visitP;
|
|
||||||
if (maxPerm < buildP) maxPerm = buildP;
|
|
||||||
|
|
||||||
string visit = loadOnGoto && p.Rank >= visitP ? "" : " &c[no]";
|
|
||||||
return Group.GetColor(maxPerm) + map + visit;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void RetrieveProps(string level, out LevelPermission visit,
|
|
||||||
out LevelPermission build, out bool loadOnGoto) {
|
|
||||||
visit = LevelPermission.Guest;
|
|
||||||
build = LevelPermission.Guest;
|
|
||||||
loadOnGoto = true;
|
|
||||||
|
|
||||||
string propsPath = LevelInfo.PropsPath(level);
|
|
||||||
SearchArgs args = new SearchArgs();
|
|
||||||
if (!PropertiesFile.Read(propsPath, ref args, ProcessLine)) return;
|
|
||||||
|
|
||||||
visit = Group.ParsePermOrName(args.Visit, visit);
|
|
||||||
build = Group.ParsePermOrName(args.Build, build);
|
|
||||||
if (!bool.TryParse(args.LoadOnGoto, out loadOnGoto))
|
|
||||||
loadOnGoto = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ProcessLine(string key, string value, ref SearchArgs args) {
|
|
||||||
if (key.CaselessEq("pervisit")) {
|
|
||||||
args.Visit = value;
|
|
||||||
} else if (key.CaselessEq("perbuild")) {
|
|
||||||
args.Build = value;
|
|
||||||
} else if (key.CaselessEq("loadongoto")) {
|
|
||||||
args.LoadOnGoto = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct SearchArgs { public string Visit, Build, LoadOnGoto; }
|
|
||||||
|
|
||||||
public override void Help(Player p) {
|
public override void Help(Player p) {
|
||||||
p.Message("&T/Levels");
|
p.Message("&T/Levels");
|
||||||
|
@ -108,6 +108,7 @@ namespace MCGalaxy.Commands.Info
|
|||||||
static void SearchMaps(Player p, string keyword, string modifier) {
|
static void SearchMaps(Player p, string keyword, string modifier) {
|
||||||
string[] allMaps = LevelInfo.AllMapNames();
|
string[] allMaps = LevelInfo.AllMapNames();
|
||||||
List<string> maps = Wildcard.Filter(allMaps, keyword, map => map);
|
List<string> maps = Wildcard.Filter(allMaps, keyword, map => map);
|
||||||
|
maps.Sort(new AlphanumComparator());
|
||||||
OutputList(p, keyword, "search levels", "maps", modifier, maps);
|
OutputList(p, keyword, "search levels", "maps", modifier, maps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,11 +56,8 @@ namespace MCGalaxy.Commands.World {
|
|||||||
string[] allMaps = LevelInfo.AllMapNames();
|
string[] allMaps = LevelInfo.AllMapNames();
|
||||||
|
|
||||||
int realmsOwned = 0;
|
int realmsOwned = 0;
|
||||||
foreach (string lvlName in allMaps)
|
foreach (string lvlName in allMaps) {
|
||||||
{
|
if (IsOwnedBy(p.name, lvlName)) {
|
||||||
if (!lvlName.CaselessStarts(p.name)) continue;
|
|
||||||
|
|
||||||
if (LevelInfo.IsRealmOwner(p.name, lvlName)) {
|
|
||||||
realmsOwned += 1;
|
realmsOwned += 1;
|
||||||
if (realmsOwned >= p.group.OverseerMaps) {
|
if (realmsOwned >= p.group.OverseerMaps) {
|
||||||
break;
|
break;
|
||||||
@ -81,6 +78,22 @@ namespace MCGalaxy.Commands.World {
|
|||||||
p.Message("You have reached the limit for your overseer maps.");
|
p.Message("You have reached the limit for your overseer maps.");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Returns all the os maps owned by p, sorted alphabetically.
|
||||||
|
/// </summary>
|
||||||
|
static List<string> AllOwnedBy(string playerName) {
|
||||||
|
string[] allMaps = LevelInfo.AllMapNames();
|
||||||
|
List<string> owned = new List<string>();
|
||||||
|
foreach (string lvlName in allMaps) {
|
||||||
|
if (IsOwnedBy(playerName, lvlName)) owned.Add(lvlName);
|
||||||
|
}
|
||||||
|
owned.Sort(new AlphanumComparator());
|
||||||
|
return owned;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsOwnedBy(string playerName, string levelName) {
|
||||||
|
return levelName.CaselessStarts(playerName) && LevelInfo.IsRealmOwner(playerName, levelName);
|
||||||
|
}
|
||||||
|
|
||||||
static string[] addHelp = new string[] {
|
static string[] addHelp = new string[] {
|
||||||
"&T/os add &H- Creates a flat map (128x128x128).",
|
"&T/os add &H- Creates a flat map (128x128x128).",
|
||||||
@ -479,6 +492,22 @@ namespace MCGalaxy.Commands.World {
|
|||||||
static void HandleRestore(Player p, string args) {
|
static void HandleRestore(Player p, string args) {
|
||||||
UseCommand(p, "Restore", args);
|
UseCommand(p, "Restore", args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static string[] listHelp = new string[] {
|
||||||
|
"&T/os list <player>",
|
||||||
|
"&H Lists all the os realms for <player>",
|
||||||
|
"&H By default, lists your own realms.",
|
||||||
|
};
|
||||||
|
static void HandleList(Player p, string args) {
|
||||||
|
string[] words = args.SplitSpaces(2);
|
||||||
|
string word0 = words[0];
|
||||||
|
string word1 = words.Length > 1 ? words[1] : ""; //How many times have I typed a variant of this
|
||||||
|
|
||||||
|
string playerName = word0.Length == 0 ? p.name : PlayerInfo.FindMatchesPreferOnline(p, word0);
|
||||||
|
if (playerName == null) return;
|
||||||
|
string page = word1;
|
||||||
|
LevelInfo.ListMaps(p, AllOwnedBy(playerName), "OS realms", "os list "+playerName, "OS realms", page, playerName != p.name);
|
||||||
|
}
|
||||||
|
|
||||||
//Placed at the end so that the help arrays aren't null
|
//Placed at the end so that the help arrays aren't null
|
||||||
internal static SubCommandGroup subCommandGroup = new SubCommandGroup(commandShortcut,
|
internal static SubCommandGroup subCommandGroup = new SubCommandGroup(commandShortcut,
|
||||||
@ -510,6 +539,7 @@ namespace MCGalaxy.Commands.World {
|
|||||||
new SubCommand("Delete", HandleDelete, deleteHelp, true, new string[] { "del", "remove" } ),
|
new SubCommand("Delete", HandleDelete, deleteHelp, true, new string[] { "del", "remove" } ),
|
||||||
new SubCommand("Rename", HandleRename, renameHelp),
|
new SubCommand("Rename", HandleRename, renameHelp),
|
||||||
new SubCommand("Restore", HandleRestore, restoreHelp),
|
new SubCommand("Restore", HandleRestore, restoreHelp),
|
||||||
|
new SubCommand("List", HandleList, listHelp, false),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
permissions and limitations under the Licenses.
|
permissions and limitations under the Licenses.
|
||||||
*/
|
*/
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using MCGalaxy.DB;
|
using MCGalaxy.DB;
|
||||||
@ -240,5 +241,56 @@ namespace MCGalaxy {
|
|||||||
// Match the backwards compatibilty case of IsRealmOwner
|
// Match the backwards compatibilty case of IsRealmOwner
|
||||||
return PlayerDB.FindName(map);
|
return PlayerDB.FindName(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void ListMaps(Player p, IList<string> maps, string levelsTitle, string listCmd, string itemName, string page, bool showVisitable = true) {
|
||||||
|
p.Message("{0} (&c[no] &Sif not visitable):", levelsTitle);
|
||||||
|
Paginator.Output(p, maps, (file) => FormatMap(p, file, showVisitable),
|
||||||
|
listCmd, itemName, page);
|
||||||
|
}
|
||||||
|
static string FormatMap(Player p, string map, bool showVisitable) {
|
||||||
|
LevelPermission visitP, buildP;
|
||||||
|
bool loadOnGoto;
|
||||||
|
RetrieveProps(map, out visitP, out buildP, out loadOnGoto);
|
||||||
|
|
||||||
|
LevelPermission maxPerm = visitP;
|
||||||
|
if (maxPerm < buildP) maxPerm = buildP;
|
||||||
|
|
||||||
|
string visit;
|
||||||
|
if (showVisitable) {
|
||||||
|
visit = loadOnGoto && p.Rank >= visitP ? "" : " &c[no]";
|
||||||
|
} else {
|
||||||
|
visit = "";
|
||||||
|
}
|
||||||
|
return Group.GetColor(maxPerm) + map + visit;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RetrieveProps(string level, out LevelPermission visit,
|
||||||
|
out LevelPermission build, out bool loadOnGoto) {
|
||||||
|
visit = LevelPermission.Guest;
|
||||||
|
build = LevelPermission.Guest;
|
||||||
|
loadOnGoto = true;
|
||||||
|
|
||||||
|
string propsPath = LevelInfo.PropsPath(level);
|
||||||
|
SearchArgs args = new SearchArgs();
|
||||||
|
if (!PropertiesFile.Read(propsPath, ref args, ProcessLine)) return;
|
||||||
|
|
||||||
|
visit = Group.ParsePermOrName(args.Visit, visit);
|
||||||
|
build = Group.ParsePermOrName(args.Build, build);
|
||||||
|
if (!bool.TryParse(args.LoadOnGoto, out loadOnGoto))
|
||||||
|
loadOnGoto = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ProcessLine(string key, string value, ref SearchArgs args) {
|
||||||
|
if (key.CaselessEq("pervisit")) {
|
||||||
|
args.Visit = value;
|
||||||
|
} else if (key.CaselessEq("perbuild")) {
|
||||||
|
args.Build = value;
|
||||||
|
} else if (key.CaselessEq("loadongoto")) {
|
||||||
|
args.LoadOnGoto = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SearchArgs { public string Visit, Build, LoadOnGoto; }
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -130,4 +130,46 @@ namespace MCGalaxy
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sorts a list of strings such that a1 a2 a3 comes before a10 a11 a12 and so on.
|
||||||
|
/// </summary>
|
||||||
|
public class AlphanumComparator : IComparer<string> {
|
||||||
|
|
||||||
|
// Simplified but based off of https://www.dotnetperls.com/alphanumeric-sorting
|
||||||
|
public int Compare(string a, string b) {
|
||||||
|
int result;
|
||||||
|
int aLen, bLen;
|
||||||
|
int aDigit = GetDigits(a, out aLen);
|
||||||
|
int bDigit = GetDigits(b, out bLen);
|
||||||
|
if (aDigit != -1 && bDigit != -1) {
|
||||||
|
result = aDigit.CompareTo(bDigit);
|
||||||
|
} else {
|
||||||
|
result = a.Substring(0, aLen).CompareTo(b.Substring(0, bLen));
|
||||||
|
}
|
||||||
|
if (result != 0) return result;
|
||||||
|
return a.Length - b.Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the digits on the end of the string. -1 if no integer found.
|
||||||
|
/// </summary>
|
||||||
|
static int GetDigits(string name, out int nameLength) {
|
||||||
|
nameLength = name.Length;
|
||||||
|
if (!Char.IsDigit(name[name.Length - 1])) return -1;
|
||||||
|
|
||||||
|
int decimalShift = 1;
|
||||||
|
int number = 0;
|
||||||
|
for (int i = name.Length - 1; i >= 0; i--) {
|
||||||
|
if (!Char.IsDigit(name[i])) return number;
|
||||||
|
|
||||||
|
nameLength--;
|
||||||
|
int digit = name[i] - '0'; //Paige Ruten: here's the most insane way to convert a digit char to an integer
|
||||||
|
number += digit * decimalShift;
|
||||||
|
decimalShift *= 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user