v1.4.4.1 (Blood in the Water Update)
This commit is contained in:
@@ -46,7 +46,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
if (localRemovedBans.Contains(bannedPlayer.UniqueIdentifier)) { continue; }
|
||||
|
||||
var playerFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.2f), ((GUIListBox)BanFrame).Content.RectTransform) { MinSize = new Point(0, 70) })
|
||||
var playerFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.2f), ((GUIListBox)BanFrame).Content.RectTransform) { MinSize = new Point(0, 70) }, style: "InnerFrame")
|
||||
{
|
||||
UserData = BanFrame
|
||||
};
|
||||
@@ -80,18 +80,22 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
CanBeFocused = true
|
||||
};
|
||||
textBlock.RectTransform.MinSize = new Point(
|
||||
(int)textBlock.Font.MeasureString(textBlock.Text.SanitizedValue).X, 0);
|
||||
textBlock.RectTransform.MinSize = new Point(0, (int)textBlock.Font.MeasureString(textBlock.Text.SanitizedValue).Y);
|
||||
|
||||
var removeButton = new GUIButton(new RectTransform(new Vector2(0.2f, 0.4f), topArea.RectTransform),
|
||||
var removeButton = new GUIButton(new RectTransform(new Vector2(0.2f, 0.4f), topArea.RectTransform, Anchor.CenterRight),
|
||||
TextManager.Get("BanListRemove"), style: "GUIButtonSmall")
|
||||
{
|
||||
IgnoreLayoutGroups = true,
|
||||
UserData = bannedPlayer,
|
||||
OnClicked = RemoveBan
|
||||
OnClicked = RemoveBan,
|
||||
Enabled = false
|
||||
};
|
||||
topArea.RectTransform.MinSize = new Point(0, (int)(removeButton.Rect.Height * 1.25f));
|
||||
|
||||
topArea.ForceLayoutRecalculation();
|
||||
removeButton.OnAddedToGUIUpdateList += (component) =>
|
||||
{
|
||||
component.Enabled = GameMain.Client?.HasPermission(ClientPermissions.Unban) ?? false;
|
||||
};
|
||||
topArea.RectTransform.MinSize = new Point(0, Math.Max(textBlock.RectTransform.MinSize.Y, removeButton.RectTransform.MinSize.Y));
|
||||
topArea.RectTransform.IsFixedSize = true;
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedPlayerFrame.RectTransform),
|
||||
bannedPlayer.ExpirationTime.TryUnwrap(out var expirationTime)
|
||||
|
||||
@@ -14,6 +14,17 @@ namespace Barotrauma.Networking
|
||||
set;
|
||||
}
|
||||
|
||||
// Players can boost per-user volume by 200%
|
||||
public const float MaxVoiceChatBoost = 2.0f;
|
||||
|
||||
private float voiceVolume = 1f;
|
||||
|
||||
public float VoiceVolume
|
||||
{
|
||||
get => voiceVolume;
|
||||
set => voiceVolume = Math.Clamp(value, 0f, MaxVoiceChatBoost);
|
||||
}
|
||||
|
||||
private SoundChannel radioNoiseChannel;
|
||||
private float radioNoise;
|
||||
|
||||
@@ -23,7 +34,6 @@ namespace Barotrauma.Networking
|
||||
set { radioNoise = MathHelper.Clamp(value, 0.0f, 1.0f); }
|
||||
}
|
||||
|
||||
|
||||
private bool mutedLocally;
|
||||
public bool MutedLocally
|
||||
{
|
||||
@@ -86,6 +96,17 @@ namespace Barotrauma.Networking
|
||||
float dist = Vector3.Distance(new Vector3(character.WorldPosition, 0.0f), GameMain.SoundManager.ListenerPosition);
|
||||
gain = 1.0f - MathUtils.InverseLerp(VoipSound.Near, VoipSound.Far, dist);
|
||||
}
|
||||
if (!VoipSound.UsingRadio)
|
||||
{
|
||||
//emulate the "garbling" of the text chat
|
||||
//this in a sense means the volume diminishes exponentially when close to the maximum range of the sound
|
||||
//(diminished by both the garbling and the distance attenuation)
|
||||
|
||||
//which is good, because we want the voice chat to become unintelligible close to the max range,
|
||||
//and we need to heavily reduce the volume to do that (otherwise it's just quiet, but still intelligible)
|
||||
float garbleAmount = ChatMessage.GetGarbleAmount(Character.Controlled, character, ChatMessage.SpeakRangeVOIP);
|
||||
gain *= 1.0f - garbleAmount;
|
||||
}
|
||||
if (RadioNoise > 0.0f)
|
||||
{
|
||||
noiseGain = gain * RadioNoise;
|
||||
|
||||
@@ -21,7 +21,12 @@ namespace Barotrauma
|
||||
DebugConsole.Log($"Received entity removal message for \"{entity}\".");
|
||||
if (entity is Item item && item.Container?.GetComponent<Deconstructor>() != null)
|
||||
{
|
||||
GameAnalyticsManager.AddDesignEvent("ItemDeconstructed:" + (GameMain.GameSession?.GameMode?.Preset.Identifier ?? "none".ToIdentifier()) + ":" + item.Prefab.Identifier);
|
||||
if (item.Prefab.ContentPackage == ContentPackageManager.VanillaCorePackage &&
|
||||
/* we don't need info of every deconstructed item, we can get a good sample size just by logging 5% */
|
||||
Rand.Range(0.0f, 1.0f) < 0.05f)
|
||||
{
|
||||
GameAnalyticsManager.AddDesignEvent("ItemDeconstructed:" + (GameMain.GameSession?.GameMode?.Preset.Identifier ?? "none".ToIdentifier()) + ":" + item.Prefab.Identifier);
|
||||
}
|
||||
}
|
||||
entity.Remove();
|
||||
}
|
||||
@@ -45,7 +50,12 @@ namespace Barotrauma
|
||||
{
|
||||
if (newItem.Container?.GetComponent<Fabricator>() != null)
|
||||
{
|
||||
GameAnalyticsManager.AddDesignEvent("ItemFabricated:" + (GameMain.GameSession?.GameMode?.Preset.Identifier ?? "none".ToIdentifier()) + ":" + newItem.Prefab.Identifier);
|
||||
if (newItem.Prefab.ContentPackage == ContentPackageManager.VanillaCorePackage &&
|
||||
/* we don't need info of every fabricated item, we can get a good sample size just by logging 5% */
|
||||
Rand.Range(0.0f, 1.0f) < 0.05f)
|
||||
{
|
||||
GameAnalyticsManager.AddDesignEvent("ItemFabricated:" + (GameMain.GameSession?.GameMode?.Preset.Identifier ?? "none".ToIdentifier()) + ":" + newItem.Prefab.Identifier);
|
||||
}
|
||||
}
|
||||
receivedEvents.Add((newItem, false));
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
public readonly List<SubmarineInfo> ServerSubmarines = new List<SubmarineInfo>();
|
||||
|
||||
public string ServerName { get; private set; }
|
||||
public string ServerName => ServerSettings.ServerName;
|
||||
|
||||
private bool canStart;
|
||||
|
||||
@@ -270,11 +270,11 @@ namespace Barotrauma.Networking
|
||||
|
||||
otherClients = new List<Client>();
|
||||
|
||||
ServerSettings = new ServerSettings(this, "Server", 0, 0, 0, false, false);
|
||||
ServerSettings = new ServerSettings(this, serverName, 0, 0, 0, false, false);
|
||||
Voting = new Voting();
|
||||
|
||||
serverEndpoints = endpoints;
|
||||
InitiateServerJoin(serverName);
|
||||
InitiateServerJoin();
|
||||
|
||||
//ServerLog = new ServerLog("");
|
||||
|
||||
@@ -289,7 +289,7 @@ namespace Barotrauma.Networking
|
||||
return serverInfo;
|
||||
}
|
||||
|
||||
private void InitiateServerJoin(string hostName)
|
||||
private void InitiateServerJoin()
|
||||
{
|
||||
LastClientListUpdateID = 0;
|
||||
|
||||
@@ -306,8 +306,6 @@ namespace Barotrauma.Networking
|
||||
GameMain.NetLobbyScreen.ChatInput.Enabled = false;
|
||||
}
|
||||
|
||||
ServerName = hostName;
|
||||
|
||||
myCharacter = Character.Controlled;
|
||||
ChatMessage.LastID = 0;
|
||||
|
||||
@@ -318,9 +316,8 @@ namespace Barotrauma.Networking
|
||||
CoroutineManager.StartCoroutine(WaitForStartingInfo(), "WaitForStartingInfo");
|
||||
}
|
||||
|
||||
public void SetLobbyPublic(bool isPublic)
|
||||
public static void SetLobbyPublic(bool isPublic)
|
||||
{
|
||||
GameMain.NetLobbyScreen.SetPublic(isPublic);
|
||||
SteamManager.SetLobbyPublic(isPublic);
|
||||
}
|
||||
|
||||
@@ -723,7 +720,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (readyToStart && !CoroutineManager.IsCoroutineRunning("WaitForStartRound"))
|
||||
{
|
||||
CoroutineManager.StartCoroutine(GameMain.NetLobbyScreen.WaitForStartRound(startButton: null), "WaitForStartRound");
|
||||
CoroutineManager.StartCoroutine(NetLobbyScreen.WaitForStartRound(startButton: null), "WaitForStartRound");
|
||||
}
|
||||
break;
|
||||
case ServerPacketHeader.STARTGAME:
|
||||
@@ -1096,7 +1093,7 @@ namespace Barotrauma.Networking
|
||||
var prevContentPackages = ClientPeer.ServerContentPackages;
|
||||
//decrement lobby update ID to make sure we update the lobby when we reconnect
|
||||
GameMain.NetLobbyScreen.LastUpdateID--;
|
||||
InitiateServerJoin(ServerName);
|
||||
InitiateServerJoin();
|
||||
if (ClientPeer != null)
|
||||
{
|
||||
//restore the previous list of content packages so we can reconnect immediately without having to recheck that the packages match
|
||||
@@ -1189,7 +1186,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
if (!CoroutineManager.IsCoroutineRunning("WaitForStartingInfo"))
|
||||
{
|
||||
InitiateServerJoin(ServerName);
|
||||
InitiateServerJoin();
|
||||
yield return new WaitForSeconds(5.0f);
|
||||
}
|
||||
yield return new WaitForSeconds(0.5f);
|
||||
@@ -1253,7 +1250,7 @@ namespace Barotrauma.Networking
|
||||
if (!(this.permittedConsoleCommands.Any(c => !permittedConsoleCommands.Contains(c)) ||
|
||||
permittedConsoleCommands.Any(c => !this.permittedConsoleCommands.Contains(c))))
|
||||
{
|
||||
if (newPermissions == permissions) return;
|
||||
if (newPermissions == permissions) { return; }
|
||||
}
|
||||
|
||||
bool refreshCampaignUI = permissions.HasFlag(ClientPermissions.ManageCampaign) != newPermissions.HasFlag(ClientPermissions.ManageCampaign) ||
|
||||
@@ -1335,6 +1332,8 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
GameMain.NetLobbyScreen.RefreshEnabledElements();
|
||||
//close settings menu in case it was open
|
||||
ServerSettings.Close();
|
||||
OnPermissionChanged.Invoke(new PermissionChangedEvent(permissions, this.permittedConsoleCommands));
|
||||
}
|
||||
|
||||
@@ -2025,18 +2024,15 @@ namespace Barotrauma.Networking
|
||||
GameMain.NetLobbyScreen.LastUpdateID = updateID;
|
||||
|
||||
ServerSettings.ServerLog.ServerName = ServerSettings.ServerName;
|
||||
|
||||
if (!GameMain.NetLobbyScreen.ServerName.Selected) { GameMain.NetLobbyScreen.ServerName.Text = ServerSettings.ServerName; }
|
||||
if (!GameMain.NetLobbyScreen.ServerMessage.Selected) { GameMain.NetLobbyScreen.ServerMessage.Text = ServerSettings.ServerMessageText; }
|
||||
GameMain.NetLobbyScreen.UsingShuttle = usingShuttle;
|
||||
|
||||
if (!allowSubVoting) { GameMain.NetLobbyScreen.TrySelectSub(selectSubName, selectSubHash, GameMain.NetLobbyScreen.SubList); }
|
||||
if (!allowSubVoting || GameMain.NetLobbyScreen.SelectedSub == null) { GameMain.NetLobbyScreen.TrySelectSub(selectSubName, selectSubHash, GameMain.NetLobbyScreen.SubList); }
|
||||
GameMain.NetLobbyScreen.TrySelectSub(selectShuttleName, selectShuttleHash, GameMain.NetLobbyScreen.ShuttleList.ListBox);
|
||||
|
||||
GameMain.NetLobbyScreen.SetTraitorProbability(traitorProbability);
|
||||
GameMain.NetLobbyScreen.SetTraitorDangerLevel(traitorDangerLevel);
|
||||
|
||||
GameMain.NetLobbyScreen.SetMissionType(missionType);
|
||||
GameMain.NetLobbyScreen.LevelSeed = levelSeed;
|
||||
|
||||
GameMain.NetLobbyScreen.SelectMode(modeIndex);
|
||||
if (isInitialUpdate && GameMain.NetLobbyScreen.SelectedMode == GameModePreset.MultiPlayerCampaign)
|
||||
@@ -2053,7 +2049,6 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
GameMain.NetLobbyScreen.SetAllowSpectating(allowSpectating);
|
||||
GameMain.NetLobbyScreen.LevelSeed = levelSeed;
|
||||
GameMain.NetLobbyScreen.SetLevelDifficulty(levelDifficulty);
|
||||
GameMain.NetLobbyScreen.SetBotSpawnMode(botSpawnMode);
|
||||
GameMain.NetLobbyScreen.SetBotCount(botCount);
|
||||
@@ -2574,12 +2569,17 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
public override void CreateEntityEvent(INetSerializable entity, NetEntityEvent.IData extraData = null)
|
||||
{
|
||||
CreateEntityEvent(entity, extraData, requireControlledCharacter: true);
|
||||
}
|
||||
|
||||
public void CreateEntityEvent(INetSerializable entity, NetEntityEvent.IData extraData, bool requireControlledCharacter)
|
||||
{
|
||||
if (entity is not IClientSerializable clientSerializable)
|
||||
{
|
||||
throw new InvalidCastException($"Entity is not {nameof(IClientSerializable)}");
|
||||
}
|
||||
EntityEventManager.CreateEvent(clientSerializable, extraData);
|
||||
EntityEventManager.CreateEvent(clientSerializable, extraData, requireControlledCharacter);
|
||||
}
|
||||
|
||||
public bool HasPermission(ClientPermissions permission)
|
||||
@@ -2703,9 +2703,19 @@ namespace Barotrauma.Networking
|
||||
|
||||
public override void AddChatMessage(ChatMessage message)
|
||||
{
|
||||
base.AddChatMessage(message);
|
||||
|
||||
if (string.IsNullOrEmpty(message.Text)) { return; }
|
||||
if (message.Sender != null && !message.Sender.IsDead)
|
||||
{
|
||||
if (message.Text.IsNullOrEmpty())
|
||||
{
|
||||
message.Sender.ShowTextlessSpeechBubble(2.0f, message.Color);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
message.Sender.ShowSpeechBubble(message.Color, message.Text);
|
||||
}
|
||||
}
|
||||
GameMain.NetLobbyScreen.NewChatMessage(message);
|
||||
chatBox.AddMessage(message);
|
||||
}
|
||||
@@ -2894,7 +2904,7 @@ namespace Barotrauma.Networking
|
||||
ClientPeer.Send(msg, DeliveryMethod.Reliable);
|
||||
}
|
||||
|
||||
public bool SpectateClicked(GUIButton button, object _)
|
||||
public bool JoinOnGoingClicked(GUIButton button, object _)
|
||||
{
|
||||
MultiPlayerCampaign campaign =
|
||||
GameMain.NetLobbyScreen.SelectedMode == GameMain.GameSession?.GameMode.Preset ?
|
||||
@@ -3283,17 +3293,36 @@ namespace Barotrauma.Networking
|
||||
|
||||
private void CreateSelectionRelatedButtons(Client client, GUIComponent frame)
|
||||
{
|
||||
var content = new GUIFrame(new RectTransform(new Vector2(1f, 1.0f - frame.RectTransform.RelativeSize.Y), frame.RectTransform, Anchor.BottomCenter, Pivot.TopCenter),
|
||||
style: null);
|
||||
var content = new GUILayoutGroup(new RectTransform(new Vector2(1f, 1.0f - frame.RectTransform.RelativeSize.Y), frame.RectTransform, Anchor.BottomCenter, Pivot.TopCenter), childAnchor: Anchor.TopCenter);
|
||||
|
||||
var mute = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.5f), content.RectTransform, Anchor.TopCenter),
|
||||
var mute = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.2f), content.RectTransform, Anchor.TopCenter),
|
||||
TextManager.Get("Mute"))
|
||||
{
|
||||
Selected = client.MutedLocally,
|
||||
OnSelected = (tickBox) => { client.MutedLocally = tickBox.Selected; return true; }
|
||||
};
|
||||
|
||||
var volumeLayout = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.45f), content.RectTransform, Anchor.TopCenter), isHorizontal: false);
|
||||
|
||||
var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.35f), content.RectTransform, Anchor.BottomCenter), isHorizontal: true, childAnchor: Anchor.BottomLeft)
|
||||
var volumeTextLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.5f), volumeLayout.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft);
|
||||
var label = new GUITextBlock(new RectTransform(new Vector2(0.6f, 1f), volumeTextLayout.RectTransform), TextManager.Get("VoiceChatVolume"));
|
||||
var percentageText = new GUITextBlock(new RectTransform(new Vector2(0.4f, 1f), volumeTextLayout.RectTransform), ToolBox.GetFormattedPercentage(client.VoiceVolume), textAlignment: Alignment.Right);
|
||||
|
||||
var volumeSlider = new GUIScrollBar(new RectTransform(new Vector2(1f, 0.5f), volumeLayout.RectTransform), barSize: 0.1f, style: "GUISlider")
|
||||
{
|
||||
Range = new Vector2(0f, 1f),
|
||||
BarScroll = client.VoiceVolume / Client.MaxVoiceChatBoost,
|
||||
OnMoved = (_, barScroll) =>
|
||||
{
|
||||
float newVolume = barScroll * Client.MaxVoiceChatBoost;
|
||||
|
||||
client.VoiceVolume = newVolume;
|
||||
percentageText.Text = ToolBox.GetFormattedPercentage(newVolume);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.35f), content.RectTransform), isHorizontal: true, childAnchor: Anchor.BottomLeft)
|
||||
{
|
||||
RelativeSpacing = 0.05f,
|
||||
Stretch = true
|
||||
@@ -3327,7 +3356,7 @@ namespace Barotrauma.Networking
|
||||
TextManager.Get("Ban"), style: "GUIButtonSmall")
|
||||
{
|
||||
UserData = client,
|
||||
OnClicked = (btn, userdata) => { GameMain.NetLobbyScreen.BanPlayer(client); return false; }
|
||||
OnClicked = (btn, userdata) => { NetLobbyScreen.BanPlayer(client); return false; }
|
||||
};
|
||||
}
|
||||
if (HasPermission(ClientPermissions.Kick) && client.AllowKicking)
|
||||
@@ -3336,7 +3365,7 @@ namespace Barotrauma.Networking
|
||||
TextManager.Get("Kick"), style: "GUIButtonSmall")
|
||||
{
|
||||
UserData = client,
|
||||
OnClicked = (btn, userdata) => { GameMain.NetLobbyScreen.KickPlayer(client); return false; }
|
||||
OnClicked = (btn, userdata) => { NetLobbyScreen.KickPlayer(client); return false; }
|
||||
};
|
||||
}
|
||||
else if (ServerSettings.AllowVoteKick && client.AllowKicking)
|
||||
|
||||
+4
-3
@@ -42,16 +42,17 @@ namespace Barotrauma.Networking
|
||||
thisClient = client;
|
||||
}
|
||||
|
||||
public void CreateEvent(IClientSerializable entity, NetEntityEvent.IData extraData = null)
|
||||
public void CreateEvent(IClientSerializable entity, NetEntityEvent.IData extraData = null, bool requireControlledCharacter = true)
|
||||
{
|
||||
if (GameMain.Client?.Character == null) { return; }
|
||||
if (GameMain.Client == null) { return; }
|
||||
if (requireControlledCharacter && GameMain.Client.Character == null) { return; }
|
||||
|
||||
if (!ValidateEntity(entity)) { return; }
|
||||
|
||||
var newEvent = new ClientEntityEvent(
|
||||
entity,
|
||||
eventId: (UInt16)(ID + 1),
|
||||
characterStateId: GameMain.Client.Character.LastNetworkUpdateID);
|
||||
characterStateId: GameMain.Client.Character?.LastNetworkUpdateID ?? Entity.NullEntityID);
|
||||
if (extraData != null) { newEvent.SetData(extraData); }
|
||||
|
||||
for (int i = events.Count - 1; i >= 0; i--)
|
||||
|
||||
@@ -18,6 +18,8 @@ namespace Barotrauma.Networking
|
||||
public ImmutableArray<ServerContentPackage> ServerContentPackages { get; set; } =
|
||||
ImmutableArray<ServerContentPackage>.Empty;
|
||||
|
||||
public bool AllowModDownloads { get; private set; } = true;
|
||||
|
||||
public readonly record struct Callbacks(
|
||||
Callbacks.MessageCallback OnMessageReceived,
|
||||
Callbacks.DisconnectCallback OnDisconnect,
|
||||
@@ -151,6 +153,7 @@ namespace Barotrauma.Networking
|
||||
if (!ContentPackageOrderReceived)
|
||||
{
|
||||
ServerContentPackages = orderPacket.ContentPackages;
|
||||
AllowModDownloads = orderPacket.AllowModDownloads;
|
||||
if (ServerContentPackages.Length == 0)
|
||||
{
|
||||
string errorMsg = "Error in ContentPackageOrder message: list of content packages enabled on the server was empty.";
|
||||
|
||||
@@ -51,20 +51,38 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
if (Character.Controlled != null || (GameMain.GameSession is not { IsRunning: true })) { return; }
|
||||
|
||||
LocalizedString text = TextManager.Get("respawnquestionprompt");
|
||||
LocalizedString text;
|
||||
GUIMessageBox respawnPrompt;
|
||||
if (SkillLossPercentageOnImmediateRespawn > 0)
|
||||
{
|
||||
// Respawn asap with extra skill loss?
|
||||
text = TextManager.GetWithVariable("respawnquestionprompt", "[percentage]", ((int)Math.Round(SkillLossPercentageOnImmediateRespawn)).ToString());
|
||||
respawnPrompt = new GUIMessageBox(
|
||||
TextManager.Get("tutorial.tryagainheader"), text,
|
||||
new LocalizedString[] { TextManager.Get("respawnquestionpromptrespawn"), TextManager.Get("respawnquestionpromptwait") })
|
||||
{
|
||||
UserData = "respawnquestionprompt"
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
// Respawn asap?
|
||||
text = TextManager.Get("respawnquestionpromptnoloss");
|
||||
respawnPrompt = new GUIMessageBox(
|
||||
TextManager.Get("tutorial.tryagainheader"), text,
|
||||
new LocalizedString[] { TextManager.Get("respawnquestionpromptrespawnnoloss"), TextManager.Get("respawnquestionpromptwait") })
|
||||
{
|
||||
UserData = "respawnquestionprompt"
|
||||
};
|
||||
}
|
||||
if (SkillLossPercentageOnDeath > 0)
|
||||
{
|
||||
// You have died... etc added BEFORE the above text
|
||||
text =
|
||||
TextManager.GetWithVariable("respawnskillpenalty", "[percentage]", ((int)SkillLossPercentageOnDeath).ToString()) +
|
||||
"\n\n" + text;
|
||||
};
|
||||
|
||||
var respawnPrompt = new GUIMessageBox(
|
||||
TextManager.Get("tutorial.tryagainheader"), text,
|
||||
new LocalizedString[] { TextManager.Get("respawnquestionpromptrespawn"), TextManager.Get("respawnquestionpromptwait") })
|
||||
{
|
||||
UserData = "respawnquestionprompt"
|
||||
};
|
||||
respawnPrompt.Buttons[0].OnClicked += (btn, userdata) =>
|
||||
{
|
||||
GameMain.Client?.SendRespawnPromptResponse(waitForNextRoundRespawn: false);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,924 @@
|
||||
using Barotrauma.Extensions;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma.Networking
|
||||
{
|
||||
partial class ServerSettings : ISerializableEntity
|
||||
{
|
||||
//GUI stuff
|
||||
private GUIFrame settingsFrame;
|
||||
private readonly Dictionary<SettingsTab, GUIComponent> settingsTabs = new Dictionary<SettingsTab, GUIComponent>();
|
||||
private readonly Dictionary<SettingsTab, GUIButton> tabButtons = new Dictionary<SettingsTab, GUIButton>();
|
||||
private SettingsTab selectedTab;
|
||||
|
||||
//UI elements relating to karma, hidden when karma is disabled
|
||||
private readonly List<GUIComponent> karmaElements = new List<GUIComponent>();
|
||||
private GUIDropDown karmaPresetDD;
|
||||
private GUIListBox karmaSettingsList;
|
||||
|
||||
private GUIComponent extraCargoPanel, monstersEnabledPanel;
|
||||
private GUIButton extraCargoButton, monstersEnabledButton;
|
||||
|
||||
enum SettingsTab
|
||||
{
|
||||
ServerIdentity,
|
||||
General,
|
||||
Antigriefing,
|
||||
Banlist
|
||||
}
|
||||
|
||||
public void AssignGUIComponent(string propertyName, GUIComponent component)
|
||||
{
|
||||
GetPropertyData(propertyName).AssignGUIComponent(component);
|
||||
}
|
||||
|
||||
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, Anchor.Center), style: null);
|
||||
new GUIFrame(new RectTransform(GUI.Canvas.RelativeSize, settingsFrame.RectTransform, Anchor.Center), style: "GUIBackgroundBlocker");
|
||||
|
||||
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.5f, 0.85f), settingsFrame.RectTransform, Anchor.Center) { MinSize = new Point(400, 430) });
|
||||
GUILayoutGroup paddedFrame = new GUILayoutGroup(new RectTransform(innerFrame.Rect.Size - new Point(GUI.IntScale(20)), innerFrame.RectTransform, Anchor.Center),
|
||||
childAnchor: Anchor.TopCenter)
|
||||
{
|
||||
Stretch = true,
|
||||
RelativeSpacing = 0.02f
|
||||
};
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedFrame.RectTransform), TextManager.Get("serversettingsbutton"), font: GUIStyle.LargeFont);
|
||||
|
||||
var buttonArea = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.04f), paddedFrame.RectTransform), isHorizontal: true)
|
||||
{
|
||||
Stretch = true,
|
||||
RelativeSpacing = 0.01f
|
||||
};
|
||||
|
||||
var tabContent = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.85f), paddedFrame.RectTransform), style: "InnerFrame");
|
||||
|
||||
//tabs
|
||||
var settingsTabTypes = Enum.GetValues(typeof(SettingsTab)).Cast<SettingsTab>();
|
||||
foreach (var settingsTab in settingsTabTypes)
|
||||
{
|
||||
settingsTabs[settingsTab] = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.95f), tabContent.RectTransform, Anchor.Center));
|
||||
tabButtons[settingsTab] = new GUIButton(new RectTransform(new Vector2(0.2f, 1.2f), buttonArea.RectTransform), TextManager.Get($"ServerSettings{settingsTab}Tab"), style: "GUITabButton")
|
||||
{
|
||||
UserData = settingsTab,
|
||||
OnClicked = SelectSettingsTab
|
||||
};
|
||||
}
|
||||
GUITextBlock.AutoScaleAndNormalize(tabButtons.Values.Select(b => b.TextBlock));
|
||||
SelectSettingsTab(tabButtons[0], 0);
|
||||
tabButtons[SettingsTab.Banlist].Enabled =
|
||||
GameMain.Client.HasPermission(Networking.ClientPermissions.Ban) ||
|
||||
GameMain.Client.HasPermission(Networking.ClientPermissions.Unban);
|
||||
|
||||
//"Close"
|
||||
var buttonContainer = new GUIFrame(new RectTransform(new Vector2(0.95f, 0.05f), paddedFrame.RectTransform), style: null);
|
||||
var closeButton = new GUIButton(new RectTransform(new Vector2(0.25f, 1.0f), buttonContainer.RectTransform, Anchor.BottomRight), TextManager.Get("Close"))
|
||||
{
|
||||
OnClicked = ToggleSettingsFrame
|
||||
};
|
||||
|
||||
CreateServerIdentityTab(settingsTabs[SettingsTab.ServerIdentity]);
|
||||
CreateGeneralTab(settingsTabs[SettingsTab.General]);
|
||||
CreateAntigriefingTab(settingsTabs[SettingsTab.Antigriefing]);
|
||||
CreateBanlistTab(settingsTabs[SettingsTab.Banlist]);
|
||||
|
||||
if (GameMain.Client == null ||
|
||||
!GameMain.Client.HasPermission(Networking.ClientPermissions.ManageSettings))
|
||||
{
|
||||
//block all settings if the client doesn't have permission to edit them
|
||||
foreach (var settingsTab in settingsTabs)
|
||||
{
|
||||
SetElementInteractability(settingsTab.Value, false);
|
||||
}
|
||||
}
|
||||
//keep these enabled, so clients can open the panels and see what's enabled even if they can't edit them
|
||||
extraCargoButton.Enabled = monstersEnabledButton.Enabled = true;
|
||||
}
|
||||
|
||||
private void SetElementInteractability(GUIComponent parent, bool interactable)
|
||||
{
|
||||
foreach (var child in parent.GetAllChildren<GUIComponent>())
|
||||
{
|
||||
child.Enabled = interactable;
|
||||
//make the disabled color slightly less dim (these should be readable, despite being non-interactable)
|
||||
child.DisabledColor = new Color(child.Color, child.Color.A / 255.0f * 0.8f);
|
||||
if (child is GUITextBlock textBlock)
|
||||
{
|
||||
textBlock.DisabledTextColor = new Color(textBlock.TextColor, textBlock.TextColor.A / 255.0f * 0.8f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateServerIdentityTab(GUIComponent parent)
|
||||
{
|
||||
//changing server visibility on the fly is not supported in dedicated servers
|
||||
if (GameMain.Client?.ClientPeer is not LidgrenClientPeer)
|
||||
{
|
||||
var isPublic = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), parent.RectTransform),
|
||||
TextManager.Get("publicserver"))
|
||||
{
|
||||
ToolTip = TextManager.Get("publicservertooltip")
|
||||
};
|
||||
AssignGUIComponent(nameof(IsPublic), isPublic);
|
||||
}
|
||||
|
||||
var serverNameLabel = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), parent.RectTransform), TextManager.Get("ServerName"));
|
||||
var serverNameBox = new GUITextBox(new RectTransform(new Vector2(0.5f, 1.0f), serverNameLabel.RectTransform, Anchor.CenterRight),
|
||||
GameMain.Client.ServerSettings.ServerName)
|
||||
{
|
||||
OverflowClip = true,
|
||||
MaxTextLength = NetConfig.ServerNameMaxLength
|
||||
};
|
||||
serverNameBox.OnDeselected += (textBox, key) =>
|
||||
{
|
||||
if (textBox.Text.IsNullOrWhiteSpace())
|
||||
{
|
||||
textBox.Flash(GUIStyle.Red);
|
||||
if (GameMain.Client != null)
|
||||
{
|
||||
textBox.Text = GameMain.Client.ServerSettings.ServerName;
|
||||
}
|
||||
}
|
||||
GameMain.Client?.ServerSettings.ClientAdminWrite(NetFlags.Properties);
|
||||
};
|
||||
AssignGUIComponent(nameof(ServerName), serverNameBox);
|
||||
|
||||
// server message *************************************************************************
|
||||
|
||||
var motdHeader = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), parent.RectTransform), TextManager.Get("ServerMOTD"));
|
||||
var motdCharacterCount = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), motdHeader.RectTransform, Anchor.CenterRight), string.Empty, textAlignment: Alignment.CenterRight);
|
||||
var serverMessageContainer = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.2f), parent.RectTransform))
|
||||
{
|
||||
Visible = true
|
||||
};
|
||||
var serverMessageBox = new GUITextBox(new RectTransform(Vector2.One, serverMessageContainer.Content.RectTransform),
|
||||
style: "GUITextBoxNoBorder", wrap: true, textAlignment: Alignment.TopLeft)
|
||||
{
|
||||
MaxTextLength = NetConfig.ServerMessageMaxLength
|
||||
};
|
||||
var serverMessageHint = new GUITextBlock(new RectTransform(Vector2.One, serverMessageBox.RectTransform),
|
||||
textColor: Color.DarkGray * 0.6f, textAlignment: Alignment.TopLeft, font: GUIStyle.Font, text: TextManager.Get("ClickToWriteServerMessage"));
|
||||
AssignGUIComponent(nameof(ServerMessageText), serverMessageBox);
|
||||
|
||||
void updateServerMessageScrollBasedOnCaret()
|
||||
{
|
||||
float caretY = serverMessageBox.CaretScreenPos.Y;
|
||||
float bottomCaretExtent = serverMessageBox.Font.LineHeight * 1.5f;
|
||||
float topCaretExtent = -serverMessageBox.Font.LineHeight * 0.5f;
|
||||
if (caretY + bottomCaretExtent > serverMessageContainer.Rect.Bottom)
|
||||
{
|
||||
serverMessageContainer.ScrollBar.BarScroll
|
||||
= (caretY - serverMessageBox.Rect.Top - serverMessageContainer.Rect.Height + bottomCaretExtent)
|
||||
/ (serverMessageBox.Rect.Height - serverMessageContainer.Rect.Height);
|
||||
}
|
||||
else if (caretY + topCaretExtent < serverMessageContainer.Rect.Top)
|
||||
{
|
||||
serverMessageContainer.ScrollBar.BarScroll
|
||||
= (caretY - serverMessageBox.Rect.Top + topCaretExtent)
|
||||
/ (serverMessageBox.Rect.Height - serverMessageContainer.Rect.Height);
|
||||
}
|
||||
}
|
||||
serverMessageBox.OnSelected += (textBox, key) =>
|
||||
{
|
||||
serverMessageHint.Visible = false;
|
||||
updateServerMessageScrollBasedOnCaret();
|
||||
};
|
||||
serverMessageBox.OnTextChanged += (textBox, text) =>
|
||||
{
|
||||
serverMessageHint.Visible = !textBox.Selected && !textBox.Readonly && string.IsNullOrWhiteSpace(textBox.Text);
|
||||
RefreshServerInfoSize();
|
||||
return true;
|
||||
};
|
||||
serverMessageBox.RectTransform.SizeChanged += RefreshServerInfoSize;
|
||||
motdCharacterCount.TextGetter += () => { return serverMessageBox.Text.Length + " / " + NetConfig.ServerMessageMaxLength; };
|
||||
|
||||
void RefreshServerInfoSize()
|
||||
{
|
||||
serverMessageHint.Visible = !serverMessageBox.Selected && !serverMessageBox.Readonly && string.IsNullOrWhiteSpace(serverMessageBox.Text);
|
||||
Vector2 textSize = serverMessageBox.Font.MeasureString(serverMessageBox.WrappedText);
|
||||
serverMessageBox.RectTransform.NonScaledSize = new Point(serverMessageBox.RectTransform.NonScaledSize.X, Math.Max(serverMessageContainer.Content.Rect.Height, (int)textSize.Y + 10));
|
||||
serverMessageContainer.UpdateScrollBarSize();
|
||||
}
|
||||
|
||||
serverMessageBox.OnEnterPressed += (textBox, text) =>
|
||||
{
|
||||
string str = textBox.Text;
|
||||
int caretIndex = textBox.CaretIndex;
|
||||
textBox.Text = $"{str[..caretIndex]}\n{str[caretIndex..]}";
|
||||
textBox.CaretIndex = caretIndex + 1;
|
||||
|
||||
return true;
|
||||
};
|
||||
serverMessageBox.OnDeselected += (textBox, key) =>
|
||||
{
|
||||
if (!textBox.Readonly)
|
||||
{
|
||||
GameMain.Client?.ServerSettings?.ClientAdminWrite(NetFlags.Properties);
|
||||
}
|
||||
serverMessageHint.Visible = !textBox.Readonly && string.IsNullOrWhiteSpace(textBox.Text);
|
||||
};
|
||||
serverMessageBox.OnKeyHit += (sender, key) => updateServerMessageScrollBasedOnCaret();
|
||||
|
||||
// *************************************************************************
|
||||
|
||||
var playStyleLayoutLabel = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), parent.RectTransform),
|
||||
TextManager.Get("ServerSettingsPlayStyle"));
|
||||
var playStyleSelection = new GUISelectionCarousel<PlayStyle>(new RectTransform(new Vector2(0.5f, 1.0f), playStyleLayoutLabel.RectTransform, Anchor.CenterRight));
|
||||
foreach (PlayStyle playStyle in Enum.GetValues(typeof(PlayStyle)))
|
||||
{
|
||||
playStyleSelection.AddElement(playStyle, TextManager.Get("servertag." + playStyle), TextManager.Get("servertagdescription." + playStyle));
|
||||
}
|
||||
AssignGUIComponent(nameof(PlayStyle), playStyleSelection);
|
||||
|
||||
var passwordLabel = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), parent.RectTransform), TextManager.Get("Password"));
|
||||
new GUIButton(new RectTransform(new Vector2(0.5f, 1.0f), passwordLabel.RectTransform, Anchor.CenterRight),
|
||||
TextManager.Get("ServerSettingsSetPassword"), style: "GUIButtonSmall")
|
||||
{
|
||||
OnClicked = (btn, userdata) => { CreateChangePasswordPrompt(); return true; }
|
||||
};
|
||||
|
||||
var wrongPasswordBanBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), parent.RectTransform), TextManager.Get("ServerSettingsBanAfterWrongPassword"));
|
||||
AssignGUIComponent(nameof(BanAfterWrongPassword), wrongPasswordBanBox);
|
||||
var allowedPasswordRetries = NetLobbyScreen.CreateLabeledNumberInput(parent, "ServerSettingsPasswordRetriesBeforeBan", 0, 10);
|
||||
AssignGUIComponent(nameof(MaxPasswordRetriesBeforeBan), allowedPasswordRetries);
|
||||
|
||||
var maxPlayers = NetLobbyScreen.CreateLabeledNumberInput(parent, "MaxPlayers", 0, NetConfig.MaxPlayers);
|
||||
AssignGUIComponent(nameof(MaxPlayers), maxPlayers);
|
||||
|
||||
// Language
|
||||
var languageLabel = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), parent.RectTransform), TextManager.Get("Language"));
|
||||
var languageDD = new GUIDropDown(new RectTransform(new Vector2(0.5f, 1.0f), languageLabel.RectTransform, Anchor.CenterRight));
|
||||
foreach (var language in ServerLanguageOptions.Options)
|
||||
{
|
||||
languageDD.AddItem(language.Label, language.Identifier);
|
||||
}
|
||||
languageLabel.InheritTotalChildrenMinHeight();
|
||||
AssignGUIComponent(nameof(Language), languageDD);
|
||||
|
||||
}
|
||||
|
||||
private static void CreateChangePasswordPrompt()
|
||||
{
|
||||
var passwordMsgBox = new GUIMessageBox(
|
||||
TextManager.Get("ServerSettingsSetPassword"),
|
||||
"", new LocalizedString[] { TextManager.Get("OK"), TextManager.Get("Cancel") },
|
||||
relativeSize: new Vector2(0.25f, 0.1f), minSize: new Point(400, GUI.IntScale(170)));
|
||||
var passwordHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.5f), passwordMsgBox.Content.RectTransform), childAnchor: Anchor.TopCenter);
|
||||
var passwordBox = new GUITextBox(new RectTransform(new Vector2(0.8f, 1f), passwordHolder.RectTransform))
|
||||
{
|
||||
Censor = true
|
||||
};
|
||||
|
||||
passwordMsgBox.Content.Recalculate();
|
||||
passwordMsgBox.Content.InheritTotalChildrenHeight();
|
||||
passwordMsgBox.Content.Parent.RectTransform.MinSize = new Point(0, (int)(passwordMsgBox.Content.RectTransform.MinSize.Y / passwordMsgBox.Content.RectTransform.RelativeSize.Y));
|
||||
|
||||
var okButton = passwordMsgBox.Buttons[0];
|
||||
okButton.OnClicked += (_, __) =>
|
||||
{
|
||||
DebugConsole.ExecuteCommand($"setpassword \"{passwordBox.Text}\"");
|
||||
return true;
|
||||
};
|
||||
okButton.OnClicked += passwordMsgBox.Close;
|
||||
|
||||
var cancelButton = passwordMsgBox.Buttons[1];
|
||||
cancelButton.OnClicked = (_, __) =>
|
||||
{
|
||||
passwordMsgBox?.Close();
|
||||
passwordMsgBox = null;
|
||||
return true;
|
||||
};
|
||||
passwordBox.OnEnterPressed += (_, __) =>
|
||||
{
|
||||
okButton.OnClicked.Invoke(okButton, okButton.UserData);
|
||||
return true;
|
||||
};
|
||||
|
||||
passwordBox.Select();
|
||||
}
|
||||
|
||||
private void CreateGeneralTab(GUIComponent parent)
|
||||
{
|
||||
var listBox = new GUIListBox(new RectTransform(Vector2.One, parent.RectTransform), style: "GUIListBoxNoBorder")
|
||||
{
|
||||
AutoHideScrollBar = true,
|
||||
CurrentSelectMode = GUIListBox.SelectMode.None
|
||||
};
|
||||
|
||||
NetLobbyScreen.CreateSubHeader("serversettingscategory.roundmanagement", listBox.Content);
|
||||
|
||||
var endVoteBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), listBox.Content.RectTransform),
|
||||
TextManager.Get("ServerSettingsEndRoundVoting"));
|
||||
AssignGUIComponent(nameof(AllowEndVoting), endVoteBox);
|
||||
|
||||
NetLobbyScreen.CreateLabeledSlider(listBox.Content, headerTag: string.Empty, valueLabelTag: "ServerSettingsEndRoundVotesRequired", tooltipTag: string.Empty, out var slider, out var sliderLabel);
|
||||
|
||||
LocalizedString endRoundLabel = sliderLabel.Text;
|
||||
slider.Step = 0.2f;
|
||||
slider.Range = new Vector2(0.5f, 1.0f);
|
||||
AssignGUIComponent(nameof(EndVoteRequiredRatio), 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);
|
||||
|
||||
//***********************************************
|
||||
|
||||
// Sub Selection
|
||||
|
||||
var subSelectionLabel = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), listBox.Content.RectTransform),
|
||||
TextManager.Get("ServerSettingsSubSelection"));
|
||||
var subSelection = new GUISelectionCarousel<SelectionMode>(new RectTransform(new Vector2(0.5f, 1.0f), subSelectionLabel.RectTransform, Anchor.CenterRight));
|
||||
foreach (SelectionMode selectionMode in Enum.GetValues(typeof(SelectionMode)))
|
||||
{
|
||||
subSelection.AddElement(selectionMode, TextManager.Get(selectionMode.ToString()));
|
||||
}
|
||||
AssignGUIComponent(nameof(SubSelectionMode), subSelection);
|
||||
|
||||
// Mode Selection
|
||||
var gameModeSelectionLabel = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), listBox.Content.RectTransform),
|
||||
TextManager.Get("ServerSettingsModeSelection"));
|
||||
var gameModeSelection = new GUISelectionCarousel<SelectionMode>(new RectTransform(new Vector2(0.5f, 1.0f), gameModeSelectionLabel.RectTransform, Anchor.CenterRight));
|
||||
foreach (SelectionMode selectionMode in Enum.GetValues(typeof(SelectionMode)))
|
||||
{
|
||||
gameModeSelection.AddElement(selectionMode, TextManager.Get(selectionMode.ToString()));
|
||||
}
|
||||
AssignGUIComponent(nameof(ModeSelectionMode), gameModeSelection);
|
||||
|
||||
//***********************************************
|
||||
|
||||
LocalizedString autoRestartDelayLabel = TextManager.Get("ServerSettingsAutoRestartDelay") + " ";
|
||||
|
||||
var autorestartBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), listBox.Content.RectTransform),
|
||||
TextManager.Get("AutoRestart"));
|
||||
AssignGUIComponent(nameof(AutoRestart), autorestartBox);
|
||||
NetLobbyScreen.CreateLabeledSlider(listBox.Content, headerTag: string.Empty, valueLabelTag: string.Empty, tooltipTag: string.Empty,
|
||||
out var startIntervalSlider, out var startIntervalSliderLabel, range: new Vector2(10.0f, 300.0f));
|
||||
startIntervalSlider.StepValue = 10.0f;
|
||||
startIntervalSlider.OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
|
||||
{
|
||||
GUITextBlock text = scrollBar.UserData as GUITextBlock;
|
||||
text.Text = autoRestartDelayLabel + ToolBox.SecondsToReadableTime(scrollBar.BarScrollValue);
|
||||
return true;
|
||||
};
|
||||
AssignGUIComponent(nameof(AutoRestartInterval), startIntervalSlider);
|
||||
startIntervalSlider.OnMoved(startIntervalSlider, startIntervalSlider.BarScroll);
|
||||
|
||||
//***********************************************
|
||||
|
||||
var startWhenClientsReady = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), listBox.Content.RectTransform),
|
||||
TextManager.Get("ServerSettingsStartWhenClientsReady"));
|
||||
AssignGUIComponent(nameof(StartWhenClientsReady), startWhenClientsReady);
|
||||
|
||||
NetLobbyScreen.CreateLabeledSlider(listBox.Content, headerTag: string.Empty, valueLabelTag: "ServerSettingsStartWhenClientsReadyRatio", tooltipTag: string.Empty,
|
||||
out slider, out sliderLabel);
|
||||
LocalizedString 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;
|
||||
};
|
||||
AssignGUIComponent(nameof(StartWhenClientsReadyRatio), slider);
|
||||
slider.OnMoved(slider, slider.BarScroll);
|
||||
|
||||
var randomizeLevelBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), listBox.Content.RectTransform), TextManager.Get("ServerSettingsRandomizeSeed"));
|
||||
AssignGUIComponent(nameof(RandomizeSeed), randomizeLevelBox);
|
||||
|
||||
//***********************************************
|
||||
|
||||
NetLobbyScreen.CreateSubHeader("serversettingsroundstab", listBox.Content);
|
||||
|
||||
var voiceChatEnabled = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), listBox.Content.RectTransform),
|
||||
TextManager.Get("ServerSettingsVoiceChatEnabled"));
|
||||
AssignGUIComponent(nameof(VoiceChatEnabled), voiceChatEnabled);
|
||||
|
||||
var allowSpecBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), listBox.Content.RectTransform), TextManager.Get("ServerSettingsAllowSpectating"));
|
||||
AssignGUIComponent(nameof(AllowSpectating), allowSpecBox);
|
||||
|
||||
var losModeLabel = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), listBox.Content.RectTransform),
|
||||
TextManager.Get("LosEffect"));
|
||||
var losModeSelection = new GUISelectionCarousel<LosMode>(new RectTransform(new Vector2(0.5f, 0.6f), losModeLabel.RectTransform, Anchor.CenterRight));
|
||||
foreach (var losMode in Enum.GetValues(typeof(LosMode)).Cast<LosMode>())
|
||||
{
|
||||
losModeSelection.AddElement(losMode, TextManager.Get($"LosMode{losMode}"), TextManager.Get($"LosMode{losMode}.tooltip"));
|
||||
}
|
||||
AssignGUIComponent(nameof(LosMode), losModeSelection);
|
||||
|
||||
var healthBarModeLabel = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), listBox.Content.RectTransform),
|
||||
TextManager.Get("ShowEnemyHealthBars"));
|
||||
var healthBarModeSelection = new GUISelectionCarousel<EnemyHealthBarMode>(new RectTransform(new Vector2(0.5f, 0.6f), healthBarModeLabel.RectTransform, Anchor.CenterRight));
|
||||
foreach (var healthBarMode in Enum.GetValues(typeof(EnemyHealthBarMode)).Cast<EnemyHealthBarMode>())
|
||||
{
|
||||
healthBarModeSelection.AddElement(healthBarMode, TextManager.Get($"ShowEnemyHealthBars.{healthBarMode}"));
|
||||
}
|
||||
AssignGUIComponent(nameof(ShowEnemyHealthBars), healthBarModeSelection);
|
||||
|
||||
var disableBotConversationsBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), listBox.Content.RectTransform), TextManager.Get("ServerSettingsDisableBotConversations"));
|
||||
AssignGUIComponent(nameof(DisableBotConversations), disableBotConversationsBox);
|
||||
|
||||
//***********************************************
|
||||
|
||||
NetLobbyScreen.CreateSubHeader("serversettingscategory.misc", listBox.Content);
|
||||
|
||||
var shareSubsBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), listBox.Content.RectTransform), TextManager.Get("ServerSettingsShareSubFiles"));
|
||||
AssignGUIComponent(nameof(AllowFileTransfers), shareSubsBox);
|
||||
|
||||
var saveLogsBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), listBox.Content.RectTransform), TextManager.Get("ServerSettingsSaveLogs"))
|
||||
{
|
||||
OnSelected = (GUITickBox) =>
|
||||
{
|
||||
//TODO: fix?
|
||||
//showLogButton.Visible = SaveServerLogs;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
AssignGUIComponent(nameof(SaveServerLogs), saveLogsBox);
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// game settings
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
GUILayoutGroup buttonHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.1f), listBox.Content.RectTransform), isHorizontal: true)
|
||||
{
|
||||
Stretch = true,
|
||||
RelativeSpacing = 0.05f
|
||||
};
|
||||
|
||||
const string MonstersEnabledUserdata = "monstersenabled";
|
||||
const string ExtraCargoUserdata = "extracargo";
|
||||
|
||||
monstersEnabledButton = new GUIButton(new RectTransform(new Vector2(0.5f, 1.0f), buttonHolder.RectTransform),
|
||||
TextManager.Get("ServerSettingsMonsterSpawns"), style: "GUIButtonSmall")
|
||||
{
|
||||
Enabled = !GameMain.NetworkMember.GameStarted
|
||||
};
|
||||
monstersEnabledPanel = CreateMonstersEnabledPanel();
|
||||
monstersEnabledButton.UserData = MonstersEnabledUserdata;
|
||||
monstersEnabledButton.OnClicked = ExtraSettingsButtonClicked;
|
||||
|
||||
extraCargoButton = new GUIButton(new RectTransform(new Vector2(0.5f, 1.0f), buttonHolder.RectTransform),
|
||||
TextManager.Get("ServerSettingsAdditionalCargo"), style: "GUIButtonSmall")
|
||||
{
|
||||
Enabled = !GameMain.NetworkMember.GameStarted
|
||||
};
|
||||
|
||||
extraCargoPanel = CreateExtraCargoPanel();
|
||||
extraCargoButton.UserData = ExtraCargoUserdata;
|
||||
extraCargoButton.OnClicked = ExtraSettingsButtonClicked;
|
||||
|
||||
GUITextBlock.AutoScaleAndNormalize(buttonHolder.Children.Select(c => ((GUIButton)c).TextBlock));
|
||||
|
||||
bool ExtraSettingsButtonClicked(GUIButton button, object obj)
|
||||
{
|
||||
//the extra settings buttons (monsters enabled, cargo) hold a reference to the panel they're supposed to toggle
|
||||
GUIComponent panel;
|
||||
switch (obj as string)
|
||||
{
|
||||
case MonstersEnabledUserdata:
|
||||
panel = monstersEnabledPanel;
|
||||
break;
|
||||
case ExtraCargoUserdata:
|
||||
panel = extraCargoPanel;
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Unrecognized extra settings button");
|
||||
}
|
||||
if (GameMain.NetworkMember.GameStarted)
|
||||
{
|
||||
panel.Visible = false;
|
||||
button.Enabled = false;
|
||||
return true;
|
||||
}
|
||||
panel.Visible = !panel.Visible;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private GUIComponent CreateMonstersEnabledPanel()
|
||||
{
|
||||
var monsterFrame = new GUIListBox(new RectTransform(new Vector2(0.5f, 0.7f), settingsTabs[SettingsTab.General].RectTransform, Anchor.BottomLeft, Pivot.BottomRight))
|
||||
{
|
||||
Visible = false,
|
||||
IgnoreLayoutGroups = true
|
||||
};
|
||||
|
||||
InitMonstersEnabled();
|
||||
List<Identifier> monsterNames = MonsterEnabled.Keys.ToList();
|
||||
tempMonsterEnabled = new Dictionary<Identifier, bool>(MonsterEnabled);
|
||||
foreach (Identifier s in monsterNames)
|
||||
{
|
||||
LocalizedString translatedLabel = TextManager.Get($"Character.{s}").Fallback(s.Value);
|
||||
var monsterEnabledBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.1f), monsterFrame.Content.RectTransform) { MinSize = new Point(0, 25) },
|
||||
label: translatedLabel)
|
||||
{
|
||||
Selected = tempMonsterEnabled[s],
|
||||
OnSelected = (GUITickBox tb) =>
|
||||
{
|
||||
tempMonsterEnabled[s] = tb.Selected;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
monsterFrame.Content.RectTransform.SortChildren((c1, c2) =>
|
||||
{
|
||||
var name1 = (c1.GUIComponent as GUITickBox)?.Text ?? string.Empty;
|
||||
var name2 = (c2.GUIComponent as GUITickBox)?.Text ?? string.Empty;
|
||||
return name1.CompareTo(name2);
|
||||
});
|
||||
|
||||
if (GameMain.Client == null ||
|
||||
!GameMain.Client.HasPermission(Networking.ClientPermissions.ManageSettings))
|
||||
{
|
||||
SetElementInteractability(monsterFrame.Content, false);
|
||||
}
|
||||
|
||||
return monsterFrame;
|
||||
}
|
||||
|
||||
private GUIComponent CreateExtraCargoPanel()
|
||||
{
|
||||
var cargoFrame = new GUIFrame(new RectTransform(new Vector2(0.5f, 0.7f), settingsTabs[SettingsTab.General].RectTransform, Anchor.BottomRight, Pivot.BottomLeft))
|
||||
{
|
||||
Visible = false,
|
||||
IgnoreLayoutGroups = true
|
||||
};
|
||||
var cargoContent = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.95f), cargoFrame.RectTransform, Anchor.Center))
|
||||
{
|
||||
Stretch = true
|
||||
};
|
||||
|
||||
var filterText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), cargoContent.RectTransform), TextManager.Get("serverlog.filter"), font: GUIStyle.SubHeadingFont);
|
||||
var entityFilterBox = new GUITextBox(new RectTransform(new Vector2(0.5f, 1.0f), filterText.RectTransform, Anchor.CenterRight), font: GUIStyle.Font, createClearButton: true);
|
||||
filterText.RectTransform.MinSize = new Point(0, entityFilterBox.RectTransform.MinSize.Y);
|
||||
var cargoList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.8f), cargoContent.RectTransform));
|
||||
entityFilterBox.OnTextChanged += (textBox, text) =>
|
||||
{
|
||||
foreach (var child in cargoList.Content.Children)
|
||||
{
|
||||
if (child.UserData is not ItemPrefab itemPrefab) { continue; }
|
||||
child.Visible = string.IsNullOrEmpty(text) || itemPrefab.Name.Contains(text, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
foreach (ItemPrefab ip in ItemPrefab.Prefabs.OrderBy(ip => ip.Name))
|
||||
{
|
||||
if (ip.AllowAsExtraCargo.HasValue)
|
||||
{
|
||||
if (!ip.AllowAsExtraCargo.Value) { continue; }
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ip.CanBeBought) { continue; }
|
||||
}
|
||||
|
||||
var itemFrame = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.15f), cargoList.Content.RectTransform) { MinSize = new Point(0, 30) }, isHorizontal: true)
|
||||
{
|
||||
Stretch = true,
|
||||
UserData = ip,
|
||||
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;
|
||||
}
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.75f, 1.0f), itemFrame.RectTransform),
|
||||
ip.Name, font: GUIStyle.SmallFont)
|
||||
{
|
||||
Wrap = true,
|
||||
CanBeFocused = false
|
||||
};
|
||||
|
||||
ExtraCargo.TryGetValue(ip, out int cargoVal);
|
||||
var amountInput = new GUINumberInput(new RectTransform(new Vector2(0.35f, 1.0f), itemFrame.RectTransform),
|
||||
NumberType.Int, textAlignment: Alignment.CenterLeft)
|
||||
{
|
||||
MinValueInt = 0,
|
||||
MaxValueInt = MaxExtraCargoItemsOfType,
|
||||
IntValue = cargoVal
|
||||
};
|
||||
amountInput.OnValueChanged += (numberInput) =>
|
||||
{
|
||||
if (ExtraCargo.ContainsKey(ip))
|
||||
{
|
||||
ExtraCargo[ip] = numberInput.IntValue;
|
||||
if (numberInput.IntValue <= 0) { ExtraCargo.Remove(ip); }
|
||||
}
|
||||
else if (ExtraCargo.Keys.Count < MaxExtraCargoItemTypes)
|
||||
{
|
||||
ExtraCargo.Add(ip, numberInput.IntValue);
|
||||
}
|
||||
numberInput.IntValue = ExtraCargo.ContainsKey(ip) ? ExtraCargo[ip] : 0;
|
||||
CoroutineManager.Invoke(() =>
|
||||
{
|
||||
foreach (var child in cargoList.Content.GetAllChildren())
|
||||
{
|
||||
if (child.GetChild<GUINumberInput>() is GUINumberInput otherNumberInput)
|
||||
{
|
||||
otherNumberInput.PlusButton.Enabled = ExtraCargo.Keys.Count < MaxExtraCargoItemTypes && otherNumberInput.IntValue < otherNumberInput.MaxValueInt;
|
||||
}
|
||||
}
|
||||
}, 0.0f);
|
||||
};
|
||||
}
|
||||
if (GameMain.Client == null ||
|
||||
!GameMain.Client.HasPermission(Networking.ClientPermissions.ManageSettings))
|
||||
{
|
||||
SetElementInteractability(cargoList.Content, false);
|
||||
}
|
||||
|
||||
return cargoFrame;
|
||||
}
|
||||
|
||||
private void CreateAntigriefingTab(GUIComponent parent)
|
||||
{
|
||||
var listBox = new GUIListBox(new RectTransform(Vector2.One, parent.RectTransform), style: "GUIListBoxNoBorder")
|
||||
{
|
||||
AutoHideScrollBar = true,
|
||||
CurrentSelectMode = GUIListBox.SelectMode.None
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// antigriefing
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
var tickBoxContainer = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.25f), listBox.Content.RectTransform))
|
||||
{
|
||||
AutoHideScrollBar = true,
|
||||
UseGridLayout = true
|
||||
};
|
||||
tickBoxContainer.Padding *= 2.0f;
|
||||
|
||||
var allowFriendlyFire = new GUITickBox(new RectTransform(new Vector2(0.48f, 0.05f), tickBoxContainer.Content.RectTransform),
|
||||
TextManager.Get("ServerSettingsAllowFriendlyFire"));
|
||||
AssignGUIComponent(nameof(AllowFriendlyFire), allowFriendlyFire);
|
||||
|
||||
var killableNPCs = new GUITickBox(new RectTransform(new Vector2(0.48f, 0.05f), tickBoxContainer.Content.RectTransform),
|
||||
TextManager.Get("ServerSettingsKillableNPCs"));
|
||||
AssignGUIComponent(nameof(KillableNPCs), killableNPCs);
|
||||
|
||||
var destructibleOutposts = new GUITickBox(new RectTransform(new Vector2(0.48f, 0.05f), tickBoxContainer.Content.RectTransform),
|
||||
TextManager.Get("ServerSettingsDestructibleOutposts"));
|
||||
AssignGUIComponent(nameof(DestructibleOutposts), destructibleOutposts);
|
||||
|
||||
var lockAllDefaultWires = new GUITickBox(new RectTransform(new Vector2(0.48f, 0.05f), tickBoxContainer.Content.RectTransform),
|
||||
TextManager.Get("ServerSettingsLockAllDefaultWires"));
|
||||
AssignGUIComponent(nameof(LockAllDefaultWires), lockAllDefaultWires);
|
||||
|
||||
var allowRewiring = new GUITickBox(new RectTransform(new Vector2(0.48f, 0.05f), tickBoxContainer.Content.RectTransform),
|
||||
TextManager.Get("ServerSettingsAllowRewiring"));
|
||||
AssignGUIComponent(nameof(AllowRewiring), allowRewiring);
|
||||
|
||||
var allowWifiChatter = new GUITickBox(new RectTransform(new Vector2(0.48f, 0.05f), tickBoxContainer.Content.RectTransform),
|
||||
TextManager.Get("ServerSettingsAllowWifiChat"));
|
||||
AssignGUIComponent(nameof(AllowLinkingWifiToChat), allowWifiChatter);
|
||||
|
||||
var allowDisguises = new GUITickBox(new RectTransform(new Vector2(0.48f, 0.05f), tickBoxContainer.Content.RectTransform),
|
||||
TextManager.Get("ServerSettingsAllowDisguises"));
|
||||
AssignGUIComponent(nameof(AllowDisguises), allowDisguises);
|
||||
|
||||
var allowImmediateItemDeliveryBox = new GUITickBox(new RectTransform(new Vector2(0.48f, 0.05f), tickBoxContainer.Content.RectTransform),
|
||||
TextManager.Get("ServerSettingsImmediateItemDelivery"));
|
||||
AssignGUIComponent(nameof(AllowImmediateItemDelivery), allowImmediateItemDeliveryBox);
|
||||
|
||||
GUITextBlock.AutoScaleAndNormalize(tickBoxContainer.Content.Children.Select(c => ((GUITickBox)c).TextBlock));
|
||||
|
||||
tickBoxContainer.RectTransform.MinSize = new Point(0, (int)(tickBoxContainer.Content.Children.First().Rect.Height * 2.0f + tickBoxContainer.Padding.Y + tickBoxContainer.Padding.W));
|
||||
|
||||
tickBoxContainer.RectTransform.MinSize = new Point(0, (int)(tickBoxContainer.Content.Children.First().Rect.Height * 2.0f + tickBoxContainer.Padding.Y + tickBoxContainer.Padding.W));
|
||||
|
||||
var voteKickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), listBox.Content.RectTransform),
|
||||
TextManager.Get("ServerSettingsAllowVoteKick"));
|
||||
AssignGUIComponent(nameof(AllowVoteKick), voteKickBox);
|
||||
|
||||
NetLobbyScreen.CreateLabeledSlider(listBox.Content, headerTag: string.Empty, valueLabelTag: "ServerSettingsKickVotesRequired", tooltipTag: string.Empty, out var slider, out var sliderLabel);
|
||||
LocalizedString 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;
|
||||
};
|
||||
AssignGUIComponent(nameof(KickVoteRequiredRatio), slider);
|
||||
slider.OnMoved(slider, slider.BarScroll);
|
||||
|
||||
NetLobbyScreen.CreateLabeledSlider(listBox.Content, headerTag: string.Empty, valueLabelTag: "ServerSettingsAutobanTime", tooltipTag: "ServerSettingsAutobanTime.Tooltip", out slider, out sliderLabel);
|
||||
LocalizedString autobanLabel = sliderLabel.Text + " ";
|
||||
slider.Range = new Vector2(0.0f, MaxAutoBanTime);
|
||||
slider.StepValue = 60.0f * 15.0f; //15 minutes
|
||||
slider.OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
|
||||
{
|
||||
((GUITextBlock)scrollBar.UserData).Text = autobanLabel + ToolBox.SecondsToReadableTime(scrollBar.BarScrollValue);
|
||||
return true;
|
||||
};
|
||||
AssignGUIComponent(nameof(AutoBanTime), slider);
|
||||
slider.OnMoved(slider, slider.BarScroll);
|
||||
|
||||
var maximumTransferAmount = NetLobbyScreen.CreateLabeledNumberInput(listBox.Content, "serversettingsmaximumtransferrequest", 0, CampaignMode.MaxMoney, "serversettingsmaximumtransferrequesttooltip");
|
||||
AssignGUIComponent(nameof(MaximumMoneyTransferRequest), maximumTransferAmount);
|
||||
|
||||
var lootedMoneyDestination = NetLobbyScreen.CreateLabeledDropdown(listBox.Content, "serversettingslootedmoneydestination", numElements: 2, "serversettingslootedmoneydestinationtooltip");
|
||||
lootedMoneyDestination.AddItem(TextManager.Get("lootedmoneydestination.bank"), LootedMoneyDestination.Bank);
|
||||
lootedMoneyDestination.AddItem(TextManager.Get("lootedmoneydestination.wallet"), LootedMoneyDestination.Wallet);
|
||||
AssignGUIComponent(nameof(LootedMoneyDestination), lootedMoneyDestination);
|
||||
|
||||
var enableDosProtection = new GUITickBox(new RectTransform(new Vector2(0.5f, 0.0f), listBox.Content.RectTransform), TextManager.Get("ServerSettingsEnableDoSProtection"))
|
||||
{
|
||||
ToolTip = TextManager.Get("ServerSettingsEnableDoSProtectionTooltip")
|
||||
};
|
||||
AssignGUIComponent(nameof(EnableDoSProtection), enableDosProtection);
|
||||
|
||||
NetLobbyScreen.CreateLabeledSlider(listBox.Content, headerTag: string.Empty, valueLabelTag: "ServerSettingsMaxPacketAmount", tooltipTag: string.Empty, out GUIScrollBar maxPacketSlider, out GUITextBlock maxPacketSliderLabel);
|
||||
LocalizedString maxPacketCountLabel = maxPacketSliderLabel.Text;
|
||||
maxPacketSlider.Step = 0.001f;
|
||||
maxPacketSlider.Range = new Vector2(PacketLimitMin, PacketLimitMax);
|
||||
maxPacketSlider.ToolTip = packetAmountTooltip;
|
||||
maxPacketSlider.OnMoved = (scrollBar, _) =>
|
||||
{
|
||||
GUITextBlock textBlock = (GUITextBlock)scrollBar.UserData;
|
||||
int value = (int)MathF.Floor(scrollBar.BarScrollValue);
|
||||
|
||||
LocalizedString valueText = value > PacketLimitMin
|
||||
? value.ToString()
|
||||
: TextManager.Get("ServerSettingsNoLimit");
|
||||
|
||||
switch (value)
|
||||
{
|
||||
case <= PacketLimitMin:
|
||||
textBlock.TextColor = GUIStyle.Green;
|
||||
scrollBar.ToolTip = packetAmountTooltip;
|
||||
break;
|
||||
case < PacketLimitWarning:
|
||||
textBlock.TextColor = GUIStyle.Red;
|
||||
scrollBar.ToolTip = packetAmountTooltipWarning;
|
||||
break;
|
||||
default:
|
||||
textBlock.TextColor = GUIStyle.TextColorNormal;
|
||||
scrollBar.ToolTip = packetAmountTooltip;
|
||||
break;
|
||||
}
|
||||
|
||||
textBlock.Text = $"{maxPacketCountLabel} {valueText}";
|
||||
return true;
|
||||
};
|
||||
AssignGUIComponent(nameof(MaxPacketAmount), maxPacketSlider);
|
||||
maxPacketSlider.OnMoved(maxPacketSlider, maxPacketSlider.BarScroll);
|
||||
|
||||
// karma --------------------------------------------------------------------------
|
||||
|
||||
NetLobbyScreen.CreateSubHeader("Karma", listBox.Content, toolTipTag: "KarmaExplanation");
|
||||
|
||||
var karmaBox = new GUITickBox(new RectTransform(new Vector2(0.5f, 1f), listBox.Content.RectTransform), TextManager.Get("ServerSettingsUseKarma"))
|
||||
{
|
||||
ToolTip = TextManager.Get("KarmaExplanation")
|
||||
};
|
||||
AssignGUIComponent(nameof(KarmaEnabled), karmaBox);
|
||||
|
||||
karmaPresetDD = new GUIDropDown(new RectTransform(new Vector2(1.0f, 0.05f), listBox.Content.RectTransform));
|
||||
foreach (string karmaPreset in GameMain.NetworkMember.KarmaManager.Presets.Keys)
|
||||
{
|
||||
karmaPresetDD.AddItem(TextManager.Get("KarmaPreset." + karmaPreset), karmaPreset);
|
||||
}
|
||||
karmaElements.Add(karmaPresetDD);
|
||||
|
||||
var karmaSettingsContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.5f), listBox.Content.RectTransform), style: null);
|
||||
karmaElements.Add(karmaSettingsContainer);
|
||||
karmaSettingsList = new GUIListBox(new RectTransform(Vector2.One, karmaSettingsContainer.RectTransform))
|
||||
{
|
||||
Spacing = (int)(8 * GUI.Scale)
|
||||
};
|
||||
karmaSettingsList.Padding *= 2.0f;
|
||||
|
||||
karmaPresetDD.SelectItem(KarmaPreset);
|
||||
SetElementInteractability(karmaSettingsList.Content, !karmaBox.Selected || KarmaPreset != "custom");
|
||||
GameMain.NetworkMember.KarmaManager.CreateSettingsFrame(karmaSettingsList.Content);
|
||||
karmaPresetDD.OnSelected = (selected, obj) =>
|
||||
{
|
||||
string newKarmaPreset = obj as string;
|
||||
if (newKarmaPreset == KarmaPreset) { return true; }
|
||||
|
||||
List<NetPropertyData> properties = netProperties.Values.ToList();
|
||||
List<object> prevValues = new List<object>();
|
||||
foreach (NetPropertyData prop in netProperties.Values)
|
||||
{
|
||||
prevValues.Add(prop.TempValue);
|
||||
if (prop.GUIComponent != null) { prop.Value = prop.GUIComponentValue; }
|
||||
}
|
||||
if (KarmaPreset == "custom")
|
||||
{
|
||||
GameMain.NetworkMember?.KarmaManager?.SaveCustomPreset();
|
||||
GameMain.NetworkMember?.KarmaManager?.Save();
|
||||
}
|
||||
KarmaPreset = newKarmaPreset;
|
||||
GameMain.NetworkMember.KarmaManager.SelectPreset(KarmaPreset);
|
||||
karmaSettingsList.Content.ClearChildren();
|
||||
GameMain.NetworkMember.KarmaManager.CreateSettingsFrame(karmaSettingsList.Content);
|
||||
SetElementInteractability(karmaSettingsList.Content, !karmaBox.Selected || KarmaPreset != "custom");
|
||||
for (int i = 0; i < netProperties.Count; i++)
|
||||
{
|
||||
properties[i].TempValue = prevValues[i];
|
||||
}
|
||||
return true;
|
||||
};
|
||||
AssignGUIComponent(nameof(KarmaPreset), karmaPresetDD);
|
||||
karmaBox.OnSelected = (tb) =>
|
||||
{
|
||||
SetElementInteractability(karmaSettingsList.Content, !karmaBox.Selected || KarmaPreset != "custom");
|
||||
karmaElements.ForEach(e => e.Visible = tb.Selected);
|
||||
return true;
|
||||
};
|
||||
karmaElements.ForEach(e => e.Visible = KarmaEnabled);
|
||||
|
||||
listBox.Content.InheritTotalChildrenMinHeight();
|
||||
}
|
||||
|
||||
private void CreateBanlistTab(GUIComponent parent)
|
||||
{
|
||||
BanList.CreateBanFrame(parent);
|
||||
}
|
||||
|
||||
private bool SelectSettingsTab(GUIButton button, object obj)
|
||||
{
|
||||
selectedTab = (SettingsTab)obj;
|
||||
foreach (var key in settingsTabs.Keys)
|
||||
{
|
||||
settingsTabs[key].Visible = key == selectedTab;
|
||||
tabButtons[key].Selected = key == selectedTab;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
if (KarmaPreset == "custom")
|
||||
{
|
||||
GameMain.NetworkMember?.KarmaManager?.SaveCustomPreset();
|
||||
GameMain.NetworkMember?.KarmaManager?.Save();
|
||||
}
|
||||
ClientAdminWrite(NetFlags.Properties);
|
||||
foreach (NetPropertyData prop in netProperties.Values)
|
||||
{
|
||||
prop.GUIComponent = null;
|
||||
}
|
||||
settingsFrame = null;
|
||||
//give control of server settings back to elements in the lobby
|
||||
GameMain.NetLobbyScreen.AssignComponentsToServerSettings();
|
||||
}
|
||||
|
||||
public bool ToggleSettingsFrame(GUIButton button, object obj)
|
||||
{
|
||||
if (GameMain.NetworkMember == null) { return false; }
|
||||
if (settingsFrame == null)
|
||||
{
|
||||
CreateSettingsFrame();
|
||||
}
|
||||
else
|
||||
{
|
||||
Close();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -275,7 +275,7 @@ namespace Barotrauma.Networking
|
||||
var messageType = !ForceLocal && ChatMessage.CanUseRadio(GameMain.Client.Character, out _) ? ChatMessageType.Radio : ChatMessageType.Default;
|
||||
if (GameMain.Client.Character.IsDead) { messageType = ChatMessageType.Dead; }
|
||||
|
||||
GameMain.Client.Character.ShowSpeechBubble(1.25f, ChatMessage.MessageColor[(int)messageType]);
|
||||
GameMain.Client.Character.ShowTextlessSpeechBubble(1.25f, ChatMessage.MessageColor[(int)messageType]);
|
||||
}
|
||||
//encode audio and enqueue it
|
||||
lock (buffers)
|
||||
|
||||
@@ -106,7 +106,7 @@ namespace Barotrauma.Networking
|
||||
if (client.VoipSound == null)
|
||||
{
|
||||
DebugConsole.Log("Recreating voipsound " + queueId);
|
||||
client.VoipSound = new VoipSound(client.Name, GameMain.SoundManager, client.VoipQueue);
|
||||
client.VoipSound = new VoipSound(client, GameMain.SoundManager, client.VoipQueue);
|
||||
}
|
||||
GameMain.SoundManager.ForceStreamUpdate();
|
||||
client.RadioNoise = 0.0f;
|
||||
@@ -122,12 +122,13 @@ namespace Barotrauma.Networking
|
||||
ChatMessage.CanUseRadio(Character.Controlled, out var recipientRadio) &&
|
||||
senderRadio.CanReceive(recipientRadio) ?
|
||||
ChatMessageType.Radio : ChatMessageType.Default;
|
||||
client.Character.ShowSpeechBubble(1.25f, ChatMessage.MessageColor[(int)messageType]);
|
||||
client.Character.ShowTextlessSpeechBubble(1.25f, ChatMessage.MessageColor[(int)messageType]);
|
||||
|
||||
client.VoipSound.UseRadioFilter = messageType == ChatMessageType.Radio && !GameSettings.CurrentConfig.Audio.DisableVoiceChatFilters;
|
||||
client.RadioNoise = 0.0f;
|
||||
if (messageType == ChatMessageType.Radio)
|
||||
{
|
||||
client.VoipSound.UsingRadio = true;
|
||||
client.VoipSound.SetRange(senderRadio.Range * RangeNear * speechImpedimentMultiplier * rangeMultiplier, senderRadio.Range * speechImpedimentMultiplier * rangeMultiplier);
|
||||
if (distanceFactor > RangeNear && !spectating)
|
||||
{
|
||||
@@ -137,11 +138,12 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
else
|
||||
{
|
||||
client.VoipSound.SetRange(ChatMessage.SpeakRange * RangeNear * speechImpedimentMultiplier * rangeMultiplier, ChatMessage.SpeakRange * speechImpedimentMultiplier * rangeMultiplier);
|
||||
client.VoipSound.UsingRadio = false;
|
||||
client.VoipSound.SetRange(ChatMessage.SpeakRangeVOIP * RangeNear * speechImpedimentMultiplier * rangeMultiplier, ChatMessage.SpeakRangeVOIP * speechImpedimentMultiplier * rangeMultiplier);
|
||||
}
|
||||
client.VoipSound.UseMuffleFilter =
|
||||
messageType != ChatMessageType.Radio && Character.Controlled != null && !GameSettings.CurrentConfig.Audio.DisableVoiceChatFilters &&
|
||||
SoundPlayer.ShouldMuffleSound(Character.Controlled, client.Character.WorldPosition, ChatMessage.SpeakRange, client.Character.CurrentHull);
|
||||
SoundPlayer.ShouldMuffleSound(Character.Controlled, client.Character.WorldPosition, ChatMessage.SpeakRangeVOIP, client.Character.CurrentHull);
|
||||
}
|
||||
|
||||
GameMain.NetLobbyScreen?.SetPlayerSpeaking(client);
|
||||
|
||||
Reference in New Issue
Block a user