diff --git a/TShockAPI/ConfigFile.cs b/TShockAPI/ConfigFile.cs index 52692e9d..149c20e5 100644 --- a/TShockAPI/ConfigFile.cs +++ b/TShockAPI/ConfigFile.cs @@ -207,6 +207,9 @@ namespace TShockAPI [Description("The maximum distance players disabled for various reasons can move from")] public int MaxRangeForDisabled = 10; + + [Description("Server password required to join server")] + public string ServerPassword = ""; public static ConfigFile Read(string path) { diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index 26354bc4..05b9b750 100644 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -91,7 +91,8 @@ namespace TShockAPI {PacketTypes.NpcSpecial, HandleSpecial}, {PacketTypes.PlayerAnimation, HandlePlayerAnimation}, {PacketTypes.PlayerBuff, HandlePlayerBuffUpdate}, - {PacketTypes.PasswordSend, HandlePassword} + {PacketTypes.PasswordSend, HandlePassword}, + {PacketTypes.ContinueConnecting2, HandleConnecting} }; } @@ -234,33 +235,89 @@ namespace TShockAPI args.TPlayer.name = name; args.Player.ReceivedInfo = true; - NetMessage.SendData((int)PacketTypes.TimeSet, -1, -1, "", 0, 0, Main.sunModY, Main.moonModY); - - if (TShock.Config.EnableGeoIP && TShock.Geo != null) - { - var code = TShock.Geo.TryGetCountryCode(IPAddress.Parse(args.Player.IP)); - args.Player.Country = code == null ? "N/A" : MaxMind.GeoIPCountry.GetCountryNameByCode(code); - if (code == "A1") - if (TShock.Config.KickProxyUsers) - TShock.Utils.Kick(args.Player, "Proxies are not allowed"); - Log.Info(string.Format("{0} ({1}) from '{2}' group from '{3}' joined. ({3}/{4})", args.Player.Name, args.Player.IP, args.Player.Group.Name, args.Player.Country, TShock.Utils.ActivePlayers(), TShock.Config.MaxSlots)); - TShock.Utils.Broadcast(args.Player.Name + " has joined from the " + args.Player.Country, Color.Yellow); - } - else - { - Log.Info(string.Format("{0} ({1}) from '{2}' group joined. ({3}/{4})", args.Player.Name, args.Player.IP, args.Player.Group.Name, TShock.Utils.ActivePlayers(), TShock.Config.MaxSlots)); - TShock.Utils.Broadcast(args.Player.Name + " has joined", Color.Yellow); - } - - if (TShock.Config.DisplayIPToAdmins) - TShock.Utils.SendLogs(string.Format("{0} has joined. IP: {1}", args.Player.Name, args.Player.IP), Color.Blue); - return false; } + private static bool HandleConnecting(GetDataHandlerArgs args) + { + var user = TShock.Users.GetUserByName(args.Player.Name); + if (user != null) + { + args.Player.RequiresPassword = true; + NetMessage.SendData((int)PacketTypes.PasswordRequired, args.Player.Index); + return true; + } + else if (!string.IsNullOrEmpty(TShock.Config.ServerPassword)) + { + args.Player.RequiresPassword = true; + NetMessage.SendData((int)PacketTypes.PasswordRequired, args.Player.Index); + return true; + } + + if (args.Player.State == 1) + args.Player.State = 2; + NetMessage.SendData((int)PacketTypes.WorldInfo, args.Player.Index); + return true; + } + private static bool HandlePassword(GetDataHandlerArgs args) { - return false; + if (!args.Player.RequiresPassword) + return true; + + string password = Encoding.ASCII.GetString(args.Data.ReadBytes((int)(args.Data.Length - args.Data.Position - 1))); + var user = TShock.Users.GetUserByName(args.Player.Name); + if (user != null) + { + string encrPass = TShock.Utils.HashPassword(password); + if (user.Password.ToUpper() == encrPass.ToUpper()) + { + args.Player.RequiresPassword = false; + args.Player.PlayerData = TShock.InventoryDB.GetPlayerData(args.Player, TShock.Users.GetUserID(args.Player.Name)); + + if (args.Player.State == 1) + args.Player.State = 2; + NetMessage.SendData((int)PacketTypes.WorldInfo, args.Player.Index); + + if (TShock.Config.ServerSideInventory) + { + if (!TShock.CheckInventory(args.Player)) + { + args.Player.SendMessage("Login Failed, Please fix the above errors then /login again.", Color.Cyan); + args.Player.IgnoreActionsForClearingTrashCan = true; + return true; + } + } + + args.Player.Group = TShock.Utils.GetGroup(user.Group); + args.Player.UserAccountName = args.Player.Name; + args.Player.UserID = TShock.Users.GetUserID(args.Player.UserAccountName); + args.Player.IsLoggedIn = true; + args.Player.IgnoreActionsForInventory = false; + + args.Player.PlayerData.CopyInventory(args.Player); + TShock.InventoryDB.InsertPlayerData(args.Player); + + args.Player.SendMessage("Authenticated as " + args.Player + " successfully.", Color.LimeGreen); + Log.ConsoleInfo(args.Player.Name + " authenticated successfully as user: " + args.Player); + + return true; + } + } + else if (!string.IsNullOrEmpty(TShock.Config.ServerPassword)) + { + if(TShock.Config.ServerPassword == password) + { + args.Player.RequiresPassword = false; + if (args.Player.State == 1) + args.Player.State = 2; + NetMessage.SendData((int)PacketTypes.WorldInfo, args.Player.Index); + return true; + } + } + + TShock.Utils.ForceKick(args.Player, "Incorrect Password"); + return true; } private static bool HandleSendTileSquare(GetDataHandlerArgs args) diff --git a/TShockAPI/TSPlayer.cs b/TShockAPI/TSPlayer.cs index 29edd2a7..d4d94813 100644 --- a/TShockAPI/TSPlayer.cs +++ b/TShockAPI/TSPlayer.cs @@ -74,6 +74,7 @@ namespace TShockAPI public string IgnoreActionsForCheating = "none"; public bool IgnoreActionsForClearingTrashCan = false; public PlayerData PlayerData; + public bool RequiresPassword = false; public bool RealPlayer { @@ -83,6 +84,13 @@ namespace TShockAPI { get { return RealPlayer && (Netplay.serverSock[Index] != null && Netplay.serverSock[Index].active && !Netplay.serverSock[Index].kill); } } + + public int State + { + get { return Netplay.serverSock[Index].state; } + set { Netplay.serverSock[Index].state = value; } + } + public string IP { get diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index 8b0c9224..d8c2dfc5 100644 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -578,6 +578,20 @@ namespace TShockAPI return; } + if (TShock.Geo != null) + { + var code = TShock.Geo.TryGetCountryCode(IPAddress.Parse(player.IP)); + player.Country = code == null ? "N/A" : MaxMind.GeoIPCountry.GetCountryNameByCode(code); + if (code == "A1") + { + if (TShock.Config.KickProxyUsers) + { + TShock.Utils.ForceKick(player, "Proxies are not allowed"); + handler.Handled = true; + return; + } + } + } Players[ply] = player; } @@ -613,6 +627,22 @@ namespace TShockAPI handler.Handled = true; return; } + + NetMessage.SendData((int)PacketTypes.TimeSet, -1, -1, "", 0, 0, Main.sunModY, Main.moonModY); + + if (TShock.Config.EnableGeoIP && TShock.Geo != null) + { + Log.Info(string.Format("{0} ({1}) from '{2}' group from '{3}' joined. ({3}/{4})", player.Name, player.IP, player.Group.Name, player.Country, TShock.Utils.ActivePlayers(), TShock.Config.MaxSlots)); + TShock.Utils.Broadcast(player.Name + " has joined from the " + player.Country, Color.Yellow); + } + else + { + Log.Info(string.Format("{0} ({1}) from '{2}' group joined. ({3}/{4})", player.Name, player.IP, player.Group.Name, TShock.Utils.ActivePlayers(), TShock.Config.MaxSlots)); + TShock.Utils.Broadcast(player.Name + " has joined", Color.Yellow); + } + + if (TShock.Config.DisplayIPToAdmins) + TShock.Utils.SendLogs(string.Format("{0} has joined. IP: {1}", player.Name, player.IP), Color.Blue); } private void OnLeave(int ply) @@ -758,6 +788,18 @@ namespace TShockAPI return; } + if (player.RequiresPassword && type != PacketTypes.PasswordSend) + { + e.Handled = true; + return; + } + + if (player.State < 10 && (int)type > 12 && (int)type != 16 && (int)type != 42 && (int)type != 50 && (int)type != 38) + { + e.Handled = true; + return; + } + using (var data = new MemoryStream(e.Msg.readBuffer, e.Index, e.Length)) { try