Split Machines ItemComponents

There's still a lot of work to do before we can get the server to compile
This commit is contained in:
Juan Pablo Arce
2017-06-18 14:36:11 -03:00
parent 7168a534ed
commit 8f37e14917
98 changed files with 5264 additions and 4291 deletions
@@ -0,0 +1,86 @@
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace Barotrauma.Networking
{
partial class BanList
{
private GUIComponent banFrame;
public GUIComponent BanFrame
{
get { return banFrame; }
}
public GUIComponent CreateBanFrame(GUIComponent parent)
{
banFrame = new GUIListBox(new Rectangle(0, 0, 0, 0), "", parent);
foreach (BannedPlayer bannedPlayer in bannedPlayers)
{
GUITextBlock textBlock = new GUITextBlock(
new Rectangle(0, 0, 0, 25),
bannedPlayer.IP + " (" + bannedPlayer.Name + ")",
"",
Alignment.Left, Alignment.Left, banFrame);
textBlock.Padding = new Vector4(10.0f, 10.0f, 0.0f, 0.0f);
textBlock.UserData = banFrame;
var removeButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Remove", Alignment.Right | Alignment.CenterY, "", textBlock);
removeButton.UserData = bannedPlayer;
removeButton.OnClicked = RemoveBan;
if (bannedPlayer.IP.IndexOf(".x") <= -1)
{
var rangeBanButton = new GUIButton(new Rectangle(-100, 0, 100, 20), "Ban range", Alignment.Right | Alignment.CenterY, "", textBlock);
rangeBanButton.UserData = bannedPlayer;
rangeBanButton.OnClicked = RangeBan;
}
}
return banFrame;
}
private bool RemoveBan(GUIButton button, object obj)
{
BannedPlayer banned = obj as BannedPlayer;
if (banned == null) return false;
RemoveBan(banned);
if (banFrame != null)
{
banFrame.Parent.RemoveChild(banFrame);
CreateBanFrame(banFrame.Parent);
}
return true;
}
private bool RangeBan(GUIButton button, object obj)
{
BannedPlayer banned = obj as BannedPlayer;
if (banned == null) return false;
RangeBan(banned);
if (banFrame != null)
{
banFrame.Parent.RemoveChild(banFrame);
CreateBanFrame(banFrame.Parent);
}
return true;
}
private bool CloseFrame(GUIButton button, object obj)
{
banFrame = null;
return true;
}
}
}
@@ -12,6 +12,8 @@ namespace Barotrauma.Networking
{
partial class GameServer : NetworkMember
{
private NetStats netStats;
private GUIButton showLogButton;
private GUIScrollBar clientListScrollBar;
@@ -54,6 +56,13 @@ namespace Barotrauma.Networking
//----------------------------------------
}
public override void AddToGUIUpdateList()
{
if (started) base.AddToGUIUpdateList();
if (settingsFrame != null) settingsFrame.AddToGUIUpdateList();
if (log.LogFrame != null) log.LogFrame.AddToGUIUpdateList();
}
public override void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch)
{
@@ -0,0 +1,534 @@
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace Barotrauma.Networking
{
partial class GameServer : NetworkMember, IPropertyObject
{
private GUIFrame settingsFrame;
private GUIFrame[] settingsTabs;
private int settingsTabIndex;
private void CreateSettingsFrame()
{
settingsFrame = new GUIFrame(new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.Black * 0.5f, null);
GUIFrame innerFrame = new GUIFrame(new Rectangle(0, 0, 400, 430), null, Alignment.Center, "", settingsFrame);
innerFrame.Padding = new Vector4(20.0f, 20.0f, 20.0f, 20.0f);
new GUITextBlock(new Rectangle(0, -5, 0, 20), "Settings", "", innerFrame, GUI.LargeFont);
string[] tabNames = { "Rounds", "Server", "Banlist", "Whitelist" };
settingsTabs = new GUIFrame[tabNames.Length];
for (int i = 0; i < tabNames.Length; i++)
{
settingsTabs[i] = new GUIFrame(new Rectangle(0, 15, 0, innerFrame.Rect.Height - 120), null, Alignment.Center, "InnerFrame", innerFrame);
settingsTabs[i].Padding = new Vector4(40.0f, 20.0f, 40.0f, 40.0f);
var tabButton = new GUIButton(new Rectangle(85 * i, 35, 80, 20), tabNames[i], "", innerFrame);
tabButton.UserData = i;
tabButton.OnClicked = SelectSettingsTab;
}
settingsTabs[2].Padding = Vector4.Zero;
SelectSettingsTab(null, 0);
var closeButton = new GUIButton(new Rectangle(10, 0, 100, 20), "Close", Alignment.BottomRight, "", innerFrame);
closeButton.OnClicked = ToggleSettingsFrame;
//--------------------------------------------------------------------------------
// game settings
//--------------------------------------------------------------------------------
int y = 0;
settingsTabs[0].Padding = new Vector4(40.0f, 5.0f, 40.0f, 40.0f);
new GUITextBlock(new Rectangle(0, y, 100, 20), "Submarine selection:", "", settingsTabs[0]);
var selectionFrame = new GUIFrame(new Rectangle(0, y + 20, 300, 20), null, settingsTabs[0]);
for (int i = 0; i < 3; i++)
{
var selectionTick = new GUITickBox(new Rectangle(i * 100, 0, 20, 20), ((SelectionMode)i).ToString(), Alignment.Left, selectionFrame);
selectionTick.Selected = i == (int)subSelectionMode;
selectionTick.OnSelected = SwitchSubSelection;
selectionTick.UserData = (SelectionMode)i;
}
y += 45;
new GUITextBlock(new Rectangle(0, y, 100, 20), "Mode selection:", "", settingsTabs[0]);
selectionFrame = new GUIFrame(new Rectangle(0, y + 20, 300, 20), null, settingsTabs[0]);
for (int i = 0; i < 3; i++)
{
var selectionTick = new GUITickBox(new Rectangle(i * 100, 0, 20, 20), ((SelectionMode)i).ToString(), Alignment.Left, selectionFrame);
selectionTick.Selected = i == (int)modeSelectionMode;
selectionTick.OnSelected = SwitchModeSelection;
selectionTick.UserData = (SelectionMode)i;
}
y += 60;
var endBox = new GUITickBox(new Rectangle(0, y, 20, 20), "End round when destination reached", Alignment.Left, settingsTabs[0]);
endBox.Selected = EndRoundAtLevelEnd;
endBox.OnSelected = (GUITickBox) => { EndRoundAtLevelEnd = GUITickBox.Selected; return true; };
y += 25;
var endVoteBox = new GUITickBox(new Rectangle(0, y, 20, 20), "End round by voting", Alignment.Left, settingsTabs[0]);
endVoteBox.Selected = Voting.AllowEndVoting;
endVoteBox.OnSelected = (GUITickBox) =>
{
Voting.AllowEndVoting = !Voting.AllowEndVoting;
GameMain.Server.UpdateVoteStatus();
return true;
};
var votesRequiredText = new GUITextBlock(new Rectangle(20, y + 15, 20, 20), "Votes required: 50 %", "", settingsTabs[0], GUI.SmallFont);
var votesRequiredSlider = new GUIScrollBar(new Rectangle(150, y + 22, 100, 15), "", 0.1f, settingsTabs[0]);
votesRequiredSlider.UserData = votesRequiredText;
votesRequiredSlider.Step = 0.2f;
votesRequiredSlider.BarScroll = (EndVoteRequiredRatio - 0.5f) * 2.0f;
votesRequiredSlider.OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
{
GUITextBlock voteText = scrollBar.UserData as GUITextBlock;
EndVoteRequiredRatio = barScroll / 2.0f + 0.5f;
voteText.Text = "Votes required: " + (int)MathUtils.Round(EndVoteRequiredRatio * 100.0f, 10.0f) + " %";
return true;
};
votesRequiredSlider.OnMoved(votesRequiredSlider, votesRequiredSlider.BarScroll);
y += 35;
var respawnBox = new GUITickBox(new Rectangle(0, y, 20, 20), "Allow respawning", Alignment.Left, settingsTabs[0]);
respawnBox.Selected = AllowRespawn;
respawnBox.OnSelected = (GUITickBox) =>
{
AllowRespawn = !AllowRespawn;
return true;
};
var respawnIntervalText = new GUITextBlock(new Rectangle(20, y + 13, 20, 20), "Respawn interval", "", settingsTabs[0], GUI.SmallFont);
var respawnIntervalSlider = new GUIScrollBar(new Rectangle(150, y + 20, 100, 15), "", 0.1f, settingsTabs[0]);
respawnIntervalSlider.UserData = respawnIntervalText;
respawnIntervalSlider.Step = 0.05f;
respawnIntervalSlider.BarScroll = RespawnInterval / 600.0f;
respawnIntervalSlider.OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
{
GUITextBlock text = scrollBar.UserData as GUITextBlock;
RespawnInterval = Math.Max(barScroll * 600.0f, 10.0f);
text.Text = "Interval: " + ToolBox.SecondsToReadableTime(RespawnInterval);
return true;
};
respawnIntervalSlider.OnMoved(respawnIntervalSlider, respawnIntervalSlider.BarScroll);
y += 35;
var minRespawnText = new GUITextBlock(new Rectangle(0, y, 200, 20), "Minimum players to respawn", "", settingsTabs[0]);
minRespawnText.ToolTip = "What percentage of players has to be dead/spectating until a respawn shuttle is dispatched";
var minRespawnSlider = new GUIScrollBar(new Rectangle(150, y + 20, 100, 15), "", 0.1f, settingsTabs[0]);
minRespawnSlider.ToolTip = minRespawnText.ToolTip;
minRespawnSlider.UserData = minRespawnText;
minRespawnSlider.Step = 0.1f;
minRespawnSlider.BarScroll = MinRespawnRatio;
minRespawnSlider.OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
{
GUITextBlock txt = scrollBar.UserData as GUITextBlock;
MinRespawnRatio = barScroll;
txt.Text = "Minimum players to respawn: " + (int)MathUtils.Round(MinRespawnRatio * 100.0f, 10.0f) + " %";
return true;
};
minRespawnSlider.OnMoved(minRespawnSlider, MinRespawnRatio);
y += 30;
var respawnDurationText = new GUITextBlock(new Rectangle(0, y, 200, 20), "Duration of respawn transport", "", settingsTabs[0]);
respawnDurationText.ToolTip = "The amount of time respawned players have to navigate the respawn shuttle to the main submarine. " +
"After the duration expires, the shuttle will automatically head back out of the level.";
var respawnDurationSlider = new GUIScrollBar(new Rectangle(150, y + 20, 100, 15), "", 0.1f, settingsTabs[0]);
respawnDurationSlider.ToolTip = minRespawnText.ToolTip;
respawnDurationSlider.UserData = respawnDurationText;
respawnDurationSlider.Step = 0.1f;
respawnDurationSlider.BarScroll = MaxTransportTime <= 0.0f ? 1.0f : (MaxTransportTime - 60.0f) / 600.0f;
respawnDurationSlider.OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
{
GUITextBlock txt = scrollBar.UserData as GUITextBlock;
if (barScroll == 1.0f)
{
MaxTransportTime = 0;
txt.Text = "Duration of respawn transport: unlimited";
}
else
{
MaxTransportTime = barScroll * 600.0f + 60.0f;
txt.Text = "Duration of respawn transport: " + ToolBox.SecondsToReadableTime(MaxTransportTime);
}
return true;
};
respawnDurationSlider.OnMoved(respawnDurationSlider, respawnDurationSlider.BarScroll);
y += 35;
var monsterButton = new GUIButton(new Rectangle(0, y, 130, 20), "Monster Spawns", "", settingsTabs[0]);
monsterButton.Enabled = !GameStarted;
var monsterFrame = new GUIListBox(new Rectangle(-290, 60, 280, 250), "", settingsTabs[0]);
monsterFrame.Visible = false;
monsterButton.UserData = monsterFrame;
monsterButton.OnClicked = (button, obj) =>
{
if (gameStarted)
{
((GUIComponent)obj).Visible = false;
button.Enabled = false;
return true;
}
((GUIComponent)obj).Visible = !((GUIComponent)obj).Visible;
return true;
};
List<string> monsterNames = monsterEnabled.Keys.ToList();
foreach (string s in monsterNames)
{
GUITextBlock textBlock = new GUITextBlock(
new Rectangle(0, 0, 260, 25),
s,
"",
Alignment.Left, Alignment.Left, monsterFrame);
textBlock.Padding = new Vector4(35.0f, 3.0f, 0.0f, 0.0f);
textBlock.UserData = monsterFrame;
textBlock.CanBeFocused = false;
var monsterEnabledBox = new GUITickBox(new Rectangle(-25, 0, 20, 20), "", Alignment.Left, textBlock);
monsterEnabledBox.Selected = monsterEnabled[s];
monsterEnabledBox.OnSelected = (GUITickBox) =>
{
if (gameStarted)
{
monsterFrame.Visible = false;
monsterButton.Enabled = false;
return true;
}
monsterEnabled[s] = !monsterEnabled[s];
return true;
};
}
var cargoButton = new GUIButton(new Rectangle(160, y, 130, 20), "Additional Cargo", "", settingsTabs[0]);
cargoButton.Enabled = !GameStarted;
var cargoFrame = new GUIListBox(new Rectangle(300, 60, 280, 250), "", settingsTabs[0]);
cargoFrame.Visible = false;
cargoButton.UserData = cargoFrame;
cargoButton.OnClicked = (button, obj) =>
{
if (gameStarted)
{
((GUIComponent)obj).Visible = false;
button.Enabled = false;
return true;
}
((GUIComponent)obj).Visible = !((GUIComponent)obj).Visible;
return true;
};
foreach (MapEntityPrefab pf in MapEntityPrefab.list)
{
if (!(pf is ItemPrefab) || (pf.Price <= 0.0f && !pf.tags.Contains("smallitem"))) continue;
GUITextBlock textBlock = new GUITextBlock(
new Rectangle(0, 0, 260, 25),
pf.Name, "",
Alignment.Left, Alignment.CenterLeft, cargoFrame, false, GUI.SmallFont);
textBlock.Padding = new Vector4(40.0f, 3.0f, 0.0f, 0.0f);
textBlock.UserData = cargoFrame;
textBlock.CanBeFocused = false;
if (pf.sprite != null)
{
float scale = Math.Min(Math.Min(30.0f / pf.sprite.SourceRect.Width, 30.0f / pf.sprite.SourceRect.Height), 1.0f);
GUIImage img = new GUIImage(new Rectangle(-20 - (int)(pf.sprite.SourceRect.Width * scale * 0.5f), 12 - (int)(pf.sprite.SourceRect.Height * scale * 0.5f), 40, 40), pf.sprite, Alignment.Left, textBlock);
img.Color = pf.SpriteColor;
img.Scale = scale;
}
int cargoVal = 0;
extraCargo.TryGetValue(pf.Name, out cargoVal);
var countText = new GUITextBlock(
new Rectangle(160, 0, 55, 25),
cargoVal.ToString(),
"",
Alignment.Left, Alignment.Center, textBlock);
var incButton = new GUIButton(new Rectangle(200, 5, 15, 15), ">", "", textBlock);
incButton.UserData = countText;
incButton.OnClicked = (button, obj) =>
{
int val;
if (extraCargo.TryGetValue(pf.Name, out val))
{
extraCargo[pf.Name]++; val = extraCargo[pf.Name];
}
else
{
extraCargo.Add(pf.Name, 1); val = 1;
}
((GUITextBlock)obj).Text = val.ToString();
((GUITextBlock)obj).SetTextPos();
return true;
};
var decButton = new GUIButton(new Rectangle(160, 5, 15, 15), "<", "", textBlock);
decButton.UserData = countText;
decButton.OnClicked = (button, obj) =>
{
int val;
if (extraCargo.TryGetValue(pf.Name, out val))
{
extraCargo[pf.Name]--;
val = extraCargo[pf.Name];
if (val <= 0)
{
extraCargo.Remove(pf.Name);
val = 0;
}
((GUITextBlock)obj).Text = val.ToString();
((GUITextBlock)obj).SetTextPos();
}
return true;
};
}
//--------------------------------------------------------------------------------
// server settings
//--------------------------------------------------------------------------------
y = 0;
var startIntervalText = new GUITextBlock(new Rectangle(-10, y, 100, 20), "Autorestart delay", "", settingsTabs[1]);
var startIntervalSlider = new GUIScrollBar(new Rectangle(10, y + 22, 100, 15), "", 0.1f, settingsTabs[1]);
startIntervalSlider.UserData = startIntervalText;
startIntervalSlider.Step = 0.05f;
startIntervalSlider.BarScroll = AutoRestartInterval / 300.0f;
startIntervalSlider.OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
{
GUITextBlock text = scrollBar.UserData as GUITextBlock;
AutoRestartInterval = Math.Max(barScroll * 300.0f, 10.0f);
text.Text = "Autorestart delay: " + ToolBox.SecondsToReadableTime(AutoRestartInterval);
return true;
};
startIntervalSlider.OnMoved(startIntervalSlider, startIntervalSlider.BarScroll);
y += 45;
var allowSpecBox = new GUITickBox(new Rectangle(0, y, 20, 20), "Allow spectating", Alignment.Left, settingsTabs[1]);
allowSpecBox.Selected = AllowSpectating;
allowSpecBox.OnSelected = (GUITickBox) =>
{
AllowSpectating = GUITickBox.Selected;
return true;
};
y += 40;
var voteKickBox = new GUITickBox(new Rectangle(0, y, 20, 20), "Allow vote kicking", Alignment.Left, settingsTabs[1]);
voteKickBox.Selected = Voting.AllowVoteKick;
voteKickBox.OnSelected = (GUITickBox) =>
{
Voting.AllowVoteKick = !Voting.AllowVoteKick;
GameMain.Server.UpdateVoteStatus();
return true;
};
var kickVotesRequiredText = new GUITextBlock(new Rectangle(20, y + 20, 20, 20), "Votes required: 50 %", "", settingsTabs[1], GUI.SmallFont);
var kickVoteSlider = new GUIScrollBar(new Rectangle(150, y + 22, 100, 15), "", 0.1f, settingsTabs[1]);
kickVoteSlider.UserData = kickVotesRequiredText;
kickVoteSlider.Step = 0.2f;
kickVoteSlider.BarScroll = (KickVoteRequiredRatio - 0.5f) * 2.0f;
kickVoteSlider.OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
{
GUITextBlock voteText = scrollBar.UserData as GUITextBlock;
KickVoteRequiredRatio = barScroll / 2.0f + 0.5f;
voteText.Text = "Votes required: " + (int)MathUtils.Round(KickVoteRequiredRatio * 100.0f, 10.0f) + " %";
return true;
};
kickVoteSlider.OnMoved(kickVoteSlider, kickVoteSlider.BarScroll);
y += 45;
var shareSubsBox = new GUITickBox(new Rectangle(0, y, 20, 20), "Share submarine files with players", Alignment.Left, settingsTabs[1]);
shareSubsBox.Selected = AllowFileTransfers;
shareSubsBox.OnSelected = (GUITickBox) =>
{
AllowFileTransfers = GUITickBox.Selected;
return true;
};
y += 40;
var randomizeLevelBox = new GUITickBox(new Rectangle(0, y, 20, 20), "Randomize level seed between rounds", Alignment.Left, settingsTabs[1]);
randomizeLevelBox.Selected = RandomizeSeed;
randomizeLevelBox.OnSelected = (GUITickBox) =>
{
RandomizeSeed = GUITickBox.Selected;
return true;
};
y += 40;
var saveLogsBox = new GUITickBox(new Rectangle(0, y, 20, 20), "Save server logs", Alignment.Left, settingsTabs[1]);
saveLogsBox.Selected = SaveServerLogs;
saveLogsBox.OnSelected = (GUITickBox) =>
{
SaveServerLogs = GUITickBox.Selected;
showLogButton.Visible = SaveServerLogs;
return true;
};
//--------------------------------------------------------------------------------
// banlist
//--------------------------------------------------------------------------------
banList.CreateBanFrame(settingsTabs[2]);
//--------------------------------------------------------------------------------
// whitelist
//--------------------------------------------------------------------------------
whitelist.CreateWhiteListFrame(settingsTabs[3]);
}
private bool SwitchSubSelection(GUITickBox tickBox)
{
subSelectionMode = (SelectionMode)tickBox.UserData;
foreach (GUIComponent otherTickBox in tickBox.Parent.children)
{
if (otherTickBox == tickBox) continue;
((GUITickBox)otherTickBox).Selected = false;
}
Voting.AllowSubVoting = subSelectionMode == SelectionMode.Vote;
if (subSelectionMode == SelectionMode.Random)
{
GameMain.NetLobbyScreen.SubList.Select(Rand.Range(0, GameMain.NetLobbyScreen.SubList.CountChildren));
}
return true;
}
private bool SelectSettingsTab(GUIButton button, object obj)
{
settingsTabIndex = (int)obj;
for (int i = 0; i < settingsTabs.Length; i++)
{
settingsTabs[i].Visible = i == settingsTabIndex;
}
return true;
}
private bool SwitchModeSelection(GUITickBox tickBox)
{
modeSelectionMode = (SelectionMode)tickBox.UserData;
foreach (GUIComponent otherTickBox in tickBox.Parent.children)
{
if (otherTickBox == tickBox) continue;
((GUITickBox)otherTickBox).Selected = false;
}
Voting.AllowModeVoting = modeSelectionMode == SelectionMode.Vote;
if (modeSelectionMode == SelectionMode.Random)
{
GameMain.NetLobbyScreen.ModeList.Select(Rand.Range(0, GameMain.NetLobbyScreen.ModeList.CountChildren));
}
return true;
}
public bool ToggleSettingsFrame(GUIButton button, object obj)
{
if (settingsFrame == null)
{
CreateSettingsFrame();
}
else
{
settingsFrame = null;
SaveSettings();
}
return false;
}
public void ManagePlayersFrame(GUIFrame infoFrame)
{
GUIListBox cList = new GUIListBox(new Rectangle(0, 0, 0, 300), Color.White * 0.7f, "", infoFrame);
cList.Padding = new Vector4(10.0f, 10.0f, 10.0f, 10.0f);
//crewList.OnSelected = SelectCrewCharacter;
foreach (Client c in ConnectedClients)
{
GUIFrame frame = new GUIFrame(new Rectangle(0, 0, 0, 40), Color.Transparent, null, cList);
frame.Padding = new Vector4(5.0f, 5.0f, 5.0f, 5.0f);
frame.Color = (c.inGame && c.Character != null && !c.Character.IsDead) ? Color.Gold * 0.2f : Color.Transparent;
frame.HoverColor = Color.LightGray * 0.5f;
frame.SelectedColor = Color.Gold * 0.5f;
GUITextBlock textBlock = new GUITextBlock(
new Rectangle(40, 0, 0, 25),
c.name + " (" + c.Connection.RemoteEndPoint.Address.ToString() + ")",
Color.Transparent, Color.White,
Alignment.Left, Alignment.Left,
null, frame);
var banButton = new GUIButton(new Rectangle(-110, 0, 100, 20), "Ban", Alignment.Right | Alignment.CenterY, "", frame);
banButton.UserData = c.name;
banButton.OnClicked = GameMain.NetLobbyScreen.BanPlayer;
var rangebanButton = new GUIButton(new Rectangle(-220, 0, 100, 20), "Ban range", Alignment.Right | Alignment.CenterY, "", frame);
rangebanButton.UserData = c.name;
rangebanButton.OnClicked = GameMain.NetLobbyScreen.BanPlayerRange;
var kickButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Kick", Alignment.Right | Alignment.CenterY, "", frame);
kickButton.UserData = c.name;
kickButton.OnClicked = GameMain.NetLobbyScreen.KickPlayer;
textBlock.Padding = new Vector4(5.0f, 0.0f, 5.0f, 0.0f);
}
}
}
}
@@ -0,0 +1,177 @@
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 float[] totalValue;
private float[] lastValue;
const float UpdateInterval = 0.1f;
float updateTimer;
public NetStats()
{
graphs = new Graph[3];
totalValue = new float[3];
lastValue = new float[3];
for (int i = 0; i < 3; i++ )
{
graphs[i] = new Graph();
}
}
public void AddValue(NetStatType statType, float value)
{
float valueChange = value - lastValue[(int)statType];
totalValue[(int)statType] += valueChange;
lastValue[(int)statType] = value;
}
public void Update(float deltaTime)
{
updateTimer -= deltaTime;
if (updateTimer > 0.0f) return;
for (int i = 0; i<3; i++)
{
graphs[i].Update(totalValue[i] / UpdateInterval);
totalValue[i] = 0.0f;
}
updateTimer = UpdateInterval;
}
public void Draw(SpriteBatch spriteBatch, Rectangle rect, GameServer server)
{
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);
GUI.SmallFont.DrawString(spriteBatch,
"Peak received: " + MathUtils.GetBytesReadable((int)graphs[(int)NetStatType.ReceivedBytes].LargestValue()) + "/s " +
"Avg received: " + MathUtils.GetBytesReadable((int)graphs[(int)NetStatType.ReceivedBytes].Average()) + "/s",
new Vector2(rect.X + 10, rect.Y + 10), Color.Cyan);
GUI.SmallFont.DrawString(spriteBatch, "Peak sent: " + MathUtils.GetBytesReadable((int)graphs[(int)NetStatType.SentBytes].LargestValue()) + "/s " +
"Avg sent: " + MathUtils.GetBytesReadable((int)graphs[(int)NetStatType.SentBytes].Average()) + "/s",
new Vector2(rect.X + 10, rect.Y + 30), Color.Orange);
GUI.SmallFont.DrawString(spriteBatch, "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))
{
GUI.SmallFont.DrawString(spriteBatch, msgBytesSent.Key + ": " + MathUtils.GetBytesReadable(msgBytesSent.Value),
new Vector2(rect.Right - 200, rect.Y + y), Color.Red);
y += 15;
}
#endif
}
}
class Graph
{
public 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 float Average()
{
return values.Length == 0 ? 0.0f : values.Average();
}
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;
}
GUI.DrawRectangle(spriteBatch, rect, Color.White);
if (values.Length == 0) return;
float lineWidth = (float)rect.Width / (float)(values.Length - 2);
float yScale = (float)rect.Height / graphMaxVal;
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);
}
}
}
@@ -0,0 +1,149 @@
using System;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System.Collections.Generic;
using Lidgren.Network;
using Barotrauma.Items.Components;
namespace Barotrauma.Networking
{
abstract partial class NetworkMember
{
protected GUIFrame inGameHUD;
protected GUIListBox chatBox;
protected GUITextBox chatMsgBox;
public GUIFrame InGameHUD
{
get { return inGameHUD; }
}
private void InitProjSpecific()
{
inGameHUD = new GUIFrame(new Rectangle(0, 0, 0, 0), null, null);
inGameHUD.CanBeFocused = false;
int width = (int)MathHelper.Clamp(GameMain.GraphicsWidth * 0.35f, 350, 500);
int height = (int)MathHelper.Clamp(GameMain.GraphicsHeight * 0.15f, 100, 200);
chatBox = new GUIListBox(new Rectangle(
GameMain.GraphicsWidth - 20 - width,
GameMain.GraphicsHeight - 40 - 25 - height,
width, height),
Color.White * 0.5f, "", inGameHUD);
chatBox.Padding = Vector4.Zero;
chatMsgBox = new GUITextBox(
new Rectangle(chatBox.Rect.X, chatBox.Rect.Y + chatBox.Rect.Height + 20, chatBox.Rect.Width, 25),
Color.White * 0.5f, Color.Black, Alignment.TopLeft, Alignment.Left, "", inGameHUD);
chatMsgBox.Font = GUI.SmallFont;
chatMsgBox.MaxTextLength = ChatMessage.MaxLength;
chatMsgBox.Padding = Vector4.Zero;
chatMsgBox.OnEnterPressed = EnterChatMessage;
chatMsgBox.OnTextChanged = TypingChatMessage;
}
public bool TypingChatMessage(GUITextBox textBox, string text)
{
string tempStr;
string command = ChatMessage.GetChatMessageCommand(text, out tempStr);
switch (command)
{
case "r":
case "radio":
textBox.TextColor = ChatMessage.MessageColor[(int)ChatMessageType.Radio];
break;
case "d":
case "dead":
textBox.TextColor = ChatMessage.MessageColor[(int)ChatMessageType.Dead];
break;
default:
textBox.TextColor = ChatMessage.MessageColor[(int)ChatMessageType.Default];
break;
}
return true;
}
public bool EnterChatMessage(GUITextBox textBox, string message)
{
textBox.TextColor = ChatMessage.MessageColor[(int)ChatMessageType.Default];
if (string.IsNullOrWhiteSpace(message)) return false;
if (this == GameMain.Server)
{
GameMain.Server.SendChatMessage(message, null, null);
}
else if (this == GameMain.Client)
{
GameMain.Client.SendChatMessage(message);
}
if (textBox == chatMsgBox) textBox.Deselect();
return true;
}
public virtual void AddToGUIUpdateList()
{
if (gameStarted && Screen.Selected == GameMain.GameScreen)
{
inGameHUD.AddToGUIUpdateList();
}
}
public virtual void Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch)
{
if (!gameStarted || Screen.Selected != GameMain.GameScreen) return;
GameMain.GameSession.CrewManager.Draw(spriteBatch);
inGameHUD.Draw(spriteBatch);
if (EndVoteCount > 0)
{
if (GameMain.NetworkMember.myCharacter == null)
{
GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - 180.0f, 40),
"Votes to end the round (y/n): " + EndVoteCount + "/" + (EndVoteMax - EndVoteCount), Color.White, null, 0, GUI.SmallFont);
}
else
{
GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - 140.0f, 40),
"Votes (y/n): " + EndVoteCount + "/" + (EndVoteMax - EndVoteCount), Color.White, null, 0, GUI.SmallFont);
}
}
if (respawnManager != null)
{
string respawnInfo = "";
if (respawnManager.CurrentState == RespawnManager.State.Waiting &&
respawnManager.CountdownStarted)
{
respawnInfo = respawnManager.RespawnTimer <= 0.0f ? "" : "Respawn Shuttle dispatching in " + ToolBox.SecondsToReadableTime(respawnManager.RespawnTimer);
}
else if (respawnManager.CurrentState == RespawnManager.State.Transporting)
{
respawnInfo = respawnManager.TransportTimer <= 0.0f ? "" : "Shuttle leaving in " + ToolBox.SecondsToReadableTime(respawnManager.TransportTimer);
}
if (!string.IsNullOrEmpty(respawnInfo))
{
GUI.DrawString(spriteBatch,
new Vector2(120.0f, 10),
respawnInfo, Color.White, null, 0, GUI.SmallFont);
}
}
}
public virtual bool SelectCrewCharacter(Character character, GUIComponent crewFrame)
{
return false;
}
}
}
@@ -0,0 +1,128 @@
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace Barotrauma.Networking
{
partial class ServerLog
{
public GUIFrame LogFrame;
private GUIListBox listBox;
public void CreateLogFrame()
{
LogFrame = new GUIFrame(new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.Black * 0.5f);
GUIFrame innerFrame = new GUIFrame(new Rectangle(0, 0, 600, 420), null, Alignment.Center, "", LogFrame);
innerFrame.Padding = new Vector4(10.0f, 20.0f, 10.0f, 20.0f);
new GUITextBlock(new Rectangle(-200, 0, 100, 15), "Filter", "", Alignment.TopRight, Alignment.CenterRight, innerFrame, false, GUI.SmallFont);
GUITextBox searchBox = new GUITextBox(new Rectangle(-20, 0, 180, 15), Alignment.TopRight, "", innerFrame);
searchBox.Font = GUI.SmallFont;
searchBox.OnTextChanged = (textBox, text) =>
{
msgFilter = text;
FilterMessages();
return true;
};
GUIComponent.KeyboardDispatcher.Subscriber = searchBox;
var clearButton = new GUIButton(new Rectangle(0, 0, 15, 15), "x", Alignment.TopRight, "", innerFrame);
clearButton.OnClicked = ClearFilter;
clearButton.UserData = searchBox;
listBox = new GUIListBox(new Rectangle(0, 30, 450, 340), "", Alignment.TopRight, innerFrame);
int y = 30;
foreach (MessageType msgType in Enum.GetValues(typeof(MessageType)))
{
var tickBox = new GUITickBox(new Rectangle(0, y, 20, 20), messageTypeName[(int)msgType], Alignment.TopLeft, GUI.SmallFont, innerFrame);
tickBox.Selected = true;
tickBox.TextColor = messageColor[(int)msgType];
tickBox.OnSelected += (GUITickBox tb) =>
{
msgTypeHidden[(int)msgType] = !tb.Selected;
FilterMessages();
return true;
};
y += 20;
}
var currLines = lines.ToList();
foreach (LogMessage line in currLines)
{
AddLine(line);
}
listBox.UpdateScrollBarSize();
if (listBox.BarScroll == 0.0f || listBox.BarScroll == 1.0f) listBox.BarScroll = 1.0f;
GUIButton closeButton = new GUIButton(new Rectangle(-100, 10, 100, 15), "Close", Alignment.BottomRight, "", innerFrame);
closeButton.OnClicked = (button, userData) =>
{
LogFrame = null;
return true;
};
msgFilter = "";
}
private void AddLine(LogMessage line)
{
float prevSize = listBox.BarSize;
var textBlock = new GUITextBlock(new Rectangle(0, 0, 0, 0), line.Text, "", Alignment.TopLeft, Alignment.TopLeft, listBox, true, GUI.SmallFont);
textBlock.Rect = new Rectangle(textBlock.Rect.X, textBlock.Rect.Y, textBlock.Rect.Width, Math.Max(13, textBlock.Rect.Height));
textBlock.TextColor = messageColor[(int)line.Type];
textBlock.CanBeFocused = false;
textBlock.UserData = line;
if ((prevSize == 1.0f && listBox.BarScroll == 0.0f) || (prevSize < 1.0f && listBox.BarScroll == 1.0f)) listBox.BarScroll = 1.0f;
}
private bool FilterMessages()
{
string filter = msgFilter == null ? "" : msgFilter.ToLower();
foreach (GUIComponent child in listBox.children)
{
var textBlock = child as GUITextBlock;
if (textBlock == null) continue;
child.Visible = true;
if (msgTypeHidden[(int)((LogMessage)child.UserData).Type])
{
child.Visible = false;
continue;
}
textBlock.Visible = string.IsNullOrEmpty(filter) || textBlock.Text.ToLower().Contains(filter);
}
listBox.BarScroll = 0.0f;
return true;
}
public bool ClearFilter(GUIComponent button, object obj)
{
var searchBox = button.UserData as GUITextBox;
if (searchBox != null) searchBox.Text = "";
msgFilter = "";
FilterMessages();
return true;
}
}
}
@@ -0,0 +1,112 @@
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace Barotrauma.Networking
{
partial class WhiteList
{
private GUIComponent whitelistFrame;
private GUITextBox nameBox;
private GUITextBox ipBox;
public GUIComponent CreateWhiteListFrame(GUIComponent parent)
{
if (whitelistFrame != null)
{
whitelistFrame.Parent.ClearChildren();
whitelistFrame = null;
}
parent.Padding = new Vector4(10.0f, 10.0f, 10.0f, 10.0f);
var enabledTick = new GUITickBox(new Rectangle(0, 0, 20, 20), "Enabled", Alignment.TopLeft, parent);
enabledTick.Selected = Enabled;
enabledTick.OnSelected = (GUITickBox box) =>
{
Enabled = !Enabled;
if (Enabled)
{
foreach (Client c in GameMain.Server.ConnectedClients)
{
if (!IsWhiteListed(c.name, c.Connection.RemoteEndPoint.Address.ToString()))
{
whitelistedPlayers.Add(new WhiteListedPlayer(c.name, c.Connection.RemoteEndPoint.Address.ToString()));
if (whitelistFrame != null) CreateWhiteListFrame(whitelistFrame.Parent);
}
}
}
Save();
return true;
};
new GUITextBlock(new Rectangle(0, -35, 90, 20), "Name:", "", Alignment.BottomLeft, Alignment.CenterLeft, parent, false, GUI.Font);
nameBox = new GUITextBox(new Rectangle(100, -35, 170, 20), Alignment.BottomLeft, "", parent);
nameBox.Font = GUI.Font;
new GUITextBlock(new Rectangle(0, 0, 90, 20), "IP Address:", "", Alignment.BottomLeft, Alignment.CenterLeft, parent, false, GUI.Font);
ipBox = new GUITextBox(new Rectangle(100, 0, 170, 20), Alignment.BottomLeft, "", parent);
ipBox.Font = GUI.Font;
var addnewButton = new GUIButton(new Rectangle(0, 35, 150, 20), "Add to whitelist", Alignment.BottomLeft, "", parent);
addnewButton.OnClicked = AddToWhiteList;
whitelistFrame = new GUIListBox(new Rectangle(0, 30, 0, parent.Rect.Height - 110), "", parent);
foreach (WhiteListedPlayer wlp in whitelistedPlayers)
{
string blockText = wlp.Name;
if (!string.IsNullOrWhiteSpace(wlp.IP)) blockText += " (" + wlp.IP + ")";
GUITextBlock textBlock = new GUITextBlock(
new Rectangle(0, 0, 0, 25),
blockText,
"",
Alignment.Left, Alignment.Left, whitelistFrame);
textBlock.Padding = new Vector4(10.0f, 10.0f, 0.0f, 0.0f);
textBlock.UserData = wlp;
var removeButton = new GUIButton(new Rectangle(0, 0, 100, 20), "Remove", Alignment.Right | Alignment.CenterY, "", textBlock);
removeButton.UserData = wlp;
removeButton.OnClicked = RemoveFromWhiteList;
}
return parent;
}
private bool RemoveFromWhiteList(GUIButton button, object obj)
{
WhiteListedPlayer wlp = obj as WhiteListedPlayer;
if (wlp == null) return false;
RemoveFromWhiteList(wlp);
if (whitelistFrame != null)
{
whitelistFrame.Parent.ClearChildren();
CreateWhiteListFrame(whitelistFrame.Parent);
}
return true;
}
private bool AddToWhiteList(GUIButton button, object obj)
{
if (string.IsNullOrWhiteSpace(nameBox.Text)) return false;
if (whitelistedPlayers.Any(x => x.Name.ToLower() == nameBox.Text.ToLower() && x.IP == ipBox.Text)) return false;
AddToWhiteList(nameBox.Text, ipBox.Text);
if (whitelistFrame != null)
{
CreateWhiteListFrame(whitelistFrame.Parent);
}
return true;
}
}
}