diff --git a/MCGalaxy/Commands/CPE/CustomBlockCommand.cs b/MCGalaxy/Commands/CPE/CustomBlockCommand.cs index fc8e5ab63..97e9a7ef5 100644 --- a/MCGalaxy/Commands/CPE/CustomBlockCommand.cs +++ b/MCGalaxy/Commands/CPE/CustomBlockCommand.cs @@ -539,9 +539,6 @@ namespace MCGalaxy.Commands.CPE { if (blockId <= 0 || blockId >= 255) { Player.Message(p, "&cBlock id must be between 1-254"); return false; } - if (!global && blockId < Block.CpeCount) { - Player.Message(p, "&cYou can only redefine standard blocks with /gb."); return false; - } return true; } diff --git a/MCGalaxy/Commands/Chat/CmdColor.cs b/MCGalaxy/Commands/Chat/CmdColor.cs index 55731cf1a..d8b0e211c 100644 --- a/MCGalaxy/Commands/Chat/CmdColor.cs +++ b/MCGalaxy/Commands/Chat/CmdColor.cs @@ -45,22 +45,22 @@ namespace MCGalaxy.Commands { } protected override void SetPlayerData(Player p, Player who, string[] args) { + string color = ""; if (args.Length == 1) { Player.SendChatFrom(who, who.ColoredName + " %Shad their color removed.", false); who.color = who.group.color; - Database.Execute("UPDATE Players SET color = '' WHERE Name = @0", who.name); } else { - string color = Colors.Parse(args[1]); + color = Colors.Parse(args[1]); if (color == "") { Player.Message(p, "There is no color \"" + args[1] + "\"."); return; } else if (color == who.color) { Player.Message(p, who.DisplayName + " %Salready has that color."); return; } Player.SendChatFrom(who, who.ColoredName + " %Shad their color changed to " + color + Colors.Name(color) + "%S.", false); who.color = color; - Database.Execute("UPDATE Players SET color = @1 WHERE Name = @0", who.name, color); } Entities.GlobalDespawn(who, true); Entities.GlobalSpawn(who, true); who.SetPrefix(); + Database.Backend.UpdateRows("Players", "color = @1", "WHERE Name = @0", who.name, color); } public override void Help(Player p) { diff --git a/MCGalaxy/Commands/Chat/CmdMe.cs b/MCGalaxy/Commands/Chat/CmdMe.cs index d7ea4a69f..254702a21 100644 --- a/MCGalaxy/Commands/Chat/CmdMe.cs +++ b/MCGalaxy/Commands/Chat/CmdMe.cs @@ -31,7 +31,7 @@ namespace MCGalaxy.Commands { if (p.joker) { Player.Message(p, "Cannot use /me while jokered."); return; } string msg = p.color + "*" + Colors.StripColors(p.DisplayName) + " " + message; - if (TryMessage(p, msg) && p.level.worldChat) + if (TryMessage(p, msg)) Player.RaisePlayerAction(p, PlayerAction.Me, message); } diff --git a/MCGalaxy/Commands/Chat/CmdTColor.cs b/MCGalaxy/Commands/Chat/CmdTColor.cs index 5258df55f..5e3e9d172 100644 --- a/MCGalaxy/Commands/Chat/CmdTColor.cs +++ b/MCGalaxy/Commands/Chat/CmdTColor.cs @@ -43,8 +43,8 @@ namespace MCGalaxy.Commands { } who.titlecolor = color; - Database.Execute("UPDATE Players SET title_color = @1 WHERE Name = @0", who.name, color); who.SetPrefix(); + Database.Backend.UpdateRows("Players", "title_color = @1", "WHERE Name = @0", who.name, color); } public override void Help(Player p) { diff --git a/MCGalaxy/Commands/Chat/CmdTitle.cs b/MCGalaxy/Commands/Chat/CmdTitle.cs index f615c0fbd..9c0119be8 100644 --- a/MCGalaxy/Commands/Chat/CmdTitle.cs +++ b/MCGalaxy/Commands/Chat/CmdTitle.cs @@ -38,13 +38,13 @@ namespace MCGalaxy.Commands { if (title == "") { Player.SendChatFrom(who, who.FullName + " %Shad their title removed.", false); - Database.Execute("UPDATE Players SET Title = '' WHERE Name = @0", who.name); } else { Player.SendChatFrom(who, who.FullName + " %Swas given the title of &b[" + title + "&b]", false); - Database.Execute("UPDATE Players SET Title = @1 WHERE Name = @0", who.name, title); - } + } + who.title = title; who.SetPrefix(); + Database.Backend.UpdateRows("Players", "Title = @1", "WHERE Name = @0", who.name, title); } public override void Help(Player p) { diff --git a/MCGalaxy/Commands/Information/CmdOpStats.cs b/MCGalaxy/Commands/Information/CmdOpStats.cs index 67e122a50..6414a2859 100644 --- a/MCGalaxy/Commands/Information/CmdOpStats.cs +++ b/MCGalaxy/Commands/Information/CmdOpStats.cs @@ -98,8 +98,10 @@ namespace MCGalaxy.Commands { } static void DoQuery(Player p, string group, string start, string end, string name, string cmd, string msg) { - DataTable table = Database.Fill("SELECT COUNT(ID) FROM Opstats WHERE Time >= @0 AND Time < @1 " + - "AND Name LIKE @2 AND Cmd LIKE @3 AND Cmdmsg " + msg, start, end, name, cmd); + DataTable table = Database.Backend.GetRows( + "Opstats", "COUNT(ID)" ,"WHERE Time >= @0 AND Time < @1 AND " + + "Name LIKE @2 AND Cmd LIKE @3 AND Cmdmsg " + msg, start, end, name, cmd); + // don't use colour codes in cli or gui Player.Message(p, (p == null ? "" : "&a") + group + (p == null ? "" : "&5") + table.Rows[0]["COUNT(id)"]); table.Dispose(); diff --git a/MCGalaxy/Commands/Information/CmdServerInfo.cs b/MCGalaxy/Commands/Information/CmdServerInfo.cs index 0168ca363..8868f2c98 100644 --- a/MCGalaxy/Commands/Information/CmdServerInfo.cs +++ b/MCGalaxy/Commands/Information/CmdServerInfo.cs @@ -73,7 +73,7 @@ namespace MCGalaxy.Commands { } } - DataTable table = Database.Backend.GetAllRows("Players", "COUNT(id)"); + DataTable table = Database.Backend.GetRows("Players", "COUNT(id)"); count = int.Parse(table.Rows[0]["COUNT(id)"].ToString()); table.Dispose(); return count; diff --git a/MCGalaxy/Commands/Information/CmdTop.cs b/MCGalaxy/Commands/Information/CmdTop.cs index 52d33866d..f7efa8ab8 100644 --- a/MCGalaxy/Commands/Information/CmdTop.cs +++ b/MCGalaxy/Commands/Information/CmdTop.cs @@ -33,106 +33,119 @@ namespace MCGalaxy.Commands { } public override void Use(Player p, string message) { - string[] args; - if (message == "" || (args = message.Split(' ')).Length < 2) { - Help(p); return; - } + string[] args = message.Split(' '); + if (args.Length < 2) { Help(p); return; } - string strLimit = args[1]; - int limit = 0; - if (!Int32.TryParse(strLimit, out limit)) { - Player.Message(p, "/Top: Invalid limit \"{0}\".", strLimit); - return; - } - if (limit < 1) { - Player.Message(p, "/Top: \"{0}\" is too small a limit, the min is 1.", strLimit); - return; - } else if (limit > 15) { - Player.Message(p, "/Top: \"{0}\" is too big a limit, the max is 15.", strLimit); - return; - } + int limit = ParseLimit(p, args); + int offset = ParseOffset(p, args); + if (limit == -1 || offset == -1) return; - string columnName, title; - string select = "Name", table = "Players"; - string order = "desc"; + string col, title; + string table = "Players", order = "desc"; switch (args[0]) { case "1": - columnName = "TotalLogin"; - title = "&aTop " + strLimit + " number of logins:"; + col = "TotalLogin"; + title = "&aMost logins:"; break; case "2": - columnName = "TotalDeaths"; - title = "&aTop " + strLimit + " number of deaths:"; + col = "TotalDeaths"; + title = "&aMost deaths:"; break; case "3": - columnName = "money"; - title = "&aTop " + strLimit + " amounts of money:"; - select = "player"; table = "Economy"; + col = "money"; + title = "&aMost " + Server.moneys + ":"; break; case "4": - columnName = "firstlogin"; - title = "&aFirst players:"; + col = "firstlogin"; + title = "&aOldest players:"; order = "asc"; break; case "5": - columnName = "lastlogin"; + col = "lastlogin"; title = "&aMost recent players:"; break; case "6": - columnName = "TotalKicked"; - title = "&aTop " + strLimit + " number of kicks:"; + col = "TotalKicked"; + title = "&aMost times kicked:"; break; case "7": - columnName = "totalBlocks & " + PlayerData.LowerBitsMask; - title = "&aTop " + strLimit + " number of blocks modified:"; + col = "totalBlocks & " + PlayerData.LowerBitsMask; + title = "&aMost blocks modified:"; break; case "8": - columnName = "totalCuboided & " + PlayerData.LowerBitsMask; - title = "&aTop " + strLimit + " number of blocks drawn:"; + col = "totalCuboided & " + PlayerData.LowerBitsMask; + title = "&aMost blocks drawn:"; break; case "9": - columnName = "totalBlocks >> " + PlayerData.LowerBits; - title = "&aTop " + strLimit + " number of blocks placed:"; + col = "totalBlocks >> " + PlayerData.LowerBits; + title = "&aMost blocks placed:"; break; case "10": - columnName = "totalCuboided >> " + PlayerData.LowerBits; - title = "&aTop " + strLimit + " number of blocks deleted:"; + col = "totalCuboided >> " + PlayerData.LowerBits; + title = "&aMost blocks deleted:"; break; case "11": - columnName = "TotalInfected"; - title = "&aTop total infections:"; + col = "TotalInfected"; + title = "&aMost players infected:"; table = "ZombieStats"; break; case "12": - columnName = "TotalRounds"; - title = "&aTop rounds survived:"; + col = "TotalRounds"; + title = "&aMost rounds survived:"; table = "ZombieStats"; break; case "13": - columnName = "MaxInfected"; - title = "&aTop consecutive infections:"; + col = "MaxInfected"; + title = "&aMost consecutive infections:"; table = "ZombieStats"; break; case "14": - columnName = "MaxRounds"; - title = "&aTop consecutive rounds survived:"; + col = "MaxRounds"; + title = "&aMost consecutive rounds survived:"; table = "ZombieStats"; break; default: Player.Message(p, "/Top: Unrecognised type \"{0}\".", args[0]); return; } - const string query = "SELECT distinct {0}, {1} from {2} order by {3} {4} limit {5}"; - DataTable db = Database.Fill( - string.Format(query, select, columnName.ToLower(), table, - columnName.ToLower(), order, limit)); + string strLimit = " LIMIT " + offset + "," + limit; + DataTable db = Database.Backend.GetRows(table, "DISTINCT Name, " + col, + "ORDER BY " + col + " " + order + strLimit); Player.Message(p, title); for (int i = 0; i < db.Rows.Count; i++) { - Player.Message(p, (i + 1) + ") " + db.Rows[i][select] + " - [" + db.Rows[i][columnName] + "]"); + Player.Message(p, (i + 1) + ") " + db.Rows[i]["Name"] + " - [" + db.Rows[i][col] + "]"); } db.Dispose(); } + static int ParseLimit(Player p, string[] args) { + int limit = 0; + if (!Int32.TryParse(args[1], out limit)) { + Player.Message(p, "&c\"{0}\" is not an integer.", args[1]); return -1; + } + + if (limit < 1) { + Player.Message(p, "&c\"{0}\" is too small, the min limit is 1.", args[1]); return -1; + } + if (limit > 15) { + Player.Message(p, "&c\"{0}\" is too large, the max limit is 15.", args[1]); return -1; + } + return limit; + } + + static int ParseOffset(Player p, string[] args) { + if (args.Length <= 2) return 0; + int offset = 0; + if (!Int32.TryParse(args[2], out offset)) { + Player.Message(p, "&c\"{0}\" is not an integer.", args[2]); return -1; + } + + if (offset < 0) { + Player.Message(p, "&cOffset must be greater than or equal to 0.", args[2]); return -1; + } + return offset; + } + public override void Help(Player p) { - Player.Message(p, "%T/top [stat] [number of players to show]"); + Player.Message(p, "%T/top [stat] [number of players to show] "); Player.Message(p, "%HPrints a list of players who have the " + "most/top of a particular stat. Available stats:"); diff --git a/MCGalaxy/Commands/Moderation/CmdInfoSwap.cs b/MCGalaxy/Commands/Moderation/CmdInfoSwap.cs index 154f485fb..ff16dfd60 100644 --- a/MCGalaxy/Commands/Moderation/CmdInfoSwap.cs +++ b/MCGalaxy/Commands/Moderation/CmdInfoSwap.cs @@ -35,10 +35,10 @@ namespace MCGalaxy.Commands { if (!Formatter.ValidName(p, args[1], "player")) return; if (PlayerInfo.FindExact(args[0]) != null) { - Player.Message(p, "\"{0}\" must be offline to use /infoswap.", args[0]); return; + Player.Message(p, "\"{0}\" must be offline to use /infoswap.", args[0]); return; } if (PlayerInfo.FindExact(args[1]) != null) { - Player.Message(p, "\"{0}\" must be offline to use /infoswap.", args[1]); return; + Player.Message(p, "\"{0}\" must be offline to use /infoswap.", args[1]); return; } PlayerData src = PlayerInfo.FindData(args[0]); @@ -67,15 +67,17 @@ namespace MCGalaxy.Commands { void SetData(PlayerData src, string dstName) { string first = src.FirstLogin.ToString(format); string last = src.LastLogin.ToString(format); - const string syntax = "UPDATE Players SET totalBlocks=@0, totalCuboided=@1" + - ", color=@2, totalDeaths=@3, FirstLogin=@4, IP=@5, totalKicked=@6, LastLogin=@7" + - ", totalLogin=@8, Money=@9, Title=@10, title_color=@11, TimeSpent=@12 WHERE Name=@13"; - long blocks = PlayerData.BlocksPacked(src.TotalPlaced, src.TotalModified); long cuboided = PlayerData.CuboidPacked(src.TotalDeleted, src.TotalDrawn); - Database.Execute(syntax, blocks, cuboided, src.Color, src.Deaths, - first, src.IP, src.Kicks, last, src.Logins, - src.Money, src.Title, src.TitleColor, src.TotalTime, dstName); + + const string columns = "totalBlocks=@0, totalCuboided=@1, color=@2" + + ", totalDeaths=@3, FirstLogin=@4, IP=@5, totalKicked=@6, LastLogin=@7" + + ", totalLogin=@8, Money=@9, Title=@10, title_color=@11, TimeSpent=@12"; + Database.Backend.UpdateRows( + "Players", columns, "WHERE Name=@13", + blocks, cuboided, src.Color, + src.Deaths, first, src.IP, src.Kicks, last, src.Logins, + src.Money, src.Title, src.TitleColor, src.TotalTime, dstName); } void SwapGroups(PlayerData src, PlayerData dst, Group srcGroup, Group dstGroup) { diff --git a/MCGalaxy/Commands/Moderation/CmdPlayerEditDB.cs b/MCGalaxy/Commands/Moderation/CmdPlayerEditDB.cs index 18a8a9f7d..df2851c6d 100644 --- a/MCGalaxy/Commands/Moderation/CmdPlayerEditDB.cs +++ b/MCGalaxy/Commands/Moderation/CmdPlayerEditDB.cs @@ -174,11 +174,7 @@ namespace MCGalaxy.Commands { } static void UpdateDB(string name, string value, string column) { - if (value != "") { - Database.Execute("UPDATE Players SET " + column + "=@1 WHERE Name=@0", name, value); - } else { - Database.Execute("UPDATE Players SET " + column + "='' WHERE Name=@0", name); - } + Database.Backend.UpdateRows("Players", column + " = @1", "WHERE Name = @0", name, value); } static void MessageDataChanged(Player p, string name, string type, string value) { diff --git a/MCGalaxy/Commands/World/CmdMap.cs b/MCGalaxy/Commands/World/CmdMap.cs index d043588ac..60add7ff6 100644 --- a/MCGalaxy/Commands/World/CmdMap.cs +++ b/MCGalaxy/Commands/World/CmdMap.cs @@ -62,10 +62,8 @@ namespace MCGalaxy.Commands.World { } static bool IsMapOption(string[] args) { - string opt = args[0].ToLower(); - const string opts = "theme|finite|ai|edge|grass|ps|physicspeed|overload|motd|death|killer|fall|drown|unload" - + "|realmowner|chat|load|loadongoto|leaf|leafdecay|flow|randomflow|tree|growtrees|buildable|deletable"; - if (!opts.Contains(opt)) return false; + string opt = LevelOptions.Map(args[0].ToLower()); + if (!LevelOptions.Options.ContainsKey(opt)) return false; // In rare case someone uses /map motd motd My MOTD if (opt == "motd" && (args.Length == 1 || !args[1].CaselessStarts("motd "))) return true; diff --git a/MCGalaxy/Commands/building/CmdMessageBlock.cs b/MCGalaxy/Commands/building/CmdMessageBlock.cs index 656a7051f..0cce95c33 100644 --- a/MCGalaxy/Commands/building/CmdMessageBlock.cs +++ b/MCGalaxy/Commands/building/CmdMessageBlock.cs @@ -133,7 +133,7 @@ namespace MCGalaxy.Commands.Building { void ShowMessageBlocks(Player p) { p.showMBs = !p.showMBs; - using (DataTable table = Database.Backend.GetAllRows("Messages" + p.level.name, "*")) { + using (DataTable table = Database.Backend.GetRows("Messages" + p.level.name, "*")) { if (p.showMBs) { ShowMessageBlocks(p, table); } else { diff --git a/MCGalaxy/Commands/building/CmdPortal.cs b/MCGalaxy/Commands/building/CmdPortal.cs index fb6fa5d42..88acad6ee 100644 --- a/MCGalaxy/Commands/building/CmdPortal.cs +++ b/MCGalaxy/Commands/building/CmdPortal.cs @@ -123,7 +123,7 @@ namespace MCGalaxy.Commands.Building { void ShowPortals(Player p) { p.showPortals = !p.showPortals; - using (DataTable table = Database.Backend.GetAllRows("Portals" + p.level.name, "*")) { + using (DataTable table = Database.Backend.GetRows("Portals" + p.level.name, "*")) { if (p.showPortals) { ShowPortals(p, table); } else { diff --git a/MCGalaxy/Database/IDatabaseBackend.cs b/MCGalaxy/Database/IDatabaseBackend.cs index 9d123a95e..64e2f4c61 100644 --- a/MCGalaxy/Database/IDatabaseBackend.cs +++ b/MCGalaxy/Database/IDatabaseBackend.cs @@ -34,7 +34,7 @@ namespace MCGalaxy.SQL { public abstract BulkTransaction CreateBulk(); /// Returns a new ParameterisedQuery instance, which executes sql statements - /// and manages binding of parameteries for sql queries. + /// and manages binding of parameters for sql queries. public abstract ParameterisedQuery CreateParameterised(); /// Returns the shared static ParamterisedQuery instance, that is only used @@ -56,7 +56,14 @@ namespace MCGalaxy.SQL { /// Adds a new coloumn to the given table. /// Note colAfter is only a hint - some database backends ignore this. public abstract void AddColumn(string table, string column, - string colype, string colAfter); + string colType, string colAfter); + + /// Completely removes the given table from the database. + public virtual void DeleteTable(string table) { + string syntax = "DROP TABLE `" + table + "`"; + Database.Execute(syntax); + } + /// Inserts/Copies all the rows from the source table into the destination table. /// Note: This may work incorrectly if the tables have different schema. @@ -65,25 +72,23 @@ namespace MCGalaxy.SQL { Database.Execute(syntax); } - /// Completely removes the given table from the database. - public virtual void DeleteTable(string table) { - string syntax = "DROP TABLE `" + table + "`"; - Database.Execute(syntax); - } - - /// Retrieves all rows for the given table from the database. - public virtual DataTable GetAllRows(string table, string columns) { - string syntax = "SELECT " + columns + " FROM `" + table + "`"; - return Database.Fill(syntax); - } - /// Retrieves rows for the given table from the database. - /// modifier is SQL which can be used to retrieve only certain rows, + /// modifier is optional SQL which can be used to retrieve only certain rows, /// return rows in a certain order, etc. public virtual DataTable GetRows(string table, string columns, - string modifier, params object[] args) { - string syntax = "SELECT " + columns + " FROM `" + table + "` " + modifier; + string modifier = "", params object[] args) { + string syntax = "SELECT " + columns + " FROM `" + table + "`"; + if (modifier != "") syntax += " " + modifier; return Database.Fill(syntax, args); } + + /// Updates rows for the given table from the database. + /// modifier is optional SQL which can be used to update only certain rows. + public virtual void UpdateRows(string table, string columns, + string modifier = "", params object[] args) { + string syntax = "UPDATE `" + table + "` SET " + columns; + if (modifier != "") syntax += " " + modifier; + Database.Execute(syntax, args); + } } } diff --git a/MCGalaxy/Economy/Economy.cs b/MCGalaxy/Economy/Economy.cs index d9b94a9e0..fa4dfbe26 100644 --- a/MCGalaxy/Economy/Economy.cs +++ b/MCGalaxy/Economy/Economy.cs @@ -59,7 +59,7 @@ PRIMARY KEY(player) public static void LoadDatabase() { Database.Execute(createTable); - using (DataTable eco = Database.Backend.GetAllRows("Economy", "*")) + using (DataTable eco = Database.Backend.GetRows("Economy", "*")) foreach (DataRow row in eco.Rows) { int money = PlayerData.ParseInt(row["money"].ToString()); @@ -159,7 +159,8 @@ PRIMARY KEY(player) } public static void UpdateMoney(string name, int money) { - Database.Execute("UPDATE Players SET Money=@0 WHERE Name=@1", money, name); + Database.Backend.UpdateRows("Players", "Money = @1", + "WHERE Name = @0", name, money); } public static List Items = new List() { new ColorItem(), new TitleColorItem(), diff --git a/MCGalaxy/Games/CTF/Auto_CTF.cs b/MCGalaxy/Games/CTF/Auto_CTF.cs index 340e2b278..93496987f 100644 --- a/MCGalaxy/Games/CTF/Auto_CTF.cs +++ b/MCGalaxy/Games/CTF/Auto_CTF.cs @@ -427,8 +427,8 @@ tags MEDIUMINT UNSIGNED{1});"; //MYSQL! cache.ForEach(delegate(Data d) { d.hasflag = false; - Database.Execute("UPDATE CTF SET Points=@1, Captures=@2, tags=@3 WHERE Name=@0", - d.p.name, d.points, d.cap, d.tag); + Database.Backend.UpdateRows("CTF", "Points=@1, Captures=@2, tags=@3", + "WHERE Name = @0", d.p.name, d.points, d.cap, d.tag); }); nextmap = Vote(); Chat.MessageLevel(mainlevel, "Starting a new game!"); diff --git a/MCGalaxy/Generator/SimpleGen.cs b/MCGalaxy/Generator/SimpleGen.cs index 703af8b47..2f1a6d266 100644 --- a/MCGalaxy/Generator/SimpleGen.cs +++ b/MCGalaxy/Generator/SimpleGen.cs @@ -51,77 +51,60 @@ namespace MCGalaxy.Generator { } return true; } - - unsafe static void MapSet(int width, int length, byte* ptr, int yStart, int yEnd, byte block) { - int start = yStart * length * width; - int end = (yEnd * length + (length - 1)) * width + (width - 1); - Utils.memset((IntPtr)ptr, block, start, end - start + 1); + + static bool GenEmpty(MapGenArgs args) { + int maxX = args.Level.Width - 1, maxZ = args.Level.Length - 1; + Cuboid(args, 0, 0, 0, maxX, 0, maxZ, () => Block.blackrock); + return true; } static bool GenPixel(MapGenArgs args) { - int width = args.Level.Width, height = args.Level.Height, length = args.Level.Length; - int index = 0; - byte[] blocks = args.Level.blocks; + int maxX = args.Level.Width - 1, maxY = args.Level.Height - 1, maxZ = args.Level.Length - 1; + Func block = () => Block.white; - for (int y = 0; y < height; ++y) - for (int z = 0; z < length; ++z) - for (int x = 0; x < width; ++x) - { - if (y == 0) - blocks[index] = Block.blackrock; - else if (x == 0 || x == width - 1 || z == 0 || z == length - 1) - blocks[index] = Block.white; - index++; - } - return true; - } - - static bool GenEmpty(MapGenArgs args) { - int width = args.Level.Width, length = args.Level.Length; - int index = 0; - byte[] blocks = args.Level.blocks; + // Cuboid the four walls + Cuboid(args, 0, 1, 0, maxX, maxY, 0, block); + Cuboid(args, 0, 1, maxZ, maxX, maxY, maxZ, block); + Cuboid(args, 0, 1, 0, 0, maxY, maxZ, block); + Cuboid(args, maxX, 1, 0, maxX, maxY, maxZ, block); - for (int z = 0; z < length; ++z) - for (int x = 0; x < width; ++x) - { - blocks[index++] = Block.blackrock; - } + // Cuboid base + Cuboid(args, 0, 0, 0, maxX, 0, maxZ, () => Block.blackrock); return true; } static bool GenSpace(MapGenArgs args) { + int maxX = args.Level.Width - 1, maxY = args.Level.Height - 1, maxZ = args.Level.Length - 1; Random rand = args.UseSeed ? new Random(args.Seed) : new Random(); - int width = args.Level.Width, height = args.Level.Height, length = args.Level.Length; - int index = 0; - byte[] blocks = args.Level.blocks; + Func block = () => rand.Next(100) == 0 ? Block.iron : Block.obsidian; + + // Cuboid the four walls + Cuboid(args, 0, 2, 0, maxX, maxY, 0, block); + Cuboid(args, 0, 2, maxZ, maxX, maxY, maxZ, block); + Cuboid(args, 0, 2, 0, 0, maxY, maxZ, block); + Cuboid(args, maxX, 2, 0, maxX, maxY, maxZ, block); - for (int y = 0; y < height; ++y) - for (int z = 0; z < length; ++z) - for (int x = 0; x < width; ++x) - { - if (y == 0) - blocks[index] = Block.blackrock; - else if (x == 0 || x == width - 1 || z == 0 || z == length - 1 || y == 1 || y == height - 1) - blocks[index] = rand.Next(100) == 0 ? Block.iron : Block.obsidian; - index++; - } + // Cuboid base and top + Cuboid(args, 0, 0, 0, maxX, 0, maxZ, () => Block.blackrock); + Cuboid(args, 0, 1, 0, maxX, 1, maxZ, block); + Cuboid(args, 0, maxY, 0, maxX, maxY, maxZ, block); return true; } static bool GenRainbow(MapGenArgs args) { + int maxX = args.Level.Width - 1, maxY = args.Level.Height - 1, maxZ = args.Level.Length - 1; Random rand = args.UseSeed ? new Random(args.Seed) : new Random(); - int width = args.Level.Width, height = args.Level.Height, length = args.Level.Length; - int index = 0; - byte[] blocks = args.Level.blocks; + Func block = () => (byte)rand.Next(Block.red, Block.white); + + // Cuboid the four walls + Cuboid(args, 0, 1, 0, maxX, maxY, 0, block); + Cuboid(args, 0, 1, maxZ, maxX, maxY, maxZ, block); + Cuboid(args, 0, 1, 0, 0, maxY, maxZ, block); + Cuboid(args, maxX, 1, 0, maxX, maxY, maxZ, block); - for (int y = 0; y < height; ++y) - for (int z = 0; z < length; ++z) - for (int x = 0; x < width; ++x) - { - if (y == 0 || y == height - 1 || x == 0 || x == width - 1 || z == 0 || z == length - 1) - blocks[index] = (byte)rand.Next(Block.red, Block.white); - index++; - } + // Cuboid base and top + Cuboid(args, 0, 0, 0, maxX, 0, maxZ, block); + Cuboid(args, 0, maxY, 0, maxX, maxY, maxZ, block); return true; } @@ -153,8 +136,29 @@ namespace MCGalaxy.Generator { return GenSimple(args); } + static bool GenSimple(MapGenArgs args) { return new RealisticMapGen().GenerateMap(args); } + + unsafe static void MapSet(int width, int length, byte* ptr, + int yStart, int yEnd, byte block) { + int start = (yStart * length) * width; + int end = (yEnd * length + (length - 1)) * width + (width - 1); + Utils.memset((IntPtr)ptr, block, start, end - start + 1); + } + + static void Cuboid(MapGenArgs args, int minX, int minY, int minZ, + int maxX, int maxY, int maxZ, Func block) { + int width = args.Level.Width, height = args.Level.Height, length = args.Level.Length; + byte[] blocks = args.Level.blocks; + + for (int y = minY; y <= maxY; y++) + for (int z = minZ; z <= maxZ; z++) + for (int x = minX; x <= maxX; x++) + { + blocks[x + width * (z + y * length)] = block(); + } + } } } diff --git a/MCGalaxy/Levels/BlockDefinitions.cs b/MCGalaxy/Levels/BlockDefinitions.cs index f879f4cbf..ad20fb2fc 100644 --- a/MCGalaxy/Levels/BlockDefinitions.cs +++ b/MCGalaxy/Levels/BlockDefinitions.cs @@ -187,12 +187,13 @@ namespace MCGalaxy { for (int i = 1; i < defs.Length; i++) { BlockDefinition def = defs[i]; if (def == null) continue; - if (pl.HasCpeExt(CpeExt.BlockDefinitionsExt, 2) && def.Shape != 0) + if (pl.HasCpeExt(CpeExt.BlockDefinitionsExt, 2) && def.Shape != 0) { SendDefineBlockExt(pl, def, true); - else if (pl.HasCpeExt(CpeExt.BlockDefinitionsExt) && def.Shape != 0) + } else if (pl.HasCpeExt(CpeExt.BlockDefinitionsExt) && def.Shape != 0) { SendDefineBlockExt(pl, def, false); - else + } else { SendDefineBlock(pl, def); + } if (pl.HasCpeExt(CpeExt.BlockPermissions)) pl.SendSetBlockPermission(def.BlockID, pl.level.CanPlace, pl.level.CanDelete); diff --git a/MCGalaxy/Levels/LevelActions.cs b/MCGalaxy/Levels/LevelActions.cs index 7173f76ab..67ad07269 100644 --- a/MCGalaxy/Levels/LevelActions.cs +++ b/MCGalaxy/Levels/LevelActions.cs @@ -71,8 +71,8 @@ namespace MCGalaxy { { if (Database.TableExists("Portals" + src)) { Database.Backend.RenameTable("Portals" + src, "Portals" + dst); - string updateSyntax = "UPDATE `Portals" + dst + "` SET ExitMap=@1 WHERE ExitMap=@0"; - Database.Execute(updateSyntax, src, dst); + Database.Backend.UpdateRows("Portals" + dst, "ExitMap = @1", + "WHERE ExitMap = @0", src, dst); } if (Database.TableExists("Messages" + src)) { @@ -209,8 +209,8 @@ namespace MCGalaxy { if (Database.TableExists("Portals" + src)) { Database.Execute(String.Format(LevelDB.createPortals, dst)); Database.Backend.CopyAllRows("Portals" + src, "Portals" + dst); - string updateSyntax = "UPDATE `Portals" + dst + "` SET ExitMap=@1 WHERE ExitMap=@0"; - Database.Execute(updateSyntax, src, dst); + Database.Backend.UpdateRows("Portals" + dst, "ExitMap = @1", + "WHERE ExitMap = @0", src, dst); } if (Database.TableExists("Messages" + src)) { diff --git a/MCGalaxy/Levels/LevelDB.cs b/MCGalaxy/Levels/LevelDB.cs index 2d3c7f166..5e2eadd0d 100644 --- a/MCGalaxy/Levels/LevelDB.cs +++ b/MCGalaxy/Levels/LevelDB.cs @@ -94,7 +94,7 @@ namespace MCGalaxy { internal static void LoadZones(Level level, string name) { if (!Database.TableExists("Zone" + name)) return; - using (DataTable table = Database.Backend.GetAllRows("Zone" + name, "*")) { + using (DataTable table = Database.Backend.GetRows("Zone" + name, "*")) { Level.Zone Zn; foreach (DataRow row in table.Rows) { Zn.smallX = ushort.Parse(row["SmallX"].ToString()); @@ -111,7 +111,7 @@ namespace MCGalaxy { internal static void LoadPortals(Level level, string name) { if (!Database.TableExists("Portals" + name)) return; - using (DataTable table = Database.Backend.GetAllRows("Portals" + name, "*")) { + using (DataTable table = Database.Backend.GetRows("Portals" + name, "*")) { foreach (DataRow row in table.Rows) { byte tile = level.GetTile(ushort.Parse(row["EntryX"].ToString()), ushort.Parse(row["EntryY"].ToString()), @@ -126,7 +126,7 @@ namespace MCGalaxy { internal static void LoadMessages(Level level, string name) { if (!Database.TableExists("Messages" + name)) return; - using (DataTable table = Database.Backend.GetAllRows("Messages" + name, "*")) { + using (DataTable table = Database.Backend.GetRows("Messages" + name, "*")) { foreach (DataRow row in table.Rows) { byte tile = level.GetTile(ushort.Parse(row["X"].ToString()), ushort.Parse(row["Y"].ToString()), diff --git a/MCGalaxy/Levels/LevelOptions.cs b/MCGalaxy/Levels/LevelOptions.cs new file mode 100644 index 000000000..b4096487a --- /dev/null +++ b/MCGalaxy/Levels/LevelOptions.cs @@ -0,0 +1,135 @@ +/* + Copyright 2015 MCGalaxy team + + 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; + +namespace MCGalaxy { + + public static class LevelOptions { + + public delegate void OptionSetter(Player p, Level lvl, string value); + + public static Dictionary Options = + new Dictionary() { + { "theme", SetTheme }, + { "motd", SetMotd }, + { "realmowner", SetRealmOwner }, + { "physicsspeed", (p, l, value) => SetPhysicsSpeed(p, l, value, "Physics speed") }, + { "overload", (p, l, value) => SetPhysicsOverload(p, l, value, "Physics overload") }, + { "fall", (p, l, value) => SetInt(p, l, ref l.fall, value, "Fall distance") }, + { "drown", (p, l, value) => SetInt(p, l, ref l.drown, value, "Drown time (in tenths of a second)") }, + { "finite", (p, l, value) => Set(p, l, ref l.finite, "Finite mode") }, + { "ai", (p, l, value) => Set(p, l, ref l.ai, "Animal AI") }, + { "edge", (p, l, value) => Set(p, l, ref l.edgeWater, "Edge water") }, + { "grass", (p, l, value) => Set(p, l, ref l.GrassGrow, "Growing grass") }, + { "death", (p, l, value) => Set(p, l, ref l.Death, "Survival death") }, + { "killer", (p, l, value) => Set(p, l, ref l.Killer, "Killer blocks") }, + { "unload", (p, l, value) => Set(p, l, ref l.unload, "Auto unload") }, + { "loadongoto", (p, l, value) => Set(p, l, ref l.loadOnGoto, "Load on goto") }, + { "leafdecay", (p, l, value) => Set(p, l, ref l.leafDecay, "Leaf decay") }, + { "randomflow", (p, l, value) => Set(p, l, ref l.randomFlow, "Random flow") }, + { "growtrees", (p, l, value) => Set(p, l, ref l.growTrees, "Tree growing") }, + { "chat", (p, l, value) => Set(p, l, ref l.worldChat, "Roleplay (level only) chat: ", true) }, + { "buildable", (p, l, value) => SetPerms(p, l, ref l.Buildable, "Buildable") }, + { "deletable", (p, l, value) => SetPerms(p, l, ref l.Deletable, "Deletable") }, + }; + + + public static string Map(string opt) { + if (opt == "ps") return "physicsspeed"; + if (opt == "load") return "loadongoto"; + if (opt == "leaf") return "leafdecay"; + if (opt == "flow") return "randomflow"; + if (opt == "tree") return "growtrees"; + return opt; + } + + static string GetBool(bool value) { return value ? "&aON" : "&cOFF"; } + + static void SetPhysicsSpeed(Player p, Level lvl, string value, string name) { + SetInt(p, lvl, ref lvl.speedPhysics, value, name, PhysicsSpeedValidator); + } + + static bool PhysicsSpeedValidator(Player p, int raw) { + if (raw < 10) { Player.Message(p, "Physics speed cannot be below 10 milliseconds."); return false; } + return true; + } + + static void SetPhysicsOverload(Player p, Level lvl, string value, string name) { + SetInt(p, lvl, ref lvl.overload, value, name, PhysicsOverloadValidator); + } + + static bool PhysicsOverloadValidator(Player p, int raw) { + if (raw < 500) { + Player.Message(p, "Physics overload cannot go below 500 (default is 1500)"); return false; + } + if (p != null && p.Rank < LevelPermission.Admin && raw > 2500) { + Player.Message(p, "Only SuperOPs may set physics overload higher than 2500"); return false; + } + return true; + } + + + static void SetTheme(Player p, Level lvl, string value) { + lvl.theme = value; + lvl.ChatLevel("Map theme: &b" + lvl.theme); + } + + static void SetMotd(Player p, Level lvl, string value) { + lvl.motd = value == "" ? "ignore" : value; + lvl.ChatLevel("Map's MOTD was changed to: &b" + lvl.motd); + + Player[] players = PlayerInfo.Online.Items; + foreach (Player pl in players) { + if (pl.level != lvl || !pl.HasCpeExt(CpeExt.HackControl)) continue; + pl.Send(Hacks.MakeHackControl(pl)); + } + } + + static void SetRealmOwner(Player p, Level lvl, string value) { + lvl.RealmOwner = value; + if (value == "") Player.Message(p, "Removed realm owner for this level."); + else Player.Message(p, "Set realm owner/owners of this level to {0}.", value); + } + + static void SetPerms(Player p, Level lvl, ref bool target, string name) { + Set(p, lvl, ref target, name); + lvl.UpdateBlockPermissions(); + } + + static void Set(Player p, Level lvl, ref bool target, string name, bool not = false) { + target = !target; + bool display = not ? !target : target; + lvl.ChatLevel(name + ": " + GetBool(display)); + + if (p == null || p.level != lvl) + Player.Message(p, name + ": " + GetBool(display)); + } + + static void SetInt(Player p, Level lvl, ref int target, string value, string name, + Func validator = null) { + if (value == "") { Player.Message(p, "You must provide an integer."); return; } + int raw; + if (!int.TryParse(value, out raw)) { Player.Message(p, "\"{0}\" is not a valid integer.", value); return; } + + if (validator != null && !validator(p, raw)) return; + target = raw; + lvl.ChatLevel(name + ": &b" + target); + } + } +} diff --git a/MCGalaxy/MCGalaxy_.csproj b/MCGalaxy/MCGalaxy_.csproj index 11543711f..8df0f7684 100644 --- a/MCGalaxy/MCGalaxy_.csproj +++ b/MCGalaxy/MCGalaxy_.csproj @@ -516,6 +516,7 @@ + diff --git a/MCGalaxy/Network/Player.Networking.cs b/MCGalaxy/Network/Player.Networking.cs index 992c3fe0a..9606aa041 100644 --- a/MCGalaxy/Network/Player.Networking.cs +++ b/MCGalaxy/Network/Player.Networking.cs @@ -381,7 +381,7 @@ namespace MCGalaxy { void RemoveOldLevelCustomBlocks(Level oldLevel) { BlockDefinition[] defs = oldLevel.CustomBlockDefs; - for (int i = Block.CpeCount; i < 256; i++) { + for (int i = 1; i < 256; i++) { BlockDefinition def = defs[i]; if (def == null || def == BlockDefinition.GlobalDefs[i]) continue; SendRaw(Opcode.CpeRemoveBlockDefinition, (byte)i); diff --git a/MCGalaxy/Player/Player.Timers.cs b/MCGalaxy/Player/Player.Timers.cs index 60b23a4c2..ab34c7650 100644 --- a/MCGalaxy/Player/Player.Timers.cs +++ b/MCGalaxy/Player/Player.Timers.cs @@ -57,7 +57,7 @@ namespace MCGalaxy { try { if (group.commands.Contains("inbox") && Database.TableExists("Inbox" + name) ) { //safe against SQL injections because no user input is given here - using (DataTable table = Database.Backend.GetAllRows("Inbox" + name, "*")) { + using (DataTable table = Database.Backend.GetRows("Inbox" + name, "*")) { if (table.Rows.Count > 0) SendMessage("You have &a" + table.Rows.Count + " %Smessages in /inbox"); } diff --git a/MCGalaxy/Server/BackupDB.cs b/MCGalaxy/Server/BackupDB.cs index babc0384c..c3471ea8d 100644 --- a/MCGalaxy/Server/BackupDB.cs +++ b/MCGalaxy/Server/BackupDB.cs @@ -56,7 +56,7 @@ namespace MCGalaxy { sql.WriteLine(); WriteTableSchema(tableName, sql); - using (DataTable data = Database.Backend.GetAllRows(tableName, "*")) { + using (DataTable data = Database.Backend.GetRows(tableName, "*")) { if (data.Rows.Count == 0) { sql.WriteLine("-- No data in table `{0}`!", tableName); sql.WriteLine();