diff --git a/Subsurface/Source/Characters/AI/EnemyAIController.cs b/Subsurface/Source/Characters/AI/EnemyAIController.cs index 5dcb56769..7dccdc1a4 100644 --- a/Subsurface/Source/Characters/AI/EnemyAIController.cs +++ b/Subsurface/Source/Characters/AI/EnemyAIController.cs @@ -558,27 +558,12 @@ namespace Barotrauma bool wallAttack = (wallAttackPos != Vector2.Zero && state == AiState.Attack); - message.Write(wallAttack); - - //if (wallAttack) - //{ - // Vector2 relativeWallAttackPos = wallAttackPos - Submarine.Loaded.SimPosition; - - // message.WriteRangedSingle(MathHelper.Clamp(relativeWallAttackPos.X, -50.0f, 50.0f), -50.0f, 50.0f, 10); - // message.WriteRangedSingle(MathHelper.Clamp(relativeWallAttackPos.Y, -50.0f, 50.0f), -50.0f, 50.0f, 10); - //} - - //message.Write(Velocity.X); - //message.Write(Velocity.Y); - - //message.Write(Character.AnimController.RefLimb.SimPosition.X); - //message.Write(Character.AnimController.RefLimb.SimPosition.Y); - + //message.Write(wallAttack); message.Write(MathUtils.AngleToByte(steeringManager.WanderAngle)); - //message.WriteRangedSingle(MathHelper.Clamp(updateTargetsTimer,0.0f, UpdateTargetsInterval), 0.0f, UpdateTargetsInterval, 8); - //message.WriteRangedSingle(MathHelper.Clamp(raycastTimer, 0.0f, RaycastInterval), 0.0f, RaycastInterval, 8); - //message.WriteRangedSingle(MathHelper.Clamp(coolDownTimer, 0.0f, attackCoolDown * 2.0f), 0.0f, attackCoolDown * 2.0f, 8); + + coolDownTimer = MathHelper.Clamp(coolDownTimer, 0.0f, 30.0f); + message.WriteRangedSingle(coolDownTimer, 0.0f, 30.0f, 8); message.Write(targetEntity==null ? (ushort)0 : (targetEntity as Entity).ID); } @@ -612,9 +597,8 @@ namespace Barotrauma //targetPosition = new Vector2(message.ReadFloat(), message.ReadFloat()); wanderAngle = MathUtils.ByteToAngle(message.ReadByte()); - //updateTargetsTimer = message.ReadRangedSingle(0.0f, UpdateTargetsInterval, 8); - //raycastTimer = message.ReadRangedSingle(0.0f, RaycastInterval, 8); - //coolDownTimer = message.ReadRangedSingle(0.0f, attackCoolDown*2.0f, 8); + + coolDownTimer = message.ReadRangedSingle(0.0f, 30.0f, 8); targetID = message.ReadUInt16(); } @@ -629,14 +613,10 @@ namespace Barotrauma return; } - //wallAttackPos = newWallAttackPos; - steeringManager.WanderAngle = wanderAngle; - //this.updateTargetsTimer = updateTargetsTimer; - //this.raycastTimer = raycastTimer; - //this.coolDownTimer = coolDownTimer; - if (targetID > 0) targetEntity = Entity.FindEntityByID(targetID) as IDamageable; + if (targetID > 0) targetEntity = Entity.FindEntityByID(targetID) as IDamageable; + updateTargetsTimer = UpdateTargetsInterval; } } @@ -647,14 +627,8 @@ namespace Barotrauma //and if the target attacks the Character, the priority increases) class AITargetMemory { - //private AITarget target; private float priority; - - //public AITarget Target - //{ - // get { return target; } - //} - + public float Priority { get { return priority; } diff --git a/Subsurface/Source/Characters/StatusEffect.cs b/Subsurface/Source/Characters/StatusEffect.cs index 8f15f84fd..89f038175 100644 --- a/Subsurface/Source/Characters/StatusEffect.cs +++ b/Subsurface/Source/Characters/StatusEffect.cs @@ -10,9 +10,9 @@ namespace Barotrauma class StatusEffect { [Flags] - public enum TargetType + public enum TargetType { - This = 1, Parent = 2, Character = 4, Contained = 8, Nearby = 16, UseTarget=32 + This = 1, Parent = 2, Character = 4, Contained = 8, Nearby = 16, UseTarget = 32, Hull = 64 } private TargetType targetTypes; diff --git a/Subsurface/Source/GUI/GUI.cs b/Subsurface/Source/GUI/GUI.cs index a3cc951f0..b5e750d23 100644 --- a/Subsurface/Source/GUI/GUI.cs +++ b/Subsurface/Source/GUI/GUI.cs @@ -304,24 +304,34 @@ namespace Barotrauma return texture; } - public static bool DrawButton(SpriteBatch sb, Rectangle rect, string text, bool isHoldable = false) + public static bool DrawButton(SpriteBatch sb, Rectangle rect, string text, Color color, bool isHoldable = false) { - Color color = new Color(200, 200, 200); - bool clicked = false; if (rect.Contains(PlayerInput.MousePosition)) { clicked = PlayerInput.LeftButtonHeld(); - color = clicked ? new Color(100, 100, 100) : new Color(250, 250, 250); + color = clicked ? + new Color((int)(color.R * 0.8f), (int)(color.G * 0.8f), (int)(color.B * 0.8f), color.A) : + new Color((int)(color.R * 1.2f), (int)(color.G * 1.2f), (int)(color.B * 1.2f), color.A); - if (!isHoldable) - clicked = PlayerInput.LeftButtonClicked(); + if (!isHoldable) clicked = PlayerInput.LeftButtonClicked(); } DrawRectangle(sb, rect, color, true); - sb.DrawString(Font, text, new Vector2(rect.X + 10, rect.Y + 10), Color.White); + + Vector2 origin; + try + { + origin = Font.MeasureString(text)/2; + } + catch + { + origin = Vector2.Zero; + } + + sb.DrawString(Font, text, new Vector2(rect.Center.X, rect.Center.Y) , Color.White, 0.0f, origin, 1.0f, SpriteEffects.None, 0.0f); return clicked; } diff --git a/Subsurface/Source/Items/Components/Holdable/Propulsion.cs b/Subsurface/Source/Items/Components/Holdable/Propulsion.cs index 5b29339db..2a2435e52 100644 --- a/Subsurface/Source/Items/Components/Holdable/Propulsion.cs +++ b/Subsurface/Source/Items/Components/Holdable/Propulsion.cs @@ -76,7 +76,7 @@ namespace Barotrauma.Items.Components { foreach (Limb limb in character.AnimController.Limbs) { - if (limb.WearingItems.Find(w => w.WearableComponent.Item != this.item)==null) continue; + if (limb.WearingItems.Find(w => w.WearableComponent.Item == this.item)==null) continue; limb.body.ApplyForce(propulsion); } diff --git a/Subsurface/Source/Items/Components/Machines/Engine.cs b/Subsurface/Source/Items/Components/Machines/Engine.cs index 3b01a68d4..f4b279a0f 100644 --- a/Subsurface/Source/Items/Components/Machines/Engine.cs +++ b/Subsurface/Source/Items/Components/Machines/Engine.cs @@ -48,6 +48,24 @@ namespace Barotrauma.Items.Components : base(item, element) { IsActive = true; + + var button = new GUIButton(new Rectangle(160, 50, 30, 30), "-", GUI.Style, GuiFrame); + button.OnClicked = (GUIButton btn, object obj) => + { + targetForce -= 1.0f; + item.NewComponentEvent(this, true, false); + + return true; + }; + + button = new GUIButton(new Rectangle(200, 50, 30, 30), "+", GUI.Style, GuiFrame); + button.OnClicked = (GUIButton btn, object obj) => + { + targetForce += 1.0f; + item.NewComponentEvent(this, true, false); + + return true; + }; } public float CurrentVolume @@ -80,7 +98,7 @@ namespace Barotrauma.Items.Components voltage = 0.0f; } - + public override void DrawHUD(SpriteBatch spriteBatch, Character character) { //isActive = true; @@ -93,18 +111,7 @@ namespace Barotrauma.Items.Components //GUI.DrawRectangle(spriteBatch, new Rectangle(x, y, width, height), Color.Black, true); spriteBatch.DrawString(GUI.Font, "Force: " + (int)(targetForce) + " %", new Vector2(GuiFrame.Rect.X + 30, GuiFrame.Rect.Y + 30), Color.White); - - if (GUI.DrawButton(spriteBatch, new Rectangle(GuiFrame.Rect.X + 280, GuiFrame.Rect.Y + 80, 40, 40), "-", true)) - { - targetForce -= 1.0f; - item.NewComponentEvent(this, true, false); - } - - if (GUI.DrawButton(spriteBatch, new Rectangle(GuiFrame.Rect.X + 280, GuiFrame.Rect.Y + 30, 40, 40), "+", true)) - { - targetForce += 1.0f; - item.NewComponentEvent(this, true, false); - } + } public override void UpdateBroken(float deltaTime, Camera cam) diff --git a/Subsurface/Source/Map/Gap.cs b/Subsurface/Source/Map/Gap.cs index d483046d2..b89793040 100644 --- a/Subsurface/Source/Map/Gap.cs +++ b/Subsurface/Source/Map/Gap.cs @@ -154,9 +154,12 @@ namespace Barotrauma if (GameMain.DebugDraw) { Vector2 center = new Vector2(WorldRect.X + rect.Width / 2.0f, -(WorldRect.Y - rect.Height/ 2.0f)); - GUI.DrawLine(sb, center, center + flowForce/10.0f, Color.Red); - GUI.DrawLine(sb, center + Vector2.One * 5.0f, center + lerpedFlowForce / 10.0f + Vector2.One * 5.0f, Color.Orange); + + + GUI.DrawLine(sb, center, center + new Vector2(flowForce.X, -flowForce.Y)/10.0f, Color.Red); + + GUI.DrawLine(sb, center + Vector2.One * 5.0f, center + new Vector2(lerpedFlowForce.X, -lerpedFlowForce.Y) / 10.0f + Vector2.One * 5.0f, Color.Orange); } if (!editing || !ShowGaps) return; @@ -288,6 +291,25 @@ namespace Barotrauma } } + + + if (flowTargetHull != null && lerpedFlowForce != Vector2.Zero) + { + foreach (Character character in Character.CharacterList) + { + if (character.AnimController.CurrentHull != flowTargetHull) continue; + + foreach (Limb limb in character.AnimController.Limbs) + { + if (!limb.inWater) continue; + + float dist = Vector2.Distance(limb.WorldPosition, WorldPosition); + if (dist > lerpedFlowForce.Length()) continue; + + limb.body.ApplyForce(lerpedFlowForce / dist/10.0f); + } + } + } } @@ -444,7 +466,7 @@ namespace Barotrauma if (open > 0.0f) { - if (hull1.Volume>hull1.FullVolume && hull2.Volume>hull2.FullVolume) + if (hull1.Volume > hull1.FullVolume - Hull.MaxCompress && hull2.Volume > hull2.FullVolume - Hull.MaxCompress) { float avgLethality = (hull1.LethalPressure + hull2.LethalPressure) / 2.0f; hull1.LethalPressure = avgLethality; @@ -497,21 +519,31 @@ namespace Barotrauma lowerSurface = rect.Y; if (hull1.Volume < hull1.FullVolume - Hull.MaxCompress && - hull1.Surface > -rect.Y) + hull1.Surface < rect.Y) { - float vel = (rect.Y + hull1.Surface) * 0.03f; + if (rect.X > hull1.Rect.X + hull1.Rect.Width / 2.0f) { + float vel = ((rect.Y - rect.Height / 2) - (hull1.Surface + hull1.WaveY[hull1.WaveY.Length - 1])) * 0.1f; + + hull1.WaveVel[hull1.WaveY.Length - 1] += vel; hull1.WaveVel[hull1.WaveY.Length - 2] += vel; } else { + float vel = ((rect.Y - rect.Height / 2) - (hull1.Surface + hull1.WaveY[0])) * 0.1f; + + hull1.WaveVel[0] += vel; hull1.WaveVel[1] += vel; } } + else + { + hull1.LethalPressure += (Submarine.Loaded != null && Submarine.Loaded.AtDamageDepth) ? 100.0f * deltaTime : 10.0f * deltaTime; + } } else { @@ -523,7 +555,12 @@ namespace Barotrauma { flowForce = new Vector2(0.0f, delta); } + if (hull1.Volume >= hull1.FullVolume - Hull.MaxCompress) + { + hull1.LethalPressure += (Submarine.Loaded != null && Submarine.Loaded.AtDamageDepth) ? 100.0f * deltaTime : 10.0f * deltaTime; + } } + } private void UpdateOxygen() diff --git a/Subsurface/Source/Map/Hull.cs b/Subsurface/Source/Map/Hull.cs index 37bce6d95..c0eb3cf8f 100644 --- a/Subsurface/Source/Map/Hull.cs +++ b/Subsurface/Source/Map/Hull.cs @@ -433,11 +433,6 @@ namespace Barotrauma update = false; } } - else - { - - LethalPressure += ( Submarine.Loaded!=null && Submarine.Loaded.AtDamageDepth) ? 100.0f*deltaTime : 10.0f * deltaTime; - } } public void Extinquish(float deltaTime, float amount, Vector2 position) diff --git a/Subsurface/Source/Map/Submarine.cs b/Subsurface/Source/Map/Submarine.cs index dbcc754f9..8c2879ee4 100644 --- a/Subsurface/Source/Map/Submarine.cs +++ b/Subsurface/Source/Map/Submarine.cs @@ -590,7 +590,7 @@ namespace Barotrauma { try { - filePaths.AddRange(Directory.GetDirectories(subDirectory)); + filePaths.AddRange(Directory.GetFiles(subDirectory).ToList()); } catch (Exception e) { @@ -604,6 +604,8 @@ namespace Barotrauma //Map savedMap = new Map(mapPath); SavedSubmarines.Add(new Submarine(path)); } + + if (GameMain.NetLobbyScreen!=null) GameMain.NetLobbyScreen.UpdateSubList(); } private XDocument OpenDoc(string file) diff --git a/Subsurface/Source/Networking/FileStreamReceiver.cs b/Subsurface/Source/Networking/FileStreamReceiver.cs index 886d5c8e4..8030dfff3 100644 --- a/Subsurface/Source/Networking/FileStreamReceiver.cs +++ b/Subsurface/Source/Networking/FileStreamReceiver.cs @@ -1,11 +1,14 @@ using Lidgren.Network; using System; using System.IO; +using System.Text.RegularExpressions; namespace Barotrauma.Networking { class FileStreamReceiver : IDisposable { + const int MaxFileSize = 1000000; + public delegate void OnFinished(FileStreamReceiver fileStreamReceiver); private OnFinished onFinished; @@ -18,12 +21,17 @@ namespace Barotrauma.Networking private string filePath; private FileTransferType fileType; - + public string FileName { get; private set; } + + public string FilePath + { + get { return filePath; } + } public ulong FileSize { @@ -35,12 +43,23 @@ namespace Barotrauma.Networking get { return received; } } + public FileTransferType FileType + { + get { return fileType; } + } + public FileTransferStatus Status { get; private set; } + public string ErrorMessage + { + get; + private set; + } + public float BytesPerSecond { get; @@ -49,13 +68,13 @@ namespace Barotrauma.Networking public float Progress { - get { return length / (float)received; } + get { return (float)received / (float)length; } } public FileStreamReceiver(NetClient client, string filePath, FileTransferType fileType, OnFinished onFinished) { - client = client; + this.client = client; this.filePath = filePath; this.fileType = fileType; @@ -78,8 +97,75 @@ namespace Barotrauma.Networking } } + private bool ValidateInitialData(byte type, string fileName, ulong fileSize) + { + if (fileSize > MaxFileSize) + { + ErrorMessage = "File too large (" + MathUtils.GetBytesReadable((long)fileSize) + ")"; + Status = FileTransferStatus.Error; + return false; + } + + if (type != (byte)fileType) + { + ErrorMessage = "Unexpected file type ''"+type+"'' (expected "+fileType+")"; + Status = FileTransferStatus.Error; + return false; + } + + if (!Regex.Match(fileName, @"^[\w\- ]+[\w\-. ]*$").Success) + { + ErrorMessage = "Illegal characters in file name ''"+fileName+"''"; + Status = FileTransferStatus.Error; + return false; + } + + switch (type) + { + case (byte)FileTransferType.Submarine: + if (Path.GetExtension(fileName) != ".sub") + { + ErrorMessage = "Wrong file extension ''" + Path.GetExtension(fileName)+"''! (Expected .sub)"; + + Status = FileTransferStatus.Error; + return false; + } + break; + } + + return true; + } + + public void DeleteFile() + { + string file = Path.Combine(filePath, FileName); + + writeStream.Flush(); + writeStream.Close(); + writeStream.Dispose(); + writeStream = null; + + Status = FileTransferStatus.Canceled; + + if (File.Exists(file)) + { + try + { + File.Delete(file); + } + catch (Exception e) + { + DebugConsole.ThrowError("Couldn't delete file ''" + file + "''!", e); + } + } + } + private void TryReadMessage(NetIncomingMessage inc) { + if (Status == FileTransferStatus.Error || + Status == FileTransferStatus.Finished || + Status == FileTransferStatus.Canceled) return; + //int chunkLen = inc.LengthBytes; if (length == 0) { @@ -90,14 +176,17 @@ namespace Barotrauma.Networking } byte fileTypeByte = inc.ReadByte(); - if (fileTypeByte != (byte)fileType) - { - Status = FileTransferStatus.Error; - return; - } length = inc.ReadUInt64(); FileName = inc.ReadString(); + + if (!ValidateInitialData(fileTypeByte, FileName, length)) + { + Status = FileTransferStatus.Error; + if (onFinished != null) onFinished(this); + return; + } + writeStream = new FileStream(Path.Combine(filePath, FileName), FileMode.Create, FileAccess.Write, FileShare.None); timeStarted = Environment.TickCount; @@ -106,6 +195,15 @@ namespace Barotrauma.Networking return; } + + if (received + (ulong)inc.LengthBytes > length*1.1f) + { + ErrorMessage = "Receiving more data than expected (> " + MathUtils.GetBytesReadable((long)(received + (ulong)inc.LengthBytes)) + ")"; + Status = FileTransferStatus.Error; + if (onFinished != null) onFinished(this); + return; + } + byte[] all = inc.ReadBytes(inc.LengthBytes - inc.PositionInBytes); received += (ulong)all.Length; writeStream.Write(all, 0, all.Length); @@ -117,6 +215,7 @@ namespace Barotrauma.Networking Status = FileTransferStatus.Receiving; + if (received >= length) { Status = FileTransferStatus.Finished; @@ -133,9 +232,12 @@ namespace Barotrauma.Networking protected virtual void Dispose(bool disposing) { - writeStream.Flush(); - writeStream.Close(); - writeStream.Dispose(); + if (writeStream != null) + { + writeStream.Flush(); + writeStream.Close(); + writeStream.Dispose(); + } } } diff --git a/Subsurface/Source/Networking/FileStreamSender.cs b/Subsurface/Source/Networking/FileStreamSender.cs index 24eb282da..86c2caf4b 100644 --- a/Subsurface/Source/Networking/FileStreamSender.cs +++ b/Subsurface/Source/Networking/FileStreamSender.cs @@ -6,7 +6,7 @@ namespace Barotrauma.Networking { enum FileTransferStatus { - NotStarted, Sending, Receiving, Finished, Error + NotStarted, Sending, Receiving, Finished, Error, Canceled } enum FileTransferType @@ -22,6 +22,8 @@ namespace Barotrauma.Networking private byte[] tempBuffer; private NetConnection connection; + float waitTimer; + private FileTransferType fileType; @@ -56,7 +58,7 @@ namespace Barotrauma.Networking chunkLen = connection.Peer.Configuration.MaximumTransmissionUnit - 100; tempBuffer = new byte[chunkLen]; sentOffset = 0; - + FileName = fileName; this.fileType = fileType; @@ -64,10 +66,13 @@ namespace Barotrauma.Networking Status = FileTransferStatus.NotStarted; } - public void Update() + public void Update(float deltaTime) { if (inputStream == null) return; + waitTimer -= deltaTime; + if (waitTimer > 0.0f) return; + if (!connection.CanSendImmediately(NetDeliveryMethod.ReliableOrdered, 1)) return; // send another part of the file! @@ -98,6 +103,8 @@ namespace Barotrauma.Networking connection.SendMessage(message, NetDeliveryMethod.ReliableOrdered, 1); sentOffset += sendBytes; + waitTimer = connection.AverageRoundtripTime + 0.05f; + //Program.Output("Sent " + m_sentOffset + "/" + m_inputStream.Length + " bytes to " + m_connection); if (remaining - sendBytes <= 0) diff --git a/Subsurface/Source/Networking/GameClient.cs b/Subsurface/Source/Networking/GameClient.cs index 29ca1f730..7b938b5d6 100644 --- a/Subsurface/Source/Networking/GameClient.cs +++ b/Subsurface/Source/Networking/GameClient.cs @@ -697,6 +697,25 @@ namespace Barotrauma.Networking { base.Draw(spriteBatch); + if (fileStreamReceiver != null && + (fileStreamReceiver.Status == FileTransferStatus.Receiving || fileStreamReceiver.Status == FileTransferStatus.NotStarted)) + { + Vector2 pos = Screen.Selected == GameMain.NetLobbyScreen ? + new Vector2(GameMain.NetLobbyScreen.SubList.Rect.X, GameMain.NetLobbyScreen.SubList.Rect.Bottom+5) : new Vector2(GameMain.GraphicsWidth / 2 - 200, 10); + + GUI.DrawString(spriteBatch, pos, "Downloading " + fileStreamReceiver.FileName, Color.White); + GUI.DrawString(spriteBatch, pos + Vector2.UnitX*300, + MathUtils.GetBytesReadable((long)fileStreamReceiver.Received) + " / " + MathUtils.GetBytesReadable((long)fileStreamReceiver.FileSize), Color.White); + GUI.DrawProgressBar(spriteBatch, new Vector2(pos.X, -pos.Y - 20), new Vector2(300, 15), fileStreamReceiver.Progress, Color.Green); + + if (GUI.DrawButton(spriteBatch, new Rectangle((int)pos.X + 310, (int)pos.Y + 20, 100, 15), "Cancel", new Color(0.88f, 0.25f, 0.15f, 0.8f))) + { + fileStreamReceiver.DeleteFile(); + fileStreamReceiver.Dispose(); + fileStreamReceiver = null; + } + } + if (!GameMain.DebugDraw) return; int width = 200, height = 300; @@ -711,27 +730,28 @@ namespace Barotrauma.Networking spriteBatch.DrawString(GUI.SmallFont, "Sent bytes: " + client.Statistics.SentBytes, new Vector2(x + 10, y + 75), Color.White); spriteBatch.DrawString(GUI.SmallFont, "Sent packets: " + client.Statistics.SentPackets, new Vector2(x + 10, y + 90), Color.White); - if (fileStreamReceiver!=null) - { - GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth / 2 - 100, 20), "Downloading "+fileStreamReceiver.FileName, Color.White); - GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth / 2 - 100, 20), - MathUtils.GetBytesReadable((long)fileStreamReceiver.Received)+" / "+MathUtils.GetBytesReadable((long)fileStreamReceiver.FileSize), Color.White); - GUI.DrawProgressBar(spriteBatch, new Vector2(GameMain.GraphicsWidth / 2 - 100, 20), new Vector2(200, 15), fileStreamReceiver.Progress, Color.Green); - } } private void OnFileReceived(FileStreamReceiver receiver) { if (receiver.Status == FileTransferStatus.Error) { - + new GUIMessageBox("Error while receiving file from server", receiver.ErrorMessage); + receiver.DeleteFile(); + } else if (receiver.Status == FileTransferStatus.Finished) { new GUIMessageBox("Download finished", "File ''"+receiver.FileName+"'' was downloaded succesfully."); + + switch (receiver.FileType) + { + case FileTransferType.Submarine: + Submarine.Preload(); + break; + } } - receiver.Dispose(); fileStreamReceiver = null; } diff --git a/Subsurface/Source/Networking/GameServer.cs b/Subsurface/Source/Networking/GameServer.cs index 94ebb4ee0..b970c6c9d 100644 --- a/Subsurface/Source/Networking/GameServer.cs +++ b/Subsurface/Source/Networking/GameServer.cs @@ -312,9 +312,9 @@ namespace Barotrauma.Networking foreach (Client c in ConnectedClients) { - if (c.FileStreamSender!=null) + if (c.FileStreamSender!=null && Rand.Range(0.0f, 1.0f)<0.01f) { - c.FileStreamSender.Update(); + c.FileStreamSender.Update(deltaTime); if (c.FileStreamSender.Status == FileTransferStatus.Finished || c.FileStreamSender.Status == FileTransferStatus.Error) @@ -516,8 +516,17 @@ namespace Barotrauma.Networking ReadCharacterData(inc); break; case (byte)PacketTypes.RequestFile: - string fileName = inc.ReadString(); + + if (!allowFileTransfers) + { + var outmsg = server.CreateMessage(); + outmsg.Write((byte)PacketTypes.RequestFile); + outmsg.Write(false); + break; + } + byte fileType = inc.ReadByte(); + string fileName = inc.ReadString(); switch (fileType) { @@ -552,11 +561,11 @@ namespace Barotrauma.Networking case (byte)PacketTypes.Vote: Voting.RegisterVote(inc, ConnectedClients); - if (Voting.AllowEndVoting && EndVoteMax > 0 && + if (Voting.AllowEndVoting && EndVoteMax > 0 && ((float)EndVoteCount / (float)EndVoteMax) >= EndVoteRequiredRatio) { - Log("Ending round by votes ("+EndVoteCount+"/"+(EndVoteMax-EndVoteCount)+")", Color.Cyan); - EndButtonHit(null,null); + Log("Ending round by votes (" + EndVoteCount + "/" + (EndVoteMax - EndVoteCount) + ")", Color.Cyan); + EndButtonHit(null, null); } break; case (byte)PacketTypes.RequestNetLobbyUpdate: diff --git a/Subsurface/Source/Networking/GameServerSettings.cs b/Subsurface/Source/Networking/GameServerSettings.cs index e945fe803..afeb6fb39 100644 --- a/Subsurface/Source/Networking/GameServerSettings.cs +++ b/Subsurface/Source/Networking/GameServerSettings.cs @@ -45,6 +45,8 @@ namespace Barotrauma.Networking private bool saveServerLogs = true; + private bool allowFileTransfers = true; + public bool AutoRestart { get { return (ConnectedClients.Count == 0) ? false : autoRestart; } diff --git a/Subsurface/Source/Networking/ServerLog.cs b/Subsurface/Source/Networking/ServerLog.cs index 4b02144de..19c0986df 100644 --- a/Subsurface/Source/Networking/ServerLog.cs +++ b/Subsurface/Source/Networking/ServerLog.cs @@ -9,7 +9,7 @@ namespace Barotrauma.Networking { class ServerLog { - const int LinesPerFile = 300; + const int LinesPerFile = 800; public const string SavePath = "ServerLogs"; diff --git a/Subsurface/Source/Properties.cs b/Subsurface/Source/Properties.cs index a2fae550f..dde192783 100644 --- a/Subsurface/Source/Properties.cs +++ b/Subsurface/Source/Properties.cs @@ -207,6 +207,11 @@ namespace Barotrauma return dictionary; } + public static Dictionary InitProperties(object obj) + { + return InitProperties(obj, null); + } + public static Dictionary InitProperties(object obj, XElement element) { var properties = TypeDescriptor.GetProperties(obj.GetType()).Cast(); @@ -226,16 +231,19 @@ namespace Barotrauma } } - //go through all the attributes in the xml element - //and set the value of the matching property if it is initializable - foreach (XAttribute attribute in element.Attributes()) + if (element!=null) { - ObjectProperty property = null; - if (!dictionary.TryGetValue(attribute.Name.ToString().ToLower(), out property)) continue; - if (!property.Attributes.OfType().Any()) continue; - property.TrySetValue(attribute.Value); + //go through all the attributes in the xml element + //and set the value of the matching property if it is initializable + foreach (XAttribute attribute in element.Attributes()) + { + ObjectProperty property = null; + if (!dictionary.TryGetValue(attribute.Name.ToString().ToLower(), out property)) continue; + if (!property.Attributes.OfType().Any()) continue; + property.TrySetValue(attribute.Value); + } } - + return dictionary; } diff --git a/Subsurface/Source/Screens/NetLobbyScreen.cs b/Subsurface/Source/Screens/NetLobbyScreen.cs index 1cd4d37fe..215131455 100644 --- a/Subsurface/Source/Screens/NetLobbyScreen.cs +++ b/Subsurface/Source/Screens/NetLobbyScreen.cs @@ -187,24 +187,7 @@ namespace Barotrauma voteText.UserData = "subvotes"; voteText.Visible = false; - if (Submarine.SavedSubmarines.Count > 0) - { - foreach (Submarine sub in Submarine.SavedSubmarines) - { - GUITextBlock textBlock = new GUITextBlock( - new Rectangle(0, 0, 0, 25), - sub.Name, GUI.Style, - Alignment.Left, Alignment.Left, - subList); - textBlock.Padding = new Vector4(10.0f, 0.0f, 0.0f, 0.0f); - textBlock.UserData = sub; - } - } - else - { - DebugConsole.ThrowError("No saved submarines found!"); - return; - } + UpdateSubList(); columnX += columnWidth + 20; @@ -213,8 +196,7 @@ namespace Barotrauma new GUITextBlock(new Rectangle(columnX, 120, 0, 30), "Game mode: ", GUI.Style, infoFrame); modeList = new GUIListBox(new Rectangle(columnX, 150, columnWidth, infoFrame.Rect.Height - 150 - 80), GUI.Style, infoFrame); modeList.OnSelected = VotableClicked; - - + voteText = new GUITextBlock(new Rectangle(columnX, 120, columnWidth, 30), "Votes: ", GUI.Style, Alignment.TopLeft, Alignment.TopRight, infoFrame); voteText.UserData = "modevotes"; voteText.Visible = false; @@ -533,6 +515,33 @@ namespace Barotrauma return true; } + public void UpdateSubList() + { + if (subList == null) return; + + subList.ClearChildren(); + + if (Submarine.SavedSubmarines.Count > 0) + { + foreach (Submarine sub in Submarine.SavedSubmarines) + { + GUITextBlock textBlock = new GUITextBlock( + new Rectangle(0, 0, 0, 25), + sub.Name, GUI.Style, + Alignment.Left, Alignment.Left, + subList); + textBlock.Padding = new Vector4(10.0f, 0.0f, 0.0f, 0.0f); + textBlock.UserData = sub; + } + } + else + { + DebugConsole.ThrowError("No saved submarines found!"); + return; + } + + } + public bool VotableClicked(GUIComponent component, object userData) { if (GameMain.Client == null) return false; @@ -921,7 +930,7 @@ namespace Barotrauma if (sub == null) { var requestFileBox = new GUIMessageBox("Submarine not found!", "The submarine ''" + subName + "'' has been selected by the server. " - +"Matching file not found in your map folder. Do you want to download the file from the server host?", new string[] { "Yes", "No" }); + +"Matching file not found in your map folder. Do you want to download the file from the server host?", new string[] { "Yes", "No" }, 400, 300); requestFileBox.Buttons[0].UserData = subName; requestFileBox.Buttons[0].OnClicked += requestFileBox.Close; requestFileBox.Buttons[0].OnClicked += (GUIButton button, object userdata) => @@ -938,10 +947,20 @@ namespace Barotrauma { if (sub.MD5Hash.Hash != md5Hash) { - new GUIMessageBox("Submarine not found!", + var requestFileBox = new GUIMessageBox("Submarine not found!", "Your version of the map file ''" + sub.Name + "'' doesn't match the server's version!" +"\nYour file: " + sub.Name + "(MD5 hash : " + sub.MD5Hash.Hash + ")" - +"\nServer's file: " + subName + "(MD5 hash : " + md5Hash + ")"); + +"\nServer's file: " + subName + "(MD5 hash : " + md5Hash + ")\n" + +"Do you want to download the file from the server host?", new string[] { "Yes", "No" }, 400, 300); + requestFileBox.Buttons[0].UserData = subName; + requestFileBox.Buttons[0].OnClicked += requestFileBox.Close; + requestFileBox.Buttons[0].OnClicked += (GUIButton button, object userdata) => + { + GameMain.Client.RequestFile(userdata.ToString(), FileTransferType.Submarine); + return true; + }; + requestFileBox.Buttons[1].OnClicked += requestFileBox.Close; + return false; } else diff --git a/Subsurface/Source/Screens/NetLobbyVoting.cs b/Subsurface/Source/Screens/NetLobbyVoting.cs index d69bd5f92..acafcfb9e 100644 --- a/Subsurface/Source/Screens/NetLobbyVoting.cs +++ b/Subsurface/Source/Screens/NetLobbyVoting.cs @@ -128,7 +128,7 @@ namespace Barotrauma voteText.UserData = "votes"; } - voteText.Text = votes.ToString(); + voteText.Text = votes == 0 ? "" : votes.ToString(); } } @@ -233,6 +233,11 @@ namespace Barotrauma AllowSubVoting = msg.ReadBoolean(); if (allowSubVoting) { + foreach (Submarine sub in Submarine.SavedSubmarines) + { + SetVoteText(GameMain.NetLobbyScreen.SubList, sub, 0); + } + int votableCount = msg.ReadByte(); for (int i = 0; i < votableCount; i++) { @@ -252,7 +257,7 @@ namespace Barotrauma int votes = msg.ReadByte(); string modeName = msg.ReadString(); GameModePreset mode = GameModePreset.list.Find(m => m.Name == modeName); - SetVoteText(GameMain.NetLobbyScreen.SubList, mode, votes); + SetVoteText(GameMain.NetLobbyScreen.ModeList, mode, votes); } } diff --git a/Subsurface/Source/Screens/ServerListScreen.cs b/Subsurface/Source/Screens/ServerListScreen.cs index 13a49f10e..26a57b4c6 100644 --- a/Subsurface/Source/Screens/ServerListScreen.cs +++ b/Subsurface/Source/Screens/ServerListScreen.cs @@ -169,7 +169,7 @@ namespace Barotrauma string maxPlayersStr = (arguments.Length > 5) ? arguments[5] : ""; - string hasPassWordStr = (arguments.Length > 5) ? arguments[5] : ""; + string hasPassWordStr = (arguments.Length > 6) ? arguments[6] : ""; var serverFrame = new GUIFrame(new Rectangle(0, 0, 0, 20), (i % 2 == 0) ? Color.Transparent : Color.White * 0.2f, null, serverList); serverFrame.UserData = IP + ":" + port; diff --git a/Subsurface_Solution.v12.suo b/Subsurface_Solution.v12.suo index a02bd522a..26a27c602 100644 Binary files a/Subsurface_Solution.v12.suo and b/Subsurface_Solution.v12.suo differ