mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-28 16:07:07 -04:00
fix /copylvl and /renamelvl with blockprops (thanks nosliw)
This commit is contained in:
parent
5514877a20
commit
fca6ae43b3
@ -56,7 +56,7 @@ namespace MCGalaxy.Blocks.Physics {
|
|||||||
public static void DoFastLava(Level lvl, ref Check C) {
|
public static void DoFastLava(Level lvl, ref Check C) {
|
||||||
if (lvl.randomFlow) {
|
if (lvl.randomFlow) {
|
||||||
DoLavaRandowFlow(lvl, ref C, false);
|
DoLavaRandowFlow(lvl, ref C, false);
|
||||||
if (C.data.Data != 255)
|
if (C.data.Data != PhysicsArgs.RemoveFromChecks)
|
||||||
C.data.Data = 0; // no lava delay
|
C.data.Data = 0; // no lava delay
|
||||||
} else {
|
} else {
|
||||||
DoLavaUniformFlow(lvl, ref C, false);
|
DoLavaUniformFlow(lvl, ref C, false);
|
||||||
|
@ -143,7 +143,7 @@ namespace MCGalaxy {
|
|||||||
|
|
||||||
public static PlayerBot FindMatches(Player pl, string name) {
|
public static PlayerBot FindMatches(Player pl, string name) {
|
||||||
int matches = 0;
|
int matches = 0;
|
||||||
return Utils.FindMatches<PlayerBot>(pl, name, out matches, Bots.Items,
|
return Matcher.Find<PlayerBot>(pl, name, out matches, Bots.Items,
|
||||||
b => true, b => b.name, "bots");
|
b => true, b => b.name, "bots");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
83
MCGalaxy/CmdMapsBy.cs
Normal file
83
MCGalaxy/CmdMapsBy.cs
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2011 MCForge
|
||||||
|
|
||||||
|
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;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace MCGalaxy.Commands {
|
||||||
|
|
||||||
|
public sealed class CmdMapsBy : Command {
|
||||||
|
public override string name { get { return "mapsby"; } }
|
||||||
|
public override string shortcut { get { return "madeby"; } }
|
||||||
|
public override string type { get { return CommandTypes.Information; } }
|
||||||
|
public override bool museumUsable { get { return true; } }
|
||||||
|
public override LevelPermission defaultRank { get { return LevelPermission.Guest; } }
|
||||||
|
|
||||||
|
public override void Use(Player p, string message) {
|
||||||
|
if (message == "") { Help(p); return; }
|
||||||
|
string author = PlayerInfo.FindOfflineNameMatches(p, message);
|
||||||
|
if (author == null) return;
|
||||||
|
|
||||||
|
string[] maps = Directory.GetFiles("levels", "*.lvl");
|
||||||
|
for (int i = 0; i < maps.Length; i++) {
|
||||||
|
maps[i] = Path.GetFileNameWithoutExtension(maps[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<string> madeBy = new List<string>();
|
||||||
|
foreach (string map in maps) {
|
||||||
|
if (!IsOwnedBy(map, author)) continue;
|
||||||
|
madeBy.Add(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
author = PlayerInfo.GetColoredName(p, author);
|
||||||
|
if (madeBy.Count == 0) {
|
||||||
|
Player.Message(p, "{0} %Shas not made any maps", author);
|
||||||
|
} else {
|
||||||
|
Player.Message(p, "{0} %Sauthored these maps: {1}", author, madeBy.Join());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsOwnedBy(string map, string name) {
|
||||||
|
if (map.CaselessStarts(name)) return true;
|
||||||
|
string file = LevelInfo.FindPropertiesFile(map);
|
||||||
|
if (file == null) return false;
|
||||||
|
|
||||||
|
string realmOwner = null;
|
||||||
|
PropertiesFile.Read(file, ref realmOwner, ProcessLine);
|
||||||
|
if (realmOwner == null) return false;
|
||||||
|
|
||||||
|
string[] owners = realmOwner.Replace(" ", "").Split(',');
|
||||||
|
foreach (string owner in owners) {
|
||||||
|
if (owner.CaselessEq(name)) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ProcessLine(string key, string value, ref string realmOwner) {
|
||||||
|
if (key.CaselessEq("realmowner")) {
|
||||||
|
realmOwner = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Help(Player p) {
|
||||||
|
Player.Message(p, "%T/mapsby %H[player]");
|
||||||
|
Player.Message(p, "%HLists all maps authored by the given player.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -49,9 +49,7 @@ namespace MCGalaxy.Commands {
|
|||||||
if (cantSend) {
|
if (cantSend) {
|
||||||
Player.Message(p, "You are now marked as being AFK.");
|
Player.Message(p, "You are now marked as being AFK.");
|
||||||
} else {
|
} else {
|
||||||
Chat.MessageWhere("-{0}%S- is AFK {1}",
|
MessageOthers(p, "-" + p.ColoredName + "%S- is AFK " + message);
|
||||||
pl => Entities.CanSee(pl, p) && !pl.listignored.Contains(p.name) && !pl.ignoreAll,
|
|
||||||
p.ColoredName, message);
|
|
||||||
Player.RaisePlayerAction(p, PlayerAction.AFK, message);
|
Player.RaisePlayerAction(p, PlayerAction.AFK, message);
|
||||||
p.CheckForMessageSpam();
|
p.CheckForMessageSpam();
|
||||||
}
|
}
|
||||||
@ -64,15 +62,18 @@ namespace MCGalaxy.Commands {
|
|||||||
if (cantSend) {
|
if (cantSend) {
|
||||||
Player.Message(p, "You are no longer marked as being AFK.");
|
Player.Message(p, "You are no longer marked as being AFK.");
|
||||||
} else {
|
} else {
|
||||||
Chat.MessageWhere("-{0}%S- is no longer AFK",
|
MessageOthers(p, "-" + p.ColoredName + "%S- is no longer AFK");
|
||||||
pl => Entities.CanSee(pl, p) && !pl.listignored.Contains(p.name) && !pl.ignoreAll,
|
|
||||||
p.ColoredName);
|
|
||||||
Player.RaisePlayerAction(p, PlayerAction.UnAFK, message);
|
Player.RaisePlayerAction(p, PlayerAction.UnAFK, message);
|
||||||
p.CheckForMessageSpam();
|
p.CheckForMessageSpam();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void MessageOthers(Player p, string msg) {
|
||||||
|
Chat.MessageWhere(msg,
|
||||||
|
pl => Entities.CanSee(pl, p) && !pl.listignored.Contains(p.name) && !pl.ignoreAll);
|
||||||
|
}
|
||||||
|
|
||||||
public override void Help(Player p) {
|
public override void Help(Player p) {
|
||||||
Player.Message(p, "%T/afk <reason>");
|
Player.Message(p, "%T/afk <reason>");
|
||||||
Player.Message(p, "%HMarks yourself as AFK. Use again to mark yourself as back");
|
Player.Message(p, "%HMarks yourself as AFK. Use again to mark yourself as back");
|
||||||
|
@ -31,7 +31,7 @@ namespace MCGalaxy.Commands {
|
|||||||
p.SendMessage("You have not teleported anywhere yet");
|
p.SendMessage("You have not teleported anywhere yet");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (p.level.name.ToLower() != p.beforeTeleportMap.ToLower())
|
if (!p.level.name.CaselessEq(p.beforeTeleportMap))
|
||||||
PlayerActions.ChangeMap(p, p.beforeTeleportMap);
|
PlayerActions.ChangeMap(p, p.beforeTeleportMap);
|
||||||
p.SendPos(Entities.SelfID, p.beforeTeleportPos[0], p.beforeTeleportPos[1], p.beforeTeleportPos[2], 0, 0);
|
p.SendPos(Entities.SelfID, p.beforeTeleportPos[0], p.beforeTeleportPos[1], p.beforeTeleportPos[2], 0, 0);
|
||||||
}
|
}
|
||||||
|
@ -196,7 +196,7 @@ namespace MCGalaxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static string FindMatches(Player p, string name, out int matches) {
|
public static string FindMatches(Player p, string name, out int matches) {
|
||||||
Award award = Utils.FindMatches<Award>(p, name, out matches, AwardsList,
|
Award award = Matcher.Find<Award>(p, name, out matches, AwardsList,
|
||||||
a => true, a => a.Name, "awards");
|
a => true, a => a.Name, "awards");
|
||||||
return award == null ? null : award.Name;
|
return award == null ? null : award.Name;
|
||||||
}
|
}
|
||||||
|
@ -30,30 +30,17 @@ namespace MCGalaxy {
|
|||||||
/// Does not perform any unloading. </summary>
|
/// Does not perform any unloading. </summary>
|
||||||
public static void Rename(string src, string dst) {
|
public static void Rename(string src, string dst) {
|
||||||
File.Move(LevelInfo.LevelPath(src), LevelInfo.LevelPath(dst));
|
File.Move(LevelInfo.LevelPath(src), LevelInfo.LevelPath(dst));
|
||||||
try {
|
|
||||||
File.Move(LevelInfo.LevelPath(src) + ".backup", LevelInfo.LevelPath(dst) + ".backup");
|
|
||||||
} catch {
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
SafeMove(LevelInfo.LevelPath(src) + ".backup",
|
||||||
File.Move("levels/level properties/" + src + ".properties",
|
LevelInfo.LevelPath(dst) + ".backup");
|
||||||
|
SafeMove("levels/level properties/" + src,
|
||||||
"levels/level properties/" + dst + ".properties");
|
"levels/level properties/" + dst + ".properties");
|
||||||
} catch {
|
SafeMove("levels/level properties/" + src + ".properties",
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
File.Move("levels/level properties/" + src,
|
|
||||||
"levels/level properties/" + dst + ".properties");
|
"levels/level properties/" + dst + ".properties");
|
||||||
} catch {
|
SafeMove("blockdefs/lvl_" + src + ".json",
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (File.Exists("blockdefs/lvl_" + src + ".json")) {
|
|
||||||
File.Move("blockdefs/lvl_" + src + ".json",
|
|
||||||
"blockdefs/lvl_" + dst + ".json");
|
"blockdefs/lvl_" + dst + ".json");
|
||||||
}
|
SafeMove("blockprops/lvl_" + src + ".txt",
|
||||||
} catch {
|
"blockprops/lvl_" + dst + ".txt");
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
MoveBackups(src, dst);
|
MoveBackups(src, dst);
|
||||||
@ -88,6 +75,15 @@ namespace MCGalaxy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void SafeMove(string src, string dst) {
|
||||||
|
if (!File.Exists(src)) return;
|
||||||
|
try {
|
||||||
|
File.Move(src, dst);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Server.ErrorLog(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool DirectoryEmpty(string dir) {
|
static bool DirectoryEmpty(string dir) {
|
||||||
if (!Directory.Exists(dir)) return true;
|
if (!Directory.Exists(dir)) return true;
|
||||||
if (Directory.GetDirectories(dir).Length > 0) return false;
|
if (Directory.GetDirectories(dir).Length > 0) return false;
|
||||||
@ -131,12 +127,10 @@ namespace MCGalaxy {
|
|||||||
File.Move(LevelInfo.LevelPath(name), "levels/deleted/" + name + ".lvl");
|
File.Move(LevelInfo.LevelPath(name), "levels/deleted/" + name + ".lvl");
|
||||||
}
|
}
|
||||||
|
|
||||||
try { File.Delete("levels/level properties/" + name + ".properties"); } catch { }
|
SafeDelete("levels/level properties/" + name);
|
||||||
try { File.Delete("levels/level properties/" + name); } catch { }
|
SafeDelete("levels/level properties/" + name + ".properties");
|
||||||
try {
|
SafeDelete("blockdefs/lvl_" + name + ".json");
|
||||||
if (File.Exists("blockdefs/lvl_" + name + ".json"))
|
SafeDelete("blockprops/lvl_" + name + ".txt");
|
||||||
File.Delete("blockdefs/lvl_" + name + ".json");
|
|
||||||
} catch {}
|
|
||||||
|
|
||||||
BotsFile.DeleteBots(name);
|
BotsFile.DeleteBots(name);
|
||||||
DeleteDatabaseTables(name);
|
DeleteDatabaseTables(name);
|
||||||
@ -161,6 +155,16 @@ namespace MCGalaxy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void SafeDelete(string src) {
|
||||||
|
if (!File.Exists(src)) return;
|
||||||
|
try {
|
||||||
|
File.Delete(src);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Server.ErrorLog(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void Replace(Level old, Level lvl) {
|
public static void Replace(Level old, Level lvl) {
|
||||||
LevelDB.SaveBlockDB(old);
|
LevelDB.SaveBlockDB(old);
|
||||||
LevelInfo.Loaded.Remove(old);
|
LevelInfo.Loaded.Remove(old);
|
||||||
@ -198,15 +202,15 @@ namespace MCGalaxy {
|
|||||||
|
|
||||||
public static void CopyLevel(string src, string dst) {
|
public static void CopyLevel(string src, string dst) {
|
||||||
File.Copy(LevelInfo.LevelPath(src), LevelInfo.LevelPath(dst));
|
File.Copy(LevelInfo.LevelPath(src), LevelInfo.LevelPath(dst));
|
||||||
if (File.Exists(LevelInfo.PropertiesPath(src))) {
|
|
||||||
File.Copy(LevelInfo.PropertiesPath(src),
|
|
||||||
LevelInfo.PropertiesPath(dst));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (File.Exists("blockdefs/lvl_" + src + ".json")) {
|
SafeCopy("levels/level properties/" + src,
|
||||||
File.Copy("blockdefs/lvl_" + src + ".json",
|
"levels/level properties/" + dst + ".properties");
|
||||||
|
SafeCopy("levels/level properties/" + src + ".properties",
|
||||||
|
"levels/level properties/" + dst + ".properties");
|
||||||
|
SafeCopy("blockdefs/lvl_" + src + ".json",
|
||||||
"blockdefs/lvl_" + dst + ".json");
|
"blockdefs/lvl_" + dst + ".json");
|
||||||
}
|
SafeCopy("blockprops/lvl_" + src + ".txt",
|
||||||
|
"blockprops/lvl_" + dst + ".txt");
|
||||||
CopyDatabaseTables(src, dst);
|
CopyDatabaseTables(src, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,5 +238,14 @@ namespace MCGalaxy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void SafeCopy(string src, string dst) {
|
||||||
|
if (!File.Exists(src)) return;
|
||||||
|
try {
|
||||||
|
File.Copy(src, dst, true);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Server.ErrorLog(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ namespace MCGalaxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Level FindMatches(Player pl, string name, out int matches) {
|
public static Level FindMatches(Player pl, string name, out int matches) {
|
||||||
return Utils.FindMatches<Level>(pl, name, out matches, LevelInfo.Loaded.Items,
|
return Matcher.Find<Level>(pl, name, out matches, LevelInfo.Loaded.Items,
|
||||||
l => true, l => l.name, "loaded levels");
|
l => true, l => l.name, "loaded levels");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ namespace MCGalaxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
string[] files = Directory.GetFiles("levels", "*.lvl");
|
string[] files = Directory.GetFiles("levels", "*.lvl");
|
||||||
string map = Utils.FindMatches<string>(pl, name, out matches, files,
|
string map = Matcher.Find<string>(pl, name, out matches, files,
|
||||||
l => true, l => Path.GetFileNameWithoutExtension(l), "levels");
|
l => true, l => Path.GetFileNameWithoutExtension(l), "levels");
|
||||||
if (map != null)
|
if (map != null)
|
||||||
map = Path.GetFileNameWithoutExtension(map);
|
map = Path.GetFileNameWithoutExtension(map);
|
||||||
|
@ -115,6 +115,7 @@
|
|||||||
<Compile Include="Chat\ChatTokens.cs" />
|
<Compile Include="Chat\ChatTokens.cs" />
|
||||||
<Compile Include="Chat\LineWrapper.cs" />
|
<Compile Include="Chat\LineWrapper.cs" />
|
||||||
<Compile Include="Chat\ProfanityFilter.cs" />
|
<Compile Include="Chat\ProfanityFilter.cs" />
|
||||||
|
<Compile Include="CmdMapsBy.cs" />
|
||||||
<Compile Include="Commands\Alias.cs" />
|
<Compile Include="Commands\Alias.cs" />
|
||||||
<Compile Include="Commands\Bots\CmdBotAdd.cs" />
|
<Compile Include="Commands\Bots\CmdBotAdd.cs" />
|
||||||
<Compile Include="Commands\Bots\CmdBotAI.cs" />
|
<Compile Include="Commands\Bots\CmdBotAI.cs" />
|
||||||
@ -620,12 +621,13 @@
|
|||||||
<Compile Include="util\Extensions\TimeExts.cs" />
|
<Compile Include="util\Extensions\TimeExts.cs" />
|
||||||
<Compile Include="util\FastList.cs" />
|
<Compile Include="util\FastList.cs" />
|
||||||
<Compile Include="util\App.cs" />
|
<Compile Include="util\App.cs" />
|
||||||
<Compile Include="util\Formatter.cs" />
|
<Compile Include="util\Formatting\Formatter.cs" />
|
||||||
|
<Compile Include="util\Formatting\Matcher.cs" />
|
||||||
|
<Compile Include="util\Formatting\MultiPageOutput.cs" />
|
||||||
<Compile Include="util\IO\BufferedBlockSender.cs" />
|
<Compile Include="util\IO\BufferedBlockSender.cs" />
|
||||||
<Compile Include="util\IO\Paths.cs" />
|
<Compile Include="util\IO\Paths.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\NET_20.cs" />
|
<Compile Include="util\NET_20.cs" />
|
||||||
<Compile Include="util\SparseBitSet.cs" />
|
<Compile Include="util\SparseBitSet.cs" />
|
||||||
<Compile Include="util\Threading\IReaderWriterLock.cs" />
|
<Compile Include="util\Threading\IReaderWriterLock.cs" />
|
||||||
@ -700,6 +702,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="Commands\Maintenance" />
|
<Folder Include="Commands\Maintenance" />
|
||||||
<Folder Include="Network\Packets" />
|
<Folder Include="Network\Packets" />
|
||||||
|
<Folder Include="util\Formatting" />
|
||||||
<Folder Include="util\Threading" />
|
<Folder Include="util\Threading" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||||
|
@ -187,7 +187,7 @@ namespace MCGalaxy {
|
|||||||
public static Group FindMatches(Player p, string name, out int matches) {
|
public static Group FindMatches(Player p, string name, out int matches) {
|
||||||
name = name.ToLower();
|
name = name.ToLower();
|
||||||
MapName(ref name);
|
MapName(ref name);
|
||||||
return Utils.FindMatches<Group>(p, name, out matches,
|
return Matcher.Find<Group>(p, name, out matches,
|
||||||
GroupList, g => true, g => g.name, "ranks");
|
GroupList, g => true, g => g.name, "ranks");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ namespace MCGalaxy {
|
|||||||
|
|
||||||
public string FindMatches(Player p, string name, string type, out int matches) {
|
public string FindMatches(Player p, string name, string type, out int matches) {
|
||||||
lock (locker) {
|
lock (locker) {
|
||||||
return Utils.FindMatches<string>(p, name, out matches, players,
|
return Matcher.Find<string>(p, name, out matches, players,
|
||||||
n => true, n => n, type, 20);
|
n => true, n => n, type, 20);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ namespace MCGalaxy {
|
|||||||
Player.Message(pl, "\"{0}\" is not a valid player name.", name); return null;
|
Player.Message(pl, "\"{0}\" is not a valid player name.", name); return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Utils.FindMatches<Player>(pl, name, out matches, Online.Items,
|
return Matcher.Find<Player>(pl, name, out matches, Online.Items,
|
||||||
p => Entities.CanSee(pl, p) || !onlyCanSee,
|
p => Entities.CanSee(pl, p) || !onlyCanSee,
|
||||||
p => p.name, "online players");
|
p => p.name, "online players");
|
||||||
}
|
}
|
||||||
@ -191,7 +191,7 @@ namespace MCGalaxy {
|
|||||||
"WHERE Name LIKE @0 LIMIT 21" + suffix,
|
"WHERE Name LIKE @0 LIMIT 21" + suffix,
|
||||||
"%" + name + "%")) {
|
"%" + name + "%")) {
|
||||||
int matches = 0;
|
int matches = 0;
|
||||||
return Utils.FindMatches<DataRow>(p, name, out matches, results.Rows,
|
return Matcher.Find<DataRow>(p, name, out matches, results.Rows,
|
||||||
r => true, r => r["Name"].ToString(), "players", 20);
|
r => true, r => r["Name"].ToString(), "players", 20);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
67
MCGalaxy/util/Formatting/Matcher.cs
Normal file
67
MCGalaxy/util/Formatting/Matcher.cs
Normal 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;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace MCGalaxy {
|
||||||
|
public static class Matcher {
|
||||||
|
|
||||||
|
const StringComparison comp = StringComparison.OrdinalIgnoreCase;
|
||||||
|
|
||||||
|
/// <summary> Finds partial matches of 'name' against the names of the items in the 'items' enumerable. </summary>
|
||||||
|
/// <param name="pl"> The player to output messages to. </param>
|
||||||
|
/// <param name="name"> The name to perform partial matching against. </param>
|
||||||
|
/// <param name="matches"> The number of found/outputted matches. </param>
|
||||||
|
/// <param name="items"> Enumerable of items that may be matched with. </param>
|
||||||
|
/// <param name="filter"> Selects which items from 'items' are actually matched. </param>
|
||||||
|
/// <param name="nameGetter"> Gets the name of a particular item. </param>
|
||||||
|
/// <param name="type"> The type of the items. (e.g. 'players', 'commands') </param>
|
||||||
|
/// <param name="limit"> The maximum number of matches that are outputted. </param>
|
||||||
|
/// <returns> If exactly one match, the matching item. </returns>
|
||||||
|
public static T Find<T>(Player pl, string name, out int matches, IEnumerable items,
|
||||||
|
Predicate<T> filter, Func<T, string> nameGetter, string type, int limit = 5) {
|
||||||
|
T match = default(T); matches = 0;
|
||||||
|
StringBuilder nameMatches = new StringBuilder();
|
||||||
|
|
||||||
|
foreach (T item in items) {
|
||||||
|
if (!filter(item)) continue;
|
||||||
|
string itemName = nameGetter(item);
|
||||||
|
if (itemName.Equals(name, comp)) { matches = 1; return item; }
|
||||||
|
if (itemName.IndexOf(name, comp) < 0) continue;
|
||||||
|
|
||||||
|
match = item; matches++;
|
||||||
|
if (matches <= limit)
|
||||||
|
nameMatches.Append(itemName).Append(", ");
|
||||||
|
else if (matches == limit + 1)
|
||||||
|
nameMatches.Append("(and more)").Append(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matches == 0) {
|
||||||
|
Player.Message(pl, "No " + type + " match \"" + name + "\"."); return default(T);
|
||||||
|
} else if (matches == 1) {
|
||||||
|
return match;
|
||||||
|
} else {
|
||||||
|
string count = matches > limit ? limit + "+ " : matches + " ";
|
||||||
|
string names = nameMatches.ToString(0, nameMatches.Length - 2);
|
||||||
|
Player.Message(pl, count + type + " match \"" + name + "\":");
|
||||||
|
Player.Message(pl, names); return default(T);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user