mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-09 15:23:28 -04:00
Perform partial name matching in /notes and /rankinfo
This commit is contained in:
parent
c5876ee307
commit
c1f13c4a5a
@ -126,15 +126,16 @@ namespace MCGalaxy.Gui {
|
|||||||
|
|
||||||
|
|
||||||
bool GetAutoload() {
|
bool GetAutoload() {
|
||||||
foreach (string line in Server.AutoloadMaps.Find(lvl.name + "="))
|
return Server.AutoloadMaps.Find(lvl.name) != null;
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetAutoload(bool value) {
|
void SetAutoload(bool value) {
|
||||||
Server.AutoloadMaps.DeleteStartsWith(lvl.name + "=");
|
if (value) {
|
||||||
if (value)
|
Server.AutoloadMaps.AddOrReplace(lvl.name, lvl.physics.ToString());
|
||||||
Server.AutoloadMaps.Append(lvl.name + "=" + lvl.physics);
|
} else {
|
||||||
|
Server.AutoloadMaps.Remove(lvl.name);
|
||||||
|
}
|
||||||
|
Server.AutoloadMaps.Save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,8 +70,7 @@ namespace MCGalaxy.Commands {
|
|||||||
BlockDBChange.OutputMessageBlock(p, b, id, x, y, z);
|
BlockDBChange.OutputMessageBlock(p, b, id, x, y, z);
|
||||||
BlockDBChange.OutputPortal(p, b, id, x, y, z);
|
BlockDBChange.OutputPortal(p, b, id, x, y, z);
|
||||||
|
|
||||||
GC.Collect();
|
Server.DoGC();
|
||||||
GC.WaitForPendingFinalizers();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ListFromDatabase(Player p, ref bool foundAny, Dictionary<int, string> names,
|
static void ListFromDatabase(Player p, ref bool foundAny, Dictionary<int, string> names,
|
||||||
|
@ -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;
|
||||||
|
|
||||||
namespace MCGalaxy.Commands {
|
namespace MCGalaxy.Commands {
|
||||||
@ -28,19 +29,17 @@ namespace MCGalaxy.Commands {
|
|||||||
public CmdRankInfo() { }
|
public CmdRankInfo() { }
|
||||||
|
|
||||||
public override void Use(Player p, string message) {
|
public override void Use(Player p, string message) {
|
||||||
if (message == "") {
|
if (CheckSuper(p, message, "player name")) return;
|
||||||
if (Player.IsSuper(p)) { SuperRequiresArgs(p, "player name"); return; }
|
if (message == "") message = p.name;
|
||||||
message = p.name;
|
|
||||||
}
|
List<string> rankings = Server.RankInfo.FindMatches(p, message, "rankings");
|
||||||
Player who = PlayerInfo.Find(message);
|
if (rankings == null) return;
|
||||||
string target = who == null ? message : who.name;
|
|
||||||
|
string target = PlayerMetaList.GetName(rankings[0]);
|
||||||
Player.Message(p, " Rank information for {0}:",
|
Player.Message(p, " Rankings for {0}:", PlayerInfo.GetColoredName(p, target));
|
||||||
PlayerInfo.GetColoredName(p, target));
|
|
||||||
bool found = false;
|
|
||||||
DateTime now = DateTime.Now;
|
DateTime now = DateTime.Now;
|
||||||
|
|
||||||
foreach (string line in Server.RankInfo.Find(target)) {
|
foreach (string line in rankings) {
|
||||||
string[] parts = line.Split(' ');
|
string[] parts = line.Split(' ');
|
||||||
string newRank = Group.GetColoredName(parts[7]);
|
string newRank = Group.GetColoredName(parts[7]);
|
||||||
string oldRank = Group.GetColoredName(parts[8]);
|
string oldRank = Group.GetColoredName(parts[8]);
|
||||||
@ -55,10 +54,7 @@ namespace MCGalaxy.Commands {
|
|||||||
Player.Message(p, "&aFrom {0} &ato {1} &a{2} ago",
|
Player.Message(p, "&aFrom {0} &ato {1} &a{2} ago",
|
||||||
oldRank, newRank, delta.Shorten(true, false));
|
oldRank, newRank, delta.Shorten(true, false));
|
||||||
Player.Message(p, "&aBy %S{0}&a, reason: %S{1}", parts[1], reason);
|
Player.Message(p, "&aBy %S{0}&a, reason: %S{1}", parts[1], reason);
|
||||||
found = true;
|
|
||||||
}
|
}
|
||||||
if (!found)
|
|
||||||
Player.Message(p, "&cPlayer has not been ranked yet.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Help(Player p) {
|
public override void Help(Player p) {
|
||||||
|
@ -28,8 +28,7 @@ namespace MCGalaxy.Commands {
|
|||||||
|
|
||||||
public override void Use(Player p, string message) {
|
public override void Use(Player p, string message) {
|
||||||
Player.Message(p, "Forcing garbage collection...");
|
Player.Message(p, "Forcing garbage collection...");
|
||||||
GC.Collect();
|
Server.DoGC();
|
||||||
GC.WaitForPendingFinalizers();
|
|
||||||
Player.Message(p, "Garbage collection completed!");
|
Player.Message(p, "Garbage collection completed!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
permissions and limitations under the Licenses.
|
permissions and limitations under the Licenses.
|
||||||
*/
|
*/
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace MCGalaxy.Commands {
|
namespace MCGalaxy.Commands {
|
||||||
public class CmdNotes : Command {
|
public class CmdNotes : Command {
|
||||||
@ -32,15 +33,13 @@ namespace MCGalaxy.Commands {
|
|||||||
if (CheckSuper(p, message, "player name")) return;
|
if (CheckSuper(p, message, "player name")) return;
|
||||||
if (message == "") message = p.name;
|
if (message == "") message = p.name;
|
||||||
|
|
||||||
int matches = 1;
|
List<string> notes = Server.Notes.FindMatches(p, message, "notes");
|
||||||
Player who = message == "" ? p : PlayerInfo.FindMatches(p, message, out matches);
|
if (notes == null) return;
|
||||||
if (matches > 1) return;
|
|
||||||
if (who != null) message = who.name;
|
|
||||||
|
|
||||||
Player.Message(p, "Notes for " + message + ":");
|
string target = PlayerMetaList.GetName(notes[0]);
|
||||||
bool foundAny = false;
|
Player.Message(p, " Notes for {0}:", PlayerInfo.GetColoredName(p, target));
|
||||||
foreach (string line in Server.Notes.Find(message)) {
|
|
||||||
foundAny = true;
|
foreach (string line in notes) {
|
||||||
string[] args = line.Split(' ');
|
string[] args = line.Split(' ');
|
||||||
if (args.Length <= 3) continue;
|
if (args.Length <= 3) continue;
|
||||||
|
|
||||||
@ -50,8 +49,6 @@ namespace MCGalaxy.Commands {
|
|||||||
Player.Message(p, Action(args[1]) + " by " + args[2] + " on " + args[3]
|
Player.Message(p, Action(args[1]) + " by " + args[2] + " on " + args[3]
|
||||||
+ " - " + args[4].Replace("%20", " "));
|
+ " - " + args[4].Replace("%20", " "));
|
||||||
}
|
}
|
||||||
if (!foundAny)
|
|
||||||
Player.Message(p, "No notes found.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static string Action(string arg) {
|
static string Action(string arg) {
|
||||||
|
@ -52,8 +52,7 @@ namespace MCGalaxy.Commands.World {
|
|||||||
lvl.Save(true);
|
lvl.Save(true);
|
||||||
} finally {
|
} finally {
|
||||||
lvl.Dispose();
|
lvl.Dispose();
|
||||||
GC.Collect();
|
Server.DoGC();
|
||||||
GC.WaitForPendingFinalizers();
|
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Server.ErrorLog(ex);
|
Server.ErrorLog(ex);
|
||||||
@ -61,7 +60,6 @@ namespace MCGalaxy.Commands.World {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Player.Message(p, "Converted map!");
|
Player.Message(p, "Converted map!");
|
||||||
//CmdLoad.LoadLevel(p, name); pls
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum FileType { Mcf, Fcm, Dat, Cw };
|
enum FileType { Mcf, Fcm, Dat, Cw };
|
||||||
|
@ -45,8 +45,7 @@ namespace MCGalaxy.Commands.World {
|
|||||||
try {
|
try {
|
||||||
return LoadLevelCore(p, name, phys, autoLoaded);
|
return LoadLevelCore(p, name, phys, autoLoaded);
|
||||||
} finally {
|
} finally {
|
||||||
GC.Collect();
|
Server.DoGC();
|
||||||
GC.WaitForPendingFinalizers();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,8 +79,7 @@ namespace MCGalaxy.Commands.World {
|
|||||||
Chat.MessageAll(format, pName, name, seed);
|
Chat.MessageAll(format, pName, name, seed);
|
||||||
} finally {
|
} finally {
|
||||||
if (p != null) Interlocked.Exchange(ref p.GeneratingMap, 0);
|
if (p != null) Interlocked.Exchange(ref p.GeneratingMap, 0);
|
||||||
GC.Collect();
|
Server.DoGC();
|
||||||
GC.WaitForPendingFinalizers();
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -46,8 +46,7 @@ namespace MCGalaxy.Commands {
|
|||||||
}
|
}
|
||||||
LevelActions.ReloadMap(p, who, true);
|
LevelActions.ReloadMap(p, who, true);
|
||||||
}
|
}
|
||||||
GC.Collect();
|
Server.DoGC();
|
||||||
GC.WaitForPendingFinalizers();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ReloadAll(Player p, string[] parts) {
|
bool ReloadAll(Player p, string[] parts) {
|
||||||
|
@ -85,8 +85,7 @@ namespace MCGalaxy.Commands.World {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GC.Collect();
|
Server.DoGC();
|
||||||
GC.WaitForPendingFinalizers();
|
|
||||||
return Level.Load(lvl.name);
|
return Level.Load(lvl.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ namespace MCGalaxy.Commands.World {
|
|||||||
|
|
||||||
public override void Use(Player p, string message) {
|
public override void Use(Player p, string message) {
|
||||||
string name = message.ToLower();
|
string name = message.ToLower();
|
||||||
if (name == "" && Player.IsSuper(p)) { SuperRequiresArgs(p, "level name"); return; }
|
if (CheckSuper(p, message, "level name")) return;
|
||||||
|
|
||||||
if (name == "") {
|
if (name == "") {
|
||||||
if (!p.level.Unload()) {
|
if (!p.level.Unload()) {
|
||||||
|
@ -158,8 +158,7 @@ namespace MCGalaxy.Drawing.Ops {
|
|||||||
if (pl.level.name.CaselessEq(lvl.name))
|
if (pl.level.name.CaselessEq(lvl.name))
|
||||||
LevelActions.ReloadMap(p, pl, true);
|
LevelActions.ReloadMap(p, pl, true);
|
||||||
}
|
}
|
||||||
GC.Collect();
|
Server.DoGC();
|
||||||
GC.WaitForPendingFinalizers();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -56,11 +56,6 @@ namespace fNbt {
|
|||||||
}
|
}
|
||||||
byte[] bytes = ZeroArray;
|
byte[] bytes = ZeroArray;
|
||||||
|
|
||||||
public byte this[int tagIndex] {
|
|
||||||
get { return Value[tagIndex]; }
|
|
||||||
set { Value[tagIndex] = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
internal override void ReadTag(NbtBinaryReader readStream) {
|
internal override void ReadTag(NbtBinaryReader readStream) {
|
||||||
int length = readStream.ReadInt32();
|
int length = readStream.ReadInt32();
|
||||||
if (length < 0)
|
if (length < 0)
|
||||||
@ -233,16 +228,14 @@ namespace fNbt {
|
|||||||
|
|
||||||
public byte ByteValue {
|
public byte ByteValue {
|
||||||
get {
|
get {
|
||||||
if (TagType == NbtTagType.Byte)
|
if (TagType == NbtTagType.Byte) return ((NbtByte)this).Value;
|
||||||
return ((NbtByte)this).Value;
|
|
||||||
throw new InvalidCastException("Cannot get ByteValue from " + TagType);
|
throw new InvalidCastException("Cannot get ByteValue from " + TagType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float FloatValue {
|
public float FloatValue {
|
||||||
get {
|
get {
|
||||||
if (TagType == NbtTagType.Float)
|
if (TagType == NbtTagType.Float) return ((NbtFloat)this).Value;
|
||||||
return ((NbtFloat)this).Value;
|
|
||||||
throw new InvalidCastException("Cannot get FloatValue from " + TagType);
|
throw new InvalidCastException("Cannot get FloatValue from " + TagType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -250,10 +243,8 @@ namespace fNbt {
|
|||||||
public short ShortValue {
|
public short ShortValue {
|
||||||
get {
|
get {
|
||||||
switch (TagType) {
|
switch (TagType) {
|
||||||
case NbtTagType.Byte:
|
case NbtTagType.Byte: return ((NbtByte)this).Value;
|
||||||
return ((NbtByte)this).Value;
|
case NbtTagType.Short: return ((NbtShort)this).Value;
|
||||||
case NbtTagType.Short:
|
|
||||||
return ((NbtShort)this).Value;
|
|
||||||
default:
|
default:
|
||||||
throw new InvalidCastException("Cannot get ShortValue from " + TagType);
|
throw new InvalidCastException("Cannot get ShortValue from " + TagType);
|
||||||
}
|
}
|
||||||
@ -263,12 +254,9 @@ namespace fNbt {
|
|||||||
public int IntValue {
|
public int IntValue {
|
||||||
get {
|
get {
|
||||||
switch (TagType) {
|
switch (TagType) {
|
||||||
case NbtTagType.Byte:
|
case NbtTagType.Byte: return ((NbtByte)this).Value;
|
||||||
return ((NbtByte)this).Value;
|
case NbtTagType.Short: return ((NbtShort)this).Value;
|
||||||
case NbtTagType.Short:
|
case NbtTagType.Int: return ((NbtInt)this).Value;
|
||||||
return ((NbtShort)this).Value;
|
|
||||||
case NbtTagType.Int:
|
|
||||||
return ((NbtInt)this).Value;
|
|
||||||
default:
|
default:
|
||||||
throw new InvalidCastException("Cannot get IntValue from " + TagType);
|
throw new InvalidCastException("Cannot get IntValue from " + TagType);
|
||||||
}
|
}
|
||||||
@ -277,16 +265,14 @@ namespace fNbt {
|
|||||||
|
|
||||||
public byte[] ByteArrayValue {
|
public byte[] ByteArrayValue {
|
||||||
get {
|
get {
|
||||||
if (TagType == NbtTagType.ByteArray)
|
if (TagType == NbtTagType.ByteArray) return ((NbtByteArray)this).Value;
|
||||||
return ((NbtByteArray)this).Value;
|
|
||||||
throw new InvalidCastException("Cannot get ByteArrayValue from " + TagType);
|
throw new InvalidCastException("Cannot get ByteArrayValue from " + TagType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string StringValue {
|
public string StringValue {
|
||||||
get {
|
get {
|
||||||
if (TagType == NbtTagType.String)
|
if (TagType == NbtTagType.String) return ((NbtString)this).Value;
|
||||||
return ((NbtString)this).Value;
|
|
||||||
throw new InvalidCastException("Cannot get StringValue from " + TagType);
|
throw new InvalidCastException("Cannot get StringValue from " + TagType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -331,25 +317,22 @@ namespace fNbt {
|
|||||||
public override short ReadInt16() {
|
public override short ReadInt16() {
|
||||||
if (swapNeeded) {
|
if (swapNeeded) {
|
||||||
return Swap(base.ReadInt16());
|
return Swap(base.ReadInt16());
|
||||||
} else {
|
|
||||||
return base.ReadInt16();
|
|
||||||
}
|
}
|
||||||
|
return base.ReadInt16();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int ReadInt32() {
|
public override int ReadInt32() {
|
||||||
if (swapNeeded) {
|
if (swapNeeded) {
|
||||||
return Swap(base.ReadInt32());
|
return Swap(base.ReadInt32());
|
||||||
} else {
|
|
||||||
return base.ReadInt32();
|
|
||||||
}
|
}
|
||||||
|
return base.ReadInt32();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override long ReadInt64() {
|
public override long ReadInt64() {
|
||||||
if (swapNeeded) {
|
if (swapNeeded) {
|
||||||
return Swap(base.ReadInt64());
|
return Swap(base.ReadInt64());
|
||||||
} else {
|
|
||||||
return base.ReadInt64();
|
|
||||||
}
|
}
|
||||||
|
return base.ReadInt64();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override float ReadSingle() {
|
public override float ReadSingle() {
|
||||||
@ -357,9 +340,8 @@ namespace fNbt {
|
|||||||
FillBuffer(sizeof(float));
|
FillBuffer(sizeof(float));
|
||||||
Array.Reverse(buffer, 0, sizeof(float));
|
Array.Reverse(buffer, 0, sizeof(float));
|
||||||
return BitConverter.ToSingle(buffer, 0);
|
return BitConverter.ToSingle(buffer, 0);
|
||||||
} else {
|
|
||||||
return base.ReadSingle();
|
|
||||||
}
|
}
|
||||||
|
return base.ReadSingle();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override double ReadDouble() {
|
public override double ReadDouble() {
|
||||||
@ -405,25 +387,19 @@ namespace fNbt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static short Swap(short v) {
|
static short Swap(short v) {
|
||||||
unchecked {
|
return (short)((v >> 8) & 0x00FF | (v << 8) & 0xFF00);
|
||||||
return (short)((v >> 8) & 0x00FF | (v << 8) & 0xFF00);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int Swap(int v) {
|
static int Swap(int v) {
|
||||||
unchecked {
|
uint v2 = (uint)v;
|
||||||
uint v2 = (uint)v;
|
return
|
||||||
return
|
(int)
|
||||||
(int)
|
((v2 >> 24) & 0x000000FF | (v2 >> 8) & 0x0000FF00 | (v2 << 8) & 0x00FF0000 |
|
||||||
((v2 >> 24) & 0x000000FF | (v2 >> 8) & 0x0000FF00 | (v2 << 8) & 0x00FF0000 |
|
(v2 << 24) & 0xFF000000);
|
||||||
(v2 << 24) & 0xFF000000);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static long Swap(long v) {
|
static long Swap(long v) {
|
||||||
unchecked {
|
return (Swap((int)v) & uint.MaxValue) << 32 | Swap((int)(v >> 32)) & uint.MaxValue;
|
||||||
return (Swap((int)v) & uint.MaxValue) << 32 | Swap((int)(v >> 32)) & uint.MaxValue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,8 +204,7 @@ namespace MCGalaxy {
|
|||||||
} catch {
|
} catch {
|
||||||
} finally {
|
} finally {
|
||||||
Dispose();
|
Dispose();
|
||||||
GC.Collect();
|
Server.DoGC();
|
||||||
GC.WaitForPendingFinalizers();
|
|
||||||
|
|
||||||
if (!silent) Chat.MessageOps(ColoredName + " %Swas unloaded.");
|
if (!silent) Chat.MessageOps(ColoredName + " %Swas unloaded.");
|
||||||
Server.s.Log(name + " was unloaded.");
|
Server.s.Log(name + " was unloaded.");
|
||||||
@ -271,8 +270,7 @@ namespace MCGalaxy {
|
|||||||
Chat.MessageAll("FAILED TO SAVE {0}", ColoredName);
|
Chat.MessageAll("FAILED TO SAVE {0}", ColoredName);
|
||||||
Server.ErrorLog(e);
|
Server.ErrorLog(e);
|
||||||
}
|
}
|
||||||
GC.Collect();
|
Server.DoGC();
|
||||||
GC.WaitForPendingFinalizers();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SaveCore(string path) {
|
void SaveCore(string path) {
|
||||||
|
@ -332,8 +332,7 @@ namespace MCGalaxy {
|
|||||||
SendMessage("There was an error sending the map data, you have been sent to the main level.");
|
SendMessage("There was an error sending the map data, you have been sent to the main level.");
|
||||||
Server.ErrorLog(ex);
|
Server.ErrorLog(ex);
|
||||||
} finally {
|
} finally {
|
||||||
GC.Collect();
|
Server.DoGC();
|
||||||
GC.WaitForPendingFinalizers();
|
|
||||||
}
|
}
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
@ -23,49 +23,50 @@ using System.Text;
|
|||||||
namespace MCGalaxy {
|
namespace MCGalaxy {
|
||||||
public sealed class PlayerExtList {
|
public sealed class PlayerExtList {
|
||||||
|
|
||||||
|
char separator = ' ';
|
||||||
string path;
|
string path;
|
||||||
List<string> players = new List<string>();
|
List<string> names = new List<string>();
|
||||||
public List<string> lines = new List<string>();
|
public List<string> lines = new List<string>();
|
||||||
readonly object locker = new object(), saveLocker = new object();
|
readonly object locker = new object(), saveLocker = new object();
|
||||||
|
|
||||||
public void Add(string p, string data) {
|
public void Add(string name, string data) {
|
||||||
p = p.ToLower();
|
name = name.ToLower();
|
||||||
lock (locker) {
|
lock (locker) {
|
||||||
players.Add(p); lines.Add(p + " " + data);
|
names.Add(name); lines.Add(name + separator + data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Remove(string p) {
|
public bool Remove(string name) {
|
||||||
lock (locker) {
|
lock (locker) {
|
||||||
int idx = players.IndexOf(p.ToLower());
|
int idx = names.IndexOf(name.ToLower());
|
||||||
if (idx == -1) return false;
|
if (idx == -1) return false;
|
||||||
|
|
||||||
players.RemoveAt(idx);
|
names.RemoveAt(idx);
|
||||||
lines.RemoveAt(idx);
|
lines.RemoveAt(idx);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddOrReplace(string p, string data) {
|
public void AddOrReplace(string name, string data) {
|
||||||
p = p.ToLower();
|
name = name.ToLower();
|
||||||
lock (locker) {
|
lock (locker) {
|
||||||
int idx = players.IndexOf(p);
|
int idx = names.IndexOf(name);
|
||||||
if (idx == -1) {
|
if (idx == -1) {
|
||||||
players.Add(p); lines.Add(p + " " + data);
|
names.Add(name); lines.Add(name + separator + data);
|
||||||
} else {
|
} else {
|
||||||
lines[idx] = p + " " + data;
|
lines[idx] = name + separator + data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Find(string p) {
|
public string Find(string name) {
|
||||||
lock (locker) {
|
lock (locker) {
|
||||||
int idx = players.IndexOf(p.ToLower());
|
int idx = names.IndexOf(name.ToLower());
|
||||||
return idx == -1 ? null : lines[idx];
|
return idx == -1 ? null : lines[idx];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Count { get { lock (locker) return players.Count; } }
|
public int Count { get { lock (locker) return names.Count; } }
|
||||||
|
|
||||||
|
|
||||||
public void Save() { Save(true); }
|
public void Save() { Save(true); }
|
||||||
@ -84,9 +85,10 @@ namespace MCGalaxy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PlayerExtList Load(string path) {
|
public static PlayerExtList Load(string path, char separator = ' ') {
|
||||||
PlayerExtList list = new PlayerExtList();
|
PlayerExtList list = new PlayerExtList();
|
||||||
list.path = path;
|
list.path = path;
|
||||||
|
list.separator = separator;
|
||||||
|
|
||||||
if (!File.Exists(path)) {
|
if (!File.Exists(path)) {
|
||||||
File.Create(path).Close();
|
File.Create(path).Close();
|
||||||
@ -98,8 +100,8 @@ namespace MCGalaxy {
|
|||||||
string line = null;
|
string line = null;
|
||||||
while ((line = r.ReadLine()) != null) {
|
while ((line = r.ReadLine()) != null) {
|
||||||
list.lines.Add(line);
|
list.lines.Add(line);
|
||||||
int space = line.IndexOf(' ');
|
int sepIndex = line.IndexOf(separator);
|
||||||
string name = space >= 0 ? line.Substring(0, space) : line;
|
string name = sepIndex >= 0 ? line.Substring(0, sepIndex) : line;
|
||||||
|
|
||||||
// Need to convert uppercase to lowercase, in case user added in entries.
|
// Need to convert uppercase to lowercase, in case user added in entries.
|
||||||
bool anyUpper = false;
|
bool anyUpper = false;
|
||||||
@ -108,7 +110,7 @@ namespace MCGalaxy {
|
|||||||
anyUpper |= (c >= 'A' && c <= 'Z');
|
anyUpper |= (c >= 'A' && c <= 'Z');
|
||||||
}
|
}
|
||||||
if (anyUpper) name = name.ToLower();
|
if (anyUpper) name = name.ToLower();
|
||||||
list.players.Add(name);
|
list.names.Add(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
|
@ -67,7 +67,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 Matcher.Find<string>(p, name, out matches, players,
|
return Matcher.Find<string>(p, name, out matches, players,
|
||||||
n => true, n => n, type, 20);
|
null, n => n, type, 20);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,9 +33,18 @@ namespace MCGalaxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void EnsureExists() {
|
public void EnsureExists() {
|
||||||
if (!File.Exists(file))
|
if (!File.Exists(file))
|
||||||
File.Create(file).Dispose();
|
File.Create(file).Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary> Adds the given line to the end of the file. </summary>
|
||||||
|
public void Append(string data) {
|
||||||
|
lock (locker) {
|
||||||
|
using (StreamWriter w = new StreamWriter(file, true))
|
||||||
|
w.WriteLine(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary> Finds all lines which caselessly start with the given name. </summary>
|
/// <summary> Finds all lines which caselessly start with the given name. </summary>
|
||||||
public IEnumerable<string> Find(string name) {
|
public IEnumerable<string> Find(string name) {
|
||||||
@ -50,36 +59,28 @@ namespace MCGalaxy {
|
|||||||
}
|
}
|
||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<string> FindMatches(Player p, string name, string group) {
|
||||||
|
int matches = 0;
|
||||||
|
return Matcher.FindMulti<string>(p, name, out matches, AllLines(),
|
||||||
|
null, GetName, group);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary> Deletes all lines which start with the given value. </summary>
|
IEnumerable<string> AllLines() {
|
||||||
public void DeleteStartsWith(string value) {
|
if (!File.Exists(file)) yield break;
|
||||||
if (!File.Exists(file)) return;
|
|
||||||
List<string> lines = new List<string>();
|
|
||||||
using (StreamReader r = new StreamReader(file)) {
|
using (StreamReader r = new StreamReader(file)) {
|
||||||
string line;
|
string line;
|
||||||
while ((line = r.ReadLine()) != null) {
|
while ((line = r.ReadLine()) != null) {
|
||||||
if (line.StartsWith(value)) continue;
|
yield return line;
|
||||||
lines.Add(line);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WriteLines(lines);
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteLines(List<string> lines) {
|
public static string GetName(string line) {
|
||||||
lock (locker) {
|
int index = line.IndexOf(' ');
|
||||||
using (StreamWriter w = new StreamWriter(file, false)) {
|
return index == -1 ? line : line.Substring(0, index);
|
||||||
foreach (string line in lines)
|
|
||||||
w.WriteLine(line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary> Adds the given line to the end of the file. </summary>
|
|
||||||
public void Append(string data) {
|
|
||||||
lock (locker) {
|
|
||||||
using (StreamWriter w = new StreamWriter(file, true))
|
|
||||||
w.WriteLine(data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,8 +59,7 @@ namespace MCGalaxy {
|
|||||||
GotoLevel(p, lvl, ignorePerms) : GotoMap(p, name, ignorePerms);
|
GotoLevel(p, lvl, ignorePerms) : GotoMap(p, name, ignorePerms);
|
||||||
} finally {
|
} finally {
|
||||||
Interlocked.Exchange(ref p.UsingGoto, 0);
|
Interlocked.Exchange(ref p.UsingGoto, 0);
|
||||||
GC.Collect();
|
Server.DoGC();
|
||||||
GC.WaitForPendingFinalizers();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!didJoin) return false;
|
if (!didJoin) return false;
|
||||||
|
@ -52,7 +52,7 @@ namespace MCGalaxy {
|
|||||||
public static Thread locationChecker;
|
public static Thread locationChecker;
|
||||||
public static DateTime StartTime, StartTimeLocal;
|
public static DateTime StartTime, StartTimeLocal;
|
||||||
|
|
||||||
public static PlayerMetaList AutoloadMaps = new PlayerMetaList("text/autoload.txt");
|
public static PlayerExtList AutoloadMaps;
|
||||||
public static PlayerMetaList RankInfo = new PlayerMetaList("text/rankinfo.txt");
|
public static PlayerMetaList RankInfo = new PlayerMetaList("text/rankinfo.txt");
|
||||||
public static PlayerMetaList TempRanks = new PlayerMetaList("text/tempranks.txt");
|
public static PlayerMetaList TempRanks = new PlayerMetaList("text/tempranks.txt");
|
||||||
public static PlayerMetaList Notes = new PlayerMetaList("text/notes.txt");
|
public static PlayerMetaList Notes = new PlayerMetaList("text/notes.txt");
|
||||||
|
@ -94,17 +94,17 @@ namespace MCGalaxy {
|
|||||||
whiteList = PlayerList.Load("whitelist.txt");
|
whiteList = PlayerList.Load("whitelist.txt");
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadAutoloadCommands() {
|
void LoadAutoloadMaps() {
|
||||||
if (File.Exists("text/autoload.txt")) {
|
AutoloadMaps = PlayerExtList.Load("text/autoload.txt", '=');
|
||||||
PropertiesFile.Read("text/autoload.txt", AutoLoadLineProcessor);
|
foreach (string line in AutoloadMaps.lines) {
|
||||||
GC.Collect();
|
int sepIndex = line.IndexOf('=');
|
||||||
GC.WaitForPendingFinalizers();
|
string name = sepIndex >= 0 ? line.Substring(0, sepIndex) : line;
|
||||||
} else {
|
string value = sepIndex >= 0 ? line.Substring(sepIndex + 1) : "";
|
||||||
Log("autoload.txt does not exist");
|
AutoLoadMap(name, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AutoLoadLineProcessor(string name, string phys) {
|
static void AutoLoadMap(string name, string phys) {
|
||||||
name = name.ToLower();
|
name = name.ToLower();
|
||||||
if (phys == "") phys = "0";
|
if (phys == "") phys = "0";
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ namespace MCGalaxy {
|
|||||||
Plugin.Load();
|
Plugin.Load();
|
||||||
Background.QueueOnce(UpgradeTasks.UpgradeOldBlacklist);
|
Background.QueueOnce(UpgradeTasks.UpgradeOldBlacklist);
|
||||||
Background.QueueOnce(LoadPlayerLists);
|
Background.QueueOnce(LoadPlayerLists);
|
||||||
Background.QueueOnce(LoadAutoloadCommands);
|
Background.QueueOnce(LoadAutoloadMaps);
|
||||||
Background.QueueOnce(UpgradeTasks.MovePreviousLevelFiles);
|
Background.QueueOnce(UpgradeTasks.MovePreviousLevelFiles);
|
||||||
Background.QueueOnce(UpgradeTasks.UpgradeOldLockdown);
|
Background.QueueOnce(UpgradeTasks.UpgradeOldLockdown);
|
||||||
|
|
||||||
@ -366,5 +366,15 @@ namespace MCGalaxy {
|
|||||||
level = mapName;
|
level = mapName;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void DoGC() {
|
||||||
|
long start = GC.GetTotalMemory(false);
|
||||||
|
GC.Collect();
|
||||||
|
GC.WaitForPendingFinalizers();
|
||||||
|
|
||||||
|
long end = GC.GetTotalMemory(false);
|
||||||
|
double delta = (start - end) / 1024.0;
|
||||||
|
Server.s.Log("GC performed (freed " + delta.ToString("F2") + " KB)", true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
@ -82,16 +83,8 @@ namespace MCGalaxy {
|
|||||||
|
|
||||||
|
|
||||||
/// <summary> Finds partial matches of 'name' against the names of the items in the 'items' enumerable. </summary>
|
/// <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="group"> The group/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>
|
/// <returns> If exactly one match, the matching item. </returns>
|
||||||
public static T Find<T>(Player pl, string name, out int matches, IEnumerable items,
|
public static T Find<T>(Player p, string name, out int matches, IEnumerable items,
|
||||||
Predicate<T> filter, Func<T, string> nameGetter, string group, int limit = 5) {
|
Predicate<T> filter, Func<T, string> nameGetter, string group, int limit = 5) {
|
||||||
T match = default(T); matches = 0;
|
T match = default(T); matches = 0;
|
||||||
StringBuilder nameMatches = new StringBuilder();
|
StringBuilder nameMatches = new StringBuilder();
|
||||||
@ -110,19 +103,76 @@ namespace MCGalaxy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (matches == 1) return match;
|
||||||
if (matches == 0) {
|
if (matches == 0) {
|
||||||
Player.Message(pl, "No " + group + " match \"" + name + "\".");
|
Player.Message(p, "No " + group + " match \"" + name + "\".");
|
||||||
return default(T);
|
|
||||||
} else if (matches == 1) {
|
|
||||||
return match;
|
|
||||||
} else {
|
} else {
|
||||||
string count = matches > limit ? limit + "+ " : matches + " ";
|
OutputMulti(p, name, nameMatches, matches, group, limit);
|
||||||
string names = nameMatches.ToString(0, nameMatches.Length - 2);
|
|
||||||
|
|
||||||
Player.Message(pl, count + group + " match \"" + name + "\":");
|
|
||||||
Player.Message(pl, names);
|
|
||||||
return default(T);
|
|
||||||
}
|
}
|
||||||
|
return default(T);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> Finds partial matches of 'name' against the names of the items in the 'items' enumerable. </summary>
|
||||||
|
/// <remarks> Outputs multiple matching entries, as 'items' enumerable may have multiple entries. </remarks>
|
||||||
|
/// <returns> If exactly one match, the matching list of items. </returns>
|
||||||
|
public static List<T> FindMulti<T>(Player p, string name, out int matches, IEnumerable items,
|
||||||
|
Predicate<T> filter, Func<T, string> nameGetter, string group, int limit = 5) {
|
||||||
|
List<T> matchItems = null; matches = 0;
|
||||||
|
StringBuilder nameMatches = new StringBuilder();
|
||||||
|
List<string> outputtedNames = new List<string>(limit);
|
||||||
|
string match = null;
|
||||||
|
|
||||||
|
foreach (T item in items) {
|
||||||
|
if (filter != null && !filter(item)) continue;
|
||||||
|
string itemName = nameGetter(item);
|
||||||
|
|
||||||
|
// Found an exact name match - only output items now which exactly match
|
||||||
|
if (itemName.Equals(name, comp)) {
|
||||||
|
if (match == null || !name.Equals(match, comp))
|
||||||
|
matchItems = new List<T>();
|
||||||
|
matchItems.Add(item);
|
||||||
|
|
||||||
|
matches = 1; match = name;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemName.IndexOf(name, comp) < 0) continue;
|
||||||
|
if (matches == 0) { // Found our first partial match - init the list
|
||||||
|
matchItems = new List<T>();
|
||||||
|
matchItems.Add(item);
|
||||||
|
match = itemName;
|
||||||
|
} else if (match != null && itemName.Equals(match, comp)) { // Found same partial match
|
||||||
|
matchItems.Add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We do not want to output the same name multiple times
|
||||||
|
if (outputtedNames.CaselessContains(itemName) || matches > (limit + 1)) continue;
|
||||||
|
matches++;
|
||||||
|
|
||||||
|
if (matches <= limit) {
|
||||||
|
nameMatches.Append(itemName).Append(", ");
|
||||||
|
} else if (matches == limit + 1) {
|
||||||
|
nameMatches.Append("(and more)").Append(", ");
|
||||||
|
}
|
||||||
|
outputtedNames.Add(itemName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matches == 1) return matchItems;
|
||||||
|
if (matches == 0) {
|
||||||
|
Player.Message(p, "No " + group + " found for \"" + name + "\".");
|
||||||
|
} else {
|
||||||
|
OutputMulti(p, name, nameMatches, matches, "players", limit);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void OutputMulti(Player p, string name, StringBuilder nameMatches,
|
||||||
|
int matches, string group, int limit = 5) {
|
||||||
|
string count = matches > limit ? limit + "+ " : matches + " ";
|
||||||
|
string names = nameMatches.ToString(0, nameMatches.Length - 2);
|
||||||
|
|
||||||
|
Player.Message(p, count + group + " match \"" + name + "\":");
|
||||||
|
Player.Message(p, names);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user