Minor code cleanup for command handling, still need to fix multiple commands in a /mb.

This commit is contained in:
UnknownShadow200 2016-06-26 00:20:19 +10:00
parent 3484d19c47
commit 8449a791b2
6 changed files with 337 additions and 32 deletions

View File

@ -77,9 +77,12 @@ namespace MCGalaxy.BlockBehaviour {
string text; string text;
List<string> cmds = ParseMB(message, out text); List<string> cmds = ParseMB(message, out text);
if (text != null) Player.Message(p, text); if (text != null) Player.Message(p, text);
foreach (string cmd in cmds) {
string[] parts = cmd.SplitSpaces(2); if (cmds.Count == 1) {
string[] parts = cmds[0].SplitSpaces(2);
p.HandleCommand(parts[0], parts.Length > 1 ? parts[1] : ""); p.HandleCommand(parts[0], parts.Length > 1 ? parts[1] : "");
} else if (cmds.Count > 0) {
p.HandleCommands(cmds);
} }
p.prevMsg = message; p.prevMsg = message;
} }

View File

@ -46,7 +46,7 @@ namespace MCGalaxy.Commands.World {
try { try {
File.Copy(LevelInfo.LevelPath(src), LevelInfo.LevelPath(dst)); File.Copy(LevelInfo.LevelPath(src), LevelInfo.LevelPath(dst));
if (File.Exists(LevelInfo.PropertiesPath(src)) if (File.Exists(LevelInfo.PropertiesPath(src)))
File.Copy(LevelInfo.PropertiesPath(src), LevelInfo.PropertiesPath(dst), false); File.Copy(LevelInfo.PropertiesPath(src), LevelInfo.PropertiesPath(dst), false);
if (File.Exists("blockdefs/lvl_" + src + ".json")) if (File.Exists("blockdefs/lvl_" + src + ".json"))
File.Copy("blockdefs/lvl_" + src + ".json", "blockdefs/lvl_" + dst + ".json"); File.Copy("blockdefs/lvl_" + src + ".json", "blockdefs/lvl_" + dst + ".json");

View File

@ -0,0 +1,111 @@
/*
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;
using System.IO;
using System.Text;
namespace MCGalaxy {
public sealed class PlayerExtList {
string path;
List<string> players = new List<string>();
List<string> lines = new List<string>();
readonly object locker = new object();
public void Add(string p, string data) {
p = p.ToLower();
lock (locker) {
players.Add(p); lines.Add(p + " " + data);
}
}
public bool Remove(string p) {
lock (locker) {
int idx = players.IndexOf(p.ToLower());
if (idx == -1) return false;
players.RemoveAt(idx);
lines.RemoveAt(idx);
return true;
}
}
public void AddOrReplace(string p, string data) {
p = p.ToLower();
lock (locker) {
int idx = players.IndexOf(p);
if (idx == -1) {
players.Add(p); lines.Add(p + " " + data);
} else {
lines[idx] = p + " " + data;
}
}
}
public string Find(string p) {
lock (locker) {
int idx = players.IndexOf(p.ToLower());
return idx == -1 ? null : lines[idx];
}
}
public int Count { get { lock (locker) return players.Count; } }
public void Save(bool console = false) {
using (StreamWriter w = new StreamWriter(path)) {
lock (locker) {
foreach (string line in lines)
w.WriteLine(line);
}
}
if (console) Server.s.Log("SAVED: " + path, true);
}
public static PlayerExtList Load(string path) {
PlayerExtList list = new PlayerExtList();
list.path = path;
if (!File.Exists(path)) {
File.Create(path).Close();
Server.s.Log("CREATED NEW: " + path);
return list;
}
using (StreamReader r = new StreamReader(path, Encoding.UTF8)) {
string line = null;
while ((line = r.ReadLine()) != null) {
list.lines.Add(line);
int space = line.IndexOf(' ');
string name = space >= 0 ? line.Substring(0, space) : line;
// Need to convert uppercase to lowercase, in case user added in entries.
bool anyUpper = false;
for (int i = 0; i < name.Length; i++) {
char c = line[i];
anyUpper |= (c >= 'A' && c <= 'Z');
}
if (anyUpper) name = name.ToLower();
list.players.Add(name);
}
}
return list;
}
}
}

107
Player/List/PlayerList.cs Normal file
View File

@ -0,0 +1,107 @@
/*
Copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/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;
using System.IO;
using System.Text;
namespace MCGalaxy {
public sealed class PlayerList {
string path;
List<string> players = new List<string>();
readonly object locker = new object();
public PlayerList() { }
public PlayerList(string path) { this.path = path; }
public void Add(string p) {
lock (locker)
players.Add(p.ToLower());
}
public bool Remove(string p) {
lock (locker)
return players.Remove(p.ToLower());
}
public bool Contains(string p) {
lock (locker)
return players.Contains(p.ToLower());
}
public List<string> All() {
lock (locker)
return new List<string>(players);
}
public int Count { get { lock (locker) return players.Count; } }
public void AddOrReplace(string p) {
p = p.ToLower();
lock (locker) {
int idx = players.IndexOf(p);
if (idx >= 0) return;
players.Add(p);
}
}
public void Save() { Save(true); }
public void Save(bool console) {
using (StreamWriter w = new StreamWriter(path)) {
lock (locker) {
foreach (string p in players)
w.WriteLine(p);
}
}
if (console) Server.s.Log("SAVED: " + path, true);
}
public static PlayerList Load(string file) {
if (!Directory.Exists("ranks")) Directory.CreateDirectory("ranks");
PlayerList list = new PlayerList(file);
if (file.IndexOf('/') == -1) file = "ranks/" + file;
list.path = file;
if (!File.Exists(list.path)) {
File.Create(list.path).Close();
Server.s.Log("CREATED NEW: " + list.path);
return list;
}
using (StreamReader r = new StreamReader(list.path, Encoding.UTF8)) {
string line = null;
while ((line = r.ReadLine()) != null) {
// Need to convert uppercase to lowercase, in case user added in entries.
bool anyUpper = false;
for (int i = 0; i < line.Length; i++) {
char c = line[i];
anyUpper |= (c >= 'A' && c <= 'Z');
}
if (anyUpper) line = line.ToLower();
list.players.Add(line);
}
}
return list;
}
[Obsolete("Group parameter is completely ignored.")]
public static PlayerList Load(string path, Group grp) { return Load(path); }
}
}

View File

@ -0,0 +1,86 @@
/*
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;
using System.IO;
namespace MCGalaxy {
/// <summary> Represents a list of extended metadata about players. (such as rank info, ban info, notes). </summary>
public sealed class PlayerMetaList {
public readonly string file;
readonly object locker;
public PlayerMetaList(string file) {
this.file = file;
locker = new object();
}
public void EnsureExists() {
if (!File.Exists(file))
File.Create(file).Dispose();
}
/// <summary> Finds all lines which caselessly start with the given name. </summary>
public IEnumerable<string> Find(string name) {
if (!File.Exists(file)) yield break;
name += " ";
using (StreamReader r = new StreamReader(file)) {
string line;
while ((line = r.ReadLine()) != null) {
if (line.CaselessStarts(name)) yield return line;
}
}
yield break;
}
/// <summary> Deletes all lines which start with the given value. </summary>
public void DeleteStartsWith(string value) {
if (!File.Exists(file)) return;
List<string> lines = new List<string>();
using (StreamReader r = new StreamReader(file)) {
string line;
while ((line = r.ReadLine()) != null) {
if (line.StartsWith(value)) continue;
lines.Add(line);
}
}
WriteLines(lines);
}
void WriteLines(List<string> lines) {
lock (locker) {
using (StreamWriter w = new StreamWriter(file, false)) {
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) {
string line = CP437Writer.ConvertToUnicode(data);
lock (locker) {
using (StreamWriter w = new StreamWriter(file, true))
w.WriteLine(line);
}
}
}
}

View File

@ -1192,14 +1192,19 @@ return;
try { try {
if (!CheckCommand(cmd)) return; if (!CheckCommand(cmd)) return;
Command command = GetCommand(ref cmd, ref message); Command command = GetCommand(ref cmd, ref message);
if (command != null) UseCommand(command, cmd, message); if (command == null) return;
Thread thread = new Thread(() => UseCommand(command, message));
thread.Name = "MCG_Command";
thread.IsBackground = true;
thread.Start();
} catch (Exception e) { } catch (Exception e) {
Server.ErrorLog(e); SendMessage("Command failed."); Server.ErrorLog(e); SendMessage("Command failed.");
} }
} }
public void HandleCommands(List<string> cmds) { public void HandleCommands(List<string> cmds) {
// TODO: finish this then do next release
} }
bool CheckCommand(string cmd) { bool CheckCommand(string cmd) {
@ -1262,33 +1267,33 @@ return;
if (cancelcommand) { cancelcommand = false; return null; } if (cancelcommand) { cancelcommand = false; return null; }
Command command = Command.all.Find(cmd); Command command = Command.all.Find(cmd);
if (command != null) return command; if (command == null) {
if (Block.Byte(cmd) != Block.Zero) { if (Block.Byte(cmd) != Block.Zero) {
message = cmd.ToLower(); cmd = "mode"; message = cmd.ToLower(); cmd = "mode";
return Command.all.Find("mode"); command = Command.all.Find("mode");
} else { } else {
SendMessage("Unknown command \"" + cmd + "\"!"); SendMessage("Unknown command \"" + cmd + "\"."); return null;
return null; }
} }
}
if (!group.CanExecute(command)) { command.MessageCannotUse(this); return null; }
void UseCommand(Command command, string cmd, string message) {
if (!group.CanExecute(command)) { command.MessageCannotUse(this); return; }
string reason = Command.GetDisabledReason(command.Enabled); string reason = Command.GetDisabledReason(command.Enabled);
if (reason != null) { if (reason != null) {
SendMessage("Command is disabled as " + reason); return; SendMessage("Command is disabled as " + reason); return null;
}
if (level.IsMuseum && !command.museumUsable ) {
SendMessage("Cannot use this command while in a museum."); return null;
} }
return command;
}
void UseCommand(Command command, string message) {
string cmd = command.name;
if (!(cmd == "repeat" || cmd == "pass" || cmd == "setpass")) { if (!(cmd == "repeat" || cmd == "pass" || cmd == "setpass")) {
lastCMD = cmd + " " + message; lastCMD = cmd + " " + message;
lastCmdTime = DateTime.Now; lastCmdTime = DateTime.Now;
} }
if (level.IsMuseum && !command.museumUsable ) {
SendMessage("Cannot use this command while in a museum!"); return;
}
if ((joker || muted) && cmd == "me") {
SendMessage("Cannot use /me while muted or jokered."); return;
}
if (!(cmd == "pass" || cmd == "setpass")) { if (!(cmd == "pass" || cmd == "setpass")) {
Server.s.CommandUsed(name + " used /" + cmd + " " + message); Server.s.CommandUsed(name + " used /" + cmd + " " + message);
} }
@ -1303,16 +1308,9 @@ return;
Database.executeQuery(query, "INSERT INTO Opstats (Time, Name, Cmd, Cmdmsg) VALUES (@Time, @Name, @Cmd, @Cmdmsg)"); Database.executeQuery(query, "INSERT INTO Opstats (Time, Name, Cmd, Cmdmsg) VALUES (@Time, @Name, @Cmd, @Cmdmsg)");
} }
} catch { } } catch { }
Thread thread = new Thread(() => DoCommand(command, message));
thread.Name = "MCG_Command";
thread.IsBackground = true;
thread.Start();
}
void DoCommand(Command cmd, string message) {
try { try {
cmd.Use(this, message); command.Use(this, message);
} catch (Exception e) { } catch (Exception e) {
Server.ErrorLog(e); Server.ErrorLog(e);
Player.Message(this, "An error occured when using the command!"); Player.Message(this, "An error occured when using the command!");