- submarines send position updates more frequently when they're moving faster

- small AICharacter syncing optimizations
- respawning can be disabled in server setting
- netstats show the total amount of bytes sent for each networkevent type
This commit is contained in:
Regalis
2016-07-20 17:20:27 +03:00
parent b81417ad16
commit 911846acff
8 changed files with 127 additions and 63 deletions

View File

@@ -100,21 +100,29 @@ namespace Barotrauma
//message.Write(AnimController.RefLimb.Rotation);
message.WriteRangedSingle(MathHelper.Clamp(AnimController.StunTimer, 0.0f, 60.0f), 0.0f, 60.0f, 8);
message.Write((byte)((health / maxHealth) * 255.0f));
Bleeding = MathHelper.Clamp(Bleeding, 0.0f, 5.0f);
message.WriteRangedSingle(Bleeding, 0.0f, 5.0f, 8);
message.Write(AnimController.StunTimer > 0.0f);
if (AnimController.StunTimer > 0.0f)
{
message.WriteRangedSingle(MathHelper.Clamp(AnimController.StunTimer, 0.0f, 60.0f), 0.0f, 60.0f, 8);
}
if (DoesBleed)
{
Bleeding = MathHelper.Clamp(Bleeding, 0.0f, 5.0f);
message.WriteRangedSingle(Bleeding, 0.0f, 5.0f, 8);
}
aiController.FillNetworkData(message);
return true;
case NetworkEventType.EntityUpdate:
message.Write(AnimController.Dir > 0.0f);
message.WriteRangedSingle(MathHelper.Clamp(AnimController.TargetMovement.X, -1.0f, 1.0f), -1.0f, 1.0f, 8);
message.WriteRangedSingle(MathHelper.Clamp(AnimController.TargetMovement.Y, -1.0f, 1.0f), -1.0f, 1.0f, 8);
message.WriteRangedSingle(MathHelper.Clamp(AnimController.TargetMovement.X, -1.0f, 1.0f), -1.0f, 1.0f, 4);
message.WriteRangedSingle(MathHelper.Clamp(AnimController.TargetMovement.Y, -1.0f, 1.0f), -1.0f, 1.0f, 4);
message.Write(Submarine != null);
if (AnimController.CanEnterSubmarine) message.Write(Submarine != null);
message.Write(AnimController.RefLimb.SimPosition.X);
message.Write(AnimController.RefLimb.SimPosition.Y);
@@ -124,7 +132,7 @@ namespace Barotrauma
#if DEBUG
DebugConsole.ThrowError("AICharacter network event had a wrong type ("+type+")");
#endif
return false;
return false;
}
}
@@ -168,11 +176,17 @@ namespace Barotrauma
try
{
newStunTimer = message.ReadRangedSingle(0.0f, 60.0f, 8);
newHealth = (message.ReadByte() / 255.0f) * maxHealth;
if (message.ReadBoolean())
{
newStunTimer = message.ReadRangedSingle(0.0f, 60.0f, 8);
}
newBleeding = message.ReadRangedSingle(0.0f, 5.0f, 8);
if (DoesBleed)
{
newBleeding = message.ReadRangedSingle(0.0f, 5.0f, 8);
}
}
catch (Exception e)
{
@@ -199,10 +213,10 @@ namespace Barotrauma
try
{
targetDir = message.ReadBoolean();
targetMovement.X = message.ReadRangedSingle(-1.0f, 1.0f, 8);
targetMovement.Y = message.ReadRangedSingle(-1.0f, 1.0f, 8);
targetMovement.X = message.ReadRangedSingle(-1.0f, 1.0f, 4);
targetMovement.Y = message.ReadRangedSingle(-1.0f, 1.0f, 4);
inSub = message.ReadBoolean();
if (AnimController.CanEnterSubmarine) inSub = message.ReadBoolean();
pos.X = message.ReadFloat();
pos.Y = message.ReadFloat();

View File

@@ -58,7 +58,7 @@ namespace Barotrauma
private Vector2 prevPosition;
private float lastNetworkUpdate;
private float lastNetworkUpdate, networkUpdateTimer;
//properties ----------------------------------------------------
@@ -425,7 +425,21 @@ namespace Barotrauma
{
if (Level.Loaded == null) return;
if (subBody!=null) subBody.Update(deltaTime);
if (subBody == null) return;
subBody.Update(deltaTime);
if (this != MainSub && MainSub.DockedTo.Contains(this)) return;
//send updates more frequently if moving fast
networkUpdateTimer -= MathHelper.Clamp(Velocity.Length(), 0.1f, 5.0f) * deltaTime;
if (networkUpdateTimer < 0.0f)
{
new Networking.NetworkEvent(ID, false);
networkUpdateTimer = 1.0f;
}
}
public void ApplyForce(Vector2 force)

View File

@@ -26,12 +26,12 @@ namespace Barotrauma
public TransitionCinematic(List<Submarine> submarines, Camera cam, float duration)
{
if (!submarines.Any(s => s != null)) return;
Vector2 targetPos = new Vector2(
submarines.Sum(s => s.Position.X),
submarines.Sum(s => s.Position.Y)) / submarines.Count;
if (!submarines.Any()) return;
if (submarines.First().AtEndPosition)
{
targetPos = Level.Loaded.EndPosition + Vector2.UnitY * 500.0f;

View File

@@ -96,9 +96,10 @@ namespace Barotrauma.Networking
NetPeerConfiguration config = new NetPeerConfiguration("barotrauma");
#if DEBUG
config.SimulatedLoss = 0.1f;
config.SimulatedMinimumLatency = 0.3f;
config.SimulatedRandomLatency = 0.5f;
config.SimulatedLoss = 0.05f;
config.SimulatedDuplicatesChance = 0.05f;
config.SimulatedMinimumLatency = 0.1f;
config.SimulatedRandomLatency = 0.2f;
#endif
config.DisableMessageType(NetIncomingMessageType.DebugMessage | NetIncomingMessageType.WarningMessage | NetIncomingMessageType.Receipt
@@ -448,32 +449,7 @@ namespace Barotrauma.Networking
message = ComposeNetworkEventMessage(NetworkEventDeliveryMethod.ReliableLidgren);
if (message != null) client.SendMessage(message, NetDeliveryMethod.ReliableUnordered);
//foreach (NetworkEvent networkEvent in NetworkEvent.Events)
//{
// if (networkEvent.IsImportant)
// {
// ReliableMessage reliableMessage = reliableChannel.CreateMessage();
// reliableMessage.InnerMessage.Write((byte)PacketTypes.NetworkEvent);
// if (networkEvent.FillData(reliableMessage.InnerMessage))
// {
// reliableChannel.SendMessage(reliableMessage, client.ServerConnection);
// }
// }
// else
// {
// NetOutgoingMessage message = client.CreateMessage();
// message.Write((byte)PacketTypes.NetworkEvent);
// if (networkEvent.FillData(message))
// {
// client.SendMessage(message, NetDeliveryMethod.Unreliable);
// }
// }
//}
NetworkEvent.Events.Clear();
// Update current time
@@ -650,7 +626,6 @@ namespace Barotrauma.Networking
endRoundButton.Selected = false;
int seed = inc.ReadInt32();
string levelSeed = inc.ReadString();
int missionTypeIndex = inc.ReadByte();
@@ -660,6 +635,8 @@ namespace Barotrauma.Networking
string modeName = inc.ReadString();
bool respawnAllowed = inc.ReadBoolean();
GameModePreset gameMode = GameModePreset.list.Find(gm => gm.Name == modeName);
if (gameMode == null)
@@ -681,7 +658,7 @@ namespace Barotrauma.Networking
GameMain.GameSession = new GameSession(GameMain.NetLobbyScreen.SelectedSub, "", gameMode, Mission.MissionTypes[missionTypeIndex]);
GameMain.GameSession.StartShift(levelSeed);
respawnManager = new RespawnManager(this);
if (respawnAllowed) respawnManager = new RespawnManager(this);
yield return CoroutineStatus.Running;

View File

@@ -63,7 +63,7 @@ namespace Barotrauma.Networking
#if DEBUG
config.SimulatedLoss = 0.05f;
config.SimulatedRandomLatency = 0.3f;
config.SimulatedRandomLatency = 0.2f;
config.SimulatedDuplicatesChance = 0.05f;
config.SimulatedMinimumLatency = 0.1f;
#endif
@@ -281,7 +281,7 @@ namespace Barotrauma.Networking
{
inGameHUD.Update((float)Physics.step);
respawnManager.Update(deltaTime);
if (respawnManager != null) respawnManager.Update(deltaTime);
bool isCrewDead =
connectedClients.Find(c => c.Character != null && !c.Character.IsDead)==null &&
@@ -391,16 +391,16 @@ namespace Barotrauma.Networking
private void SparseUpdate()
{
if (gameStarted)
{
foreach (Submarine sub in Submarine.Loaded)
{
//no need to send position updates for submarines that are docked to mainsub
if (sub != Submarine.MainSub && sub.DockedTo.Contains(Submarine.MainSub)) continue;
//if (gameStarted)
//{
// foreach (Submarine sub in Submarine.Loaded)
// {
// //no need to send position updates for submarines that are docked to mainsub
// if (sub != Submarine.MainSub && sub.DockedTo.Contains(Submarine.MainSub)) continue;
new NetworkEvent(sub.ID, false);
}
}
// new NetworkEvent(sub.ID, false);
// }
//}
foreach (Character c in Character.CharacterList)
{
@@ -957,7 +957,7 @@ namespace Barotrauma.Networking
GameServer.Log("Game mode: " + selectedMode.Name, Color.Cyan);
GameServer.Log("Level seed: " + GameMain.NetLobbyScreen.LevelSeed, Color.Cyan);
respawnManager = new RespawnManager(this);
if (AllowRespawn) respawnManager = new RespawnManager(this);
yield return CoroutineStatus.Running;
@@ -1061,6 +1061,8 @@ namespace Barotrauma.Networking
msg.Write(selectedMode.Name);
msg.Write(AllowRespawn);
//msg.Write(GameMain.NetLobbyScreen.GameDuration.TotalMinutes);
List<Client> playingClients = connectedClients.FindAll(c => c.Character != null);
@@ -1154,6 +1156,8 @@ namespace Barotrauma.Networking
public void SendRespawnManagerMsg()
{
if (respawnManager == null) return;
NetOutgoingMessage msg = server.CreateMessage();
respawnManager.WriteNetworkEvent(msg);
@@ -1418,7 +1422,7 @@ namespace Barotrauma.Networking
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));
netStats.Draw(spriteBatch, new Rectangle(200,0,800,200), this);
}

View File

@@ -68,6 +68,12 @@ namespace Barotrauma.Networking
set;
}
public bool AllowRespawn
{
get;
set;
}
public SelectionMode SubSelectionMode
{
get { return subSelectionMode; }
@@ -123,6 +129,8 @@ namespace Barotrauma.Networking
writer.WriteAttributeString("SubSelection", subSelectionMode.ToString());
writer.WriteAttributeString("ModeSelection", modeSelectionMode.ToString());
writer.WriteAttributeString("AllowRespawn", AllowRespawn.ToString());
writer.Flush();
}
}
@@ -160,6 +168,8 @@ namespace Barotrauma.Networking
Enum.TryParse<SelectionMode>(ToolBox.GetAttributeString(doc.Root, "ModeSelection", "Manual"), out modeSelectionMode);
Voting.AllowModeVoting = modeSelectionMode == SelectionMode.Vote;
AllowRespawn = ToolBox.GetAttributeBool(doc.Root, "AllowRespawn", true);
FileStreamSender.MaxTransferDuration = new TimeSpan(0,0,ToolBox.GetAttributeInt(doc.Root, "MaxFileTransferDuration", 150));
}
@@ -190,9 +200,20 @@ namespace Barotrauma.Networking
return true;
};
var votesRequiredText = new GUITextBlock(new Rectangle(20, y+20, 20, 20), "Votes required: 50 %", GUI.Style, innerFrame, GUI.SmallFont);
y += 30;
var votesRequiredSlider = new GUIScrollBar(new Rectangle(150, y+22, 100, 10), GUI.Style, 0.1f, innerFrame);
var respawnBox = new GUITickBox(new Rectangle(0, y, 20, 20), "Allow respawning", Alignment.Left, innerFrame);
respawnBox.Selected = AllowRespawn;
respawnBox.OnSelected = (GUITickBox) =>
{
AllowRespawn = !AllowRespawn;
return true;
};
var votesRequiredText = new GUITextBlock(new Rectangle(20, y + 20, 20, 20), "Votes required: 50 %", GUI.Style, innerFrame, GUI.SmallFont);
var votesRequiredSlider = new GUIScrollBar(new Rectangle(150, y + 22, 100, 10), GUI.Style, 0.1f, innerFrame);
votesRequiredSlider.UserData = votesRequiredText;
votesRequiredSlider.Step = 0.2f;
votesRequiredSlider.BarScroll = (EndVoteRequiredRatio - 0.5f) * 2.0f;

View File

@@ -61,7 +61,7 @@ namespace Barotrauma.Networking
updateTimer = UpdateInterval;
}
public void Draw(SpriteBatch spriteBatch, Rectangle rect)
public void Draw(SpriteBatch spriteBatch, Rectangle rect, GameServer server)
{
GUI.DrawRectangle(spriteBatch, rect, Color.Black*0.4f, true);
@@ -83,6 +83,17 @@ namespace Barotrauma.Networking
spriteBatch.DrawString(GUI.SmallFont, "Peak resent: " + graphs[(int)NetStatType.ResentMessages].LargestValue() + " messages/s",
new Vector2(rect.X + 10, rect.Y + 50), Color.Red);
#if DEBUG
int y = 10;
foreach (KeyValuePair<string, long> msgBytesSent in server.messageCount.OrderBy(key => key.Value))
{
spriteBatch.DrawString(GUI.SmallFont, msgBytesSent.Key + ": " + MathUtils.GetBytesReadable(msgBytesSent.Value),
new Vector2(rect.Right - 200, rect.Y + y), Color.Red);
y += 15;
}
#endif
}
}

View File

@@ -55,6 +55,10 @@ namespace Barotrauma.Networking
abstract class NetworkMember
{
#if DEBUG
public Dictionary<string, long> messageCount = new Dictionary<string, long>();
#endif
protected NetPeer netPeer;
protected string name;
@@ -163,6 +167,24 @@ namespace Barotrauma.Networking
tempMessage.Position = 0;
msgBytes.Add(tempMessage.ReadBytes(tempMessage.LengthBytes));
#if DEBUG
string msgType = networkEvent.Type.ToString();
if (networkEvent.Type == NetworkEventType.EntityUpdate)
{
msgType += " (" + Entity.FindEntityByID(networkEvent.ID) + ")";
}
long sentBytes = 0;
if (!messageCount.TryGetValue(msgType, out sentBytes))
{
messageCount.Add(msgType, tempMessage.LengthBytes);
}
else
{
messageCount[msgType] += tempMessage.LengthBytes;
}
#endif
}
if (msgBytes.Count == 0) return null;
@@ -181,6 +203,7 @@ namespace Barotrauma.Networking
message.Write(msgData);
}
return message;
}