v0.2.2: updated Lidgren, railgun shells can be bought, autorestart server, netstats, tutorial moloch spawning in a wall fix, misc error checks
This commit is contained in:
@@ -244,7 +244,7 @@ namespace Barotrauma.Networking
|
||||
NetConnectionStatus connectionStatus = (NetConnectionStatus)inc.ReadByte();
|
||||
Debug.WriteLine(connectionStatus);
|
||||
|
||||
if (connectionStatus != NetConnectionStatus.Connected)
|
||||
if (connectionStatus == NetConnectionStatus.Disconnected)
|
||||
{
|
||||
string denyMessage = inc.ReadString();
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@ namespace Barotrauma.Networking
|
||||
//for keeping track of disconnected clients in case the reconnect shortly after
|
||||
private List<Client> disconnectedClients = new List<Client>();
|
||||
|
||||
private NetStats netStats;
|
||||
|
||||
//is the server running
|
||||
bool started;
|
||||
|
||||
@@ -34,6 +36,20 @@ namespace Barotrauma.Networking
|
||||
|
||||
private string password;
|
||||
|
||||
private bool autoRestart;
|
||||
|
||||
public bool AutoRestart
|
||||
{
|
||||
get { return (connectedClients.Count==0) ? false : autoRestart; }
|
||||
set
|
||||
{
|
||||
autoRestart = value;
|
||||
|
||||
AutoRestartTimer = autoRestart ? 20.0f : 0.0f;
|
||||
}
|
||||
}
|
||||
public float AutoRestartTimer;
|
||||
|
||||
public GameServer(string name, int port, bool isPublic = false, string password = "", bool attemptUPnP = false, int maxPlayers = 10)
|
||||
{
|
||||
var endRoundButton = new GUIButton(new Rectangle(GameMain.GraphicsWidth - 290, 20, 150, 25), "End round", Alignment.TopLeft, GUI.Style, inGameHUD);
|
||||
@@ -44,9 +60,13 @@ namespace Barotrauma.Networking
|
||||
|
||||
config = new NetPeerConfiguration("barotrauma");
|
||||
|
||||
netStats = new NetStats();
|
||||
|
||||
#if DEBUG
|
||||
config.SimulatedLoss = 0.2f;
|
||||
config.SimulatedMinimumLatency = 0.3f;
|
||||
config.SimulatedDuplicatesChance = 0.05f;
|
||||
config.SimulatedMinimumLatency = 0.1f;
|
||||
#endif
|
||||
config.Port = port;
|
||||
Port = port;
|
||||
@@ -61,9 +81,9 @@ namespace Barotrauma.Networking
|
||||
config.DisableMessageType(NetIncomingMessageType.DebugMessage |
|
||||
NetIncomingMessageType.WarningMessage | NetIncomingMessageType.Receipt |
|
||||
NetIncomingMessageType.ErrorMessage | NetIncomingMessageType.Error);
|
||||
|
||||
|
||||
config.EnableMessageType(NetIncomingMessageType.ConnectionApproval);
|
||||
|
||||
|
||||
CoroutineManager.StartCoroutine(StartServer(isPublic));
|
||||
}
|
||||
|
||||
@@ -190,21 +210,23 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (response.ErrorException != null)
|
||||
{
|
||||
DebugConsole.ThrowError("Error while connecting to master server", response.ErrorException);
|
||||
DebugConsole.ThrowError("Error while registering to master server", response.ErrorException);
|
||||
registeredToMaster = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (response.StatusCode != System.Net.HttpStatusCode.OK)
|
||||
{
|
||||
DebugConsole.ThrowError("Error while connecting to master server (" + response.StatusCode + ": " + response.StatusDescription + ")");
|
||||
registeredToMaster = false;
|
||||
DebugConsole.NewMessage("Error while reporting to master server (" + response.StatusCode + ": " + response.StatusDescription + ")", Color.Red);
|
||||
//registeredToMaster = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
if (GameMain.DebugDraw) netStats.Update(deltaTime);
|
||||
|
||||
if (!started) return;
|
||||
|
||||
base.Update(deltaTime);
|
||||
@@ -212,6 +234,24 @@ namespace Barotrauma.Networking
|
||||
if (gameStarted)
|
||||
{
|
||||
inGameHUD.Update((float)Physics.step);
|
||||
|
||||
//if all characters dead
|
||||
if (AutoRestart &&
|
||||
connectedClients.Find(c => c.character != null && !c.character.IsDead)==null &&
|
||||
(myCharacter == null || myCharacter.IsDead))
|
||||
{
|
||||
EndButtonHit(null, null);
|
||||
AutoRestartTimer = 20.0f;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (autoRestart && Screen.Selected == GameMain.NetLobbyScreen && connectedClients.Count>0)
|
||||
{
|
||||
AutoRestartTimer -= deltaTime;
|
||||
if (AutoRestartTimer < 0.0f)
|
||||
{
|
||||
StartGameClicked(null,null);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = disconnectedClients.Count - 1; i >= 0; i-- )
|
||||
@@ -628,7 +668,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
List<Character> crew = new List<Character>();
|
||||
WayPoint[] assignedWayPoints = WayPoint.SelectCrewSpawnPoints(characterInfos);
|
||||
|
||||
|
||||
for (int i = 0; i < connectedClients.Count; i++)
|
||||
{
|
||||
connectedClients[i].character = new Character(
|
||||
@@ -817,7 +857,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
public void NewTraitor(Client traitor, Client target)
|
||||
{
|
||||
new GUIMessageBox("New traitor", traitor.name + " is the traitor and the target is " + target.name+".");
|
||||
//new GUIMessageBox("New traitor", traitor.name + " is the traitor and the target is " + target.name+".");
|
||||
|
||||
NetOutgoingMessage msg = server.CreateMessage();
|
||||
msg.Write((byte)PacketTypes.Traitor);
|
||||
@@ -846,15 +886,27 @@ namespace Barotrauma.Networking
|
||||
|
||||
spriteBatch.DrawString(GUI.SmallFont, "Sent bytes: " + server.Statistics.SentBytes, new Vector2(x + 10, y + 75), Color.White);
|
||||
spriteBatch.DrawString(GUI.SmallFont, "Sent packets: " + server.Statistics.SentPackets, new Vector2(x + 10, y + 90), Color.White);
|
||||
|
||||
|
||||
int resentMessages = 0;
|
||||
|
||||
y += 110;
|
||||
foreach (Client c in connectedClients)
|
||||
{
|
||||
spriteBatch.DrawString(GUI.SmallFont, c.name + ":", new Vector2(x + 10, y), Color.White);
|
||||
spriteBatch.DrawString(GUI.SmallFont, "- avg roundtrip " + c.Connection.AverageRoundtripTime+" s", new Vector2(x + 20, y + 15), Color.White);
|
||||
y += 50;
|
||||
|
||||
spriteBatch.DrawString(GUI.SmallFont, "- resent messages " + c.Connection.Statistics.ResentMessages, new Vector2(x + 20, y + 30), Color.White);
|
||||
|
||||
resentMessages += (int)c.Connection.Statistics.ResentMessages;
|
||||
|
||||
y += 50;
|
||||
}
|
||||
|
||||
netStats.AddValue(NetStats.NetStatType.ResentMessages, resentMessages);
|
||||
netStats.AddValue(NetStats.NetStatType.SentBytes, server.Statistics.SentBytes);
|
||||
netStats.AddValue(NetStats.NetStatType.ReceivedBytes, server.Statistics.ReceivedBytes);
|
||||
|
||||
netStats.Draw(spriteBatch, new Rectangle(200,0,800,200));
|
||||
|
||||
}
|
||||
|
||||
public bool UpdateNetLobby(object obj)
|
||||
|
||||
163
Subsurface/Source/Networking/NetStats.cs
Normal file
163
Subsurface/Source/Networking/NetStats.cs
Normal file
@@ -0,0 +1,163 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Barotrauma.Networking
|
||||
{
|
||||
class NetStats
|
||||
{
|
||||
public enum NetStatType
|
||||
{
|
||||
SentBytes = 0,
|
||||
ReceivedBytes = 1,
|
||||
ResentMessages = 2
|
||||
}
|
||||
|
||||
private Graph[] graphs;
|
||||
|
||||
private Queue<float>[] valueQueue;
|
||||
|
||||
private float[] lastValues;
|
||||
|
||||
const float UpdateInterval = 1.0f;
|
||||
float updateTimer;
|
||||
|
||||
public NetStats()
|
||||
{
|
||||
graphs = new Graph[3];
|
||||
|
||||
valueQueue = new Queue<float>[3];
|
||||
for (int i = 0; i < 3; i++ )
|
||||
{
|
||||
valueQueue[i] = new Queue<float>();
|
||||
graphs[i] = new Graph();
|
||||
}
|
||||
|
||||
lastValues = new float[3];
|
||||
}
|
||||
|
||||
public void AddValue(NetStatType statType, float value)
|
||||
{
|
||||
float valueChange = value - lastValues[(int)statType];
|
||||
|
||||
valueQueue[(int)statType].Enqueue(valueChange);
|
||||
|
||||
lastValues[(int)statType] = value;
|
||||
}
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
updateTimer -= deltaTime;
|
||||
|
||||
if (updateTimer > 0.0f) return;
|
||||
|
||||
for (int i = 0; i<3; i++)
|
||||
{
|
||||
int valueCount = valueQueue[i].Count;
|
||||
float totalValue = 0.0f;
|
||||
while (valueQueue[i].Count>1)
|
||||
{
|
||||
totalValue += valueQueue[i].Dequeue();
|
||||
}
|
||||
|
||||
graphs[i].Update(valueCount==0 ? 0.0f : totalValue/valueCount);
|
||||
}
|
||||
|
||||
updateTimer = UpdateInterval;
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, Rectangle rect)
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch, rect, Color.Black*0.4f, true);
|
||||
|
||||
graphs[(int)NetStatType.ReceivedBytes].Draw(spriteBatch, rect, null, 0.0f, Color.Cyan);
|
||||
|
||||
graphs[(int)NetStatType.SentBytes].Draw(spriteBatch, rect, null, 0.0f, Color.Orange);
|
||||
|
||||
graphs[(int)NetStatType.ResentMessages].Draw(spriteBatch, rect, null, 0.0f, Color.Red);
|
||||
|
||||
spriteBatch.DrawString(GUI.SmallFont, "Max received: "+graphs[(int)NetStatType.ReceivedBytes].LargestValue()+" bytes/s",
|
||||
new Vector2(rect.X + 10, rect.Y+10), Color.Cyan);
|
||||
|
||||
spriteBatch.DrawString(GUI.SmallFont, "Max sent: " + graphs[(int)NetStatType.SentBytes].LargestValue() + " bytes/s",
|
||||
new Vector2(rect.X + 10, rect.Y + 30), Color.Orange);
|
||||
|
||||
spriteBatch.DrawString(GUI.SmallFont, "Max resent: " + graphs[(int)NetStatType.ResentMessages].LargestValue() + " messages/s",
|
||||
new Vector2(rect.X + 10, rect.Y + 50), Color.Red);
|
||||
}
|
||||
}
|
||||
|
||||
class Graph
|
||||
{
|
||||
const int ArraySize = 100;
|
||||
|
||||
private float[] values;
|
||||
|
||||
public Graph()
|
||||
{
|
||||
values = new float[ArraySize];
|
||||
}
|
||||
|
||||
public float LargestValue()
|
||||
{
|
||||
float maxValue = 0.0f;
|
||||
for (int i = 0; i < values.Length; i++)
|
||||
{
|
||||
if (values[i] > maxValue) maxValue = values[i];
|
||||
}
|
||||
return maxValue;
|
||||
}
|
||||
|
||||
public void Update(float newValue)
|
||||
{
|
||||
for (int i = values.Length-1; i > 0; i--)
|
||||
{
|
||||
values[i] = values[i - 1];
|
||||
}
|
||||
values[0] = newValue;
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, Rectangle rect, float? maxVal, float xOffset, Color color)
|
||||
{
|
||||
float graphMaxVal = 1.0f;
|
||||
if (maxVal == null)
|
||||
{
|
||||
graphMaxVal = LargestValue();
|
||||
}
|
||||
else if (maxVal > 0.0f)
|
||||
{
|
||||
graphMaxVal = (float)maxVal;
|
||||
}
|
||||
|
||||
float lineWidth = (float)rect.Width / (float)(values.Length - 2);
|
||||
float yScale = (float)rect.Height / graphMaxVal;
|
||||
|
||||
GUI.DrawRectangle(spriteBatch, rect, Color.White);
|
||||
|
||||
Vector2 prevPoint = new Vector2(rect.Right, rect.Bottom - (values[1] + (values[0] - values[1]) * xOffset) * yScale);
|
||||
|
||||
float currX = rect.Right - ((xOffset - 1.0f) * lineWidth);
|
||||
|
||||
for (int i = 1; i < values.Length - 1; i++)
|
||||
{
|
||||
currX -= lineWidth;
|
||||
|
||||
Vector2 newPoint = new Vector2(currX, rect.Bottom - values[i] * yScale);
|
||||
|
||||
GUI.DrawLine(spriteBatch, prevPoint, newPoint - new Vector2(1.0f, 0), color);
|
||||
|
||||
prevPoint = newPoint;
|
||||
}
|
||||
|
||||
Vector2 lastPoint = new Vector2(rect.X,
|
||||
rect.Bottom - (values[values.Length - 1] + (values[values.Length - 2] - values[values.Length - 1]) * xOffset) * yScale);
|
||||
|
||||
GUI.DrawLine(spriteBatch, prevPoint, lastPoint, color);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -124,8 +124,15 @@ namespace Barotrauma.Networking
|
||||
System.Diagnostics.Debug.WriteLine("Networkevent entity: "+e.ToString());
|
||||
|
||||
//System.Diagnostics.Debug.WriteLine("new message: " + eventType +" - "+e);
|
||||
|
||||
e.ReadNetworkData(eventType, message);
|
||||
try
|
||||
{
|
||||
e.ReadNetworkData(eventType, message);
|
||||
}
|
||||
catch
|
||||
{
|
||||
DebugConsole.ThrowError("Received invalid network message");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user