Add a multi page command output (thanks fCraft for layout idea).

This commit is contained in:
UnknownShadow200 2016-09-06 15:25:07 +10:00
parent e18d4df815
commit 683179d162
4 changed files with 91 additions and 51 deletions

View File

@ -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;
@ -30,59 +31,30 @@ namespace MCGalaxy.Commands {
public CmdUnloaded() { } public CmdUnloaded() { }
public override void Use(Player p, string message) { public override void Use(Player p, string message) {
bool all = false;
int start = 0, end = 0;
if (message.CaselessStarts("all")) {
all = true;
int index = message.IndexOf(' ');
message = message.Substring(index == -1 ? message.Length : (index + 1));
}
if (message != "") {
if (!int.TryParse(message, out end) || end <= 0) { Help(p); return; }
end *= 50;
start = end - 50;
}
string[] files = Directory.GetFiles("levels", "*.lvl"); string[] files = Directory.GetFiles("levels", "*.lvl");
if (end == 0) { Player.Message(p, "Unloaded maps (&c[no] %Sif not accessible): ");
StringBuilder list = ListMaps(p, all, files, 0, files.Length); MultiPageOutput.Output(p, GetMaps(files), file => FormatMap(p, file),
if (list.Length > 0) { "unloaded", "maps", message);
Player.Message(p, "Unloaded levels (&c[no] %Sif not accessible): "); }
Player.Message(p, list.Remove(0, 2).ToString());
if (files.Length > 50) { Player.Message(p, "For a more structured list, use /unloaded <1/2/3/..>"); }
} else {
Player.Message(p, "No maps are unloaded");
}
} else {
if (end > files.Length) end = files.Length;
if (start > files.Length) { Player.Message(p, "No maps beyond number " + files.Length); return; }
StringBuilder list = ListMaps(p, all, files, start, end); static IEnumerable<string> GetMaps(string[] files) {
if (list.Length > 0) { foreach (string file in files) {
Player.Message(p, "Unloaded levels (&c[no] %Sif not accessible) (" + start + " to " + end + "):"); Level[] loaded = LevelInfo.Loaded.Items;
Player.Message(p, list.Remove(0, 2).ToString()); string level = Path.GetFileNameWithoutExtension(file);
} else { if (IsLoaded(loaded, level)) continue;
Player.Message(p, "No maps are unloaded"); yield return level;
}
} }
} }
static StringBuilder ListMaps(Player p, bool all, string[] files, int start, int end) { static string FormatMap(Player p, string file) {
StringBuilder builder = new StringBuilder(); string level = Path.GetFileNameWithoutExtension(file);
Level[] loaded = LevelInfo.Loaded.Items; LevelPermission visitP, buildP;
for (int i = start; i < end; i++) { bool loadOnGoto;
string level = Path.GetFileNameWithoutExtension(files[i]); RetrieveProps(level, out visitP, out buildP, out loadOnGoto);
if (!all && IsLoaded(loaded, level)) continue;
LevelPermission visitP, buildP; string color = Group.findPerm(buildP).color;
bool loadOnGoto; string visit = loadOnGoto && (p == null || p.Rank >= visitP) ? "" : " &c[no]" + color;
RetrieveProps(level, out visitP, out buildP, out loadOnGoto); return color + level + visit;
string color = Group.findPerm(buildP).color;
string visit = loadOnGoto && (p == null || p.Rank >= visitP) ? "" : " &c[no]" + color;
builder.Append(", ").Append(color + level + visit);
}
return builder;
} }
static bool IsLoaded(Level[] loaded, string level) { static bool IsLoaded(Level[] loaded, string level) {

View File

@ -112,7 +112,7 @@ namespace MCGalaxy.Commands {
} }
void HandleClear(Player p, string[] args) { void HandleClear(Player p, string[] args) {
if (!CheckExtraPerm(p)) { MessageNeedExtra(p, "clear the list of reports."); return; } if (!CheckExtraPerm(p)) { MessageNeedExtra(p, "clear the list of reports."); return; }
if (!Directory.Exists("extra/reportedbackups")) if (!Directory.Exists("extra/reportedbackups"))
Directory.CreateDirectory("extra/reportedbackups"); Directory.CreateDirectory("extra/reportedbackups");
string[] files = Directory.GetFiles("extra/reported", "*.txt"); string[] files = Directory.GetFiles("extra/reported", "*.txt");

View File

@ -610,6 +610,7 @@
<Compile Include="util\Formatter.cs" /> <Compile Include="util\Formatter.cs" />
<Compile Include="util\Math\DirUtils.cs" /> <Compile Include="util\Math\DirUtils.cs" />
<Compile Include="util\Math\Vectors.cs" /> <Compile Include="util\Math\Vectors.cs" />
<Compile Include="util\MultiPageOutput.cs" />
<Compile Include="util\SparseBitSet.cs" /> <Compile Include="util\SparseBitSet.cs" />
<Compile Include="util\TimeUtils.cs" /> <Compile Include="util\TimeUtils.cs" />
<Compile Include="util\Utils.cs" /> <Compile Include="util\Utils.cs" />

67
util/MultiPageOutput.cs Normal file
View File

@ -0,0 +1,67 @@
/*
Copyright 2015 MCGalaxy
Dual-licensed under the Educational Community License, Version 2.0 and
the GNU General Public License, Version 3 (the "Licenses"); you may
not use this file except in compliance with the Licenses. You may
obtain a copy of the Licenses at
http://www.opensource.org/licenses/ecl2.php
http://www.gnu.org/licenses/gpl-3.0.html
Unless required by applicable law or agreed to in writing,
software distributed under the Licenses are distributed on an "AS IS"
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
or implied. See the Licenses for the specific language governing
permissions and limitations under the Licenses.
*/
using System;
using System.Collections.Generic;
namespace MCGalaxy {
/// <summary> Outputs a large range of values across a number of 'pages'. </summary>
public static class MultiPageOutput {
const int perPage = 30;
public static void Output<T>(Player p, IEnumerable<T> items, Func<T, string> formatter,
string cmd, string type, string input) {
List<T> all = new List<T>(items);
int page = 0, total = all.Count;
if (input == "") {
OutputPage(p, all, formatter, cmd, type, 0);
if (total <= perPage) return;
Player.Message(p, "To see all {0}, use %T/{1} all", type, cmd);
} else if (input.CaselessEq("all")) {
Player.Message(p, all.Join(formatter, ", "));
Player.Message(p, "Showing {0} 1-{1} (out of {1})", type, all.Count);
} else if (!int.TryParse(input, out page)) {
Player.Message(p, "Page must be either \"all\" or an integer.");
} else {
OutputPage(p, all, formatter, cmd, type, page);
}
}
static void OutputPage<T>(Player p, List<T> all, Func<T, string> formatter,
string cmd, string type, int page) {
int total = all.Count, maxPage = total / perPage;
page = Utils.Clamp(page, 0, maxPage);
all.RemoveRange(0, page * perPage);
if (all.Count > perPage)
all.RemoveRange(perPage, all.Count - perPage);
Player.Message(p, all.Join(formatter, ", "));
int entriesEnd = Math.Min((page + 1) * perPage, total);
if (page < maxPage) {
Player.Message(p, "Showing {0} {1}-{2} (out of {3}) Next: %T/{4} {5}",
type, page * perPage + 1, entriesEnd, total, cmd, page + 1);
} else {
Player.Message(p, "Showing {0} {1}-{2} (out of {3})",
type, page * perPage + 1, entriesEnd, total);
}
}
}
}