Simplify /texture, /os map texture, and /botai

This commit is contained in:
UnknownShadow200 2018-04-04 11:37:48 +10:00
parent c7a57a39b0
commit dc70196f85
9 changed files with 173 additions and 171 deletions

View File

@ -49,7 +49,7 @@ namespace MCGalaxy.Bots {
}
public override void Output(Player p, string[] args, StreamWriter w) {
string time = args.Length > 3 ? args[3] : "10";
string time = args.Length > 3 ? args[3] : "10";
string speed = args.Length > 4 ? args[4] : "2";
w.WriteLine(Name + " " + short.Parse(time) + " " + byte.Parse(speed));
}

View File

@ -23,13 +23,13 @@ namespace MCGalaxy.Bots {
public static class ScriptFile {
public static bool Parse(Player p, PlayerBot bot, string file) {
if (!File.Exists(file)) {
Player.Message(p, "Could not find specified AI."); return false;
if (!File.Exists(file)) {
Player.Message(p, "Could not find specified AI."); return false;
}
string[] instructions = File.ReadAllLines(file);
if (instructions.Length == 0 || !instructions[0].CaselessEq("#Version 2")) {
Player.Message(p, "Invalid file version. Remake"); return false;
if (instructions.Length == 0) {
Player.Message(p, "No instructions in the AI."); return false;
}
bot.Instructions.Clear();
@ -53,22 +53,29 @@ namespace MCGalaxy.Bots {
return true;
}
public static void Append(Player p, string ai, string action, string[] args) {
public static string Append(Player p, string ai, string action, string[] args) {
using (StreamWriter w = new StreamWriter("bots/" + ai, true)) {
if (action.Length == 0) action = "walk";
if (action.Length == 0) action = "walk";
if (action.CaselessEq("tp")) action = "teleport";
BotInstruction ins = BotInstruction.Find(action);
if (ins == null) {
Player.Message(p, "Could not find instruction \"" + action + "\""); return;
Player.Message(p, "Could not find instruction \"" + action + "\""); return null;
}
LevelPermission killPerm = CommandExtraPerms.MinPerm("botset");
if (ins.Name.CaselessEq("kill") && p.Rank < killPerm) {
Formatter.MessageNeedMinPerm(p, "+ can toggle a bot's killer instinct.", killPerm);
return;
return null;
}
ins.Output(p, args, w);
try {
ins.Output(p, args, w);
} catch {
Player.Message(p, "Invalid arguments given for instruction " + ins.Name);
return null;
}
return ins.Name;
}
}
}

View File

@ -31,7 +31,8 @@ namespace MCGalaxy.Commands.Bots{
public override void Use(Player p, string message) {
string[] args = message.SplitSpaces();
if (args[0].CaselessEq("list")) {
string cmd = args[0];
if (cmd.CaselessEq("list")) {
string modifier = args.Length > 1 ? args[1] : "";
HandleList(p, modifier);
return;
@ -43,11 +44,14 @@ namespace MCGalaxy.Commands.Bots{
if (!Formatter.ValidName(p, ai, "bot AI")) return;
if (ai == "hunt" || ai == "kill") { Player.Message(p, "Reserved for special AI."); return; }
switch (args[0].ToLower()) {
case "add": HandleAdd(p, ai, args); break;
case "del": HandleDelete(p, ai, args); break;
case "info": HandleInfo(p, ai); break;
default: Help(p); break;
if (cmd.CaselessEq("add")) {
HandleAdd(p, ai, args);
} else if (cmd.CaselessEq("del")) {
HandleDelete(p, ai, args);
} else if (cmd.CaselessEq("info")) {
HandleInfo(p, ai);
} else {
Help(p);
}
}
@ -55,7 +59,7 @@ namespace MCGalaxy.Commands.Bots{
if (!Directory.Exists("bots/deleted"))
Directory.CreateDirectory("bots/deleted");
if (!File.Exists("bots/" + ai)) {
Player.Message(p, "Could not find specified AI."); return;
Player.Message(p, "Could not find specified bot AI."); return;
}
for (int attempt = 0; attempt < 10; attempt++) {
@ -78,7 +82,7 @@ namespace MCGalaxy.Commands.Bots{
} else {
File.Move("bots/" + ai, "bots/deleted/" + ai + attempt);
}
Player.Message(p, "Deleted &b" + ai);
Player.Message(p, "Deleted bot AI &b" + ai);
}
static void DeleteLast(Player p, string ai) {
@ -86,47 +90,39 @@ namespace MCGalaxy.Commands.Bots{
if (lines.Count > 0) lines.RemoveAt(lines.Count - 1);
File.WriteAllLines("bots/" + ai, lines.ToArray());
Player.Message(p, "Deleted the last instruction from " + ai);
Player.Message(p, "Deleted last instruction from bot AI &b" + ai);
}
void HandleAdd(Player p, string ai, string[] args) {
string[] instructions;
try { instructions = File.ReadAllLines("bots/" + ai); }
catch { instructions = new string[1]; }
try {
if (!File.Exists("bots/" + ai)) {
Player.Message(p, "Created new bot AI: &b" + ai);
using (StreamWriter w = new StreamWriter("bots/" + ai))
w.WriteLine("#Version 2");
} else if (!instructions[0].CaselessEq("#Version 2")) {
Player.Message(p, "File found is out-of-date. Overwriting");
File.Delete("bots/" + ai);
using (StreamWriter w = new StreamWriter("bots/" + ai))
w.WriteLine("#Version 2");
} else {
Player.Message(p, "Appended to bot AI: &b" + ai);
if (!File.Exists("bots/" + ai)) {
Player.Message(p, "Created new bot AI: &b" + ai);
using (StreamWriter w = new StreamWriter("bots/" + ai)) {
// For backwards compatibility
w.WriteLine("#Version 2");
}
} catch {
Player.Message(p, "An error occurred when accessing the files. You may need to delete it."); return;
}
try {
string action = args.Length > 2 ? args[2] : "";
if (!action.CaselessEq("reverse")) {
ScriptFile.Append(p, ai, action, args); return;
string action = args.Length > 2 ? args[2] : "";
if (action.CaselessEq("reverse")) {
HandleReverse(p, ai);
} else {
string instruction = ScriptFile.Append(p, ai, action, args);
if (instruction != null) {
Player.Message(p, "Appended " + instruction + " instruction to bot AI &b" + ai);
}
using (StreamWriter w = new StreamWriter("bots/" + ai, true)) {
for (int i = instructions.Length - 1; i > 0; i--) {
if (instructions[i].Length > 0 && instructions[i][0] != '#') {
w.WriteLine(instructions[i]);
}
}
}
void HandleReverse(Player p, string ai) {
string[] instructions = File.ReadAllLines("bots/" + ai);
using (StreamWriter w = new StreamWriter("bots/" + ai, true)) {
for (int i = instructions.Length - 1; i > 0; i--) {
if (instructions[i].Length > 0 && instructions[i][0] != '#') {
w.WriteLine(instructions[i]);
}
}
} catch {
Player.Message(p, "Invalid parameter");
}
Player.Message(p, "Appended all instructions in reverse order to bot AI &b" + ai);
}
void HandleList(Player p, string modifier) {
@ -157,7 +153,7 @@ namespace MCGalaxy.Commands.Bots{
Player.Message(p, "%T/BotAI add [name] [instruction] <args>");
Player.Message(p, "%HInstructions: %S{0}, reverse",
BotInstruction.Instructions.Join(ins => ins.Name.ToLower()));
BotInstruction.Instructions.Join(ins => ins.Name));
Player.Message(p, "%HTo see detailed help, type %T/Help BotAI [instruction]");
}
@ -165,7 +161,7 @@ namespace MCGalaxy.Commands.Bots{
BotInstruction ins = BotInstruction.Find(message);
if (ins == null) {
Player.Message(p, "%HInstructions: %S{0}, reverse",
BotInstruction.Instructions.Join(ins2 => ins2.Name.ToLower()));
BotInstruction.Instructions.Join(ins2 => ins2.Name));
} else {
Player.MessageLines(p, ins.Help);
}

View File

@ -17,111 +17,116 @@
*/
namespace MCGalaxy.Commands.CPE {
public sealed class CmdTexture : Command {
public override string name { get { return "Texture"; } }
public override string type { get { return CommandTypes.Other; } }
public override LevelPermission defaultRank { get { return LevelPermission.Operator; } }
public sealed class CmdTexture : Command {
public override string name { get { return "Texture"; } }
public override string type { get { return CommandTypes.Other; } }
public override LevelPermission defaultRank { get { return LevelPermission.Operator; } }
public override void Use(Player p, string message) {
if (message.Length == 0) { Help(p); return; }
string[] args = message.SplitSpaces();
string scope = args[0].ToLower();
if (scope == "local") scope = "level";
if (scope == "localzip") scope = "levelzip";
if (args.Length == 1) {
if (scope == "level")
Player.Message(p, "Level terrain: " + GetPath(p.level.Config.Terrain));
else if (scope == "levelzip")
Player.Message(p, "Level tex pack: " + GetPath(p.level.Config.TexturePack));
else if (scope == "global")
Player.Message(p, "Global terrain: " + GetPath(ServerConfig.DefaultTerrain));
else if (scope == "globalzip")
Player.Message(p, "Global tex pack: " + GetPath(ServerConfig.DefaultTexture));
else
Help(p);
return;
}
string url = args[1];
if (url.CaselessEq("normal") || url.CaselessEq("reset")) {
url = "";
} else if (!(url.StartsWith("http://") || url.StartsWith("https://"))) {
Player.Message(p, "Please use http:// or https:// in front of your URL"); return;
}
FilterURL(ref url);
if ((scope == "global" || scope == "level") && !(url.Length == 0 || url.EndsWith(".png"))) {
Player.Message(p, "The terrain URL must end in a .png"); return;
}
if ((scope == "globalzip" || scope == "levelzip") && !(url.Length == 0 || url.EndsWith(".zip"))) {
Player.Message(p, "The texture pack URL must end in a .zip"); return;
}
if (url.Length > NetUtils.StringSize) {
Player.Message(p, "The URL must be " + NetUtils.StringSize + " characters or less."); return;
}
string path = url.Length == 0 ? "normal" : url;
if (scope == "global") {
ServerConfig.DefaultTerrain = url;
Player.Message(p, "Set server's default terrain to " + path);
UpdateGlobally(p, false);
} else if (scope == "level") {
if (!LevelInfo.ValidateAction(p, p.level.name, "set texture of this level")) return;
p.level.Config.Terrain = url;
Player.Message(p, "Set level's terrain to " + path);
UpdateLevel(p);
} else if (scope == "globalzip") {
ServerConfig.DefaultTexture = url;
Player.Message(p, "Set server's default texture pack to " + path);
UpdateGlobally(p, true);
} else if (scope == "levelzip") {
if (!LevelInfo.ValidateAction(p, p.level.name, "set texture pack of this level")) return;
p.level.Config.TexturePack = url;
Player.Message(p, "Set level's texture pack to " + path);
UpdateLevel(p);
} else {
Help(p);
}
}
internal static void FilterURL(ref string url) {
// a lot of people try linking to the dropbox page instead of directly to file, so we auto correct them
if (url.StartsWith("http://www.dropbox")) {
url = "http://dl.dropbox" + url.Substring("http://www.dropbox".Length);
url = url.Replace("?dl=0", "");
} else if (url.StartsWith("https://www.dropbox")) {
url = "https://dl.dropbox" + url.Substring("https://www.dropbox".Length);
url = url.Replace("?dl=0", "");
}
}
static string GetPath(string url) { return url.Length == 0 ? "(none)" : url; }
void UpdateGlobally(Player p, bool zip) {
Player[] players = PlayerInfo.Online.Items;
foreach (Player pl in players) {
string url = zip ? pl.level.Config.TexturePack : pl.level.Config.Terrain;
if (url.Length == 0) pl.SendCurrentTextures();
}
SrvProperties.Save();
}
void UpdateLevel(Player p) {
Player[] players = PlayerInfo.Online.Items;
foreach (Player pl in players) {
if (pl.level != p.level) continue;
pl.SendCurrentTextures();
}
Level.SaveSettings(p.level);
}
public override void Help(Player p) {
Player.Message(p, "%T/Texture [scope] [url]");
Player.Message(p, "%H global/globalzip scope: Changes server's default texture.");
Player.Message(p, "%H level/levelzip scope: Changes current level's texture.");
Player.Message(p, "%HUsing 'reset' as a url will reset the texture to default.");
Player.Message(p, "%HNote: zip texture packs are not supported by all clients.");
}
}
public override void Use(Player p, string message) {
if (message.Length == 0) { Help(p); return; }
string[] args = message.SplitSpaces();
string scope = args[0].ToLower();
if (scope == "local") scope = "level";
if (scope == "localzip") scope = "levelzip";
if (args.Length == 1) {
if (scope == "level")
Player.Message(p, "Level terrain: " + GetPath(p.level.Config.Terrain));
else if (scope == "levelzip")
Player.Message(p, "Level tex pack: " + GetPath(p.level.Config.TexturePack));
else if (scope == "global")
Player.Message(p, "Global terrain: " + GetPath(ServerConfig.DefaultTerrain));
else if (scope == "globalzip")
Player.Message(p, "Global tex pack: " + GetPath(ServerConfig.DefaultTexture));
else
Help(p);
return;
}
string url = args[1];
if (url.CaselessEq("normal") || url.CaselessEq("reset")) {
url = "";
} else if (!(url.StartsWith("http://") || url.StartsWith("https://"))) {
Player.Message(p, "Please use http:// or https:// in front of your URL"); return;
}
FilterURL(ref url);
if (url.Length > NetUtils.StringSize) {
Player.Message(p, "The URL must be " + NetUtils.StringSize + " characters or less."); return;
}
if (url.Length > 0 && !(url.EndsWith(".png") || url.EndsWith(".zip"))) {
Player.Message(p, "URL must end in .png (for terrain) or .zip (for texture pack)"); return;
}
if (scope == "global" || scope == "globalzip") {
if (url.Length == 0) {
ServerConfig.DefaultTerrain = "";
ServerConfig.DefaultTexture = "";
Player.Message(p, "Reset server textures to default");
} else if (url.CaselessEnds(".png")) {
ServerConfig.DefaultTerrain = url;
Player.Message(p, "Set server's default terrain to " + url);
} else if (url.CaselessEnds(".zip")) {
ServerConfig.DefaultTexture = url;
Player.Message(p, "Set server's default texture pack to " + url);
}
UpdateGlobal(p);
} else if (scope == "level" || scope == "levelzip") {
if (!LevelInfo.ValidateAction(p, p.level.name, "set texture of this level")) return;
if (url.Length == 0) {
p.level.Config.Terrain = "";
p.level.Config.TexturePack = "";
Player.Message(p, "Reset level textures to server default");
} else if (url.CaselessEnds(".png")) {
p.level.Config.Terrain = url;
Player.Message(p, "Set level's default terrain to " + url);
} else if (url.CaselessEnds(".zip")) {
p.level.Config.TexturePack = url;
Player.Message(p, "Set level's default texture pack to " + url);
}
UpdateLevel(p);
} else {
Help(p);
}
}
internal static void FilterURL(ref string url) {
// a lot of people try linking to the dropbox page instead of directly to file, so we auto correct them
if (url.StartsWith("http://www.dropbox")) {
url = "http://dl.dropbox" + url.Substring("http://www.dropbox".Length);
url = url.Replace("?dl=0", "");
} else if (url.StartsWith("https://www.dropbox")) {
url = "https://dl.dropbox" + url.Substring("https://www.dropbox".Length);
url = url.Replace("?dl=0", "");
}
}
static string GetPath(string url) { return url.Length == 0 ? "(none)" : url; }
void UpdateGlobal(Player p) {
Player[] players = PlayerInfo.Online.Items;
foreach (Player pl in players) {
pl.SendCurrentTextures();
}
SrvProperties.Save();
}
void UpdateLevel(Player p) {
Player[] players = PlayerInfo.Online.Items;
foreach (Player pl in players) {
if (pl.level != p.level) continue;
pl.SendCurrentTextures();
}
Level.SaveSettings(p.level);
}
public override void Help(Player p) {
Player.Message(p, "%T/Texture global/level [url]");
Player.Message(p, "%HChanges server default or current level's texture.");
Player.Message(p, "%H[url] must end with .png (terrain) or .zip (texture pack)");
Player.Message(p, "%HUsing 'reset' for [url] will reset the texture to default");
Player.Message(p, "%H Note: zip texture packs are not supported by all clients");
}
}
}

View File

@ -157,9 +157,9 @@ namespace MCGalaxy.Commands.Info {
void ShowEnv(Player p, MapInfoData data, LevelConfig cfg) {
string url = cfg.Terrain.Length > 0 ? cfg.Terrain : ServerConfig.DefaultTerrain;
if (url.Length > 0) {
Player.Message(p, "Texture: %b" + url);
Player.Message(p, "Terrain: %b" + url);
} else {
Player.Message(p, "No custom texture set for this map.");
Player.Message(p, "No custom terrain set for this map.");
}
url = cfg.TexturePack.Length > 0 ? cfg.TexturePack : ServerConfig.DefaultTexture;

View File

@ -130,13 +130,7 @@ namespace MCGalaxy.Commands.World {
string rank = value.Length == 0 ? ServerConfig.DefaultRankName : value;
Group grp = Matcher.FindRanks(p, rank);
if (grp != null) p.level.BuildAccess.SetMin(null, grp);
} else if (cmd == "TEXTURE") {
if (value.Length == 0) {
Command.all.FindByName("Texture").Use(p, "level normal");
} else {
Command.all.FindByName("Texture").Use(p, "level " + value);
}
} else if (cmd == "TEXTUREZIP" || cmd == "TEXTUREPACK") {
} else if (cmd == "TEXTURE" || cmd == "TEXTUREZIP" || cmd == "TEXTUREPACK") {
if (value.Length == 0) {
Command.all.FindByName("Texture").Use(p, "levelzip normal");
} else {

View File

@ -60,9 +60,9 @@ namespace MCGalaxy.DB {
BlockDBFile.ReadHeader(s, out Dims);
}
/// <summary> Writes the entries from the in-memory cache to disc. </summary>
/// <summary> Flushes the entries from the in-memory cache to disc. </summary>
/// <remarks> You must lock using Locker.AccquireWrite() **before** entering this method. </remarks>
public void WriteEntries() {
public void FlushCache() {
if (Cache.Head == null) return;
BlockDBFile format = ValidateBackingFile();

View File

@ -224,7 +224,7 @@ namespace MCGalaxy.Drawing.Ops {
op.TotalModified++;
// Attempt to prevent the BlockDB from growing too large (> 1,000,000 entries)
// Attempt to prevent BlockDB in-memory cache from growing too large (> 1,000,000 entries)
int count = lvl.BlockDB.Cache.Count;
if (count == 0 || (count % 1000000) != 0) return;
@ -236,7 +236,7 @@ namespace MCGalaxy.Drawing.Ops {
}
using (IDisposable wLock = lvl.BlockDB.Locker.AccquireWrite(100)) {
if (wLock != null) lvl.BlockDB.WriteEntries();
if (wLock != null) lvl.BlockDB.FlushCache();
}
if (!hasReadLock) return;

View File

@ -34,7 +34,7 @@ namespace MCGalaxy {
Logger.Log(LogType.Warning, "Couldn't accquire BlockDB write lock on {0}, skipping save", lvl.name);
return;
}
lvl.BlockDB.WriteEntries();
lvl.BlockDB.FlushCache();
}
Logger.Log(LogType.BackgroundActivity, "Saved BlockDB changes for: {0}", lvl.name);
}