From b72579bd18bec29fad426a5c857cbd473b2eb7ec Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sat, 18 Nov 2023 21:27:17 +1100 Subject: [PATCH] Save a few kilobytes of memory in Level instances --- MCGalaxy/Blocks/Behaviour/BlockBehaviour.cs | 45 ++++++---- MCGalaxy/Commands/other/CmdRide.cs | 1 + MCGalaxy/Database/Backends/SQLiteBackend.cs | 89 ++++++------------- MCGalaxy/Player/Player.Fields.cs | 6 +- MCGalaxy/Player/Player.cs | 4 + .../Authentication/PassAuthenticator.cs | 24 ++--- 6 files changed, 77 insertions(+), 92 deletions(-) diff --git a/MCGalaxy/Blocks/Behaviour/BlockBehaviour.cs b/MCGalaxy/Blocks/Behaviour/BlockBehaviour.cs index ab847b3f6..b2c547e84 100644 --- a/MCGalaxy/Blocks/Behaviour/BlockBehaviour.cs +++ b/MCGalaxy/Blocks/Behaviour/BlockBehaviour.cs @@ -51,23 +51,31 @@ namespace MCGalaxy.Blocks { return null; } + // NOTE: These static declarations are just to save a few memory allocations + // Behind the scenes, 'return XYZ;' is actually compiled into 'return new HandleDelete(XYZ);' + // So by declaring a static variable, 'new HandleDelete(XYZ)' is only ever called once + // instead of over and over - thereby slightly reducing memory usage + static HandleDelete DB_revert = DeleteBehaviour.RevertDoor; + static HandleDelete DB_oDoor = DeleteBehaviour.oDoor; + static HandleDelete DB_Door = DeleteBehaviour.Door; + /// Retrieves the default delete block handler for the given block. internal static HandleDelete GetDeleteHandler(BlockID block, BlockProps[] props) { switch (block) { case Block.RocketStart: return DeleteBehaviour.RocketStart; case Block.Fireworks: return DeleteBehaviour.Firework; case Block.C4Detonator: return DeleteBehaviour.C4Det; - case Block.Door_Log_air: return DeleteBehaviour.RevertDoor; - case Block.Door_TNT_air: return DeleteBehaviour.RevertDoor; - case Block.Door_Green_air: return DeleteBehaviour.RevertDoor; + case Block.Door_Log_air: return DB_revert; + case Block.Door_TNT_air: return DB_revert; + case Block.Door_Green_air: return DB_revert; } // NOTE: If this gets changed, make sure to change BlockOptions.cs too if (props[block].IsMessageBlock) return DeleteBehaviour.DoMessageBlock; if (props[block].IsPortal) return DeleteBehaviour.DoPortal; - if (props[block].IsTDoor) return DeleteBehaviour.RevertDoor; - if (props[block].oDoorBlock != Block.Invalid) return DeleteBehaviour.oDoor; - if (props[block].IsDoor) return DeleteBehaviour.Door; + if (props[block].IsTDoor) return DB_revert; + if (props[block].oDoorBlock != Block.Invalid) return DB_oDoor; + if (props[block].IsDoor) return DB_Door; return null; } @@ -87,12 +95,17 @@ namespace MCGalaxy.Blocks { } + // See comments noted above for reasoning behind static declaration of some HandleDelete handlers + static HandlePhysics PH_do_Door = DoorPhysics.Do; + static HandlePhysics PH_do_oDoor = DoorPhysics.oDoor; + static HandlePhysics PH_do_Other = OtherPhysics.DoOther; + /// Retrieves the default physics block handler for the given block. internal static HandlePhysics GetPhysicsHandler(BlockID block, BlockProps[] props) { switch (block) { - case Block.Door_Log_air: return DoorPhysics.Do; - case Block.Door_TNT_air: return DoorPhysics.Do; - case Block.Door_Green_air: return DoorPhysics.Do; + case Block.Door_Log_air: return PH_do_Door; + case Block.Door_TNT_air: return PH_do_Door; + case Block.Door_Green_air: return PH_do_Door; case Block.SnakeTail: return SnakePhysics.DoTail; case Block.Snake: return SnakePhysics.Do; @@ -156,25 +169,25 @@ namespace MCGalaxy.Blocks { HandlePhysics animalAI = AnimalAIHandler(props[block].AnimalAI); if (animalAI != null) return animalAI; - if (props[block].oDoorBlock != Block.Invalid) return DoorPhysics.oDoor; + if (props[block].oDoorBlock != Block.Invalid) return PH_do_oDoor; if (props[block].GrassBlock != Block.Invalid) return OtherPhysics.DoDirtGrow; if (props[block].DirtBlock != Block.Invalid) return OtherPhysics.DoGrassDie; // TODO: should this be checking WaterKills/LavaKills // Adv physics updating anything placed next to water or lava if ((block >= Block.Red && block <= Block.RedMushroom) || block == Block.Wood || block == Block.Log || block == Block.Bookshelf) { - return OtherPhysics.DoOther; + return PH_do_Other; } return null; } /// Retrieves the default physics block handler for the given block. internal static HandlePhysics GetPhysicsDoorsHandler(BlockID block, BlockProps[] props) { - if (block == Block.Air) return DoorPhysics.Do; - if (block == Block.Door_Log_air) return DoorPhysics.Do; - if (block == Block.Door_TNT_air) return DoorPhysics.Do; - if (block == Block.Door_Green_air) return DoorPhysics.Do; - if (props[block].oDoorBlock != Block.Invalid) return DoorPhysics.oDoor; + if (block == Block.Air) return PH_do_Door; + if (block == Block.Door_Log_air) return PH_do_Door; + if (block == Block.Door_TNT_air) return PH_do_Door; + if (block == Block.Door_Green_air) return PH_do_Door; + if (props[block].oDoorBlock != Block.Invalid) return PH_do_oDoor; return null; } diff --git a/MCGalaxy/Commands/other/CmdRide.cs b/MCGalaxy/Commands/other/CmdRide.cs index 74e5f1d83..b273fbdde 100644 --- a/MCGalaxy/Commands/other/CmdRide.cs +++ b/MCGalaxy/Commands/other/CmdRide.cs @@ -24,6 +24,7 @@ namespace MCGalaxy.Commands.Misc { public override string name { get { return "Ride"; } } public override string type { get { return CommandTypes.Other; } } public override bool museumUsable { get { return false; } } + public override bool SuperUseable { get { return false; } } public override void Use(Player p, string message, CommandData data) { p.onTrain = !p.onTrain; diff --git a/MCGalaxy/Database/Backends/SQLiteBackend.cs b/MCGalaxy/Database/Backends/SQLiteBackend.cs index 8dc705f81..f3506cc91 100644 --- a/MCGalaxy/Database/Backends/SQLiteBackend.cs +++ b/MCGalaxy/Database/Backends/SQLiteBackend.cs @@ -15,15 +15,6 @@ using SQLiteErrorCode = System.Int32; namespace MCGalaxy.SQL { - enum SqlType - { - Single, Double, Decimal, - SByte, Int16, Int32, Int64, - Byte, UInt16, UInt32, UInt64, - Boolean, DateTime, - Binary, String, Object, - } - [SuppressUnmanagedCodeSecurity] static class Interop { @@ -410,38 +401,6 @@ namespace MCGalaxy.SQL Thread.Sleep((int)(seed % 150) + 1); } } - - - internal static SqlType TypeToDbType(Type typ) { - TypeCode tc = Type.GetTypeCode(typ); - if (tc == TypeCode.Object) { - if (typ == typeof(byte[])) return SqlType.Binary; - return SqlType.String; - } - return type_to_dbtype[(int)tc]; - } - - static SqlType[] type_to_dbtype = { - SqlType.Object, // Empty (0) - SqlType.Binary, // Object (1) - SqlType.Object, // DBNull (2) - SqlType.Boolean, // Boolean (3) - SqlType.SByte, // Char (4) - SqlType.SByte, // SByte (5) - SqlType.Byte, // Byte (6) - SqlType.Int16, // Int16 (7) - SqlType.UInt16, // UInt16 (8) - SqlType.Int32, // Int32 (9) - SqlType.UInt32, // UInt32 (10) - SqlType.Int64, // Int64 (11) - SqlType.UInt64, // UInt64 (12) - SqlType.Single, // Single (13) - SqlType.Double, // Double (14) - SqlType.Decimal, // Decimal (15) - SqlType.DateTime, // DateTime (16) - SqlType.Object, // ?? (17) - SqlType.String // String (18) - }; } enum TypeAffinity @@ -766,41 +725,47 @@ namespace MCGalaxy.SQL } return -1; } - + SQLiteErrorCode BindParameter(int i, object obj) { if (obj == null || obj == DBNull.Value) { return Interop.sqlite3_bind_null(handle, i); } - SqlType type = SQLiteConvert.TypeToDbType(obj.GetType()); - switch (type) { - case SqlType.DateTime: - return Bind_DateTime(i, Convert.ToDateTime(obj, CultureInfo.InvariantCulture)); - case SqlType.Boolean: - return Bind_Int32(i, Convert.ToBoolean(obj) ? 1 : 0); - case SqlType.SByte: + Type t = obj.GetType(); + TypeCode tc = Type.GetTypeCode(t); + + // byte[] doesn't have its own typecode, so needs special handling here + if (tc == TypeCode.Object && t == typeof(byte[])) { + byte[] b = (byte[])obj; + return Interop.sqlite3_bind_blob(handle, i, b, b.Length, (IntPtr)(-1)); + } + + switch (tc) { + case TypeCode.DateTime: + return Bind_DateTime(i, (DateTime)obj); + case TypeCode.Boolean: + return Bind_Int32(i, ((bool)obj) ? 1 : 0); + case TypeCode.Char: // TODO ushort instead? + case TypeCode.SByte: return Bind_Int32(i, Convert.ToSByte(obj)); - case SqlType.Int16: + case TypeCode.Int16: return Bind_Int32(i, Convert.ToInt16(obj)); - case SqlType.Int32: + case TypeCode.Int32: return Bind_Int32(i, Convert.ToInt32(obj)); - case SqlType.Int64: + case TypeCode.Int64: return Bind_Int64(i, Convert.ToInt64(obj)); - case SqlType.Byte: + case TypeCode.Byte: return Bind_Int32(i, Convert.ToByte(obj)); - case SqlType.UInt16: + case TypeCode.UInt16: return Bind_Int32(i, Convert.ToUInt16(obj)); - case SqlType.UInt32: + case TypeCode.UInt32: return Bind_Int32(i, (int)Convert.ToUInt32(obj)); - case SqlType.UInt64: + case TypeCode.UInt64: return Bind_Int64(i, (long)Convert.ToUInt64(obj)); - case SqlType.Single: - case SqlType.Double: - case SqlType.Decimal: + case TypeCode.Single: + case TypeCode.Double: + case TypeCode.Decimal: return Interop.sqlite3_bind_double(handle, i, Convert.ToDouble(obj)); - case SqlType.Binary: - byte[] b = (byte[])obj; - return Interop.sqlite3_bind_blob(handle, i, b, b.Length, (IntPtr)(-1)); default: return Bind_Text(i, obj.ToString()); } diff --git a/MCGalaxy/Player/Player.Fields.cs b/MCGalaxy/Player/Player.Fields.cs index 0928cc285..d333ef749 100644 --- a/MCGalaxy/Player/Player.Fields.cs +++ b/MCGalaxy/Player/Player.Fields.cs @@ -134,7 +134,7 @@ namespace MCGalaxy { public bool staticCommands; internal DateTime lastAccessStatus; - public VolatileArray CriticalTasks = new VolatileArray(); + public VolatileArray CriticalTasks; public bool isFlying; public bool aiming; @@ -174,7 +174,7 @@ namespace MCGalaxy { } // BlockDefinitions - internal int gbStep = 0, lbStep = 0; + internal int gbStep, lbStep; internal BlockDefinition gbBlock, lbBlock; //Undo @@ -221,7 +221,7 @@ namespace MCGalaxy { internal DateTime cmdUnblocked; List partialLog; - public WarpList Waypoints = new WarpList(); + public WarpList Waypoints; public DateTime LastPatrol; public LevelPermission Rank { get { return group.Permission; } } diff --git a/MCGalaxy/Player/Player.cs b/MCGalaxy/Player/Player.cs index f48a7ba6b..75c859c3f 100644 --- a/MCGalaxy/Player/Player.cs +++ b/MCGalaxy/Player/Player.cs @@ -27,6 +27,7 @@ using MCGalaxy.Games; using MCGalaxy.Maths; using MCGalaxy.Network; using MCGalaxy.SQL; +using MCGalaxy.Tasks; using BlockID = System.UInt16; namespace MCGalaxy { @@ -68,6 +69,9 @@ namespace MCGalaxy { Session = session; SetIP(Socket.IP); + CriticalTasks = new VolatileArray(); + Waypoints = new WarpList(); + spamChecker = new SpamChecker(this); partialLog = new List(20); session.ID = Interlocked.Increment(ref sessionCounter) & SESSION_ID_MASK; diff --git a/MCGalaxy/Server/Authentication/PassAuthenticator.cs b/MCGalaxy/Server/Authentication/PassAuthenticator.cs index 53acb57f6..9ba32e431 100644 --- a/MCGalaxy/Server/Authentication/PassAuthenticator.cs +++ b/MCGalaxy/Server/Authentication/PassAuthenticator.cs @@ -65,14 +65,14 @@ namespace MCGalaxy.Authentication public abstract class PassAuthenticator : ExtraAuthenticator { public override void RequiresVerification(Player p, string action) { - p.Message("&WYou must first verify with &T/Pass [Password] &Wbefore you can {0}", action); + p.Message("&WYou must first verify with &T/Pass [password] &Wbefore you can {0}", action); } public override void NeedVerification(Player p) { if (!HasPassword(p.name)) { - p.Message("&WPlease set your account verification password with &T/SetPass [password]!"); + p.Message("&WPlease set your account verification password with &T/SetPass [password]"); } else { - p.Message("&WPlease complete account verification with &T/Pass [password]!"); + p.Message("&WPlease complete account verification with &T/Pass [password]"); } } @@ -158,7 +158,7 @@ namespace MCGalaxy.Authentication if (password.IndexOf(' ') >= 0) { p.Message("Your password must be &Wone &Sword!"); return; } if (!HasPassword(p.name)) { - p.Message("You have not &Wset a password, &Suse &T/SetPass [Password] &Wto set one"); + p.Message("You have not &Wset a verification password yet, &Suse &T/SetPass [password] &Wto set one"); p.Message("Make sure to use a different password than your Minecraft one!"); return; } @@ -173,14 +173,16 @@ namespace MCGalaxy.Authentication void DoSetPassword(Player p, string password) { if (p.Unverified && HasPassword(p.name)) { - RequiresVerification(p, "can change your password"); + RequiresVerification(p, "can change your verification password"); p.Message("Forgot your password? Contact &W{0} &Sto &Wreset it.", Server.Config.OwnerName); return; } + if (password.IndexOf(' ') >= 0) { + p.Message("&WPassword must be one word."); return; + } - if (password.IndexOf(' ') >= 0) { p.Message("&WPassword must be one word."); return; } StorePassword(p.name, password); - p.Message("Your password was &aset to: &c" + password); + p.Message("Your verification password was &aset to: &c" + password); } void DoResetPassword(Player p, string name, CommandData data) { @@ -188,19 +190,19 @@ namespace MCGalaxy.Authentication if (target == null) return; if (p.Unverified) { - RequiresVerification(p, "can reset passwords"); + RequiresVerification(p, "can reset verification passwords"); return; } if (data.Rank < Server.Config.ResetPasswordRank) { - p.Message("Only {0}&S+ can reset passwords", + p.Message("Only {0}&S+ can reset verification passwords", Group.GetColoredName(Server.Config.ResetPasswordRank)); return; } if (ResetPassword(target)) { - p.Message("Reset password for {0}", p.FormatNick(target)); + p.Message("Reset verification password for {0}", p.FormatNick(target)); } else { - p.Message("{0} &Sdoes not have a password.", p.FormatNick(target)); + p.Message("{0} &Sdoes not have a verification password.", p.FormatNick(target)); } }