diff --git a/CHANGELOG.md b/CHANGELOG.md index d7ab5308..2e455dab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ This is the rolling changelog for TShock for Terraria. Use past tense when addin * Fixed /spawnmob not spawning negative IDs (@MarioE) * Validated tile placement on PlaceObject; clients can no longer place frames, paintings etc with dirt blocks (@bartico6, @ProfessorXZ) * Updated to new stat tracking system with more data so we can actually make informed software decisions (Jordan Coulam) +* Fixed /time display at the end of Terraria hours (@koneko-nyan) +* Added a warning notifying users of the minimum memory required to run TShock (@bartico6) ## TShock 4.3.24 * API: Changed `PlayerHooks` permission hook mechanisms to allow negation from hooks (@deadsurgeon42) diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..9e7b1cc8 --- /dev/null +++ b/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1 @@ + diff --git a/TShockAPI/Commands.cs b/TShockAPI/Commands.cs index 5e7b84bf..fbc6c061 100644 --- a/TShockAPI/Commands.cs +++ b/TShockAPI/Commands.cs @@ -3872,7 +3872,7 @@ namespace TShockAPI if (!Main.dayTime) time += 15.0; time = time % 24.0; - args.Player.SendInfoMessage("The current time is {0}:{1:D2}.", (int)Math.Floor(time), (int)Math.Round((time % 1.0) * 60.0)); + args.Player.SendInfoMessage("The current time is {0}:{1:D2}.", (int)Math.Floor(time), (int)Math.Floor((time % 1.0) * 60.0)); return; } diff --git a/TShockAPI/DB/UserManager.cs b/TShockAPI/DB/UserManager.cs index e79fb933..07662b2b 100644 --- a/TShockAPI/DB/UserManager.cs +++ b/TShockAPI/DB/UserManager.cs @@ -363,7 +363,7 @@ namespace TShockAPI.DB } /// A database user. - public class User + public class User : IEquatable { /// The database ID of the user. public int ID { get; set; } @@ -581,6 +581,67 @@ namespace TShockAPI.DB return HashPassword(Encoding.UTF8.GetBytes(password)); } + #region IEquatable + + /// Indicates whether the current is equal to another . + /// true if the is equal to the parameter; otherwise, false. + /// An to compare with this . + public bool Equals(User other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return ID == other.ID && string.Equals(Name, other.Name); + } + + /// Indicates whether the current is equal to another object. + /// true if the is equal to the parameter; otherwise, false. + /// An to compare with this . + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((User)obj); + } + + /// Serves as the hash function. + /// A hash code for the current . + public override int GetHashCode() + { + unchecked + { + return (ID * 397) ^ (Name != null ? Name.GetHashCode() : 0); + } + } + + /// + /// Compares equality of two objects. + /// + /// Left hand of the comparison. + /// Right hand of the comparison. + /// true if the objects are equal; otherwise, false. + public static bool operator ==(User left, User right) + { + return Equals(left, right); + } + + /// + /// Compares equality of two objects. + /// + /// Left hand of the comparison. + /// Right hand of the comparison. + /// true if the objects aren't equal; otherwise, false. + public static bool operator !=(User left, User right) + { + return !Equals(left, right); + } + + #endregion + + public override string ToString() + { + return Name; + } } /// UserManagerException - An exception generated by the user manager. @@ -643,4 +704,4 @@ namespace TShockAPI.DB { } } -} \ No newline at end of file +} diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index 77e37c03..b593af2c 100644 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -895,14 +895,14 @@ namespace TShockAPI /// /// Time the buff lasts /// - public short Time { get; set; } + public int Time { get; set; } } /// /// PlayerBuff - Called when a player is buffed /// public static HandlerList PlayerBuff; - private static bool OnPlayerBuff(byte id, byte type, short time) + private static bool OnPlayerBuff(byte id, byte type, int time) { if (PlayerBuff == null) return false; @@ -911,7 +911,7 @@ namespace TShockAPI { ID = id, Type = type, - Time = time, + Time = time }; PlayerBuff.Invoke(null, args); return args.Handled; @@ -3425,7 +3425,7 @@ namespace TShockAPI { var id = args.Data.ReadInt8(); var type = args.Data.ReadInt8(); - var time = args.Data.ReadInt16(); + var time = args.Data.ReadInt32(); if (OnPlayerBuff(id, type, time)) return true; diff --git a/TShockAPI/Sockets/LinuxTcpSocket.cs b/TShockAPI/Sockets/LinuxTcpSocket.cs index 98df1674..86381237 100644 --- a/TShockAPI/Sockets/LinuxTcpSocket.cs +++ b/TShockAPI/Sockets/LinuxTcpSocket.cs @@ -12,23 +12,23 @@ namespace TShockAPI.Sockets { public class LinuxTcpSocket : ISocket { - private byte[] _packetBuffer = new byte[1024]; + public byte[] _packetBuffer = new byte[1024]; - private int _packetBufferLength; + public int _packetBufferLength; - private List _callbackBuffer = new List(); + public List _callbackBuffer = new List(); - private int _messagesInQueue; + public int _messagesInQueue; - private TcpClient _connection; + public TcpClient _connection; - private TcpListener _listener; + public TcpListener _listener; - private SocketConnectionAccepted _listenerCallback; + public SocketConnectionAccepted _listenerCallback; - private RemoteAddress _remoteAddress; + public RemoteAddress _remoteAddress; - private bool _isListening; + public bool _isListening; public int MessagesInQueue { diff --git a/TShockAPI/StatTracker.cs b/TShockAPI/StatTracker.cs index 47e5d2cc..1151d170 100644 --- a/TShockAPI/StatTracker.cs +++ b/TShockAPI/StatTracker.cs @@ -27,7 +27,8 @@ using System.Runtime.InteropServices; using System.Net.Http; using System.Threading.Tasks; using TShockAPI.Extensions; - +using System.IO; +using System.Text.RegularExpressions; namespace TShockAPI { @@ -177,7 +178,50 @@ namespace TShockAPI return plugins; } - private long GetTotalSystemRam(bool isMono) + /// + /// Returns the amount of free RAM, in megabytes. + /// + /// Whether or not this program is being executed in a Mono runtime + /// Free RAM memory amount, in megabytes + public long GetFreeSystemRam(bool mono) + { + if (mono) + { + //Temporary in case mono won't work + if (File.Exists("/proc/meminfo")) + { + var l = File.ReadAllLines("/proc/meminfo"); + foreach (string s in l) + { + if (s.StartsWith("MemFree:")) + { + var m = Regex.Match(s, "MemFree:(\\s*)(\\d*) kB"); + if (m.Success) + { + long val; + if (long.TryParse(m.Groups[2].Value, out val)) + { + return val / 1024; + } + } + } + } + } + return -1; + } + else + { + var pc = new PerformanceCounter("Memory", "Available MBytes"); + return pc.RawValue; + } + } + + /// + /// Returns the total amount of installed RAM, in gigabytes. + /// + /// Whether or not this program is being executed in a Mono runtime + /// Total RAM memory amount, in gigabytes + public long GetTotalSystemRam(bool isMono) { if (totalMem != 0) { @@ -267,4 +311,4 @@ namespace TShockAPI /// public bool mono; } -} \ No newline at end of file +} diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index 022e70e5..db15277b 100644 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -329,6 +329,12 @@ namespace TShockAPI Log.ConsoleInfo("TShock {0} ({1}) now running.", Version, VersionCodename); + var systemRam = StatTracker.GetFreeSystemRam(ServerApi.RunningMono); + if (systemRam > -1 && systemRam < 2048) + { + Log.ConsoleError("This machine has less than 2 gigabytes of RAM free. Be advised that it might not be enough to run TShock."); + } + ServerApi.Hooks.GamePostInitialize.Register(this, OnPostInit); ServerApi.Hooks.GameUpdate.Register(this, OnUpdate); ServerApi.Hooks.GameHardmodeTileUpdate.Register(this, OnHardUpdate); diff --git a/TShockAPI/Utils.cs b/TShockAPI/Utils.cs index 520bed9c..5081f8e4 100644 --- a/TShockAPI/Utils.cs +++ b/TShockAPI/Utils.cs @@ -465,7 +465,7 @@ namespace TShockAPI /// description public string GetBuffDescription(int id) { - return (id > 0 && id < Main.maxBuffTypes) ? Lang.GetBuffName(id) : "null"; + return (id > 0 && id < Main.maxBuffTypes) ? Lang.GetBuffDescription(id) : "null"; } ///