diff --git a/Subsurface/Barotrauma.csproj b/Subsurface/Barotrauma.csproj index 662e956f3..e7c9eb510 100644 --- a/Subsurface/Barotrauma.csproj +++ b/Subsurface/Barotrauma.csproj @@ -1488,7 +1488,6 @@ PreserveNewest - diff --git a/Subsurface/Content/Characters/Watcher/watcher.xml b/Subsurface/Content/Characters/Watcher/watcher.xml index c83554741..9cf6a49a4 100644 --- a/Subsurface/Content/Characters/Watcher/watcher.xml +++ b/Subsurface/Content/Characters/Watcher/watcher.xml @@ -14,7 +14,7 @@ - + diff --git a/Subsurface/Source/Characters/Animation/Ragdoll.cs b/Subsurface/Source/Characters/Animation/Ragdoll.cs index d1bcf0596..ad996634c 100644 --- a/Subsurface/Source/Characters/Animation/Ragdoll.cs +++ b/Subsurface/Source/Characters/Animation/Ragdoll.cs @@ -343,7 +343,7 @@ namespace Barotrauma if (collider[0] == null) { - DebugConsole.ThrowError("No collider configured for ''"+character.Name+"''!"); + DebugConsole.ThrowError("No collider configured for \""+character.Name+"\"!"); collider[0] = new PhysicsBody(0.0f, 0.0f, 0.5f, 5.0f); collider[0].BodyType = BodyType.Dynamic; collider[0].CollisionCategories = Physics.CollisionCharacter; @@ -624,7 +624,7 @@ namespace Barotrauma public virtual void Flip() { dir = (dir == Direction.Left) ? Direction.Right : Direction.Left; - + for (int i = 0; i < limbJoints.Length; i++) { float lowerLimit = -limbJoints[i].UpperLimit; @@ -648,6 +648,11 @@ namespace Barotrauma Limbs[i].Dir = Dir; + if (Limbs[i].LightSource != null) + { + Limbs[i].LightSource.SpriteEffect = (dir == Direction.Left) ? SpriteEffects.FlipHorizontally : SpriteEffects.None; + } + if (Limbs[i].pullJoint == null) continue; Limbs[i].pullJoint.LocalAnchorA = @@ -913,6 +918,10 @@ namespace Barotrauma } } + if (limb.LightSource != null) + { + limb.LightSource.Rotation = limb.Rotation; + } limb.Update(deltaTime); } diff --git a/Subsurface/Source/DebugConsole.cs b/Subsurface/Source/DebugConsole.cs index d18889d4e..a505c9da7 100644 --- a/Subsurface/Source/DebugConsole.cs +++ b/Subsurface/Source/DebugConsole.cs @@ -6,6 +6,7 @@ using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Barotrauma.Networking; using Barotrauma.Items.Components; +using System.Text; namespace Barotrauma { @@ -123,7 +124,6 @@ namespace Barotrauma if (PlayerInput.KeyDown(Keys.Enter) && textBox.Text != "") { - NewMessage(textBox.Text, Color.White); ExecuteCommand(textBox.Text, game); textBox.Text = ""; @@ -165,6 +165,7 @@ namespace Barotrauma case "netstats": case "help": case "dumpids": + case "admin": return true; default: return false; @@ -175,7 +176,11 @@ namespace Barotrauma { if (string.IsNullOrWhiteSpace(command)) return; string[] commands = command.Split(' '); - + + if (!commands[0].ToLowerInvariant().Equals("admin")) + { + NewMessage(textBox.Text, Color.White); + } #if !DEBUG if (GameMain.Client != null && !IsCommandPermitted(commands[0].ToLowerInvariant(), GameMain.Client)) @@ -370,6 +375,19 @@ namespace Barotrauma case "enablecrewai": HumanAIController.DisableCrewAI = false; break; + case "admin": + if (commands.Length < 2) break; + + if (GameMain.Server != null) + { + GameMain.Server.AdminAuthPass = commands[1]; + + } + else if (GameMain.Client != null) + { + GameMain.Client.RequestAdminAuth(commands[1]); + } + break; case "kick": if (GameMain.NetworkMember == null || commands.Length < 2) break; GameMain.NetworkMember.KickPlayer(string.Join(" ", commands.Skip(1)), false); diff --git a/Subsurface/Source/Items/Components/ItemComponent.cs b/Subsurface/Source/Items/Components/ItemComponent.cs index 82ade6dd9..bdd3a3735 100644 --- a/Subsurface/Source/Items/Components/ItemComponent.cs +++ b/Subsurface/Source/Items/Components/ItemComponent.cs @@ -119,7 +119,7 @@ namespace Barotrauma.Items.Components if (value == drawable) return; if (!(this is IDrawableComponent)) { - DebugConsole.ThrowError("Couldn't make ''"+this+"'' drawable (the component doesn't implement the IDrawableComponent interface)"); + DebugConsole.ThrowError("Couldn't make \""+this+"\" drawable (the component doesn't implement the IDrawableComponent interface)"); return; } diff --git a/Subsurface/Source/Map/Lights/LightSource.cs b/Subsurface/Source/Map/Lights/LightSource.cs index 36f7dbd3b..770d25443 100644 --- a/Subsurface/Source/Map/Lights/LightSource.cs +++ b/Subsurface/Source/Map/Lights/LightSource.cs @@ -18,6 +18,8 @@ namespace Barotrauma.Lights private float range; + public SpriteEffects SpriteEffect = SpriteEffects.None; + private Texture2D texture; public Sprite LightSprite; @@ -312,13 +314,14 @@ namespace Barotrauma.Lights overrideLightTexture.Draw(spriteBatch, drawPos, color * (color.A / 255.0f), overrideLightTexture.Origin, -Rotation, - new Vector2(overrideLightTexture.size.X / overrideLightTexture.SourceRect.Width, overrideLightTexture.size.Y / overrideLightTexture.SourceRect.Height)); + new Vector2(overrideLightTexture.size.X / overrideLightTexture.SourceRect.Width, overrideLightTexture.size.Y / overrideLightTexture.SourceRect.Height), + SpriteEffect); } } if (LightSprite != null) { - LightSprite.Draw(spriteBatch, drawPos, Color, LightSprite.Origin); + LightSprite.Draw(spriteBatch, drawPos, Color, LightSprite.Origin, -Rotation, 1, SpriteEffect); } } diff --git a/Subsurface/Source/Networking/ChatMessage.cs b/Subsurface/Source/Networking/ChatMessage.cs index ed71aa84c..4386318c0 100644 --- a/Subsurface/Source/Networking/ChatMessage.cs +++ b/Subsurface/Source/Networking/ChatMessage.cs @@ -116,9 +116,9 @@ namespace Barotrauma.Networking public void WriteNetworkMessage(NetOutgoingMessage msg) { - msg.WriteRangedInteger(0, Enum.GetValues(typeof(ChatMessageType)).Length, (byte)Type); - if (GameMain.Server != null) - { + msg.WriteRangedInteger(0, Enum.GetValues(typeof(ChatMessageType)).Length, (byte)Type); + if (GameMain.Server != null) + { msg.Write(Sender == null ? (ushort)0 : Sender.ID); msg.Write(SenderName); } @@ -128,30 +128,30 @@ namespace Barotrauma.Networking public static ChatMessage ReadNetworkMessage(NetBuffer msg) { - ChatMessageType type = (ChatMessageType)msg.ReadRangedInteger(0, Enum.GetValues(typeof(ChatMessageType)).Length); - string senderName=""; - Character character = null; - if (GameMain.Server == null) - { + ChatMessageType type = (ChatMessageType)msg.ReadRangedInteger(0, Enum.GetValues(typeof(ChatMessageType)).Length); + string senderName=""; + Character character = null; + if (GameMain.Server == null) + { ushort senderId = msg.ReadUInt16(); character = Entity.FindEntityByID(senderId) as Character; senderName = msg.ReadString(); } - else - { - NetIncomingMessage inc = msg as NetIncomingMessage; - if (inc == null) return null; - Client sender = GameMain.Server.ConnectedClients.Find(x => x.Connection == inc.SenderConnection); - if (sender == null) return null; - character = sender.Character; - if (character != null) - { - senderName = character.Name; - } - else - { - senderName = sender.name; - } + else + { + NetIncomingMessage inc = msg as NetIncomingMessage; + if (inc == null) return null; + Client sender = GameMain.Server.ConnectedClients.Find(x => x.Connection == inc.SenderConnection); + if (sender == null) return null; + character = sender.Character; + if (character != null) + { + senderName = character.Name; + } + else + { + senderName = sender.name; + } } string text = msg.ReadString(); diff --git a/Subsurface/Source/Networking/Client.cs b/Subsurface/Source/Networking/Client.cs index 9cafb37d6..5d3e6ee96 100644 --- a/Subsurface/Source/Networking/Client.cs +++ b/Subsurface/Source/Networking/Client.cs @@ -52,13 +52,13 @@ namespace Barotrauma.Networking public float deleteDisconnectedTimer; - public ClientPermissions Permissions; + public ClientPermissions Permissions = ClientPermissions.None; public int KickVoteCount { get { return kickVoters.Count; } } - + public Client(NetPeer server, string name, byte ID) : this(name, ID) { @@ -90,6 +90,7 @@ namespace Barotrauma.Networking public static string SanitizeName(string name) { + name = name.Trim(); if (name.Length > 20) { name = name.Substring(0, 20); @@ -128,7 +129,7 @@ namespace Barotrauma.Networking public bool HasPermission(ClientPermissions permission) { - return false; //Permissions.HasFlag(permission); + return this.Permissions.HasFlag(permission); } public T GetVote(VoteType voteType) diff --git a/Subsurface/Source/Networking/GameClient.cs b/Subsurface/Source/Networking/GameClient.cs index 0c92a62f6..887b7854b 100644 --- a/Subsurface/Source/Networking/GameClient.cs +++ b/Subsurface/Source/Networking/GameClient.cs @@ -26,7 +26,7 @@ namespace Barotrauma.Networking private GUIButton endRoundButton; private GUITickBox endVoteTickBox; - private ClientPermissions permissions; + private ClientPermissions permissions = ClientPermissions.None; private bool connected; @@ -839,7 +839,7 @@ namespace Barotrauma.Networking public bool HasPermission(ClientPermissions permission) { - return false;// permissions.HasFlag(permission); + return permissions.HasFlag(permission); } public override void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch) @@ -1026,6 +1026,15 @@ namespace Barotrauma.Networking client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered); } + public void RequestAdminAuth(string pass) + { + NetOutgoingMessage msg = client.CreateMessage(); + msg.Write((byte)PacketTypes.RequestAdminAuth); + msg.Write(Encoding.UTF8.GetString(NetUtility.ComputeSHAHash(Encoding.UTF8.GetBytes(pass)))); + + client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered); + } + public override void KickPlayer(string kickedName, bool ban, bool range = false) { if (!permissions.HasFlag(ClientPermissions.Kick) && !ban) return; @@ -1036,7 +1045,7 @@ namespace Barotrauma.Networking msg.Write(ban); msg.Write(kickedName); - client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered); + client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered); } public bool VoteForKick(GUIButton button, object userdata) @@ -1117,7 +1126,7 @@ namespace Barotrauma.Networking NetOutgoingMessage msg = client.CreateMessage(); msg.Write((byte)PacketTypes.CharacterInfo); - msg.Write(characterInfo.Name); + //msg.Write(characterInfo.Name); msg.Write(characterInfo.Gender == Gender.Male); msg.Write((byte)characterInfo.HeadSpriteId); diff --git a/Subsurface/Source/Networking/GameServer.cs b/Subsurface/Source/Networking/GameServer.cs index 82fda3bbf..0ec6463da 100644 --- a/Subsurface/Source/Networking/GameServer.cs +++ b/Subsurface/Source/Networking/GameServer.cs @@ -55,6 +55,8 @@ namespace Barotrauma.Networking name = name.Replace(":", ""); name = name.Replace(";", ""); + AdminAuthPass = ""; + this.name = name; this.password = ""; if (password.Length>0) @@ -551,6 +553,32 @@ namespace Barotrauma.Networking EndGame(); } break; + case (byte)PacketTypes.RequestAdminAuth: + string pass = inc.ReadString(); + if (adminAuthPass.Length == 0) + { + Log(sender.name + " tried to become admin!", Color.Red); + return; + } + if (adminAuthPass==pass) + { + if (sender.Permissions == ClientPermissions.None) + { + Log(sender.name + " is now an admin.", Color.Yellow); + sender.SetPermissions(ClientPermissions.Kick | ClientPermissions.Ban | ClientPermissions.EndRound); + } + else + { + Log(sender.name + " is no longer an admin.", Color.Yellow); + sender.SetPermissions(ClientPermissions.None); + } + UpdateClientPermissions(sender); + } + else + { + Log(sender.name + " has failed admin authentication!", Color.Red); + } + break; case (byte)PacketTypes.KickPlayer: bool ban = inc.ReadBoolean(); string kickedName = inc.ReadString(); @@ -561,7 +589,6 @@ namespace Barotrauma.Networking if (ban && !sender.HasPermission(ClientPermissions.Ban)) { Log(sender.name + " attempted to ban " + kickedClient.name + " (insufficient permissions)", Color.Red); - } else if (!sender.HasPermission(ClientPermissions.Kick)) { @@ -1719,24 +1746,25 @@ namespace Barotrauma.Networking Gender gender = Gender.Male; int headSpriteId = 0; + name = sender.name; try { - name = message.ReadString(); + //name = message.ReadString(); gender = message.ReadBoolean() ? Gender.Male : Gender.Female; headSpriteId = message.ReadByte(); } catch { - name = ""; + //name = ""; gender = Gender.Male; headSpriteId = 0; } - if (sender.characterInfo != null) + /*if (sender.characterInfo != null) { //clients can't change their character's name once it's been set name = sender.characterInfo.Name; - } + }*/ List jobPreferences = new List(); int count = message.ReadByte(); diff --git a/Subsurface/Source/Networking/GameServerLogin.cs b/Subsurface/Source/Networking/GameServerLogin.cs index 5008d08b5..66ab12f7c 100644 --- a/Subsurface/Source/Networking/GameServerLogin.cs +++ b/Subsurface/Source/Networking/GameServerLogin.cs @@ -143,14 +143,14 @@ 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())) - { + 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; + return; } //existing user re-joining @@ -198,6 +198,10 @@ namespace Barotrauma.Networking { newClient.SetPermissions(savedPermissions.Permissions); } + else + { + newClient.SetPermissions(ClientPermissions.None); + } connectedClients.Add(newClient); diff --git a/Subsurface/Source/Networking/GameServerSettings.cs b/Subsurface/Source/Networking/GameServerSettings.cs index 41432ee04..b89738ede 100644 --- a/Subsurface/Source/Networking/GameServerSettings.cs +++ b/Subsurface/Source/Networking/GameServerSettings.cs @@ -63,6 +63,20 @@ namespace Barotrauma.Networking private string password; + private string adminAuthPass = ""; + public string AdminAuthPass + { + set + { + DebugConsole.NewMessage("Admin auth pass changed!",Color.Yellow); + adminAuthPass = ""; + if (value.Length > 0) + { + adminAuthPass = Encoding.UTF8.GetString(Lidgren.Network.NetUtility.ComputeSHAHash(Encoding.UTF8.GetBytes(value))); + } + } + } + private GUIFrame settingsFrame; private GUIFrame[] settingsTabs; private int settingsTabIndex; diff --git a/Subsurface/Source/Networking/NetworkMember.cs b/Subsurface/Source/Networking/NetworkMember.cs index 21edefb26..8ff348815 100644 --- a/Subsurface/Source/Networking/NetworkMember.cs +++ b/Subsurface/Source/Networking/NetworkMember.cs @@ -19,6 +19,8 @@ namespace Barotrauma.Networking KickPlayer, + RequestAdminAuth, + Permissions, RequestNetLobbyUpdate, diff --git a/Subsurface/Source/Screens/EditMapScreen.cs b/Subsurface/Source/Screens/EditMapScreen.cs index 06f926915..e798b90bc 100644 --- a/Subsurface/Source/Screens/EditMapScreen.cs +++ b/Subsurface/Source/Screens/EditMapScreen.cs @@ -63,6 +63,41 @@ namespace Barotrauma return "Structures: " + (MapEntity.mapEntityList.Count - Item.ItemList.Count); } + private string GetTotalHullVolume() + { + float totalVol = 0.0f; + Hull.hullList.ForEach(h => { totalVol += h.FullVolume; }); + return "Total Hull Volume:\n" + totalVol; + } + + private string GetSelectedHullVolume() + { + float buoyancyVol = 0.0f; + float selectedVol = 0.0f; + float neutralPercentage = 0.07f; + Hull.hullList.ForEach(h => { + buoyancyVol += h.FullVolume; + if (h.IsSelected) + { + selectedVol += h.FullVolume; + } + }); + buoyancyVol *= neutralPercentage; + string retVal = "Selected Hull Volume:\n" + selectedVol; + if (selectedVol>0.0f && buoyancyVol>0.0f) + { + if (buoyancyVol / selectedVol < 1.0f) + { + retVal += " (optimal NeutralBallastLevel is " + (buoyancyVol / selectedVol) + ")"; + } + else + { + retVal += " (insufficient volume for buoyancy control)"; + } + } + return retVal; + } + private string GetPhysicsBodyCount() { return "Physics bodies: " + GameMain.World.BodyList.Count; @@ -89,6 +124,15 @@ namespace Barotrauma topPanel = new GUIFrame(new Rectangle(0, 0, 0, 31), GUI.Style); topPanel.Padding = new Vector4(5.0f, 5.0f, 5.0f, 5.0f); + GUIFrame hullVolumeFrame = new GUIFrame(new Rectangle(145, 26, 400, 100), GUI.Style, topPanel); + hullVolumeFrame.Padding = new Vector4(3.0f, 3.0f, 3.0f, 3.0f); + + GUITextBlock totalHullVolume = new GUITextBlock(new Rectangle(0, 0, 0, 20), "", GUI.Style, hullVolumeFrame); + totalHullVolume.TextGetter = GetTotalHullVolume; + + GUITextBlock selectedHullVolume = new GUITextBlock(new Rectangle(0, 50, 0, 20), "", GUI.Style, hullVolumeFrame); + selectedHullVolume.TextGetter = GetSelectedHullVolume; + var button = new GUIButton(new Rectangle(0, 0, 70, 20), "Open...", GUI.Style, topPanel); button.OnClicked = CreateLoadScreen; diff --git a/Subsurface/Source/Sounds/SoundPlayer.cs b/Subsurface/Source/Sounds/SoundPlayer.cs index 4fbe35629..9053d899e 100644 --- a/Subsurface/Source/Sounds/SoundPlayer.cs +++ b/Subsurface/Source/Sounds/SoundPlayer.cs @@ -314,7 +314,7 @@ namespace Barotrauma { return musicClips.Where(x => x != null && x.type == OverrideMusicType).ToList(); } - else if (Character.Controlled != null && Level.Loaded != null && Level.Loaded.Ruins.Any(r => r.Area.Contains(Character.Controlled.WorldPosition))) + else if (Character.Controlled != null && Level.Loaded != null && Level.Loaded.Ruins!=null && Level.Loaded.Ruins.Any(r => r.Area.Contains(Character.Controlled.WorldPosition))) { return musicClips.Where(x => x != null && x.type == "ruins").ToList(); } diff --git a/Subsurface/Source/Utils/ToolBox.cs b/Subsurface/Source/Utils/ToolBox.cs index 101f2dd00..decd88e39 100644 --- a/Subsurface/Source/Utils/ToolBox.cs +++ b/Subsurface/Source/Utils/ToolBox.cs @@ -320,7 +320,7 @@ namespace Barotrauma if (components.Length!=3) { if (!errorMessages) return vector; - DebugConsole.ThrowError("Failed to parse the string ''"+stringVector3+"'' to Vector3"); + DebugConsole.ThrowError("Failed to parse the string \""+stringVector3+"\" to Vector3"); return vector; }