mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-25 06:04:46 -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) {
|
||||
if (lvl.randomFlow) {
|
||||
DoLavaRandowFlow(lvl, ref C, false);
|
||||
if (C.data.Data != 255)
|
||||
if (C.data.Data != PhysicsArgs.RemoveFromChecks)
|
||||
C.data.Data = 0; // no lava delay
|
||||
} else {
|
||||
DoLavaUniformFlow(lvl, ref C, false);
|
||||
|
@ -143,8 +143,8 @@ namespace MCGalaxy {
|
||||
|
||||
public static PlayerBot FindMatches(Player pl, string name) {
|
||||
int matches = 0;
|
||||
return Utils.FindMatches<PlayerBot>(pl, name, out matches, Bots.Items,
|
||||
b => true, b => b.name, "bots");
|
||||
return Matcher.Find<PlayerBot>(pl, name, out matches, Bots.Items,
|
||||
b => true, b => b.name, "bots");
|
||||
}
|
||||
|
||||
public static PlayerBot FindMatchesPreferLevel(Player pl, string name) {
|
||||
|
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.");
|
||||
}
|
||||
}
|
||||
}
|
@ -47,11 +47,9 @@ namespace MCGalaxy.Commands {
|
||||
bool cantSend = p.muted || (Server.chatmod && !p.voice);
|
||||
if (p.IsAfk) {
|
||||
if (cantSend) {
|
||||
Player.Message(p, "You are now marked as being AFK.");
|
||||
Player.Message(p, "You are now marked as being AFK.");
|
||||
} else {
|
||||
Chat.MessageWhere("-{0}%S- is AFK {1}",
|
||||
pl => Entities.CanSee(pl, p) && !pl.listignored.Contains(p.name) && !pl.ignoreAll,
|
||||
p.ColoredName, message);
|
||||
MessageOthers(p, "-" + p.ColoredName + "%S- is AFK " + message);
|
||||
Player.RaisePlayerAction(p, PlayerAction.AFK, message);
|
||||
p.CheckForMessageSpam();
|
||||
}
|
||||
@ -64,15 +62,18 @@ namespace MCGalaxy.Commands {
|
||||
if (cantSend) {
|
||||
Player.Message(p, "You are no longer marked as being AFK.");
|
||||
} else {
|
||||
Chat.MessageWhere("-{0}%S- is no longer AFK",
|
||||
pl => Entities.CanSee(pl, p) && !pl.listignored.Contains(p.name) && !pl.ignoreAll,
|
||||
p.ColoredName);
|
||||
MessageOthers(p, "-" + p.ColoredName + "%S- is no longer AFK");
|
||||
Player.RaisePlayerAction(p, PlayerAction.UnAFK, message);
|
||||
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) {
|
||||
Player.Message(p, "%T/afk <reason>");
|
||||
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");
|
||||
return;
|
||||
}
|
||||
if (p.level.name.ToLower() != p.beforeTeleportMap.ToLower())
|
||||
if (!p.level.name.CaselessEq(p.beforeTeleportMap))
|
||||
PlayerActions.ChangeMap(p, p.beforeTeleportMap);
|
||||
p.SendPos(Entities.SelfID, p.beforeTeleportPos[0], p.beforeTeleportPos[1], p.beforeTeleportPos[2], 0, 0);
|
||||
}
|
||||
|
@ -196,8 +196,8 @@ namespace MCGalaxy {
|
||||
}
|
||||
|
||||
public static string FindMatches(Player p, string name, out int matches) {
|
||||
Award award = Utils.FindMatches<Award>(p, name, out matches, AwardsList,
|
||||
a => true, a => a.Name, "awards");
|
||||
Award award = Matcher.Find<Award>(p, name, out matches, AwardsList,
|
||||
a => true, a => a.Name, "awards");
|
||||
return award == null ? null : award.Name;
|
||||
}
|
||||
|
||||
|
@ -30,31 +30,18 @@ namespace MCGalaxy {
|
||||
/// Does not perform any unloading. </summary>
|
||||
public static void Rename(string src, string dst) {
|
||||
File.Move(LevelInfo.LevelPath(src), LevelInfo.LevelPath(dst));
|
||||
try {
|
||||
File.Move(LevelInfo.LevelPath(src) + ".backup", LevelInfo.LevelPath(dst) + ".backup");
|
||||
} catch {
|
||||
}
|
||||
|
||||
try {
|
||||
File.Move("levels/level properties/" + src + ".properties",
|
||||
"levels/level properties/" + dst + ".properties");
|
||||
} catch {
|
||||
}
|
||||
SafeMove(LevelInfo.LevelPath(src) + ".backup",
|
||||
LevelInfo.LevelPath(dst) + ".backup");
|
||||
SafeMove("levels/level properties/" + src,
|
||||
"levels/level properties/" + dst + ".properties");
|
||||
SafeMove("levels/level properties/" + src + ".properties",
|
||||
"levels/level properties/" + dst + ".properties");
|
||||
SafeMove("blockdefs/lvl_" + src + ".json",
|
||||
"blockdefs/lvl_" + dst + ".json");
|
||||
SafeMove("blockprops/lvl_" + src + ".txt",
|
||||
"blockprops/lvl_" + dst + ".txt");
|
||||
|
||||
try {
|
||||
File.Move("levels/level properties/" + src,
|
||||
"levels/level properties/" + dst + ".properties");
|
||||
} catch {
|
||||
}
|
||||
|
||||
try {
|
||||
if (File.Exists("blockdefs/lvl_" + src + ".json")) {
|
||||
File.Move("blockdefs/lvl_" + src + ".json",
|
||||
"blockdefs/lvl_" + dst + ".json");
|
||||
}
|
||||
} catch {
|
||||
}
|
||||
|
||||
try {
|
||||
MoveBackups(src, dst);
|
||||
} catch {
|
||||
@ -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) {
|
||||
if (!Directory.Exists(dir)) return true;
|
||||
if (Directory.GetDirectories(dir).Length > 0) return false;
|
||||
@ -131,13 +127,11 @@ namespace MCGalaxy {
|
||||
File.Move(LevelInfo.LevelPath(name), "levels/deleted/" + name + ".lvl");
|
||||
}
|
||||
|
||||
try { File.Delete("levels/level properties/" + name + ".properties"); } catch { }
|
||||
try { File.Delete("levels/level properties/" + name); } catch { }
|
||||
try {
|
||||
if (File.Exists("blockdefs/lvl_" + name + ".json"))
|
||||
File.Delete("blockdefs/lvl_" + name + ".json");
|
||||
} catch {}
|
||||
|
||||
SafeDelete("levels/level properties/" + name);
|
||||
SafeDelete("levels/level properties/" + name + ".properties");
|
||||
SafeDelete("blockdefs/lvl_" + name + ".json");
|
||||
SafeDelete("blockprops/lvl_" + name + ".txt");
|
||||
|
||||
BotsFile.DeleteBots(name);
|
||||
DeleteDatabaseTables(name);
|
||||
BlockDBFile.DeleteBackingFile(name);
|
||||
@ -160,6 +154,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) {
|
||||
LevelDB.SaveBlockDB(old);
|
||||
@ -198,15 +202,15 @@ namespace MCGalaxy {
|
||||
|
||||
public static void CopyLevel(string src, string 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")) {
|
||||
File.Copy("blockdefs/lvl_" + src + ".json",
|
||||
"blockdefs/lvl_" + dst + ".json");
|
||||
}
|
||||
SafeCopy("levels/level properties/" + src,
|
||||
"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");
|
||||
SafeCopy("blockprops/lvl_" + src + ".txt",
|
||||
"blockprops/lvl_" + dst + ".txt");
|
||||
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,8 +45,8 @@ namespace MCGalaxy {
|
||||
}
|
||||
|
||||
public static Level FindMatches(Player pl, string name, out int matches) {
|
||||
return Utils.FindMatches<Level>(pl, name, out matches, LevelInfo.Loaded.Items,
|
||||
l => true, l => l.name, "loaded levels");
|
||||
return Matcher.Find<Level>(pl, name, out matches, LevelInfo.Loaded.Items,
|
||||
l => true, l => l.name, "loaded levels");
|
||||
}
|
||||
|
||||
public static string FindMapMatches(Player pl, string name) {
|
||||
@ -60,8 +60,8 @@ namespace MCGalaxy {
|
||||
}
|
||||
|
||||
string[] files = Directory.GetFiles("levels", "*.lvl");
|
||||
string map = Utils.FindMatches<string>(pl, name, out matches, files,
|
||||
l => true, l => Path.GetFileNameWithoutExtension(l), "levels");
|
||||
string map = Matcher.Find<string>(pl, name, out matches, files,
|
||||
l => true, l => Path.GetFileNameWithoutExtension(l), "levels");
|
||||
if (map != null)
|
||||
map = Path.GetFileNameWithoutExtension(map);
|
||||
return map;
|
||||
|
@ -115,6 +115,7 @@
|
||||
<Compile Include="Chat\ChatTokens.cs" />
|
||||
<Compile Include="Chat\LineWrapper.cs" />
|
||||
<Compile Include="Chat\ProfanityFilter.cs" />
|
||||
<Compile Include="CmdMapsBy.cs" />
|
||||
<Compile Include="Commands\Alias.cs" />
|
||||
<Compile Include="Commands\Bots\CmdBotAdd.cs" />
|
||||
<Compile Include="Commands\Bots\CmdBotAI.cs" />
|
||||
@ -620,12 +621,13 @@
|
||||
<Compile Include="util\Extensions\TimeExts.cs" />
|
||||
<Compile Include="util\FastList.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\Paths.cs" />
|
||||
<Compile Include="util\Math\DirUtils.cs" />
|
||||
<Compile Include="util\Math\Vectors.cs" />
|
||||
<Compile Include="util\MultiPageOutput.cs" />
|
||||
<Compile Include="util\NET_20.cs" />
|
||||
<Compile Include="util\SparseBitSet.cs" />
|
||||
<Compile Include="util\Threading\IReaderWriterLock.cs" />
|
||||
@ -700,6 +702,7 @@
|
||||
<ItemGroup>
|
||||
<Folder Include="Commands\Maintenance" />
|
||||
<Folder Include="Network\Packets" />
|
||||
<Folder Include="util\Formatting" />
|
||||
<Folder Include="util\Threading" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
|
@ -187,8 +187,8 @@ namespace MCGalaxy {
|
||||
public static Group FindMatches(Player p, string name, out int matches) {
|
||||
name = name.ToLower();
|
||||
MapName(ref name);
|
||||
return Utils.FindMatches<Group>(p, name, out matches,
|
||||
GroupList, g => true, g => g.name, "ranks");
|
||||
return Matcher.Find<Group>(p, name, out matches,
|
||||
GroupList, g => true, g => g.name, "ranks");
|
||||
}
|
||||
|
||||
/// <summary> Find the group(s) which contain the given name. </summary>
|
||||
|
@ -66,8 +66,8 @@ namespace MCGalaxy {
|
||||
|
||||
public string FindMatches(Player p, string name, string type, out int matches) {
|
||||
lock (locker) {
|
||||
return Utils.FindMatches<string>(p, name, out matches, players,
|
||||
n => true, n => n, type, 20);
|
||||
return Matcher.Find<string>(p, name, out matches, players,
|
||||
n => true, n => n, type, 20);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,9 +63,9 @@ namespace MCGalaxy {
|
||||
Player.Message(pl, "\"{0}\" is not a valid player name.", name); return null;
|
||||
}
|
||||
|
||||
return Utils.FindMatches<Player>(pl, name, out matches, Online.Items,
|
||||
p => Entities.CanSee(pl, p) || !onlyCanSee,
|
||||
p => p.name, "online players");
|
||||
return Matcher.Find<Player>(pl, name, out matches, Online.Items,
|
||||
p => Entities.CanSee(pl, p) || !onlyCanSee,
|
||||
p => p.name, "online players");
|
||||
}
|
||||
|
||||
public static string FindMatchesPreferOnline(Player p, string name) {
|
||||
@ -191,8 +191,8 @@ namespace MCGalaxy {
|
||||
"WHERE Name LIKE @0 LIMIT 21" + suffix,
|
||||
"%" + name + "%")) {
|
||||
int matches = 0;
|
||||
return Utils.FindMatches<DataRow>(p, name, out matches, results.Rows,
|
||||
r => true, r => r["Name"].ToString(), "players", 20);
|
||||
return Matcher.Find<DataRow>(p, name, out matches, results.Rows,
|
||||
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