diff --git a/.vs/Subsurface_Solution/v14/.suo b/.vs/Subsurface_Solution/v14/.suo index 188fc21d5..f87552f79 100644 Binary files a/.vs/Subsurface_Solution/v14/.suo and b/.vs/Subsurface_Solution/v14/.suo differ diff --git a/Subsurface/Barotrauma.csproj b/Subsurface/Barotrauma.csproj index f840aa579..6d0b466df 100644 --- a/Subsurface/Barotrauma.csproj +++ b/Subsurface/Barotrauma.csproj @@ -159,6 +159,7 @@ + @@ -352,7 +353,6 @@ PreserveNewest - Designer PreserveNewest diff --git a/Subsurface/Data/ContentPackages/Vanilla 0.3.xml b/Subsurface/Data/ContentPackages/Vanilla 0.3.xml index 2e2d2444c..1d35a45ca 100644 --- a/Subsurface/Data/ContentPackages/Vanilla 0.3.xml +++ b/Subsurface/Data/ContentPackages/Vanilla 0.3.xml @@ -42,6 +42,8 @@ + + diff --git a/Subsurface/Source/Characters/BackgroundSprite/BackgroundCreatureManager.cs b/Subsurface/Source/Characters/BackgroundSprite/BackgroundCreatureManager.cs index 1153c3b6b..4a3de9511 100644 --- a/Subsurface/Source/Characters/BackgroundSprite/BackgroundCreatureManager.cs +++ b/Subsurface/Source/Characters/BackgroundSprite/BackgroundCreatureManager.cs @@ -16,23 +16,37 @@ namespace Barotrauma float checkActiveTimer; - private List prefabs; - private List activeSprites; + private List prefabs = new List(); + private List activeSprites = new List(); public BackgroundCreatureManager(string configPath) { - activeSprites = new List(); - prefabs = new List(); - - XDocument doc = ToolBox.TryLoadXml(configPath); - if (doc == null || doc.Root == null) return; - - foreach (XElement element in doc.Root.Elements()) + LoadConfig(configPath); + } + public BackgroundCreatureManager(List files) + { + foreach(var file in files) { - prefabs.Add(new BackgroundCreaturePrefab(element)); + LoadConfig(file); } } + private void LoadConfig(string configPath) + { + try + { + XDocument doc = ToolBox.TryLoadXml(configPath); + if (doc == null || doc.Root == null) return; + foreach (XElement element in doc.Root.Elements()) + { + prefabs.Add(new BackgroundCreaturePrefab(element)); + }; + } + catch (Exception e) + { + DebugConsole.ThrowError(String.Format("Failed to load BackgroundCreatures from {0}", configPath), e); + } + } public void SpawnSprites(int count, Vector2? position = null) { activeSprites.Clear(); diff --git a/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs b/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs index a69c83229..67521f327 100644 --- a/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs +++ b/Subsurface/Source/Characters/BackgroundSprite/BackgroundSpriteManager.cs @@ -34,25 +34,39 @@ namespace Barotrauma { const int GridSize = 1000; - private List prefabs; - //private List sprites; + private List prefabs = new List(); + private List[,] sprites; public BackgroundSpriteManager(string configPath) { - //sprites = new List[2,2](); - prefabs = new List(); - - XDocument doc = ToolBox.TryLoadXml(configPath); - if (doc == null || doc.Root == null) return; - - foreach (XElement element in doc.Root.Elements()) + LoadConfig(configPath); + } + public BackgroundSpriteManager(List files) + { + foreach (var file in files) { - prefabs.Add(new BackgroundSpritePrefab(element)); + LoadConfig(file); } } + private void LoadConfig(string configPath) + { + try + { + XDocument doc = ToolBox.TryLoadXml(configPath); + if (doc == null || doc.Root == null) return; + foreach (XElement element in doc.Root.Elements()) + { + prefabs.Add(new BackgroundSpritePrefab(element)); + } + } + catch (Exception e) + { + DebugConsole.ThrowError(String.Format("Failed to load BackgroundSprites from {0}", configPath), e); + } + } public void PlaceSprites(Level level, int amount) { sprites = new List[ diff --git a/Subsurface/Source/ContentPackage.cs b/Subsurface/Source/ContentPackage.cs index caa18b81c..52a3397de 100644 --- a/Subsurface/Source/ContentPackage.cs +++ b/Subsurface/Source/ContentPackage.cs @@ -10,7 +10,7 @@ namespace Barotrauma { public enum ContentType { - None, Jobs, Item, Character, Structure, Executable, LocationTypes, RandomEvents, Missions + None, Jobs, Item, Character, Structure, Executable, LocationTypes, RandomEvents, Missions, BackgroundCreaturePrefabs, BackgroundSpritePrefabs } public class ContentPackage diff --git a/Subsurface/Source/GameSession/GameSession.cs b/Subsurface/Source/GameSession/GameSession.cs index beb6e15eb..31be54638 100644 --- a/Subsurface/Source/GameSession/GameSession.cs +++ b/Subsurface/Source/GameSession/GameSession.cs @@ -244,7 +244,7 @@ namespace Barotrauma missionButton.UserData = InfoFrameTab.Mission; missionButton.OnClicked = SelectInfoFrameTab; - if (GameMain.Server != null) + if (GameMain.Server != null) { var manageButton = new GUIButton(new Rectangle(200, -30, 130, 20), "Manage players", GUI.Style, infoFrame); manageButton.UserData = InfoFrameTab.ManagePlayers; @@ -269,7 +269,7 @@ namespace Barotrauma break; case InfoFrameTab.Mission: CreateMissionInfo(infoFrame); - break; + break; case InfoFrameTab.ManagePlayers: GameMain.Server.ManagePlayersFrame(infoFrame); break; diff --git a/Subsurface/Source/Map/Levels/LevelRenderer.cs b/Subsurface/Source/Map/Levels/LevelRenderer.cs index 22e4a433a..6324bcd89 100644 --- a/Subsurface/Source/Map/Levels/LevelRenderer.cs +++ b/Subsurface/Source/Map/Levels/LevelRenderer.cs @@ -30,7 +30,7 @@ namespace Barotrauma public LevelRenderer(Level level) { - if (shaftTexture == null) shaftTexture = TextureLoader.FromFile("Content/Map/shaft.png"); + if (shaftTexture == null) shaftTexture = TextureLoader.FromFile("Content/Map/iceWall.png"); if (background==null) { @@ -50,7 +50,12 @@ namespace Barotrauma if (backgroundSpriteManager==null) { - backgroundSpriteManager = new BackgroundSpriteManager("Content/BackgroundSprites/BackgroundSpritePrefabs.xml"); + + var files = GameMain.SelectedPackage.GetFilesOfType(ContentType.BackgroundSpritePrefabs); + if (files.Count > 0) + backgroundSpriteManager = new BackgroundSpriteManager(files); + else + backgroundSpriteManager = new BackgroundSpriteManager("Content/BackgroundSprites/BackgroundSpritePrefabs.xml"); } this.level = level; @@ -173,22 +178,21 @@ namespace Barotrauma Vector2 pos = new Vector2(0.0f, -level.Size.Y);// level.EndPosition; - if (GameMain.GameScreen.Cam.WorldView.Y < -pos.Y - 512) return; + if (GameMain.GameScreen.Cam.WorldView.Y < -pos.Y - 1024) return; - pos.X = GameMain.GameScreen.Cam.WorldView.X -512.0f; + pos.X = GameMain.GameScreen.Cam.WorldView.X -1024; - int width = (int)(Math.Ceiling(GameMain.GameScreen.Cam.WorldView.Width / 512.0f + 2.0f) * 512.0f); + int width = (int)(Math.Ceiling(GameMain.GameScreen.Cam.WorldView.Width / 1024 + 4.0f) * 1024); + GUI.DrawRectangle(spriteBatch,new Rectangle((int)(MathUtils.Round(pos.X, 1024)), (int)-GameMain.GameScreen.Cam.WorldView.Y, width, (int)(GameMain.GameScreen.Cam.WorldView.Y - level.Size.Y) + 30),Color.Black, true); spriteBatch.Draw(shaftTexture, - new Rectangle((int)(MathUtils.Round(pos.X, 512.0f)), (int)pos.Y, width, 512), - new Rectangle(0, 0, width, 256), + new Rectangle((int)(MathUtils.Round(pos.X, 1024)), (int)pos.Y, width, 1024), + new Rectangle(0, 0, width, 1024), level.BackgroundColor, 0.0f, Vector2.Zero, SpriteEffects.None, 0.0f); - GUI.DrawRectangle(spriteBatch, - new Rectangle((int)(MathUtils.Round(pos.X, 512.0f)), (int)-GameMain.GameScreen.Cam.WorldView.Y, width, (int)(GameMain.GameScreen.Cam.WorldView.Y - level.Size.Y)+10), - Color.Black, true ); + //background.DrawTiled(spriteBatch, // (backgroundPos.Y < 0) ? new Vector2(0.0f, -backgroundPos.Y) : Vector2.Zero, @@ -199,6 +203,7 @@ namespace Barotrauma public void RenderWalls(GraphicsDevice graphicsDevice, Camera cam) { + if (wallVertices == null) return; basicEffect.World = cam.ShaderTransform diff --git a/Subsurface/Source/Networking/BanList.cs b/Subsurface/Source/Networking/BanList.cs index f9960dbd1..8a650ed73 100644 --- a/Subsurface/Source/Networking/BanList.cs +++ b/Subsurface/Source/Networking/BanList.cs @@ -12,6 +12,20 @@ namespace Barotrauma.Networking public string Name; public string IP; + public bool CompareTo(string ipCompare) + { + int rangeBanIndex = IP.IndexOf(".x"); + if (rangeBanIndex<=-1) + { + return ipCompare == IP; + } + else + { + if (ipCompare.Length < rangeBanIndex) return false; + return ipCompare.Substring(0, rangeBanIndex) == IP.Substring(0, rangeBanIndex); + } + } + public BannedPlayer(string name, string ip) { this.Name = name; @@ -74,7 +88,7 @@ namespace Barotrauma.Networking public bool IsBanned(string IP) { - return bannedPlayers.Any(bp => bp.IP == IP); + return bannedPlayers.Any(bp => bp.CompareTo(IP)); } public GUIComponent CreateBanFrame(GUIComponent parent) @@ -94,6 +108,12 @@ namespace Barotrauma.Networking var removeButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Remove", Alignment.Right | Alignment.CenterY, GUI.Style, textBlock); removeButton.UserData = bannedPlayer; removeButton.OnClicked = RemoveBan; + if (bannedPlayer.IP.IndexOf(".x") <= -1) + { + var rangeBanButton = new GUIButton(new Rectangle(-100, 0, 100, 20), "Ban range", Alignment.Right | Alignment.CenterY, GUI.Style, textBlock); + rangeBanButton.UserData = bannedPlayer; + rangeBanButton.OnClicked = RangeBan; + } } return banFrame; @@ -120,6 +140,46 @@ namespace Barotrauma.Networking return true; } + public string ToRange(string ip) + { + for (int i = ip.Length - 1; i > 0; i--) + { + if (ip[i] == '.') + { + ip = ip.Substring(0, i) + ".x"; + break; + } + } + return ip; + } + + private bool RangeBan(GUIButton button, object obj) + { + BannedPlayer banned = obj as BannedPlayer; + if (banned == null) return false; + + banned.IP = ToRange(banned.IP); + + BannedPlayer bp; + while ((bp = bannedPlayers.Find(x => banned.CompareTo(x.IP)))!=null) + { + //remove all specific bans that are now covered by the rangeban + bannedPlayers.Remove(bp); + } + + bannedPlayers.Add(banned); + + Save(); + + if (banFrame != null) + { + banFrame.Parent.RemoveChild(banFrame); + CreateBanFrame(banFrame.Parent); + } + + return true; + } + private bool CloseFrame(GUIButton button, object obj) { banFrame = null; diff --git a/Subsurface/Source/Networking/GameClient.cs b/Subsurface/Source/Networking/GameClient.cs index 22faf005a..a415b93f1 100644 --- a/Subsurface/Source/Networking/GameClient.cs +++ b/Subsurface/Source/Networking/GameClient.cs @@ -1025,7 +1025,7 @@ namespace Barotrauma.Networking client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered); } - public override void KickPlayer(string kickedName, bool ban) + public override void KickPlayer(string kickedName, bool ban, bool range = false) { if (!permissions.HasFlag(ClientPermissions.Kick) && !ban) return; if (!permissions.HasFlag(ClientPermissions.Ban) && ban) return; diff --git a/Subsurface/Source/Networking/GameServer.cs b/Subsurface/Source/Networking/GameServer.cs index 8e4898810..7f0848986 100644 --- a/Subsurface/Source/Networking/GameServer.cs +++ b/Subsurface/Source/Networking/GameServer.cs @@ -114,6 +114,12 @@ namespace Barotrauma.Networking settingsButton.OnClicked = ToggleSettingsFrame; settingsButton.UserData = "settingsButton"; + whitelist = new WhiteList(); + + GUIButton whitelistButton = new GUIButton(new Rectangle(GameMain.GraphicsWidth - 170 - 170 - 170 - 170, 20, 150, 20), "Whitelist", Alignment.TopLeft, GUI.Style, inGameHUD); + whitelistButton.OnClicked = ToggleWhiteListFrame; + whitelistButton.UserData = "whitelistButton"; + banList = new BanList(); LoadSettings(); @@ -282,6 +288,7 @@ namespace Barotrauma.Networking { if (ShowNetStats) netStats.Update(deltaTime); if (settingsFrame != null) settingsFrame.Update(deltaTime); + if (whitelist.WhiteListFrame != null) whitelist.WhiteListFrame.Update(deltaTime); if (!started) return; @@ -477,6 +484,11 @@ namespace Barotrauma.Networking } break; case NetIncomingMessageType.Data: + if (banList.IsBanned(inc.SenderEndPoint.Address.ToString())) + { + inc.SenderConnection.Disconnect("You have been banned from the server"); + return; + } byte packetType = inc.ReadByte(); @@ -1172,7 +1184,7 @@ namespace Barotrauma.Networking //if (GameMain.GameSession!=null) GameMain.GameSession.CrewManager.CreateCrewFrame(crew); } - public override void KickPlayer(string playerName, bool ban) + public override void KickPlayer(string playerName, bool ban, bool range = false) { playerName = playerName.ToLowerInvariant(); @@ -1180,17 +1192,19 @@ namespace Barotrauma.Networking c.name.ToLowerInvariant() == playerName || (c.Character != null && c.Character.Name.ToLowerInvariant() == playerName)); - KickClient(client, ban); + KickClient(client, ban, range); } - public void KickClient(Client client, bool ban = false) + public void KickClient(Client client, bool ban = false, bool range = false) { if (client == null) return; if (ban) { DisconnectClient(client, client.name + " has been banned from the server", "You have been banned from the server"); - banList.BanPlayer(client.name, client.Connection.RemoteEndPoint.Address.ToString()); + string ip = client.Connection.RemoteEndPoint.Address.ToString(); + if (range) { ip = banList.ToRange(ip); } + banList.BanPlayer(client.name, ip); } else { @@ -1291,6 +1305,10 @@ namespace Barotrauma.Networking log.LogFrame.Update(0.016f); log.LogFrame.Draw(spriteBatch); } + else if (whitelist.WhiteListFrame != null) + { + whitelist.WhiteListFrame.Draw(spriteBatch); + } if (!ShowNetStats) return; @@ -1431,6 +1449,10 @@ namespace Barotrauma.Networking banButton.UserData = character.Name; banButton.OnClicked += GameMain.NetLobbyScreen.BanPlayer; + var rangebanButton = new GUIButton(new Rectangle(0, -25, 100, 20), "Ban range", Alignment.BottomRight, GUI.Style, characterFrame); + rangebanButton.UserData = character.Name; + rangebanButton.OnClicked += GameMain.NetLobbyScreen.BanPlayerRange; + var kickButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Kick", Alignment.BottomLeft, GUI.Style, characterFrame); kickButton.UserData = character.Name; kickButton.OnClicked += GameMain.NetLobbyScreen.KickPlayer; diff --git a/Subsurface/Source/Networking/GameServerLogin.cs b/Subsurface/Source/Networking/GameServerLogin.cs index ff617de88..a5bb4af8c 100644 --- a/Subsurface/Source/Networking/GameServerLogin.cs +++ b/Subsurface/Source/Networking/GameServerLogin.cs @@ -45,7 +45,7 @@ namespace Barotrauma.Networking inc.SenderConnection.Deny("Connection error - already joined"); return; } - + int nonce = CryptoRandom.Instance.Next(); var msg = server.CreateMessage(); msg.Write(nonce); @@ -143,9 +143,15 @@ namespace Barotrauma.Networking inc.SenderConnection.Disconnect("The name ''" + name + "'' is already in use. Please choose another name."); DebugConsole.NewMessage(name + " couldn't join the server (name already in use)", Color.Red); return; - } - + } + #endif + if (!whitelist.IsWhiteListed(name, inc.SenderConnection.RemoteEndPoint.Address.ToString())) + { + inc.SenderConnection.Disconnect("You're not in this server's whitelist."); + DebugConsole.NewMessage(name + " (" + inc.SenderConnection.RemoteEndPoint.Address.ToString() + ") couldn't join the server (not in whitelist)", Color.Red); + return; + } //existing user re-joining if (userID > 0) diff --git a/Subsurface/Source/Networking/GameServerSettings.cs b/Subsurface/Source/Networking/GameServerSettings.cs index fe6161671..82d495148 100644 --- a/Subsurface/Source/Networking/GameServerSettings.cs +++ b/Subsurface/Source/Networking/GameServerSettings.cs @@ -55,6 +55,7 @@ namespace Barotrauma.Networking private bool registeredToMaster; + private WhiteList whitelist; private BanList banList; private string password; @@ -257,7 +258,7 @@ namespace Barotrauma.Networking private void CreateSettingsFrame() { - settingsFrame = new GUIFrame(new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.Black * 0.5f); + settingsFrame = new GUIFrame(new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.Black * 0.5f); GUIFrame innerFrame = new GUIFrame(new Rectangle(0, 0, 400, 430), null, Alignment.Center, GUI.Style, settingsFrame); innerFrame.Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f); @@ -647,6 +648,20 @@ namespace Barotrauma.Networking return false; } + public bool ToggleWhiteListFrame(GUIButton button, object obj) + { + if (whitelist.WhiteListFrame == null) + { + whitelist.CreateWhiteListFrame(); + } + else + { + whitelist.CloseFrame(); + } + + return false; + } + public void ManagePlayersFrame(GUIFrame infoFrame) { GUIListBox cList = new GUIListBox(new Rectangle(0, 0, 0, 300), Color.White * 0.7f, GUI.Style, infoFrame); @@ -668,13 +683,17 @@ namespace Barotrauma.Networking Alignment.Left, Alignment.Left, null, frame); - var banButton = new GUIButton(new Rectangle(-120, 0, 100, 20), "Ban", Alignment.Right | Alignment.CenterY, GUI.Style, frame); + var banButton = new GUIButton(new Rectangle(-110, 0, 100, 20), "Ban", Alignment.Right | Alignment.CenterY, GUI.Style, frame); banButton.UserData = c.name; - banButton.OnClicked += GameMain.NetLobbyScreen.BanPlayer; + banButton.OnClicked = GameMain.NetLobbyScreen.BanPlayer; + + var rangebanButton = new GUIButton(new Rectangle(-220, 0, 100, 20), "Ban range", Alignment.Right | Alignment.CenterY, GUI.Style, frame); + rangebanButton.UserData = c.name; + rangebanButton.OnClicked = GameMain.NetLobbyScreen.BanPlayerRange; var kickButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Kick", Alignment.Right | Alignment.CenterY, GUI.Style, frame); kickButton.UserData = c.name; - kickButton.OnClicked += GameMain.NetLobbyScreen.KickPlayer; + kickButton.OnClicked = GameMain.NetLobbyScreen.KickPlayer; textBlock.Padding = new Vector4(5.0f, 0.0f, 5.0f, 0.0f); } diff --git a/Subsurface/Source/Networking/NetworkMember.cs b/Subsurface/Source/Networking/NetworkMember.cs index d18587249..c75ee1094 100644 --- a/Subsurface/Source/Networking/NetworkMember.cs +++ b/Subsurface/Source/Networking/NetworkMember.cs @@ -336,7 +336,7 @@ namespace Barotrauma.Networking public virtual void SendChatMessage(string message, ChatMessageType? type = null) { } - public virtual void KickPlayer(string kickedName, bool ban) { } + public virtual void KickPlayer(string kickedName, bool ban, bool range = false) { } public virtual void Update(float deltaTime) { diff --git a/Subsurface/Source/Networking/WhiteList.cs b/Subsurface/Source/Networking/WhiteList.cs new file mode 100644 index 000000000..aa6459992 --- /dev/null +++ b/Subsurface/Source/Networking/WhiteList.cs @@ -0,0 +1,227 @@ +using Microsoft.Xna.Framework; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; + +namespace Barotrauma.Networking +{ + class WhiteListedPlayer + { + public string Name; + public string IP; + + public WhiteListedPlayer(string name,string ip) + { + Name = name; + IP = ip; + } + } + + class WhiteList + { + const string SavePath = "Data/whitelist.txt"; + + private List whitelistedPlayers; + public List WhiteListedPlayers + { + get { return whitelistedPlayers; } + } + + private GUIComponent whitelistFrame; + private GUIComponent innerlistFrame; + + private GUITextBox nameBox; + private GUITextBox ipBox; + + public bool enabled; + + public GUIComponent WhiteListFrame + { + get { return whitelistFrame; } + } + + public WhiteList() + { + enabled = false; + whitelistedPlayers = new List(); + + if (File.Exists(SavePath)) + { + string[] lines; + try + { + lines = File.ReadAllLines(SavePath); + } + catch (Exception e) + { + DebugConsole.ThrowError("Failed to open whitelist in " + SavePath, e); + return; + } + + foreach (string line in lines) + { + if (line[0] == '#') + { + string lineval = line.Substring(1, line.Length - 1); + int intVal = 0; + Int32.TryParse(lineval, out intVal); + if (lineval.ToLower() == "true" || intVal != 0) + { + enabled = true; + } + else + { + enabled = false; + } + } + else + { + string[] separatedLine = line.Split(','); + if (separatedLine.Length < 2) continue; + + string name = String.Join(",", separatedLine.Take(separatedLine.Length - 1)); + string ip = separatedLine.Last(); + + whitelistedPlayers.Add(new WhiteListedPlayer(name, ip)); + } + } + } + } + + public void Save() + { + GameServer.Log("Saving whitelist", null); + + List lines = new List(); + + if (enabled) + { + lines.Add("#true"); + } + else + { + lines.Add("#false"); + } + foreach (WhiteListedPlayer wlp in whitelistedPlayers) + { + lines.Add(wlp.Name + "," + wlp.IP); + } + + try + { + File.WriteAllLines(SavePath, lines); + } + catch (Exception e) + { + DebugConsole.ThrowError("Saving the whitelist to " + SavePath + " failed", e); + } + } + + public bool IsWhiteListed(string name, string ip) + { + if (!enabled) return true; + WhiteListedPlayer wlp = whitelistedPlayers.Find(p => p.Name == name); + if (wlp == null) return false; + if (wlp.IP != ip && !string.IsNullOrWhiteSpace(wlp.IP)) return false; + return true; + } + + public GUIComponent CreateWhiteListFrame() + { + whitelistFrame = new GUIFrame(new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.Black * 0.5f); + + GUIFrame innerFrame = new GUIFrame(new Rectangle(0, 0, 500, 430), null, Alignment.Center, GUI.Style, whitelistFrame); + innerFrame.Padding = new Vector4(20.0f, 50.0f, 20.0f, 100.0f); + + var closeButton = new GUIButton(new Rectangle(0, 85, 100, 20), "Close", Alignment.BottomRight, GUI.Style, innerFrame); + closeButton.OnClicked = GameMain.Server.ToggleWhiteListFrame; + + new GUITextBlock(new Rectangle(0, -35, 200, 20), "Whitelist", GUI.Style, innerFrame, GUI.LargeFont); + var enabledTick = new GUITickBox(new Rectangle(200, -30, 20, 20), "Enabled", Alignment.Left, innerFrame); + enabledTick.Selected = enabled; + enabledTick.OnSelected = (GUITickBox box) => + { + enabled = !enabled; + if (enabled) + { + foreach (Client c in GameMain.Server.ConnectedClients) + { + if (!IsWhiteListed(c.name,c.Connection.RemoteEndPoint.Address.ToString())) + { + whitelistedPlayers.Add(new WhiteListedPlayer(c.name, c.Connection.RemoteEndPoint.Address.ToString())); + CloseFrame(); CreateWhiteListFrame(); + } + } + } + Save(); + return true; + }; + + new GUITextBlock(new Rectangle(0, 35, 90, 25), "Name:", GUI.Style, Alignment.BottomLeft, Alignment.TopLeft, innerFrame, false, GUI.Font); + nameBox = new GUITextBox(new Rectangle(100, 30, 170, 25), Alignment.BottomLeft, GUI.Style, innerFrame); + nameBox.Font = GUI.Font; + + new GUITextBlock(new Rectangle(0, 65, 90, 25), "IP Address:", GUI.Style, Alignment.BottomLeft, Alignment.TopLeft, innerFrame, false, GUI.Font); + ipBox = new GUITextBox(new Rectangle(100, 60, 170, 25), Alignment.BottomLeft, GUI.Style, innerFrame); + ipBox.Font = GUI.Font; + + var addnewButton = new GUIButton(new Rectangle(300, 45, 150, 20), "Add to whitelist", Alignment.BottomLeft, GUI.Style, innerFrame); + addnewButton.OnClicked = AddToWhiteList; + + innerlistFrame = new GUIListBox(new Rectangle(0, 0, 0, 0), GUI.Style, innerFrame); + + foreach (WhiteListedPlayer wlp in whitelistedPlayers) + { + string blockText = wlp.Name; + if (!string.IsNullOrWhiteSpace(wlp.IP)) blockText += " (" + wlp.IP + ")"; + GUITextBlock textBlock = new GUITextBlock( + new Rectangle(0, 0, 0, 25), + blockText, + GUI.Style, + Alignment.Left, Alignment.Left, innerlistFrame); + textBlock.Padding = new Vector4(10.0f, 10.0f, 0.0f, 0.0f); + textBlock.UserData = wlp; + + var removeButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Remove", Alignment.Right | Alignment.CenterY, GUI.Style, textBlock); + removeButton.UserData = wlp; + removeButton.OnClicked = RemoveFromWhiteList; + } + + return whitelistFrame; + } + + private bool RemoveFromWhiteList(GUIButton button, object obj) + { + WhiteListedPlayer wlp = obj as WhiteListedPlayer; + if (wlp == null) return false; + + DebugConsole.Log("Removing " + wlp.Name + " from whitelist"); + GameServer.Log("Removing " + wlp.Name + " from whitelist", null); + + whitelistedPlayers.Remove(wlp); + Save(); + CloseFrame(); CreateWhiteListFrame(); + + return true; + } + + private bool AddToWhiteList(GUIButton button, object obj) + { + if (string.IsNullOrWhiteSpace(nameBox.Text)) return false; + if (whitelistedPlayers.Find(x => x.Name.ToLower() == nameBox.Text.ToLower() && x.IP == ipBox.Text) != null) return false; + whitelistedPlayers.Add(new WhiteListedPlayer(nameBox.Text,ipBox.Text)); + Save(); + CloseFrame(); CreateWhiteListFrame(); + return true; + } + + public bool CloseFrame(GUIButton button=null, object obj=null) + { + whitelistFrame = null; + + return true; + } + } +} diff --git a/Subsurface/Source/Screens/GameScreen.cs b/Subsurface/Source/Screens/GameScreen.cs index dd0880ec7..611616aad 100644 --- a/Subsurface/Source/Screens/GameScreen.cs +++ b/Subsurface/Source/Screens/GameScreen.cs @@ -33,8 +33,12 @@ namespace Barotrauma renderTarget = new RenderTarget2D(graphics, GameMain.GraphicsWidth, GameMain.GraphicsHeight); renderTargetWater = new RenderTarget2D(graphics, GameMain.GraphicsWidth, GameMain.GraphicsHeight); renderTargetAir = new RenderTarget2D(graphics, GameMain.GraphicsWidth, GameMain.GraphicsHeight); - - BackgroundCreatureManager = new BackgroundCreatureManager("Content/BackgroundSprites/BackgroundCreaturePrefabs.xml"); + + var files = GameMain.SelectedPackage.GetFilesOfType(ContentType.BackgroundCreaturePrefabs); + if(files.Count > 0) + BackgroundCreatureManager = new BackgroundCreatureManager(files); + else + BackgroundCreatureManager = new BackgroundCreatureManager("Content/BackgroundSprites/BackgroundCreaturePrefabs.xml"); #if LINUX var blurEffect = content.Load("blurshader_opengl"); diff --git a/Subsurface/Source/Screens/NetLobbyScreen.cs b/Subsurface/Source/Screens/NetLobbyScreen.cs index 309306e04..351ff3f15 100644 --- a/Subsurface/Source/Screens/NetLobbyScreen.cs +++ b/Subsurface/Source/Screens/NetLobbyScreen.cs @@ -397,7 +397,11 @@ namespace Barotrauma GUIButton settingsButton = new GUIButton(new Rectangle(-100, 0, 80, 30), "Settings", Alignment.BottomRight, GUI.Style, infoFrame); settingsButton.OnClicked = GameMain.Server.ToggleSettingsFrame; settingsButton.UserData = "settingsButton"; - + + GUIButton whitelistButton = new GUIButton(new Rectangle(-200, 0, 80, 30), "Whitelist", Alignment.BottomRight, GUI.Style, infoFrame); + whitelistButton.OnClicked = GameMain.Server.ToggleWhiteListFrame; + whitelistButton.UserData = "whitelistButton"; + if (subList.Selected == null) subList.Select(Math.Max(0, prevSelectedSub)); if (shuttleList.Selected == null) { @@ -771,7 +775,7 @@ namespace Barotrauma playerFrame = new GUIFrame(new Rectangle(0, 0, 0, 0), Color.Black * 0.3f); - var playerFrameInner = new GUIFrame(new Rectangle(0, 0, 300, 150), null, Alignment.Center, GUI.Style, playerFrame); + var playerFrameInner = new GUIFrame(new Rectangle(0, 0, 300, 250), null, Alignment.Center, GUI.Style, playerFrame); playerFrameInner.Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f); new GUITextBlock(new Rectangle(0,0,200,20), component.UserData.ToString(), @@ -832,7 +836,7 @@ namespace Barotrauma if (GameMain.Server != null || GameMain.Client.HasPermission(ClientPermissions.Kick)) { - var kickButton = new GUIButton(new Rectangle(0, -30, 100, 20), "Kick", Alignment.BottomLeft, GUI.Style, playerFrameInner); + var kickButton = new GUIButton(new Rectangle(0, -50, 100, 20), "Kick", Alignment.BottomLeft, GUI.Style, playerFrameInner); kickButton.UserData = obj; kickButton.OnClicked += KickPlayer; kickButton.OnClicked += ClosePlayerFrame; @@ -844,6 +848,11 @@ namespace Barotrauma banButton.UserData = obj; banButton.OnClicked += BanPlayer; banButton.OnClicked += ClosePlayerFrame; + + var rangebanButton = new GUIButton(new Rectangle(0, -25, 100, 20), "Ban range", Alignment.BottomLeft, GUI.Style, playerFrameInner); + rangebanButton.UserData = obj; + rangebanButton.OnClicked += BanPlayerRange; + rangebanButton.OnClicked += ClosePlayerFrame; } var closeButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Close", Alignment.BottomRight, GUI.Style, playerFrameInner); @@ -886,7 +895,23 @@ namespace Barotrauma else if (GameMain.Client != null && GameMain.Client.HasPermission(ClientPermissions.Ban)) { GameMain.Client.KickPlayer(userData.ToString(), true); - } + } + + return false; + } + + public bool BanPlayerRange(GUIButton button, object userData) + { + if (userData == null) return false; + + if (GameMain.Server != null) + { + GameMain.Server.KickPlayer(userData.ToString(), true, true); + } + else if (GameMain.Client != null && GameMain.Client.HasPermission(ClientPermissions.Ban)) + { + GameMain.Client.KickPlayer(userData.ToString(), true, true); + } return false; }