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;
}