diff --git a/GUI/Window/Window.Main.cs b/GUI/Window/Window.Main.cs index ef48295cd..39ef132f8 100644 --- a/GUI/Window/Window.Main.cs +++ b/GUI/Window/Window.Main.cs @@ -189,53 +189,43 @@ namespace MCGalaxy.Gui { void Main_UpdateMapList() { Level[] loaded = LevelInfo.Loaded.Items; + string selected = GetSelected(main_Maps); - // Try to keep the same selection on update - string selected = null; - var selectedRows = main_Maps.SelectedRows; - if (selectedRows.Count > 0) { - selected = (string)selectedRows[0].Cells[0].Value; - } - - // Update the data source and control - lc = new LevelCollection(); + // Always new data source, avoids "-1 does not have a value" when clicking a row + LevelCollection lc = new LevelCollection(); foreach (Level lvl in loaded) { lc.Add(lvl); } main_Maps.DataSource = lc; - // Reselect map - if (selected != null) { - foreach (DataGridViewRow row in main_Maps.Rows) { - string name = (string)row.Cells[0].Value; - if (name.CaselessEq(selected)) row.Selected = true; - } - } + Reselect(main_Maps, selected); main_Maps.Refresh(); } void Main_UpdatePlayersList() { UpdateNotifyIconText(); Player[] players = PlayerInfo.Online.Items; + string selected = GetSelected(main_Players); - // Try to keep the same selection on update - string selected = null; - var selectedRows = main_Players.SelectedRows; - if (selectedRows.Count > 0) { - selected = (string)selectedRows[0].Cells[0].Value; - } - - // Update the data source and control - pc = new PlayerCollection(); + PlayerCollection pc = new PlayerCollection(); foreach (Player pl in players) { pc.Add(pl); } main_Players.DataSource = pc; - // Reselect player - if (selected != null) { - foreach (DataGridViewRow row in main_Players.Rows) { - string name = (string)row.Cells[0].Value; - if (name.CaselessEq(selected)) row.Selected = true; - } - } + Reselect(main_Players, selected); main_Players.Refresh(); } + + static string GetSelected(DataGridView view) { + DataGridViewSelectedRowCollection selected = view.SelectedRows; + if (selected.Count == 0) return null; + return (string)selected[0].Cells[0].Value; + } + + static void Reselect(DataGridView view, string selected) { + if (selected == null) return; + + foreach (DataGridViewRow row in view.Rows) { + string name = (string)row.Cells[0].Value; + if (name.CaselessEq(selected)) row.Selected = true; + } + } } } diff --git a/GUI/Window/Window.cs b/GUI/Window/Window.cs index 75ac9260f..2c4c0b0bb 100644 --- a/GUI/Window/Window.cs +++ b/GUI/Window/Window.cs @@ -34,8 +34,6 @@ namespace MCGalaxy.Gui { delegate void VoidDelegate(); bool mapgen = false; - PlayerCollection pc; - LevelCollection lc; public NotifyIcon notifyIcon = new NotifyIcon(); Player curPlayer; @@ -59,11 +57,9 @@ namespace MCGalaxy.Gui { Text = ServerConfig.Name + " - " + Server.SoftwareNameVersioned; MakeNotifyIcon(); - // Bind player list - main_Players.DataSource = pc; - main_Players.Font = new Font("Calibri", 8.25f); - - main_Maps.DataSource = new LevelCollection(); // Otherwise "-1 does not have a value" exception when clicking a row + main_Players.DataSource = new PlayerCollection(); + main_Players.Font = new Font("Calibri", 8.25f); + main_Maps.DataSource = new LevelCollection(); main_Maps.Font = new Font("Calibri", 8.25f); } diff --git a/MCGalaxy/Commands/Fun/CmdTeam.cs b/MCGalaxy/Commands/Fun/CmdTeam.cs index 7c9414e5e..15999bd11 100644 --- a/MCGalaxy/Commands/Fun/CmdTeam.cs +++ b/MCGalaxy/Commands/Fun/CmdTeam.cs @@ -87,7 +87,7 @@ namespace MCGalaxy.Commands.Fun { who.SetPrefix(); } - team.RemoveIfEmpty(); + team.DeleteIfEmpty(); Team.SaveList(); } else { Player.Message(p, "The given player was not found. You need to use their full account name."); @@ -182,7 +182,7 @@ namespace MCGalaxy.Commands.Fun { team.Remove(p.name); p.Game.Team = null; - team.RemoveIfEmpty(); + team.DeleteIfEmpty(); p.SetPrefix(); Team.SaveList(); } diff --git a/MCGalaxy/Commands/Maintenance/CmdPlayerEdit.cs b/MCGalaxy/Commands/Maintenance/CmdPlayerEdit.cs index 6dc25c6dc..abb3deebf 100644 --- a/MCGalaxy/Commands/Maintenance/CmdPlayerEdit.cs +++ b/MCGalaxy/Commands/Maintenance/CmdPlayerEdit.cs @@ -40,7 +40,7 @@ namespace MCGalaxy.Commands.Maintenance { if (args[0] == null) return; Player who = PlayerInfo.FindExact(args[0]); if (args.Length == 1) { - Player.Message(p, Colors.red + "You must specify a type to modify."); + Player.Message(p, "&cYou must specify a type to modify."); MessageValidTypes(p); return; } @@ -98,7 +98,7 @@ namespace MCGalaxy.Commands.Maintenance { } else if (opt == "titlecolor") { SetColor(p, args, PlayerData.ColumnTColor, who, v => who.titlecolor = v); } else { - Player.Message(p, Colors.red + "Invalid type."); + Player.Message(p, "&cInvalid type"); MessageValidTypes(p); } } diff --git a/MCGalaxy/Commands/Moderation/CmdLocation.cs b/MCGalaxy/Commands/Moderation/CmdLocation.cs index bf7a45473..f0d1684e6 100644 --- a/MCGalaxy/Commands/Moderation/CmdLocation.cs +++ b/MCGalaxy/Commands/Moderation/CmdLocation.cs @@ -45,7 +45,7 @@ namespace MCGalaxy.Commands.Moderation { } if (HttpUtil.IsPrivateIP(ip)) { - Player.Message(p, Colors.red + "Player has an internal IP, cannot trace"); return; + Player.Message(p, "&cPlayer has an internal IP, cannot trace"); return; } string country = null; diff --git a/MCGalaxy/Commands/other/CmdHackRank.cs b/MCGalaxy/Commands/other/CmdHackRank.cs index a24ad5a49..476dfa16b 100644 --- a/MCGalaxy/Commands/other/CmdHackRank.cs +++ b/MCGalaxy/Commands/other/CmdHackRank.cs @@ -32,7 +32,7 @@ namespace MCGalaxy.Commands.Misc { if (message.Length == 0) { Help(p); return; } if (p.hackrank) { - Player.Message(p, Colors.red + "You have already hacked a rank!"); return; + Player.Message(p, "&cYou have already hacked a rank!"); return; } Group grp = Matcher.FindRanks(p, message); diff --git a/MCGalaxy/Database/BlockDB/BlockDBChange.cs b/MCGalaxy/Database/BlockDB/BlockDBChange.cs index 043aa5e47..d077670c7 100644 --- a/MCGalaxy/Database/BlockDB/BlockDBChange.cs +++ b/MCGalaxy/Database/BlockDB/BlockDBChange.cs @@ -48,7 +48,7 @@ namespace MCGalaxy.DB { if (!p.level.Props[block].IsMessageBlock) return; try { - if (!Database.Backend.TableExists("Messages" + p.level.name)) return; + if (!Database.TableExists("Messages" + p.level.name)) return; DataTable messages = Database.Backend.GetRows("Messages" + p.level.name, "*", "WHERE X=@0 AND Y=@1 AND Z=@2", x, y, z); int last = messages.Rows.Count - 1; @@ -65,7 +65,7 @@ namespace MCGalaxy.DB { if (!p.level.Props[block].IsPortal) return; try { - if (!Database.Backend.TableExists("Portals" + p.level.name)) return; + if (!Database.TableExists("Portals" + p.level.name)) return; DataTable portals = Database.Backend.GetRows("Portals" + p.level.name, "*", "WHERE EntryX=@0 AND EntryY=@1 AND EntryZ=@2", x, y, z); int last = portals.Rows.Count - 1; diff --git a/MCGalaxy/Database/Database.cs b/MCGalaxy/Database/Database.cs index 391eac0b3..7445be662 100644 --- a/MCGalaxy/Database/Database.cs +++ b/MCGalaxy/Database/Database.cs @@ -25,9 +25,7 @@ namespace MCGalaxy.SQL { public static IDatabaseBackend Backend; /// Returns whether the given table exists in the database. - public static bool TableExists(string table) { - return Backend.TableExists(table); - } + public static bool TableExists(string table) { return Backend.TableExists(table); } /// Executes an SQL command that does not return any results. @@ -74,7 +72,7 @@ namespace MCGalaxy.SQL { static void DoDatabaseCall(ParameterisedQuery query, string sql, bool createDB, DataTable results, ReaderCallback callback, params object[] args) { - BindParams(query, args); + query.parameters = args; string connString = Backend.ConnectionString; Exception e = null; @@ -88,38 +86,27 @@ namespace MCGalaxy.SQL { query.Fill(sql, connString, results); } - query.ClearParams(); + query.parameters = null; return; } catch (Exception ex) { e = ex; // try yet again } } + query.parameters = null; File.AppendAllText("MySQL_error.log", DateTime.Now + " " + sql + "\r\n"); Logger.LogError(e); } - static readonly object idsLock = new object(); - static string[] ids = null; - static void BindParams(ParameterisedQuery query, object[] args) { - if (args == null || args.Length == 0) return; - string[] names = GetParamNames(args.Length); - for (int i = 0; i < args.Length; i++) - query.AddParam(names[i], args[i]); - } - + volatile static string[] ids; internal static string[] GetParamNames(int count) { // Avoid allocation overhead from string concat every query by caching - string[] names = null; - lock (idsLock) { - names = ids; - if (ids == null || count > ids.Length) { - ids = new string[count]; - for (int i = 0; i < count; i++) - ids[i] = "@" + i; - names = ids; - } + string[] names = ids; + if (names == null || count > names.Length) { + names = new string[count]; + for (int i = 0; i < names.Length; i++) { names[i] = "@" + i; } + ids = names; } return names; } diff --git a/MCGalaxy/Database/ParameterisedQuery.cs b/MCGalaxy/Database/ParameterisedQuery.cs index 5b4a271e5..41167be68 100644 --- a/MCGalaxy/Database/ParameterisedQuery.cs +++ b/MCGalaxy/Database/ParameterisedQuery.cs @@ -28,23 +28,12 @@ namespace MCGalaxy.SQL { /// Represents an SQL command or query, that takes named parameters/arguments. public abstract class ParameterisedQuery { - protected Dictionary parameters = new Dictionary(); - - /// Adds a named parameter/argument to this query. - public void AddParam(string name, object param) { parameters.Add(name, param); } - - /// Clears the cached named parameters/arguments. - public void ClearParams() { parameters.Clear(); } - - + internal object[] parameters; protected abstract bool MultipleSchema { get; } - protected abstract IDbConnection CreateConnection(string connString); - - protected abstract IDbCommand CreateCommand(string query, IDbConnection conn); - - protected abstract DbDataAdapter CreateDataAdapter(string query, IDbConnection conn); - + protected abstract IDbConnection CreateConnection(string connString); + protected abstract IDbCommand CreateCommand(string query, IDbConnection conn); + protected abstract DbDataAdapter CreateDataAdapter(string query, IDbConnection conn); protected abstract IDbDataParameter CreateParameter(); @@ -97,12 +86,16 @@ namespace MCGalaxy.SQL { } void FillParams(IDbCommand cmd) { - foreach (var param in parameters) { - IDbDataParameter dParam = CreateParameter(); - dParam.ParameterName = param.Key; - dParam.Value = param.Value; - cmd.Parameters.Add(dParam); + object[] args = parameters; + if (args == null || args.Length == 0) return; + + string[] names = Database.GetParamNames(args.Length); + for (int i = 0; i < args.Length; i++) { + IDbDataParameter dbParam = CreateParameter(); + dbParam.ParameterName = names[i]; + dbParam.Value = args[i]; + cmd.Parameters.Add(dbParam); } - } + } } } diff --git a/MCGalaxy/Games/Countdown/CountdownGame.Plugin.cs b/MCGalaxy/Games/Countdown/CountdownGame.Plugin.cs index 96b380bb5..0ed11eec3 100644 --- a/MCGalaxy/Games/Countdown/CountdownGame.Plugin.cs +++ b/MCGalaxy/Games/Countdown/CountdownGame.Plugin.cs @@ -42,8 +42,10 @@ namespace MCGalaxy.Games { if (Status != CountdownGameStatus.RoundInProgress || !FreezeMode) return; if (!Remaining.Contains(p)) return; - if (next.X != p.CountdownFreezeX || next.Z != p.CountdownFreezeZ) { - next.X = p.CountdownFreezeX; next.Z = p.CountdownFreezeZ; + int freezeX = p.Extras.GetInt("MCG_CD_X"); + int freezeZ = p.Extras.GetInt("MCG_CD_Z"); + if (next.X != freezeX || next.Z != freezeZ) { + next.X = freezeX; next.Z = freezeZ; p.SendPos(Entities.SelfID, next, new Orientation(yaw, pitch)); } diff --git a/MCGalaxy/Games/Countdown/CountdownGame.Round.cs b/MCGalaxy/Games/Countdown/CountdownGame.Round.cs index 3bd0a283e..93c62ae27 100644 --- a/MCGalaxy/Games/Countdown/CountdownGame.Round.cs +++ b/MCGalaxy/Games/Countdown/CountdownGame.Round.cs @@ -104,8 +104,8 @@ namespace MCGalaxy.Games { Player[] players = Players.Items; foreach (Player pl in players) { Position pos = pl.Pos; - pl.CountdownFreezeX = pos.X; - pl.CountdownFreezeZ = pos.Z; + pl.Extras.PutInt("MCG_CD_X", pos.X); + pl.Extras.PutInt("MCG_CD_Z", pos.Z); } RemoveAllSquareBorders(); } diff --git a/MCGalaxy/Games/Team.cs b/MCGalaxy/Games/Team.cs index a3a9a5e17..6c4e372e0 100644 --- a/MCGalaxy/Games/Team.cs +++ b/MCGalaxy/Games/Team.cs @@ -47,10 +47,10 @@ namespace MCGalaxy.Games { } public bool Remove(string name) { - return Members.CaselessRemove(name); + return Members.CaselessRemove(name); } - public void RemoveIfEmpty() { + public void DeleteIfEmpty() { if (Members.Count > 0) return; Teams.Remove(this); } diff --git a/MCGalaxy/Generator/MapGen.cs b/MCGalaxy/Generator/MapGen.cs index d77d9e614..97d719cb6 100644 --- a/MCGalaxy/Generator/MapGen.cs +++ b/MCGalaxy/Generator/MapGen.cs @@ -82,7 +82,7 @@ namespace MCGalaxy.Generator { } - static Dictionary simpleGens, advGens; + static Dictionary simpleGens, advGens; public static void RegisterSimpleGen(string theme, MapGenerator gen) { simpleGens[theme.ToLower()] = gen; } diff --git a/MCGalaxy/Levels/LevelActions.cs b/MCGalaxy/Levels/LevelActions.cs index a626a5f8e..2d82652e2 100644 --- a/MCGalaxy/Levels/LevelActions.cs +++ b/MCGalaxy/Levels/LevelActions.cs @@ -63,8 +63,9 @@ namespace MCGalaxy { } static void RenameDatabaseTables(string src, string dst) { - if (Database.Backend.TableExists("Block" + src)) + if (Database.TableExists("Block" + src)) { Database.Backend.RenameTable("Block" + src, "Block" + dst); + } object srcLocker = ThreadSafeCache.DBCache.GetLocker(src); object dstLockder = ThreadSafeCache.DBCache.GetLocker(dst); @@ -132,8 +133,9 @@ namespace MCGalaxy { } static void DeleteDatabaseTables(string map) { - if (Database.Backend.TableExists("Block" + map)) + if (Database.TableExists("Block" + map)) { Database.Backend.DeleteTable("Block" + map); + } object locker = ThreadSafeCache.DBCache.GetLocker(map); lock (locker) { diff --git a/MCGalaxy/Levels/LevelOptions.cs b/MCGalaxy/Levels/LevelOptions.cs index 7390140e1..7c7230a23 100644 --- a/MCGalaxy/Levels/LevelOptions.cs +++ b/MCGalaxy/Levels/LevelOptions.cs @@ -40,10 +40,10 @@ namespace MCGalaxy { public const string Chat = "Chat", Guns = "Guns", Buildable = "Buildable", Deletable = "Deletable", LoadDelay = "LoadDelay"; public static List Options = new List() { - new LevelOption(MOTD, SetMotd, "%HSets the motd for this map. (leave blank to use default motd)"), - new LevelOption(RealmOwner, SetOwner, "%HSets the players allowed to use /realm on this map."), - new LevelOption(TreeType, SetTree, "%HSets the type of trees saplings grow into."), - new LevelOption(Speed, SetSpeed, "%HSets the delay (in milliseconds) between physics ticks."), + new LevelOption(MOTD, SetMotd, "%HSets the motd for this map. (leave blank to use default motd)"), + new LevelOption(RealmOwner, SetOwner, "%HSets the players allowed to use /realm on this map."), + new LevelOption(TreeType, SetTree, "%HSets the type of trees saplings grow into."), + new LevelOption(Speed, SetSpeed, "%HSets the delay (in milliseconds) between physics ticks."), new LevelOption(Overload, SetOverload, "%HSets how hard (high values) or easy (low values) it is to kill physics."), new LevelOption(Fall, SetFall, "%HSets how many blocks you can fall before dying."), new LevelOption(Drown, SetDrown, "%HSets how long you can stay underwater (in tenths of a second) before drowning."), diff --git a/MCGalaxy/Player/Player.Fields.cs b/MCGalaxy/Player/Player.Fields.cs index 9d77ed1ca..480993fb7 100644 --- a/MCGalaxy/Player/Player.Fields.cs +++ b/MCGalaxy/Player/Player.Fields.cs @@ -143,10 +143,6 @@ namespace MCGalaxy { /// Temp unique ID for this session only. public int SessionID; - //Countdown - public int CountdownFreezeX; - public int CountdownFreezeZ; - //Tnt Wars public bool PlayingTntWars; public int CurrentAmountOfTnt;