240 lines
10 KiB
C#
240 lines
10 KiB
C#
using Lidgren.Network;
|
|
using Microsoft.Xna.Framework;
|
|
using System;
|
|
using System.Linq;
|
|
|
|
namespace Barotrauma.Networking
|
|
{
|
|
partial class GameServer : NetworkMember
|
|
{
|
|
private NetStats netStats;
|
|
|
|
private GUIScrollBar clientListScrollBar;
|
|
|
|
void InitProjSpecific()
|
|
{
|
|
var buttonContainer = new GUILayoutGroup(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.ButtonAreaTop, inGameHUD.RectTransform),
|
|
isHorizontal: true, childAnchor: Anchor.CenterRight)
|
|
{
|
|
CanBeFocused = false
|
|
};
|
|
|
|
var endRoundButton = new GUIButton(new RectTransform(new Vector2(0.1f, 0.6f), buttonContainer.RectTransform) { MinSize = new Point(150, 0) },
|
|
TextManager.Get("EndRound"))
|
|
{
|
|
OnClicked = (btn, userdata) => { EndGame(); return true; }
|
|
};
|
|
|
|
showLogButton = new GUIButton(new RectTransform(new Vector2(0.1f, 0.6f), buttonContainer.RectTransform) { MinSize = new Point(150, 0) },
|
|
TextManager.Get("ServerLog"))
|
|
{
|
|
OnClicked = (GUIButton button, object userData) =>
|
|
{
|
|
if (ServerLog.LogFrame == null)
|
|
{
|
|
ServerLog.CreateLogFrame();
|
|
}
|
|
else
|
|
{
|
|
ServerLog.LogFrame = null;
|
|
GUI.KeyboardDispatcher.Subscriber = null;
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
GUIButton settingsButton = new GUIButton(new RectTransform(new Vector2(0.1f, 0.6f), buttonContainer.RectTransform) { MinSize = new Point(150, 0) },
|
|
TextManager.Get("ServerSettingsButton"))
|
|
{
|
|
OnClicked = ToggleSettingsFrame,
|
|
UserData = "settingsButton"
|
|
};
|
|
}
|
|
|
|
public override void AddToGUIUpdateList()
|
|
{
|
|
if (GUI.DisableHUD) return;
|
|
base.AddToGUIUpdateList();
|
|
settingsFrame?.AddToGUIUpdateList();
|
|
}
|
|
|
|
public override void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch)
|
|
{
|
|
base.Draw(spriteBatch);
|
|
if (!ShowNetStats) return;
|
|
|
|
GUI.Font.DrawString(spriteBatch, "Unique Events: " + entityEventManager.UniqueEvents.Count, new Vector2(10, 50), Color.White);
|
|
|
|
int width = 200, height = 300;
|
|
int x = GameMain.GraphicsWidth - width, y = (int)(GameMain.GraphicsHeight * 0.3f);
|
|
|
|
if (clientListScrollBar == null)
|
|
{
|
|
clientListScrollBar = new GUIScrollBar(new RectTransform(new Point(10, height), GUI.Canvas) { AbsoluteOffset = new Point(x + width - 10, y) });
|
|
}
|
|
|
|
GUI.DrawRectangle(spriteBatch, new Rectangle(x, y, width, height), Color.Black * 0.7f, true);
|
|
GUI.Font.DrawString(spriteBatch, "Network statistics:", new Vector2(x + 10, y + 10), Color.White);
|
|
|
|
GUI.SmallFont.DrawString(spriteBatch, "Connections: " + server.ConnectionsCount, new Vector2(x + 10, y + 30), Color.White);
|
|
GUI.SmallFont.DrawString(spriteBatch, "Received bytes: " + MathUtils.GetBytesReadable(server.Statistics.ReceivedBytes), new Vector2(x + 10, y + 45), Color.White);
|
|
GUI.SmallFont.DrawString(spriteBatch, "Received packets: " + server.Statistics.ReceivedPackets, new Vector2(x + 10, y + 60), Color.White);
|
|
|
|
GUI.SmallFont.DrawString(spriteBatch, "Sent bytes: " + MathUtils.GetBytesReadable(server.Statistics.SentBytes), new Vector2(x + 10, y + 75), Color.White);
|
|
GUI.SmallFont.DrawString(spriteBatch, "Sent packets: " + server.Statistics.SentPackets, new Vector2(x + 10, y + 90), Color.White);
|
|
|
|
int resentMessages = 0;
|
|
|
|
int clientListHeight = connectedClients.Count * 40;
|
|
float scrollBarHeight = (height - 110) / (float)Math.Max(clientListHeight, 110);
|
|
|
|
if (clientListScrollBar.BarSize != scrollBarHeight)
|
|
{
|
|
clientListScrollBar.BarSize = scrollBarHeight;
|
|
}
|
|
|
|
int startY = y + 110;
|
|
y = (startY - (int)(clientListScrollBar.BarScroll * (clientListHeight - (height - 110))));
|
|
foreach (Client c in connectedClients)
|
|
{
|
|
Color clientColor = c.Connection.AverageRoundtripTime > 0.3f ? Color.Red : Color.White;
|
|
|
|
if (y >= startY && y < startY + height - 120)
|
|
{
|
|
GUI.SmallFont.DrawString(spriteBatch, c.Name + " (" + c.Connection.RemoteEndPoint.Address.ToString() + ")", new Vector2(x + 10, y), clientColor);
|
|
GUI.SmallFont.DrawString(spriteBatch, "Ping: " + (int)(c.Connection.AverageRoundtripTime * 1000.0f) + " ms", new Vector2(x + 20, y + 10), clientColor);
|
|
}
|
|
if (y + 25 >= startY && y < startY + height - 130) GUI.SmallFont.DrawString(spriteBatch, "Resent messages: " + c.Connection.Statistics.ResentMessages, new Vector2(x + 20, y + 20), clientColor);
|
|
|
|
resentMessages += (int)c.Connection.Statistics.ResentMessages;
|
|
|
|
y += 40;
|
|
}
|
|
|
|
clientListScrollBar.UpdateManually(1.0f / 60.0f);
|
|
clientListScrollBar.DrawManually(spriteBatch);
|
|
|
|
netStats.AddValue(NetStats.NetStatType.ResentMessages, Math.Max(resentMessages, 0));
|
|
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), this);
|
|
}
|
|
|
|
|
|
private void UpdateFileTransferIndicator(Client client)
|
|
{
|
|
var transfers = fileSender.ActiveTransfers.FindAll(t => t.Connection == client.Connection);
|
|
|
|
var clientNameBox = GameMain.NetLobbyScreen.PlayerList.Content.FindChild(client.Name);
|
|
|
|
var clientInfo = clientNameBox.FindChild("filetransfer");
|
|
if (clientInfo == null)
|
|
{
|
|
clientInfo = new GUIFrame(new RectTransform(new Vector2(0.4f, 0.9f), clientNameBox.RectTransform, Anchor.CenterRight) { RelativeOffset = new Vector2(0.1f, 0.0f) }, style: null)
|
|
{
|
|
UserData = "filetransfer"
|
|
};
|
|
var textBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), clientInfo.RectTransform),
|
|
"", textAlignment: Alignment.CenterRight, font: GUI.SmallFont)
|
|
{
|
|
TextScale = 0.8f,
|
|
TextGetter = () =>
|
|
{
|
|
string txt = "";
|
|
if (transfers.Count > 0)
|
|
{
|
|
txt += transfers[0].FileName + " ";
|
|
if (transfers.Count > 1) txt += "+ " + (transfers.Count - 1) + " others ";
|
|
}
|
|
txt += "(" + MathUtils.GetBytesReadable(transfers.Sum(t => t.SentOffset)) + " / " + MathUtils.GetBytesReadable(transfers.Sum(t => t.Data.Length)) + ")";
|
|
return txt;
|
|
}
|
|
};
|
|
|
|
var progressBar = new GUIProgressBar(new RectTransform(new Vector2(0.8f, 0.5f), clientInfo.RectTransform, Anchor.BottomLeft),
|
|
barSize: 0.0f, color: Color.Green)
|
|
{
|
|
IsHorizontal = true,
|
|
ProgressGetter = () => { return transfers.Sum(t => t.Progress) / transfers.Count; }
|
|
};
|
|
|
|
var cancelButton = new GUIButton(new RectTransform(new Vector2(0.2f, 0.5f), clientInfo.RectTransform, Anchor.BottomRight), "X")
|
|
{
|
|
OnClicked = (GUIButton button, object userdata) =>
|
|
{
|
|
transfers.ForEach(t => fileSender.CancelTransfer(t));
|
|
return true;
|
|
}
|
|
};
|
|
}
|
|
else if (transfers.Count == 0)
|
|
{
|
|
clientInfo.Parent.RemoveChild(clientInfo);
|
|
}
|
|
}
|
|
|
|
public override bool SelectCrewCharacter(Character character, GUIComponent characterFrame)
|
|
{
|
|
if (character == null) return false;
|
|
|
|
if (character != myCharacter)
|
|
{
|
|
var banButton = new GUIButton(new RectTransform(new Vector2(0.45f, 0.15f), characterFrame.RectTransform, Anchor.BottomRight),
|
|
TextManager.Get("Ban"))
|
|
{
|
|
UserData = character.Name,
|
|
OnClicked = GameMain.NetLobbyScreen.BanPlayer
|
|
};
|
|
var rangebanButton = new GUIButton(new RectTransform(new Vector2(0.45f, 0.15f), characterFrame.RectTransform, Anchor.BottomRight) { RelativeOffset = new Vector2(0.0f, 0.16f) },
|
|
TextManager.Get("BanRange"))
|
|
{
|
|
UserData = character.Name,
|
|
OnClicked = GameMain.NetLobbyScreen.BanPlayerRange
|
|
};
|
|
var kickButton = new GUIButton(new RectTransform(new Vector2(0.45f, 0.15f), characterFrame.RectTransform, Anchor.BottomLeft),
|
|
TextManager.Get("Kick"))
|
|
{
|
|
UserData = character.Name,
|
|
OnClicked = GameMain.NetLobbyScreen.KickPlayer
|
|
};
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private GUIMessageBox upnpBox;
|
|
void InitUPnP()
|
|
{
|
|
server.UPnP.ForwardPort(NetPeerConfiguration.Port, "barotrauma");
|
|
|
|
upnpBox = new GUIMessageBox(TextManager.Get("PleaseWaitUPnP"), TextManager.Get("AttemptingUPnP"), new string[] { TextManager.Get("Cancel") });
|
|
upnpBox.Buttons[0].OnClicked = upnpBox.Close;
|
|
}
|
|
|
|
bool DiscoveringUPnP()
|
|
{
|
|
return server.UPnP.Status == UPnPStatus.Discovering && GUIMessageBox.VisibleBox == upnpBox;
|
|
}
|
|
|
|
void FinishUPnP()
|
|
{
|
|
upnpBox.Close(null, null);
|
|
|
|
if (server.UPnP.Status == UPnPStatus.NotAvailable)
|
|
{
|
|
new GUIMessageBox(TextManager.Get("Error"), TextManager.Get("UPnPUnavailable"));
|
|
}
|
|
else if (server.UPnP.Status == UPnPStatus.Discovering)
|
|
{
|
|
new GUIMessageBox(TextManager.Get("Error"), TextManager.Get("UPnPTimedOut"));
|
|
}
|
|
}
|
|
|
|
public bool StartGameClicked(GUIButton button, object obj)
|
|
{
|
|
return StartGame();
|
|
}
|
|
}
|
|
}
|