5202af9...3ea33fb
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
using Lidgren.Network;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma.Networking
|
||||
{
|
||||
@@ -65,13 +66,13 @@ namespace Barotrauma.Networking
|
||||
if (order.TargetAllCharacters)
|
||||
{
|
||||
GameMain.GameSession?.CrewManager?.AddOrder(
|
||||
new Order(order.Prefab, targetEntity, (targetEntity as Item)?.GetComponent<Items.Components.ItemComponent>()),
|
||||
new Order(order.Prefab, targetEntity, (targetEntity as Item)?.Components.FirstOrDefault(ic => ic.GetType() == order.ItemComponentType)),
|
||||
order.Prefab.FadeOutTime);
|
||||
}
|
||||
else if (targetCharacter != null)
|
||||
{
|
||||
targetCharacter.SetOrder(
|
||||
new Order(order.Prefab, targetEntity, (targetEntity as Item)?.GetComponent<Items.Components.ItemComponent>()),
|
||||
new Order(order.Prefab, targetEntity, (targetEntity as Item)?.Components.FirstOrDefault(ic => ic.GetType() == order.ItemComponentType)),
|
||||
orderOption, senderCharacter);
|
||||
}
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
get { return entityEventManager.MidRoundSyncing; }
|
||||
}
|
||||
|
||||
|
||||
private int ownerKey;
|
||||
|
||||
public GameClient(string newName, string ip, int ownerKey=0)
|
||||
@@ -146,7 +146,7 @@ namespace Barotrauma.Networking
|
||||
OnSelected = ToggleEndRoundVote,
|
||||
Visible = false
|
||||
};
|
||||
|
||||
|
||||
ShowLogButton = new GUIButton(new RectTransform(new Vector2(0.1f, 0.6f), buttonContainer.RectTransform) { MinSize = new Point(150, 0) },
|
||||
TextManager.Get("ServerLog"))
|
||||
{
|
||||
@@ -222,7 +222,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
// Create new instance of configs. Parameter is "application Id". It has to be same on client and server.
|
||||
NetPeerConfiguration = new NetPeerConfiguration("barotrauma");
|
||||
|
||||
|
||||
NetPeerConfiguration.DisableMessageType(NetIncomingMessageType.DebugMessage | NetIncomingMessageType.WarningMessage | NetIncomingMessageType.Receipt
|
||||
| NetIncomingMessageType.ErrorMessage | NetIncomingMessageType.Error);
|
||||
|
||||
@@ -245,7 +245,7 @@ namespace Barotrauma.Networking
|
||||
NetOutgoingMessage outmsg = client.CreateMessage();
|
||||
WriteAuthRequest(outmsg);
|
||||
|
||||
// Connect client, to ip previously requested from user
|
||||
// Connect client, to ip previously requested from user
|
||||
try
|
||||
{
|
||||
client.Connect(IPEndPoint, outmsg);
|
||||
@@ -557,16 +557,16 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
System.Threading.Thread.Sleep(10);
|
||||
}
|
||||
|
||||
|
||||
outmsg.Write(SteamManager.GetSteamID());
|
||||
outmsg.Write(steamAuthTicket.Data.Length);
|
||||
outmsg.Write(steamAuthTicket.Data);
|
||||
|
||||
DebugConsole.Log("Sending Steam auth request");
|
||||
DebugConsole.Log(" Steam ID: " + SteamManager.GetSteamID());
|
||||
DebugConsole.Log(" Ticket data: " +
|
||||
DebugConsole.Log(" Ticket data: " +
|
||||
ToolBox.LimitString(string.Concat(steamAuthTicket.Data.Select(b => b.ToString("X2"))), 16));
|
||||
DebugConsole.Log(" Msg length: " + outmsg.LengthBytes);
|
||||
DebugConsole.Log(" Msg length: " + outmsg.LengthBytes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -580,7 +580,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
c.UpdateSoundPosition();
|
||||
}
|
||||
|
||||
|
||||
if (VoipCapture.Instance != null)
|
||||
{
|
||||
if (VoipCapture.Instance.LastEnqueueAudio > DateTime.Now - new TimeSpan(0, 0, 0, 0, milliseconds: 100))
|
||||
@@ -633,7 +633,7 @@ namespace Barotrauma.Networking
|
||||
GameMain.MainMenuScreen.Select();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (gameStarted && Screen.Selected == GameMain.GameScreen)
|
||||
{
|
||||
EndVoteTickBox.Visible = serverSettings.Voting.AllowEndVoting && HasSpawned;
|
||||
@@ -658,7 +658,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
// Update current time
|
||||
updateTimer = DateTime.Now + updateInterval;
|
||||
updateTimer = DateTime.Now + updateInterval;
|
||||
}
|
||||
|
||||
private CoroutineHandle startGameCoroutine;
|
||||
@@ -735,8 +735,8 @@ namespace Barotrauma.Networking
|
||||
GameMain.NetLobbyScreen.TrySelectSub(shuttleName, shuttleHash, GameMain.NetLobbyScreen.ShuttleList.ListBox));
|
||||
|
||||
WriteCharacterInfo(readyToStartMsg);
|
||||
|
||||
client.SendMessage(readyToStartMsg, NetDeliveryMethod.ReliableUnordered);
|
||||
|
||||
client.SendMessage(readyToStartMsg, NetDeliveryMethod.ReliableUnordered);
|
||||
break;
|
||||
case ServerPacketHeader.STARTGAME:
|
||||
startGameCoroutine = GameMain.Instance.ShowLoading(StartGame(inc), false);
|
||||
@@ -861,9 +861,10 @@ namespace Barotrauma.Networking
|
||||
else
|
||||
{
|
||||
msg = TextManager.Get("DisconnectReason." + disconnectReason.ToString());
|
||||
|
||||
for (int i = 1; i < splitMsg.Length; i++)
|
||||
{
|
||||
msg += splitMsg[i];
|
||||
msg += TextManager.GetServerMessage(splitMsg[i]);
|
||||
}
|
||||
}
|
||||
var msgBox = new GUIMessageBox(TextManager.Get(allowReconnect ? "ConnectionLost" : "CouldNotConnectToServer"), msg);
|
||||
@@ -927,6 +928,15 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
private void SetMyPermissions(ClientPermissions newPermissions, IEnumerable<string> permittedConsoleCommands)
|
||||
{
|
||||
if (!(this.permittedConsoleCommands.Any(c => !permittedConsoleCommands.Contains(c)) ||
|
||||
permittedConsoleCommands.Any(c => !this.permittedConsoleCommands.Contains(c))))
|
||||
{
|
||||
if (newPermissions == permissions) return;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetMyPermissions(ClientPermissions newPermissions, IEnumerable<string> permittedConsoleCommands)
|
||||
{
|
||||
if (!(this.permittedConsoleCommands.Any(c => !permittedConsoleCommands.Contains(c)) ||
|
||||
@@ -940,7 +950,7 @@ namespace Barotrauma.Networking
|
||||
//don't show the "permissions changed" popup if the client owns the server
|
||||
if (ownerKey == 0)
|
||||
{
|
||||
GUIMessageBox.MessageBoxes.RemoveAll(mb => mb.UserData as string == "permissions");
|
||||
GUIMessageBox.MessageBoxes.RemoveAll(mb => mb.UserData as string == "permissions");
|
||||
|
||||
string msg = "";
|
||||
if (newPermissions == ClientPermissions.None)
|
||||
@@ -977,7 +987,7 @@ namespace Barotrauma.Networking
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GameMain.NetLobbyScreen.UpdatePermissions();
|
||||
}
|
||||
@@ -986,13 +996,13 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
if (Character != null) Character.Remove();
|
||||
HasSpawned = false;
|
||||
|
||||
|
||||
GameMain.LightManager.LightingEnabled = true;
|
||||
|
||||
//enable spectate button in case we fail to start the round now
|
||||
//(for example, due to a missing sub file or an error)
|
||||
GameMain.NetLobbyScreen.ShowSpectateButton();
|
||||
|
||||
|
||||
entityEventManager.Clear();
|
||||
LastSentEntityEventID = 0;
|
||||
|
||||
@@ -1063,14 +1073,14 @@ namespace Barotrauma.Networking
|
||||
else
|
||||
{
|
||||
if (GameMain.GameSession?.CrewManager != null) GameMain.GameSession.CrewManager.Reset();
|
||||
GameMain.GameSession.StartRound(campaign.Map.SelectedConnection.Level,
|
||||
reloadSub: true,
|
||||
GameMain.GameSession.StartRound(campaign.Map.SelectedConnection.Level,
|
||||
reloadSub: true,
|
||||
loadSecondSub: false,
|
||||
mirrorLevel: campaign.Map.CurrentLocation != campaign.Map.SelectedConnection.Locations[0]);
|
||||
}
|
||||
|
||||
|
||||
if (respawnAllowed) respawnManager = new RespawnManager(this, GameMain.NetLobbyScreen.UsingShuttle ? GameMain.NetLobbyScreen.SelectedShuttle : null);
|
||||
|
||||
|
||||
gameStarted = true;
|
||||
|
||||
GameMain.GameScreen.Select();
|
||||
@@ -1137,7 +1147,7 @@ namespace Barotrauma.Networking
|
||||
submarines.Add(new Submarine(Path.Combine(Submarine.SavePath, subName) + ".sub", subHash, false));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GameMain.NetLobbyScreen.UpdateSubList(GameMain.NetLobbyScreen.SubList, submarines);
|
||||
GameMain.NetLobbyScreen.UpdateSubList(GameMain.NetLobbyScreen.ShuttleList.ListBox, submarines);
|
||||
|
||||
@@ -1241,7 +1251,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
UInt16 settingsLen = inc.ReadUInt16();
|
||||
byte[] settingsData = inc.ReadBytes(settingsLen);
|
||||
|
||||
|
||||
if (inc.ReadBoolean())
|
||||
{
|
||||
if (GameSettings.VerboseLogging)
|
||||
@@ -1272,12 +1282,15 @@ namespace Barotrauma.Networking
|
||||
string levelSeed = inc.ReadString();
|
||||
float levelDifficulty = inc.ReadFloat();
|
||||
|
||||
byte botCount = inc.ReadByte();
|
||||
BotSpawnMode botSpawnMode = inc.ReadBoolean() ? BotSpawnMode.Fill : BotSpawnMode.Normal;
|
||||
|
||||
byte botCount = inc.ReadByte();
|
||||
BotSpawnMode botSpawnMode = inc.ReadBoolean() ? BotSpawnMode.Fill : BotSpawnMode.Normal;
|
||||
|
||||
bool autoRestartEnabled = inc.ReadBoolean();
|
||||
float autoRestartTimer = autoRestartEnabled ? inc.ReadFloat() : 0.0f;
|
||||
|
||||
|
||||
//ignore the message if we already a more up-to-date one
|
||||
if (NetIdUtils.IdMoreRecent(updateID, GameMain.NetLobbyScreen.LastUpdateID))
|
||||
{
|
||||
@@ -1299,13 +1312,13 @@ namespace Barotrauma.Networking
|
||||
GameMain.NetLobbyScreen.SetTraitorsEnabled(traitorsEnabled);
|
||||
GameMain.NetLobbyScreen.SetMissionType(missionTypeIndex);
|
||||
|
||||
if (!allowModeVoting) GameMain.NetLobbyScreen.SelectMode(modeIndex);
|
||||
|
||||
if (!allowModeVoting) GameMain.NetLobbyScreen.SelectMode(modeIndex);
|
||||
|
||||
GameMain.NetLobbyScreen.SetAllowSpectating(allowSpectating);
|
||||
GameMain.NetLobbyScreen.LevelSeed = levelSeed;
|
||||
GameMain.NetLobbyScreen.SetLevelDifficulty(levelDifficulty);
|
||||
GameMain.NetLobbyScreen.SetBotCount(botCount);
|
||||
GameMain.NetLobbyScreen.SetBotSpawnMode(botSpawnMode);
|
||||
GameMain.NetLobbyScreen.SetBotSpawnMode(botSpawnMode);
|
||||
GameMain.NetLobbyScreen.SetAutoRestart(autoRestartEnabled, autoRestartTimer);
|
||||
|
||||
serverSettings.VoiceChatEnabled = voiceChatEnabled;
|
||||
@@ -1373,7 +1386,7 @@ namespace Barotrauma.Networking
|
||||
entity.ClientRead(objHeader, inc, sendingTime);
|
||||
}
|
||||
|
||||
//force to the correct position in case the entity doesn't exist
|
||||
//force to the correct position in case the entity doesn't exist
|
||||
//or the message wasn't read correctly for whatever reason
|
||||
inc.Position = msgEndPos;
|
||||
inc.ReadPadBits();
|
||||
@@ -1409,7 +1422,7 @@ namespace Barotrauma.Networking
|
||||
errorLines.Add(" - " + e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
foreach (string line in errorLines)
|
||||
{
|
||||
DebugConsole.ThrowError(line);
|
||||
@@ -1476,7 +1489,7 @@ namespace Barotrauma.Networking
|
||||
chatMsgQueue[i].ClientWrite(outmsg);
|
||||
}
|
||||
outmsg.Write((byte)ClientNetObject.END_OF_MESSAGE);
|
||||
|
||||
|
||||
if (outmsg.LengthBytes > client.Configuration.MaximumTransmissionUnit)
|
||||
{
|
||||
DebugConsole.ThrowError("Maximum packet size exceeded (" + outmsg.LengthBytes + " > " + client.Configuration.MaximumTransmissionUnit);
|
||||
@@ -1509,7 +1522,7 @@ namespace Barotrauma.Networking
|
||||
return;
|
||||
}
|
||||
chatMsgQueue[i].ClientWrite(outmsg);
|
||||
}
|
||||
}
|
||||
|
||||
outmsg.Write((byte)ClientNetObject.END_OF_MESSAGE);
|
||||
|
||||
@@ -1523,7 +1536,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
public void SendChatMessage(ChatMessage msg)
|
||||
{
|
||||
if (client.ServerConnection == null) return;
|
||||
if (client.ServerConnection == null) return;
|
||||
lastQueueChatMsgID++;
|
||||
msg.NetStateID = lastQueueChatMsgID;
|
||||
chatMsgQueue.Add(msg);
|
||||
@@ -1536,7 +1549,7 @@ namespace Barotrauma.Networking
|
||||
ChatMessage chatMessage = ChatMessage.Create(
|
||||
gameStarted && myCharacter != null ? myCharacter.Name : name,
|
||||
message,
|
||||
type,
|
||||
type,
|
||||
gameStarted && myCharacter != null ? myCharacter : null);
|
||||
|
||||
lastQueueChatMsgID++;
|
||||
@@ -1586,12 +1599,12 @@ namespace Barotrauma.Networking
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
IEnumerable<GUIComponent> subListChildren = (i == 0) ?
|
||||
GameMain.NetLobbyScreen.ShuttleList.ListBox.Content.Children :
|
||||
IEnumerable<GUIComponent> subListChildren = (i == 0) ?
|
||||
GameMain.NetLobbyScreen.ShuttleList.ListBox.Content.Children :
|
||||
GameMain.NetLobbyScreen.SubList.Content.Children;
|
||||
|
||||
var subElement = subListChildren.FirstOrDefault(c =>
|
||||
((Submarine)c.UserData).Name == newSub.Name &&
|
||||
var subElement = subListChildren.FirstOrDefault(c =>
|
||||
((Submarine)c.UserData).Name == newSub.Name &&
|
||||
((Submarine)c.UserData).MD5Hash.Hash == newSub.MD5Hash.Hash);
|
||||
if (subElement == null) continue;
|
||||
|
||||
@@ -1613,7 +1626,7 @@ namespace Barotrauma.Networking
|
||||
};
|
||||
}
|
||||
|
||||
if (GameMain.NetLobbyScreen.FailedSelectedSub != null &&
|
||||
if (GameMain.NetLobbyScreen.FailedSelectedSub != null &&
|
||||
GameMain.NetLobbyScreen.FailedSelectedSub.First == newSub.Name &&
|
||||
GameMain.NetLobbyScreen.FailedSelectedSub.Second == newSub.MD5Hash.Hash)
|
||||
{
|
||||
@@ -1636,7 +1649,7 @@ namespace Barotrauma.Networking
|
||||
if (GameMain.GameSession.Submarine == null)
|
||||
{
|
||||
var gameSessionDoc = SaveUtil.LoadGameSessionDoc(GameMain.GameSession.SavePath);
|
||||
string subPath = Path.Combine(SaveUtil.TempPath, gameSessionDoc.Root.GetAttributeString("submarine", "")) + ".sub";
|
||||
string subPath = Path.Combine(SaveUtil.TempPath, gameSessionDoc.Root.GetAttributeString("submarine", "")) + ".sub";
|
||||
GameMain.GameSession.Submarine = new Submarine(subPath, "");
|
||||
}
|
||||
|
||||
@@ -1662,7 +1675,7 @@ namespace Barotrauma.Networking
|
||||
if (!(entity is IClientSerializable)) throw new InvalidCastException("entity is not IClientSerializable");
|
||||
entityEventManager.CreateEvent(entity as IClientSerializable, extraData);
|
||||
}
|
||||
|
||||
|
||||
public bool HasPermission(ClientPermissions permission)
|
||||
{
|
||||
return permissions.HasFlag(permission);
|
||||
@@ -1675,7 +1688,7 @@ namespace Barotrauma.Networking
|
||||
command = command.ToLowerInvariant();
|
||||
return permittedConsoleCommands.Any(c => c.ToLowerInvariant() == command);
|
||||
}
|
||||
|
||||
|
||||
public override void Disconnect()
|
||||
{
|
||||
client.Shutdown("");
|
||||
@@ -1711,7 +1724,7 @@ namespace Barotrauma.Networking
|
||||
VoipClient = null;
|
||||
GameMain.Client = null;
|
||||
}
|
||||
|
||||
|
||||
public void WriteCharacterInfo(NetOutgoingMessage msg)
|
||||
{
|
||||
msg.Write(characterInfo == null);
|
||||
@@ -1733,7 +1746,7 @@ namespace Barotrauma.Networking
|
||||
msg.Write(jobPreferences[i].Identifier);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void Vote(VoteType voteType, object data)
|
||||
{
|
||||
NetOutgoingMessage msg = client.CreateMessage();
|
||||
@@ -1771,7 +1784,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
NetOutgoingMessage msg = client.CreateMessage();
|
||||
msg.Write((byte)ClientPacketHeader.SERVER_COMMAND);
|
||||
msg.Write((UInt16)ClientPermissions.Kick);
|
||||
msg.Write((UInt16)ClientPermissions.Kick);
|
||||
msg.Write(kickedName);
|
||||
msg.Write(reason);
|
||||
|
||||
@@ -1926,7 +1939,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
msg.Write(false); msg.WritePadBits();
|
||||
msg.Write(saveName);
|
||||
|
||||
|
||||
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
|
||||
|
||||
GameMain.NetLobbyScreen.CampaignSetupUI = null;
|
||||
@@ -1948,13 +1961,13 @@ namespace Barotrauma.Networking
|
||||
public bool SpectateClicked(GUIButton button, object userData)
|
||||
{
|
||||
if (button != null) button.Enabled = false;
|
||||
|
||||
|
||||
NetOutgoingMessage readyToStartMsg = client.CreateMessage();
|
||||
readyToStartMsg.Write((byte)ClientPacketHeader.RESPONSE_STARTGAME);
|
||||
|
||||
//assume we have the required sub files to start the round
|
||||
//(if not, we'll find out when the server sends the STARTGAME message and can initiate a file transfer)
|
||||
readyToStartMsg.Write(true);
|
||||
readyToStartMsg.Write(true);
|
||||
|
||||
WriteCharacterInfo(readyToStartMsg);
|
||||
|
||||
@@ -2052,9 +2065,9 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
SendChatMessage(message);
|
||||
|
||||
|
||||
textBox.Deselect();
|
||||
textBox.Text = "";
|
||||
textBox.Text = "";
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -2080,10 +2093,14 @@ namespace Barotrauma.Networking
|
||||
GUITextBox msgBox = null;
|
||||
|
||||
if (Screen.Selected == GameMain.GameScreen)
|
||||
{ msgBox = chatBox.InputBox; }
|
||||
{
|
||||
msgBox = chatBox.InputBox;
|
||||
}
|
||||
else if (Screen.Selected == GameMain.NetLobbyScreen)
|
||||
{ msgBox = GameMain.NetLobbyScreen.TextBox; }
|
||||
|
||||
{
|
||||
msgBox = GameMain.NetLobbyScreen.TextBox;
|
||||
}
|
||||
|
||||
if (gameStarted && Screen.Selected == GameMain.GameScreen)
|
||||
{
|
||||
if (!GUI.DisableHUD && !GUI.DisableUpperHUD)
|
||||
@@ -2112,11 +2129,11 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
//tab doesn't autoselect the chatbox when debug console is open,
|
||||
//tab doesn't autoselect the chatbox when debug console is open,
|
||||
//because tab is used for autocompleting console commands
|
||||
if (msgBox != null)
|
||||
{
|
||||
if ((PlayerInput.KeyHit(InputType.Chat) || PlayerInput.KeyHit(InputType.RadioChat)) &&
|
||||
if ((PlayerInput.KeyHit(InputType.Chat) || PlayerInput.KeyHit(InputType.RadioChat)) &&
|
||||
GUI.KeyboardDispatcher.Subscriber == null)
|
||||
{
|
||||
if (msgBox.Selected)
|
||||
@@ -2182,15 +2199,15 @@ namespace Barotrauma.Networking
|
||||
|
||||
GUI.DrawRectangle(spriteBatch, new Rectangle(
|
||||
(int)pos.X,
|
||||
(int)pos.Y,
|
||||
fileReceiver.ActiveTransfers.Count * 210 + 10,
|
||||
32),
|
||||
(int)pos.Y,
|
||||
fileReceiver.ActiveTransfers.Count * 210 + 10,
|
||||
32),
|
||||
Color.Black * 0.8f, true);
|
||||
|
||||
|
||||
for (int i = 0; i < fileReceiver.ActiveTransfers.Count; i++)
|
||||
{
|
||||
var transfer = fileReceiver.ActiveTransfers[i];
|
||||
|
||||
|
||||
GUI.DrawString(spriteBatch,
|
||||
pos,
|
||||
ToolBox.LimitString(TextManager.Get("DownloadingFile").Replace("[filename]", transfer.FileName), GUI.SmallFont, 200),
|
||||
|
||||
@@ -0,0 +1,808 @@
|
||||
using Lidgren.Network;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma.Networking
|
||||
{
|
||||
partial class ServerSettings : ISerializableEntity
|
||||
{
|
||||
partial class NetPropertyData
|
||||
{
|
||||
public GUIComponent GUIComponent;
|
||||
public object TempValue;
|
||||
|
||||
public void AssignGUIComponent(GUIComponent component)
|
||||
{
|
||||
GUIComponent = component;
|
||||
GUIComponentValue = property.GetValue(serverSettings);
|
||||
TempValue = GUIComponentValue;
|
||||
}
|
||||
|
||||
public object GUIComponentValue
|
||||
{
|
||||
get
|
||||
{
|
||||
if (GUIComponent == null) return null;
|
||||
else if (GUIComponent is GUITickBox tickBox) return tickBox.Selected;
|
||||
else if (GUIComponent is GUITextBox textBox) return textBox.Text;
|
||||
else if (GUIComponent is GUIScrollBar scrollBar) return scrollBar.BarScrollValue;
|
||||
else if (GUIComponent is GUIRadioButtonGroup radioButtonGroup) return radioButtonGroup.Selected;
|
||||
return null;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (GUIComponent == null) return;
|
||||
else if (GUIComponent is GUITickBox tickBox) tickBox.Selected = (bool)value;
|
||||
else if (GUIComponent is GUITextBox textBox) textBox.Text = (string)value;
|
||||
else if (GUIComponent is GUIScrollBar scrollBar) scrollBar.BarScrollValue = (float)value;
|
||||
else if (GUIComponent is GUIRadioButtonGroup radioButtonGroup) radioButtonGroup.Selected = (Enum)value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool ChangedLocally
|
||||
{
|
||||
get
|
||||
{
|
||||
if (GUIComponent == null) return false;
|
||||
return !PropEquals(TempValue, GUIComponentValue);
|
||||
}
|
||||
}
|
||||
|
||||
public bool PropEquals(object a,object b)
|
||||
{
|
||||
switch (typeString)
|
||||
{
|
||||
case "float":
|
||||
if (!(a is float?)) return false;
|
||||
if (!(b is float?)) return false;
|
||||
return (float)a == (float)b;
|
||||
case "int":
|
||||
if (!(a is int?)) return false;
|
||||
if (!(b is int?)) return false;
|
||||
return (int)a == (int)b;
|
||||
case "bool":
|
||||
if (!(a is bool?)) return false;
|
||||
if (!(b is bool?)) return false;
|
||||
return (bool)a == (bool)b;
|
||||
case "Enum":
|
||||
if (!(a is Enum)) return false;
|
||||
if (!(b is Enum)) return false;
|
||||
return ((Enum)a).Equals((Enum)b);
|
||||
default:
|
||||
return a.ToString().Equals(b.ToString(),StringComparison.InvariantCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
private Dictionary<string, bool> tempMonsterEnabled;
|
||||
|
||||
partial void InitProjSpecific()
|
||||
{
|
||||
var properties = TypeDescriptor.GetProperties(GetType()).Cast<PropertyDescriptor>();
|
||||
|
||||
SerializableProperties = new Dictionary<string, SerializableProperty>();
|
||||
|
||||
foreach (var property in properties)
|
||||
{
|
||||
SerializableProperty objProperty = new SerializableProperty(property, this);
|
||||
SerializableProperties.Add(property.Name.ToLowerInvariant(), objProperty);
|
||||
}
|
||||
}
|
||||
|
||||
public void ClientAdminRead(NetBuffer incMsg)
|
||||
{
|
||||
int count = incMsg.ReadUInt16();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
UInt32 key = incMsg.ReadUInt32();
|
||||
if (netProperties.ContainsKey(key))
|
||||
{
|
||||
bool changedLocally = netProperties[key].ChangedLocally;
|
||||
netProperties[key].Read(incMsg);
|
||||
netProperties[key].TempValue = netProperties[key].Value;
|
||||
|
||||
if (netProperties[key].GUIComponent != null)
|
||||
{
|
||||
if (!changedLocally)
|
||||
{
|
||||
netProperties[key].GUIComponentValue = netProperties[key].Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UInt32 size = incMsg.ReadVariableUInt32();
|
||||
incMsg.Position += 8 * size;
|
||||
}
|
||||
}
|
||||
|
||||
ReadMonsterEnabled(incMsg);
|
||||
BanList.ClientAdminRead(incMsg);
|
||||
Whitelist.ClientAdminRead(incMsg);
|
||||
}
|
||||
|
||||
public void ClientRead(NetBuffer incMsg)
|
||||
{
|
||||
ServerName = incMsg.ReadString();
|
||||
ServerMessageText = incMsg.ReadString();
|
||||
TickRate = incMsg.ReadRangedInteger(1, 60);
|
||||
GameMain.NetworkMember.TickRate = TickRate;
|
||||
|
||||
ReadExtraCargo(incMsg);
|
||||
|
||||
Voting.ClientRead(incMsg);
|
||||
|
||||
bool isAdmin = incMsg.ReadBoolean();
|
||||
incMsg.ReadPadBits();
|
||||
if (isAdmin)
|
||||
{
|
||||
ClientAdminRead(incMsg);
|
||||
}
|
||||
}
|
||||
|
||||
public void ClientAdminWrite(NetFlags dataToSend, int missionType = 0, float? levelDifficulty = null, bool? autoRestart = null, int traitorSetting = 0, int botCount = 0, int botSpawnMode = 0)
|
||||
{
|
||||
if (!GameMain.Client.HasPermission(Networking.ClientPermissions.ManageSettings)) return;
|
||||
|
||||
NetOutgoingMessage outMsg = GameMain.NetworkMember.NetPeer.CreateMessage();
|
||||
|
||||
outMsg.Write((byte)ClientPacketHeader.SERVER_SETTINGS);
|
||||
|
||||
outMsg.Write((byte)dataToSend);
|
||||
|
||||
if (dataToSend.HasFlag(NetFlags.Name))
|
||||
{
|
||||
if (GameMain.NetLobbyScreen.ServerName.Text != ServerName)
|
||||
{
|
||||
ServerName = GameMain.NetLobbyScreen.ServerName.Text;
|
||||
}
|
||||
outMsg.Write(ServerName);
|
||||
}
|
||||
|
||||
if (dataToSend.HasFlag(NetFlags.Message))
|
||||
{
|
||||
if (GameMain.NetLobbyScreen.ServerMessage.Text != ServerMessageText)
|
||||
{
|
||||
ServerMessageText = GameMain.NetLobbyScreen.ServerMessage.Text;
|
||||
}
|
||||
outMsg.Write(ServerMessageText);
|
||||
}
|
||||
|
||||
if (dataToSend.HasFlag(NetFlags.Properties))
|
||||
{
|
||||
//TODO: split this up?
|
||||
WriteExtraCargo(outMsg);
|
||||
|
||||
IEnumerable<KeyValuePair<UInt32, NetPropertyData>> changedProperties = netProperties.Where(kvp => kvp.Value.ChangedLocally);
|
||||
UInt32 count = (UInt32)changedProperties.Count();
|
||||
bool changedMonsterSettings = tempMonsterEnabled != null && tempMonsterEnabled.Any(p => p.Value != MonsterEnabled[p.Key]);
|
||||
|
||||
outMsg.Write(count);
|
||||
foreach (KeyValuePair<UInt32, NetPropertyData> prop in changedProperties)
|
||||
{
|
||||
DebugConsole.NewMessage(prop.Value.Name, Color.Lime);
|
||||
outMsg.Write(prop.Key);
|
||||
prop.Value.Write(outMsg, prop.Value.GUIComponentValue);
|
||||
}
|
||||
|
||||
outMsg.Write(changedMonsterSettings); outMsg.WritePadBits();
|
||||
if (changedMonsterSettings) WriteMonsterEnabled(outMsg, tempMonsterEnabled);
|
||||
BanList.ClientAdminWrite(outMsg);
|
||||
Whitelist.ClientAdminWrite(outMsg);
|
||||
}
|
||||
|
||||
if (dataToSend.HasFlag(NetFlags.Misc))
|
||||
{
|
||||
outMsg.Write((byte)(missionType + 1));
|
||||
outMsg.Write((byte)(traitorSetting + 1));
|
||||
outMsg.Write((byte)(botCount + 1));
|
||||
outMsg.Write((byte)(botSpawnMode + 1));
|
||||
|
||||
outMsg.Write(levelDifficulty ?? -1000.0f);
|
||||
|
||||
outMsg.Write(autoRestart != null);
|
||||
outMsg.Write(autoRestart ?? false);
|
||||
outMsg.WritePadBits();
|
||||
}
|
||||
|
||||
if (dataToSend.HasFlag(NetFlags.LevelSeed))
|
||||
{
|
||||
outMsg.Write(GameMain.NetLobbyScreen.SeedBox.Text);
|
||||
}
|
||||
|
||||
(GameMain.NetworkMember.NetPeer as NetClient).SendMessage(outMsg, NetDeliveryMethod.ReliableOrdered);
|
||||
}
|
||||
|
||||
//GUI stuff
|
||||
private GUIFrame settingsFrame;
|
||||
private GUIFrame[] settingsTabs;
|
||||
private GUIButton[] tabButtons;
|
||||
private int settingsTabIndex;
|
||||
|
||||
enum SettingsTab
|
||||
{
|
||||
Rounds,
|
||||
Server,
|
||||
Banlist,
|
||||
Whitelist
|
||||
}
|
||||
|
||||
private NetPropertyData GetPropertyData(string name)
|
||||
{
|
||||
return netProperties.First(p => p.Value.Name == name).Value;
|
||||
}
|
||||
|
||||
public void AddToGUIUpdateList()
|
||||
{
|
||||
if (GUI.DisableHUD) return;
|
||||
|
||||
settingsFrame?.AddToGUIUpdateList();
|
||||
}
|
||||
|
||||
private void CreateSettingsFrame()
|
||||
{
|
||||
foreach (NetPropertyData prop in netProperties.Values)
|
||||
{
|
||||
prop.TempValue = prop.Value;
|
||||
}
|
||||
|
||||
//background frame
|
||||
settingsFrame = new GUIFrame(new RectTransform(Vector2.One, GUI.Canvas), style: null, color: Color.Black * 0.5f);
|
||||
new GUIButton(new RectTransform(Vector2.One, settingsFrame.RectTransform), "", style: null).OnClicked += (btn, userData) =>
|
||||
{
|
||||
if (GUI.MouseOn == btn || GUI.MouseOn == btn.TextBlock) ToggleSettingsFrame(btn, userData);
|
||||
return true;
|
||||
};
|
||||
|
||||
new GUIButton(new RectTransform(Vector2.One, settingsFrame.RectTransform), "", style: null)
|
||||
{
|
||||
OnClicked = ToggleSettingsFrame
|
||||
};
|
||||
|
||||
//center frames
|
||||
GUIFrame innerFrame = new GUIFrame(new RectTransform(new Vector2(0.3f, 0.7f), settingsFrame.RectTransform, Anchor.Center) { MinSize = new Point(400, 430) });
|
||||
GUIFrame paddedFrame = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.9f), innerFrame.RectTransform, Anchor.Center), style: null);
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), paddedFrame.RectTransform), TextManager.Get("Settings"), font: GUI.LargeFont);
|
||||
|
||||
var buttonArea = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.07f), paddedFrame.RectTransform) { RelativeOffset = new Vector2(0.0f, 0.1f) }, isHorizontal: true)
|
||||
{
|
||||
Stretch = true,
|
||||
RelativeSpacing = 0.01f
|
||||
};
|
||||
|
||||
//tabs
|
||||
var tabValues = Enum.GetValues(typeof(SettingsTab)).Cast<SettingsTab>().ToArray();
|
||||
string[] tabNames = new string[tabValues.Count()];
|
||||
for (int i = 0; i < tabNames.Length; i++)
|
||||
{
|
||||
tabNames[i] = TextManager.Get("ServerSettings" + tabValues[i] + "Tab");
|
||||
}
|
||||
settingsTabs = new GUIFrame[tabNames.Length];
|
||||
tabButtons = new GUIButton[tabNames.Length];
|
||||
for (int i = 0; i < tabNames.Length; i++)
|
||||
{
|
||||
settingsTabs[i] = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.79f), paddedFrame.RectTransform, Anchor.Center) { RelativeOffset = new Vector2(0.0f, 0.05f) },
|
||||
style: "InnerFrame");
|
||||
|
||||
tabButtons[i] = new GUIButton(new RectTransform(new Vector2(0.2f, 1.0f), buttonArea.RectTransform), tabNames[i], style: "GUITabButton")
|
||||
{
|
||||
UserData = i,
|
||||
OnClicked = SelectSettingsTab
|
||||
};
|
||||
}
|
||||
|
||||
SelectSettingsTab(tabButtons[0], 0);
|
||||
|
||||
//"Close"
|
||||
var closeButton = new GUIButton(new RectTransform(new Vector2(0.25f, 0.05f), paddedFrame.RectTransform, Anchor.BottomRight), TextManager.Get("Close"))
|
||||
{
|
||||
OnClicked = ToggleSettingsFrame
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// game settings
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
var roundsTab = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.95f), settingsTabs[(int)SettingsTab.Rounds].RectTransform, Anchor.Center))
|
||||
{
|
||||
Stretch = true,
|
||||
RelativeSpacing = 0.02f
|
||||
};
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), roundsTab.RectTransform), TextManager.Get("ServerSettingsSubSelection"));
|
||||
var selectionFrame = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.05f), roundsTab.RectTransform), isHorizontal: true)
|
||||
{
|
||||
Stretch = true,
|
||||
RelativeSpacing = 0.05f
|
||||
};
|
||||
|
||||
GUIRadioButtonGroup selectionMode = new GUIRadioButtonGroup();
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
var selectionTick = new GUITickBox(new RectTransform(new Vector2(0.3f, 1.0f), selectionFrame.RectTransform), TextManager.Get(((SelectionMode)i).ToString()), font: GUI.SmallFont);
|
||||
selectionMode.AddRadioButton((SelectionMode)i, selectionTick);
|
||||
}
|
||||
DebugConsole.NewMessage(SubSelectionMode.ToString(),Color.White);
|
||||
GetPropertyData("SubSelectionMode").AssignGUIComponent(selectionMode);
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), roundsTab.RectTransform), TextManager.Get("ServerSettingsModeSelection"));
|
||||
selectionFrame = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.05f), roundsTab.RectTransform), isHorizontal: true)
|
||||
{
|
||||
Stretch = true,
|
||||
RelativeSpacing = 0.05f
|
||||
};
|
||||
|
||||
selectionMode = new GUIRadioButtonGroup();
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
var selectionTick = new GUITickBox(new RectTransform(new Vector2(0.3f, 1.0f), selectionFrame.RectTransform), TextManager.Get(((SelectionMode)i).ToString()), font: GUI.SmallFont);
|
||||
selectionMode.AddRadioButton((SelectionMode)i, selectionTick);
|
||||
}
|
||||
GetPropertyData("ModeSelectionMode").AssignGUIComponent(selectionMode);
|
||||
|
||||
var endBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), roundsTab.RectTransform),
|
||||
TextManager.Get("ServerSettingsEndRoundWhenDestReached"));
|
||||
GetPropertyData("EndRoundAtLevelEnd").AssignGUIComponent(endBox);
|
||||
|
||||
var endVoteBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), roundsTab.RectTransform),
|
||||
TextManager.Get("ServerSettingsEndRoundVoting"));
|
||||
GetPropertyData("AllowEndVoting").AssignGUIComponent(endVoteBox);
|
||||
|
||||
CreateLabeledSlider(roundsTab, "ServerSettingsEndRoundVotesRequired", out GUIScrollBar slider, out GUITextBlock sliderLabel);
|
||||
|
||||
string endRoundLabel = sliderLabel.Text;
|
||||
slider.Step = 0.2f;
|
||||
slider.Range = new Vector2(0.5f, 1.0f);
|
||||
GetPropertyData("EndVoteRequiredRatio").AssignGUIComponent(slider);
|
||||
slider.OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
|
||||
{
|
||||
((GUITextBlock)scrollBar.UserData).Text = endRoundLabel + (int)MathUtils.Round(scrollBar.BarScrollValue * 100.0f, 10.0f) + " %";
|
||||
return true;
|
||||
};
|
||||
slider.OnMoved(slider, slider.BarScroll);
|
||||
|
||||
var respawnBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), roundsTab.RectTransform),
|
||||
TextManager.Get("ServerSettingsAllowRespawning"));
|
||||
GetPropertyData("AllowRespawn").AssignGUIComponent(respawnBox);
|
||||
|
||||
CreateLabeledSlider(roundsTab, "ServerSettingsRespawnInterval", out slider, out sliderLabel);
|
||||
string intervalLabel = sliderLabel.Text;
|
||||
slider.Step = 0.05f;
|
||||
slider.Range = new Vector2(10.0f, 600.0f);
|
||||
GetPropertyData("RespawnInterval").AssignGUIComponent(slider);
|
||||
slider.OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
|
||||
{
|
||||
GUITextBlock text = scrollBar.UserData as GUITextBlock;
|
||||
text.Text = intervalLabel + ToolBox.SecondsToReadableTime(scrollBar.BarScrollValue);
|
||||
return true;
|
||||
};
|
||||
slider.OnMoved(slider, slider.BarScroll);
|
||||
|
||||
var minRespawnText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), roundsTab.RectTransform), "")
|
||||
{
|
||||
ToolTip = TextManager.Get("ServerSettingsMinRespawnToolTip")
|
||||
};
|
||||
|
||||
string minRespawnLabel = TextManager.Get("ServerSettingsMinRespawn");
|
||||
CreateLabeledSlider(roundsTab, "", out slider, out sliderLabel);
|
||||
slider.ToolTip = minRespawnText.ToolTip;
|
||||
slider.UserData = minRespawnText;
|
||||
slider.Step = 0.1f;
|
||||
slider.Range = new Vector2(0.0f, 1.0f);
|
||||
GetPropertyData("MinRespawnRatio").AssignGUIComponent(slider);
|
||||
slider.OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
|
||||
{
|
||||
((GUITextBlock)scrollBar.UserData).Text = minRespawnLabel + (int)MathUtils.Round(scrollBar.BarScrollValue * 100.0f, 10.0f) + " %";
|
||||
return true;
|
||||
};
|
||||
slider.OnMoved(slider, MinRespawnRatio);
|
||||
|
||||
var respawnDurationText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), roundsTab.RectTransform), "")
|
||||
{
|
||||
ToolTip = TextManager.Get("ServerSettingsRespawnDurationToolTip")
|
||||
};
|
||||
|
||||
string respawnDurationLabel = TextManager.Get("ServerSettingsRespawnDuration");
|
||||
CreateLabeledSlider(roundsTab, "", out slider, out sliderLabel);
|
||||
slider.ToolTip = respawnDurationText.ToolTip;
|
||||
slider.UserData = respawnDurationText;
|
||||
slider.Step = 0.1f;
|
||||
slider.Range = new Vector2(60.0f, 660.0f);
|
||||
slider.ScrollToValue = (GUIScrollBar scrollBar, float barScroll) =>
|
||||
{
|
||||
return barScroll >= 1.0f ? 0.0f : barScroll * (scrollBar.Range.Y - scrollBar.Range.X) + scrollBar.Range.X;
|
||||
};
|
||||
slider.ValueToScroll = (GUIScrollBar scrollBar, float value) =>
|
||||
{
|
||||
return value <= 0.0f ? 1.0f : (value - scrollBar.Range.X) / (scrollBar.Range.Y - scrollBar.Range.X);
|
||||
};
|
||||
GetPropertyData("MaxTransportTime").AssignGUIComponent(slider);
|
||||
slider.OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
|
||||
{
|
||||
if (barScroll == 1.0f)
|
||||
{
|
||||
((GUITextBlock)scrollBar.UserData).Text = respawnDurationLabel + TextManager.Get("Unlimited");
|
||||
}
|
||||
else
|
||||
{
|
||||
((GUITextBlock)scrollBar.UserData).Text = respawnDurationLabel + ToolBox.SecondsToReadableTime(scrollBar.BarScrollValue);
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
slider.OnMoved(slider, slider.BarScroll);
|
||||
|
||||
var buttonHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.07f), roundsTab.RectTransform), isHorizontal: true)
|
||||
{
|
||||
Stretch = true,
|
||||
RelativeSpacing = 0.05f
|
||||
};
|
||||
|
||||
var monsterButton = new GUIButton(new RectTransform(new Vector2(0.5f, 1.0f), buttonHolder.RectTransform),
|
||||
TextManager.Get("ServerSettingsMonsterSpawns"))
|
||||
{
|
||||
Enabled = !GameMain.NetworkMember.GameStarted
|
||||
};
|
||||
var monsterFrame = new GUIListBox(new RectTransform(new Vector2(0.6f, 0.7f), settingsTabs[(int)SettingsTab.Rounds].RectTransform, Anchor.BottomLeft, Pivot.BottomRight))
|
||||
{
|
||||
Visible = false
|
||||
};
|
||||
monsterButton.UserData = monsterFrame;
|
||||
monsterButton.OnClicked = (button, obj) =>
|
||||
{
|
||||
if (GameMain.NetworkMember.GameStarted)
|
||||
{
|
||||
((GUIComponent)obj).Visible = false;
|
||||
button.Enabled = false;
|
||||
return true;
|
||||
}
|
||||
((GUIComponent)obj).Visible = !((GUIComponent)obj).Visible;
|
||||
return true;
|
||||
};
|
||||
|
||||
List<string> monsterNames = MonsterEnabled.Keys.ToList();
|
||||
tempMonsterEnabled = new Dictionary<string, bool>(MonsterEnabled);
|
||||
foreach (string s in monsterNames)
|
||||
{
|
||||
string translatedLabel = TextManager.Get($"Character.{s}", true);
|
||||
var monsterEnabledBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.1f), monsterFrame.Content.RectTransform) { MinSize = new Point(0, 25) },
|
||||
label: translatedLabel != null ? translatedLabel : s)
|
||||
{
|
||||
Selected = tempMonsterEnabled[s],
|
||||
OnSelected = (GUITickBox tb) =>
|
||||
{
|
||||
tempMonsterEnabled[s] = tb.Selected;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var cargoButton = new GUIButton(new RectTransform(new Vector2(0.5f, 1.0f), buttonHolder.RectTransform),
|
||||
TextManager.Get("ServerSettingsAdditionalCargo"))
|
||||
{
|
||||
Enabled = !GameMain.NetworkMember.GameStarted
|
||||
};
|
||||
var cargoFrame = new GUIListBox(new RectTransform(new Vector2(0.6f, 0.7f), settingsTabs[(int)SettingsTab.Rounds].RectTransform, Anchor.BottomRight, Pivot.BottomLeft))
|
||||
{
|
||||
Visible = false
|
||||
};
|
||||
cargoButton.UserData = cargoFrame;
|
||||
cargoButton.OnClicked = (button, obj) =>
|
||||
{
|
||||
if (GameMain.NetworkMember.GameStarted)
|
||||
{
|
||||
((GUIComponent)obj).Visible = false;
|
||||
button.Enabled = false;
|
||||
return true;
|
||||
}
|
||||
((GUIComponent)obj).Visible = !((GUIComponent)obj).Visible;
|
||||
return true;
|
||||
};
|
||||
|
||||
foreach (ItemPrefab ip in MapEntityPrefab.List.Where(p => p is ItemPrefab).Select(p => p as ItemPrefab))
|
||||
{
|
||||
if (!ip.CanBeBought && !ip.Tags.Contains("smallitem")) continue;
|
||||
|
||||
var itemFrame = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.15f), cargoFrame.Content.RectTransform) { MinSize = new Point(0, 30) }, isHorizontal: true)
|
||||
{
|
||||
Stretch = true,
|
||||
UserData = cargoFrame,
|
||||
RelativeSpacing = 0.05f
|
||||
};
|
||||
|
||||
|
||||
if (ip.InventoryIcon != null || ip.sprite != null)
|
||||
{
|
||||
GUIImage img = new GUIImage(new RectTransform(new Point(itemFrame.Rect.Height), itemFrame.RectTransform),
|
||||
ip.InventoryIcon ?? ip.sprite, scaleToFit: true)
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
img.Color = img.Sprite == ip.InventoryIcon ? ip.InventoryIconColor : ip.SpriteColor;
|
||||
}
|
||||
|
||||
ExtraCargo.TryGetValue(ip, out int cargoVal);
|
||||
var amountInput = new GUINumberInput(new RectTransform(new Vector2(0.3f, 1.0f), itemFrame.RectTransform),
|
||||
GUINumberInput.NumberType.Int, textAlignment: Alignment.CenterLeft)
|
||||
{
|
||||
MinValueInt = 0,
|
||||
MaxValueInt = 100,
|
||||
IntValue = cargoVal
|
||||
};
|
||||
amountInput.OnValueChanged += (numberInput) =>
|
||||
{
|
||||
if (ExtraCargo.ContainsKey(ip))
|
||||
{
|
||||
ExtraCargo[ip] = numberInput.IntValue;
|
||||
if (numberInput.IntValue <= 0) ExtraCargo.Remove(ip);
|
||||
}
|
||||
else
|
||||
{
|
||||
ExtraCargo.Add(ip, numberInput.IntValue);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// server settings
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
var serverTab = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.95f), settingsTabs[(int)SettingsTab.Server].RectTransform, Anchor.Center))
|
||||
{
|
||||
Stretch = true,
|
||||
RelativeSpacing = 0.02f
|
||||
};
|
||||
|
||||
//***********************************************
|
||||
|
||||
var voiceChatEnabled = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), serverTab.RectTransform),
|
||||
TextManager.Get("ServerSettingsVoiceChatEnabled"));
|
||||
GetPropertyData("VoiceChatEnabled").AssignGUIComponent(voiceChatEnabled);
|
||||
|
||||
//***********************************************
|
||||
|
||||
string autoRestartDelayLabel = TextManager.Get("ServerSettingsAutoRestartDelay");
|
||||
var startIntervalText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), serverTab.RectTransform), autoRestartDelayLabel);
|
||||
var startIntervalSlider = new GUIScrollBar(new RectTransform(new Vector2(1.0f, 0.05f), serverTab.RectTransform), barSize: 0.1f)
|
||||
{
|
||||
UserData = startIntervalText,
|
||||
Step = 0.05f,
|
||||
OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
|
||||
{
|
||||
GUITextBlock text = scrollBar.UserData as GUITextBlock;
|
||||
text.Text = autoRestartDelayLabel + ToolBox.SecondsToReadableTime(scrollBar.BarScrollValue);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
startIntervalSlider.Range = new Vector2(10.0f, 300.0f);
|
||||
GetPropertyData("AutoRestartInterval").AssignGUIComponent(startIntervalSlider);
|
||||
startIntervalSlider.OnMoved(startIntervalSlider, startIntervalSlider.BarScroll);
|
||||
|
||||
//***********************************************
|
||||
|
||||
var startWhenClientsReady = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), serverTab.RectTransform),
|
||||
TextManager.Get("ServerSettingsStartWhenClientsReady"));
|
||||
GetPropertyData("StartWhenClientsReady").AssignGUIComponent(startWhenClientsReady);
|
||||
|
||||
CreateLabeledSlider(serverTab, "ServerSettingsStartWhenClientsReadyRatio", out slider, out sliderLabel);
|
||||
string clientsReadyRequiredLabel = sliderLabel.Text;
|
||||
slider.Step = 0.2f;
|
||||
slider.Range = new Vector2(0.5f, 1.0f);
|
||||
slider.OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
|
||||
{
|
||||
((GUITextBlock)scrollBar.UserData).Text = clientsReadyRequiredLabel.Replace("[percentage]", ((int)MathUtils.Round(scrollBar.BarScrollValue * 100.0f, 10.0f)).ToString());
|
||||
return true;
|
||||
};
|
||||
GetPropertyData("StartWhenClientsReadyRatio").AssignGUIComponent(slider);
|
||||
slider.OnMoved(slider, slider.BarScroll);
|
||||
|
||||
//***********************************************
|
||||
|
||||
var allowSpecBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), serverTab.RectTransform), TextManager.Get("ServerSettingsAllowSpectating"));
|
||||
GetPropertyData("AllowSpectating").AssignGUIComponent(allowSpecBox);
|
||||
|
||||
var voteKickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), serverTab.RectTransform), TextManager.Get("ServerSettingsAllowVoteKick"));
|
||||
GetPropertyData("AllowVoteKick").AssignGUIComponent(voteKickBox);
|
||||
|
||||
CreateLabeledSlider(serverTab, "ServerSettingsKickVotesRequired", out slider, out sliderLabel);
|
||||
string votesRequiredLabel = sliderLabel.Text;
|
||||
slider.Step = 0.2f;
|
||||
slider.Range = new Vector2(0.5f, 1.0f);
|
||||
slider.OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
|
||||
{
|
||||
((GUITextBlock)scrollBar.UserData).Text = votesRequiredLabel + (int)MathUtils.Round(scrollBar.BarScrollValue * 100.0f, 10.0f) + " %";
|
||||
return true;
|
||||
};
|
||||
GetPropertyData("KickVoteRequiredRatio").AssignGUIComponent(slider);
|
||||
slider.OnMoved(slider, slider.BarScroll);
|
||||
|
||||
CreateLabeledSlider(serverTab, "ServerSettingsAutobanTime", out slider, out sliderLabel);
|
||||
string autobanLabel = sliderLabel.Text;
|
||||
slider.Step = 0.05f;
|
||||
slider.Range = new Vector2(0.0f, MaxAutoBanTime);
|
||||
slider.OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
|
||||
{
|
||||
((GUITextBlock)scrollBar.UserData).Text = autobanLabel + ToolBox.SecondsToReadableTime(scrollBar.BarScrollValue);
|
||||
return true;
|
||||
};
|
||||
GetPropertyData("AutoBanTime").AssignGUIComponent(slider);
|
||||
slider.OnMoved(slider, slider.BarScroll);
|
||||
|
||||
var shareSubsBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), serverTab.RectTransform), TextManager.Get("ServerSettingsShareSubFiles"));
|
||||
GetPropertyData("AllowFileTransfers").AssignGUIComponent(shareSubsBox);
|
||||
|
||||
var randomizeLevelBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), serverTab.RectTransform), TextManager.Get("ServerSettingsRandomizeSeed"));
|
||||
GetPropertyData("RandomizeSeed").AssignGUIComponent(randomizeLevelBox);
|
||||
|
||||
var saveLogsBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), serverTab.RectTransform), TextManager.Get("ServerSettingsSaveLogs"))
|
||||
{
|
||||
OnSelected = (GUITickBox) =>
|
||||
{
|
||||
//TODO: fix?
|
||||
//showLogButton.Visible = SaveServerLogs;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
GetPropertyData("SaveServerLogs").AssignGUIComponent(saveLogsBox);
|
||||
|
||||
var ragdollButtonBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), serverTab.RectTransform), TextManager.Get("ServerSettingsAllowRagdollButton"));
|
||||
GetPropertyData("AllowRagdollButton").AssignGUIComponent(ragdollButtonBox);
|
||||
|
||||
var traitorRatioBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), serverTab.RectTransform), TextManager.Get("ServerSettingsUseTraitorRatio"));
|
||||
|
||||
CreateLabeledSlider(serverTab, "", out slider, out sliderLabel);
|
||||
/*var traitorRatioText = new GUITextBlock(new Rectangle(20, y + 20, 20, 20), "Traitor ratio: 20 %", "", settingsTabs[1], GUI.SmallFont);
|
||||
var traitorRatioSlider = new GUIScrollBar(new Rectangle(150, y + 22, 100, 15), "", 0.1f, settingsTabs[1]);*/
|
||||
var traitorRatioSlider = slider;
|
||||
traitorRatioBox.OnSelected = (GUITickBox) =>
|
||||
{
|
||||
traitorRatioSlider.OnMoved(traitorRatioSlider, traitorRatioSlider.BarScroll);
|
||||
return true;
|
||||
};
|
||||
|
||||
if (TraitorUseRatio)
|
||||
{
|
||||
traitorRatioSlider.Range = new Vector2(0.1f, 1.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
traitorRatioSlider.Range = new Vector2(1.0f, maxPlayers);
|
||||
}
|
||||
|
||||
string traitorRatioLabel = TextManager.Get("ServerSettingsTraitorRatio");
|
||||
string traitorCountLabel = TextManager.Get("ServerSettingsTraitorCount");
|
||||
|
||||
traitorRatioSlider.Range = new Vector2(0.1f, 1.0f);
|
||||
traitorRatioSlider.OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
|
||||
{
|
||||
GUITextBlock traitorText = scrollBar.UserData as GUITextBlock;
|
||||
if (traitorRatioBox.Selected)
|
||||
{
|
||||
scrollBar.Step = 0.01f;
|
||||
scrollBar.Range = new Vector2(0.1f, 1.0f);
|
||||
traitorText.Text = traitorRatioLabel + (int)MathUtils.Round(scrollBar.BarScrollValue * 100.0f, 1.0f) + " %";
|
||||
}
|
||||
else
|
||||
{
|
||||
scrollBar.Step = 1f / (maxPlayers - 1);
|
||||
scrollBar.Range = new Vector2(1.0f, maxPlayers);
|
||||
traitorText.Text = traitorCountLabel + scrollBar.BarScrollValue;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
GetPropertyData("TraitorUseRatio").AssignGUIComponent(traitorRatioBox);
|
||||
GetPropertyData("TraitorRatio").AssignGUIComponent(traitorRatioSlider);
|
||||
|
||||
traitorRatioSlider.OnMoved(traitorRatioSlider, traitorRatioSlider.BarScroll);
|
||||
traitorRatioBox.OnSelected(traitorRatioBox);
|
||||
|
||||
|
||||
var karmaBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), serverTab.RectTransform), TextManager.Get("ServerSettingsUseKarma"));
|
||||
GetPropertyData("KarmaEnabled").AssignGUIComponent(karmaBox);
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// banlist
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
BanList.CreateBanFrame(settingsTabs[2]);
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// whitelist
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
Whitelist.CreateWhiteListFrame(settingsTabs[3]);
|
||||
|
||||
}
|
||||
|
||||
private void CreateLabeledSlider(GUIComponent parent, string labelTag, out GUIScrollBar slider, out GUITextBlock label)
|
||||
{
|
||||
var container = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.05f), parent.RectTransform), isHorizontal: true)
|
||||
{
|
||||
Stretch = true,
|
||||
RelativeSpacing = 0.05f
|
||||
};
|
||||
|
||||
slider = new GUIScrollBar(new RectTransform(new Vector2(0.5f, 0.8f), container.RectTransform), barSize: 0.1f);
|
||||
label = new GUITextBlock(new RectTransform(new Vector2(0.5f, 0.8f), container.RectTransform),
|
||||
string.IsNullOrEmpty(labelTag) ? "" : TextManager.Get(labelTag), font: GUI.SmallFont);
|
||||
|
||||
//slider has a reference to the label to change the text when it's used
|
||||
slider.UserData = label;
|
||||
}
|
||||
|
||||
private bool SelectSettingsTab(GUIButton button, object obj)
|
||||
{
|
||||
settingsTabIndex = (int)obj;
|
||||
|
||||
for (int i = 0; i < settingsTabs.Length; i++)
|
||||
{
|
||||
settingsTabs[i].Visible = i == settingsTabIndex;
|
||||
tabButtons[i].Selected = i == settingsTabIndex;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool ToggleSettingsFrame(GUIButton button, object obj)
|
||||
{
|
||||
if (settingsFrame == null)
|
||||
{
|
||||
CreateSettingsFrame();
|
||||
}
|
||||
else
|
||||
{
|
||||
ClientAdminWrite(NetFlags.Properties);
|
||||
foreach (NetPropertyData prop in netProperties.Values)
|
||||
{
|
||||
prop.GUIComponent = null;
|
||||
}
|
||||
settingsFrame = null;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void ManagePlayersFrame(GUIFrame infoFrame)
|
||||
{
|
||||
GUIListBox cList = new GUIListBox(new RectTransform(Vector2.One, infoFrame.RectTransform));
|
||||
/*foreach (Client c in ConnectedClients)
|
||||
{
|
||||
var frame = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), cList.Content.RectTransform),
|
||||
c.Name + " (" + c.Connection.RemoteEndPoint.Address.ToString() + ")", style: "ListBoxElement")
|
||||
{
|
||||
Color = (c.InGame && c.Character != null && !c.Character.IsDead) ? Color.Gold * 0.2f : Color.Transparent,
|
||||
HoverColor = Color.LightGray * 0.5f,
|
||||
SelectedColor = Color.Gold * 0.5f
|
||||
};
|
||||
|
||||
var buttonArea = new GUILayoutGroup(new RectTransform(new Vector2(0.45f, 0.85f), frame.RectTransform, Anchor.CenterRight) { RelativeOffset = new Vector2(0.05f, 0.0f) },
|
||||
isHorizontal: true);
|
||||
|
||||
var kickButton = new GUIButton(new RectTransform(new Vector2(0.25f, 1.0f), buttonArea.RectTransform),
|
||||
TextManager.Get("Kick"))
|
||||
{
|
||||
UserData = c.Name,
|
||||
OnClicked = GameMain.NetLobbyScreen.KickPlayer
|
||||
};
|
||||
|
||||
var banButton = new GUIButton(new RectTransform(new Vector2(0.25f, 1.0f), buttonArea.RectTransform),
|
||||
TextManager.Get("Ban"))
|
||||
{
|
||||
UserData = c.Name,
|
||||
OnClicked = GameMain.NetLobbyScreen.BanPlayer
|
||||
};
|
||||
|
||||
var rangebanButton = new GUIButton(new RectTransform(new Vector2(0.25f, 1.0f), buttonArea.RectTransform),
|
||||
TextManager.Get("BanRange"))
|
||||
{
|
||||
UserData = c.Name,
|
||||
OnClicked = GameMain.NetLobbyScreen.BanPlayerRange
|
||||
};
|
||||
}*/ //TODO: reimplement
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,7 @@ namespace Barotrauma.Networking
|
||||
private set;
|
||||
}
|
||||
|
||||
public DateTime LastEnqueueAudio;
|
||||
public DateTime LastEnqueueAudio;
|
||||
|
||||
public override byte QueueID
|
||||
{
|
||||
@@ -47,10 +47,14 @@ namespace Barotrauma.Networking
|
||||
throw new Exception("Tried to instance more than one VoipCapture object");
|
||||
}
|
||||
|
||||
Instance = new VoipCapture(deviceName)
|
||||
var capture = new VoipCapture(deviceName)
|
||||
{
|
||||
LatestBufferID = storedBufferID ?? BUFFER_COUNT - 1
|
||||
};
|
||||
if (capture.captureDevice != IntPtr.Zero)
|
||||
{
|
||||
Instance = capture;
|
||||
}
|
||||
}
|
||||
|
||||
private VoipCapture(string deviceName) : base(GameMain.Client?.ID ?? 0, true, false)
|
||||
@@ -60,6 +64,14 @@ namespace Barotrauma.Networking
|
||||
//set up capture device
|
||||
captureDevice = Alc.CaptureOpenDevice(deviceName, VoipConfig.FREQUENCY, ALFormat.Mono16, VoipConfig.BUFFER_SIZE * 5);
|
||||
|
||||
if (captureDevice == IntPtr.Zero)
|
||||
{
|
||||
new GUIMessageBox(TextManager.Get("Error"), TextManager.Get("VoipCaptureDeviceNotFound"));
|
||||
Instance?.Dispose();
|
||||
Instance = null;
|
||||
return;
|
||||
}
|
||||
|
||||
ALError alError = AL.GetError();
|
||||
AlcError alcError = Alc.GetError(captureDevice);
|
||||
if (alcError != AlcError.NoError)
|
||||
@@ -70,7 +82,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
throw new Exception("Failed to open capture device: " + alError.ToString() + " (AL)");
|
||||
}
|
||||
|
||||
|
||||
Alc.CaptureStart(captureDevice);
|
||||
alcError = Alc.GetError(captureDevice);
|
||||
if (alcError != AlcError.NoError)
|
||||
@@ -159,7 +171,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
else if (GameMain.Config.VoiceSetting == GameSettings.VoiceMode.PushToTalk)
|
||||
{
|
||||
if (PlayerInput.KeyDown(InputType.Voice))
|
||||
if (PlayerInput.KeyDown(InputType.Voice) && GUI.KeyboardDispatcher.Subscriber == null)
|
||||
{
|
||||
allowEnqueue = true;
|
||||
}
|
||||
@@ -201,7 +213,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
Instance = null;
|
||||
capturing = false;
|
||||
captureThread.Join();
|
||||
captureThread?.Join();
|
||||
captureThread = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace Barotrauma.Networking
|
||||
else
|
||||
{
|
||||
if (VoipCapture.Instance == null) VoipCapture.Create(GameMain.Config.VoiceCaptureDevice, storedBufferID);
|
||||
if (VoipCapture.Instance.EnqueuedTotalLength <= 0) return;
|
||||
if (VoipCapture.Instance == null || VoipCapture.Instance.EnqueuedTotalLength <= 0) return;
|
||||
}
|
||||
|
||||
if (DateTime.Now >= lastSendTime + VoipConfig.SEND_INTERVAL)
|
||||
|
||||
Reference in New Issue
Block a user