Unstable 0.16.0.0
This commit is contained in:
@@ -61,9 +61,9 @@ namespace Barotrauma
|
||||
GameMain.NetworkMember.CreateEntityEvent(this, new object[] { NetEntityEvent.Type.UpdateMoney });
|
||||
}
|
||||
|
||||
partial void OnTalentGiven(string talentIdentifier)
|
||||
partial void OnTalentGiven(TalentPrefab talentPrefab)
|
||||
{
|
||||
GameServer.Log($"{GameServer.CharacterLogName(this)} has gained the talent '{talentIdentifier}'", ServerLog.MessageType.Talent);
|
||||
GameServer.Log($"{GameServer.CharacterLogName(this)} has gained the talent '{talentPrefab.DisplayName}'", ServerLog.MessageType.Talent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,15 +288,18 @@ namespace Barotrauma
|
||||
{
|
||||
UInt32 talentIdentifier = msg.ReadUInt32();
|
||||
var prefab = TalentPrefab.TalentPrefabs.Find(p => p.UIntIdentifier == talentIdentifier);
|
||||
if (prefab != null) { talentSelection.Add(prefab.Identifier); }
|
||||
if (prefab == null) { continue; }
|
||||
|
||||
if (TalentTree.IsViableTalentForCharacter(this, prefab.Identifier, talentSelection))
|
||||
{
|
||||
GiveTalent(prefab.Identifier);
|
||||
talentSelection.Add(prefab.Identifier);
|
||||
}
|
||||
}
|
||||
talentSelection = TalentTree.CheckTalentSelection(this, talentSelection);
|
||||
|
||||
foreach (string talent in talentSelection)
|
||||
if (talentSelection.Count != talentCount)
|
||||
{
|
||||
GiveTalent(talent);
|
||||
DebugConsole.AddWarning($"Failed to unlock talents: the amount of unlocked talents doesn't match (client: {talentCount}, server: {talentSelection.Count})");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -17,6 +17,9 @@ namespace Barotrauma
|
||||
{
|
||||
public static readonly Version Version = Assembly.GetEntryAssembly().GetName().Version;
|
||||
|
||||
public static bool IsSingleplayer => NetworkMember == null;
|
||||
public static bool IsMultiplayer => NetworkMember != null;
|
||||
|
||||
|
||||
private static World world;
|
||||
public static World World
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace Barotrauma
|
||||
foreach (var activeOrder in ActiveOrders)
|
||||
{
|
||||
if (!(activeOrder?.First is Order order) || activeOrder.Second.HasValue) { continue; }
|
||||
OrderChatMessage.WriteOrder(msg, order, null, order.TargetSpatialEntity, null, 0, order.WallSectionIndex);
|
||||
OrderChatMessage.WriteOrder(msg, order, targetCharacter: null, order.TargetSpatialEntity, orderOption: null, orderPriority: 0, order.WallSectionIndex, isNewOrder: true);
|
||||
bool hasOrderGiver = order.OrderGiver != null;
|
||||
msg.Write(hasOrderGiver);
|
||||
if (hasOrderGiver)
|
||||
|
||||
+1
-34
@@ -348,7 +348,6 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
UpdateCampaignSubs();
|
||||
|
||||
SaveUtil.SaveGame(GameMain.GameSession.SavePath);
|
||||
PendingSubmarineSwitch = null;
|
||||
@@ -399,44 +398,12 @@ namespace Barotrauma
|
||||
Map.OnMissionsSelected += (loc, mission) => { LastUpdateID++; };
|
||||
Reputation.OnAnyReputationValueChanged += () => { LastUpdateID++; };
|
||||
|
||||
UpdateCampaignSubs();
|
||||
|
||||
//increment save ID so clients know they're lacking the most up-to-date save file
|
||||
LastSaveID++;
|
||||
}
|
||||
|
||||
public static void UpdateCampaignSubs()
|
||||
{
|
||||
bool isSubmarineVisible(SubmarineInfo s)
|
||||
=> !GameMain.Server.ServerSettings.HiddenSubs.Any(h
|
||||
=> s.Name.Equals(h, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
List<SubmarineInfo> availableSubs =
|
||||
SubmarineInfo.SavedSubmarines
|
||||
.Where(s =>
|
||||
s.IsCampaignCompatible
|
||||
&& isSubmarineVisible(s))
|
||||
.ToList();
|
||||
|
||||
if (!availableSubs.Any())
|
||||
{
|
||||
//None of the available subs were marked as campaign-compatible, just include all visible subs
|
||||
availableSubs.AddRange(
|
||||
SubmarineInfo.SavedSubmarines
|
||||
.Where(isSubmarineVisible));
|
||||
}
|
||||
|
||||
if (!availableSubs.Any())
|
||||
{
|
||||
//No subs are visible at all! Just make the selected one available
|
||||
availableSubs.Add(GameMain.NetLobbyScreen.SelectedSub);
|
||||
}
|
||||
|
||||
GameMain.NetLobbyScreen.CampaignSubmarines = availableSubs;
|
||||
}
|
||||
|
||||
public bool CanPurchaseSub(SubmarineInfo info)
|
||||
=> info.Price <= Money && GameMain.NetLobbyScreen.CampaignSubmarines.Contains(info);
|
||||
=> info.Price <= Money && GetCampaignSubs().Contains(info);
|
||||
|
||||
public void DiscardClientCharacterData(Client client)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Barotrauma.Networking;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
internal partial class MedicalClinic
|
||||
{
|
||||
private enum RateLimitResult
|
||||
{
|
||||
OK,
|
||||
LimitReached
|
||||
}
|
||||
|
||||
private struct RateLimitInfo
|
||||
{
|
||||
public int Requests;
|
||||
public const int MaxRequests = 5;
|
||||
public DateTimeOffset Expiry;
|
||||
}
|
||||
|
||||
private readonly Dictionary<Client, RateLimitInfo> rateLimits = new Dictionary<Client, RateLimitInfo>();
|
||||
|
||||
public void ServerRead(IReadMessage inc, Client sender)
|
||||
{
|
||||
NetworkHeader header = (NetworkHeader)inc.ReadByte();
|
||||
|
||||
switch (header)
|
||||
{
|
||||
case NetworkHeader.REQUEST_AFFLICTIONS:
|
||||
ProcessRequestedAfflictions(inc, sender);
|
||||
break;
|
||||
case NetworkHeader.REQUEST_PENDING:
|
||||
ProcessRequestedPending(sender);
|
||||
break;
|
||||
case NetworkHeader.ADD_PENDING:
|
||||
ProcessNewAddition(inc, sender);
|
||||
break;
|
||||
case NetworkHeader.REMOVE_PENDING:
|
||||
ProcessNewRemoval(inc, sender);
|
||||
break;
|
||||
case NetworkHeader.HEAL_PENDING:
|
||||
ProcessHealing(sender);
|
||||
break;
|
||||
case NetworkHeader.CLEAR_PENDING:
|
||||
ProcessClearing(sender);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessNewAddition(IReadMessage inc, Client client)
|
||||
{
|
||||
if (CheckRateLimit(client) == RateLimitResult.LimitReached) { return; }
|
||||
|
||||
NetCrewMember newCrewMember = INetSerializableStruct.Read<NetCrewMember>(inc);
|
||||
InsertPendingCrewMember(newCrewMember);
|
||||
ServerSend(newCrewMember, NetworkHeader.ADD_PENDING, DeliveryMethod.Reliable, reponseClient: client);
|
||||
}
|
||||
|
||||
private void ProcessNewRemoval(IReadMessage inc, Client client)
|
||||
{
|
||||
if (CheckRateLimit(client) == RateLimitResult.LimitReached) { return; }
|
||||
|
||||
NetRemovedAffliction removed = INetSerializableStruct.Read<NetRemovedAffliction>(inc);
|
||||
RemovePendingAffliction(removed.CrewMember, removed.Affliction);
|
||||
ServerSend(removed, NetworkHeader.REMOVE_PENDING, DeliveryMethod.Reliable, reponseClient: client);
|
||||
}
|
||||
|
||||
private void ProcessRequestedPending(Client client)
|
||||
{
|
||||
if (CheckRateLimit(client) == RateLimitResult.LimitReached) { return; }
|
||||
|
||||
INetSerializableStruct writeCrewMember = new NetPendingCrew
|
||||
{
|
||||
CrewMembers = PendingHeals.ToArray()
|
||||
};
|
||||
|
||||
ServerSend(writeCrewMember, NetworkHeader.REQUEST_PENDING, DeliveryMethod.Reliable, targetClient: client);
|
||||
}
|
||||
|
||||
private void ProcessHealing(Client client)
|
||||
{
|
||||
if (CheckRateLimit(client) == RateLimitResult.LimitReached) { return; }
|
||||
|
||||
HealRequestResult result = HealAllPending();
|
||||
ServerSend(new NetHealRequest { Result = result }, NetworkHeader.HEAL_PENDING, DeliveryMethod.Reliable, reponseClient: client);
|
||||
}
|
||||
|
||||
private void ProcessClearing(Client client)
|
||||
{
|
||||
if (CheckRateLimit(client) == RateLimitResult.LimitReached) { return; }
|
||||
|
||||
if (!PendingHeals.Any()) { return; }
|
||||
|
||||
ClearPendingHeals();
|
||||
ServerSend(null, NetworkHeader.CLEAR_PENDING, DeliveryMethod.Reliable, reponseClient: client);
|
||||
}
|
||||
|
||||
private void ProcessRequestedAfflictions(IReadMessage inc, Client client)
|
||||
{
|
||||
if (CheckRateLimit(client) == RateLimitResult.LimitReached) { return; }
|
||||
|
||||
NetCrewMember crewMember = INetSerializableStruct.Read<NetCrewMember>(inc);
|
||||
|
||||
CharacterInfo? foundInfo = crewMember.FindCharacterInfo(GetCrewCharacters());
|
||||
|
||||
NetAffliction[] pendingAfflictions = Array.Empty<NetAffliction>();
|
||||
int infoId = 0;
|
||||
|
||||
if (foundInfo is { Character: { CharacterHealth: { } health } })
|
||||
{
|
||||
pendingAfflictions = GetAllAfflictions(health);
|
||||
infoId = foundInfo.GetIdentifierUsingOriginalName();
|
||||
}
|
||||
|
||||
INetSerializableStruct writeCrewMember = new NetCrewMember
|
||||
{
|
||||
CharacterInfoID = infoId,
|
||||
Afflictions = pendingAfflictions
|
||||
};
|
||||
|
||||
ServerSend(writeCrewMember, NetworkHeader.REQUEST_AFFLICTIONS, DeliveryMethod.Unreliable, client);
|
||||
}
|
||||
|
||||
private RateLimitResult CheckRateLimit(Client client)
|
||||
{
|
||||
if (rateLimits.TryGetValue(client, out RateLimitInfo rateLimitInfo))
|
||||
{
|
||||
if (rateLimitInfo.Expiry < DateTimeOffset.Now)
|
||||
{
|
||||
rateLimitInfo.Expiry = DateTimeOffset.Now.AddSeconds(5);
|
||||
rateLimitInfo.Requests = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rateLimitInfo.Requests > RateLimitInfo.MaxRequests) { return RateLimitResult.LimitReached; }
|
||||
|
||||
rateLimitInfo.Requests++;
|
||||
}
|
||||
|
||||
rateLimits[client] = rateLimitInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
rateLimits.Add(client, new RateLimitInfo { Requests = 1, Expiry = DateTimeOffset.Now.AddSeconds(5) });
|
||||
}
|
||||
|
||||
return RateLimitResult.OK;
|
||||
}
|
||||
|
||||
private IWriteMessage StartSending()
|
||||
{
|
||||
IWriteMessage msg = new WriteOnlyMessage();
|
||||
msg.Write((byte)ServerPacketHeader.MEDICAL);
|
||||
return msg;
|
||||
}
|
||||
|
||||
private void ServerSend(INetSerializableStruct? netStruct, NetworkHeader header, DeliveryMethod deliveryMethod, Client? targetClient = null, Client? reponseClient = null)
|
||||
{
|
||||
if (targetClient is null)
|
||||
{
|
||||
foreach (Client c in GameMain.Server.ConnectedClients)
|
||||
{
|
||||
SendToClient(c);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
SendToClient(targetClient);
|
||||
|
||||
void SendToClient(Client c)
|
||||
{
|
||||
MessageFlag flag = MessageFlag.Announce;
|
||||
if (reponseClient != null && reponseClient == c)
|
||||
{
|
||||
flag = MessageFlag.Response;
|
||||
}
|
||||
|
||||
IWriteMessage msg = StartSending();
|
||||
msg.Write((byte)header);
|
||||
msg.Write((byte)flag);
|
||||
netStruct?.Write(msg);
|
||||
GameMain.Server.ServerPeer.Send(msg, c.Connection, deliveryMethod);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,14 +50,14 @@ namespace Barotrauma.Items.Components
|
||||
newSteeringInput = new Vector2(msg.ReadSingle(), msg.ReadSingle());
|
||||
}
|
||||
|
||||
if (!item.CanClientAccess(c)) return;
|
||||
if (!item.CanClientAccess(c)) { return; }
|
||||
|
||||
user = c.Character;
|
||||
AutoPilot = autoPilot;
|
||||
|
||||
if (dockingButtonClicked)
|
||||
{
|
||||
item.SendSignal("1", "toggle_docking");
|
||||
item.SendSignal(new Signal("1", sender: c.Character), "toggle_docking");
|
||||
GameMain.Server.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.ComponentState, item.GetComponentIndex(this), true });
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ namespace Barotrauma.Items.Components
|
||||
msg.Write(DeteriorateAlways);
|
||||
msg.Write(tinkeringDuration);
|
||||
msg.Write(tinkeringStrength);
|
||||
msg.Write(tinkeringPowersDevices);
|
||||
msg.Write(CurrentFixer == null ? (ushort)0 : CurrentFixer.ID);
|
||||
msg.WriteRangedInteger((int)currentFixerAction, 0, 2);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
int signalIndex = msg.ReadRangedInteger(0, Signals.Length - 1);
|
||||
if (!item.CanClientAccess(c)) { return; }
|
||||
if (!SendSignal(signalIndex)) { return; }
|
||||
if (!SendSignal(signalIndex, c.Character)) { return; }
|
||||
GameServer.Log($"{GameServer.CharacterLogName(c.Character)} sent a signal \"{Signals[signalIndex]}\" from {item.Name}", ServerLog.MessageType.ItemInteraction);
|
||||
item.CreateServerEvent(this, new object[] { signalIndex });
|
||||
}
|
||||
|
||||
@@ -218,33 +218,6 @@ namespace Barotrauma.Networking
|
||||
if (shuttle != null) { GameMain.NetLobbyScreen.SelectedShuttle = shuttle; }
|
||||
}
|
||||
|
||||
List<SubmarineInfo> campaignSubs = new List<SubmarineInfo>();
|
||||
if (serverSettings.CampaignSubmarines != null && serverSettings.CampaignSubmarines.Length > 0)
|
||||
{
|
||||
string[] submarines = serverSettings.CampaignSubmarines.Split(ServerSettings.SubmarineSeparatorChar);
|
||||
for (int i = 0; i < submarines.Length; i++)
|
||||
{
|
||||
SubmarineInfo subInfo = SubmarineInfo.SavedSubmarines.FirstOrDefault(s => s.Name == submarines[i]);
|
||||
if (subInfo != null && subInfo.IsCampaignCompatible)
|
||||
{
|
||||
campaignSubs.Add(subInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add vanilla submarines by default
|
||||
for (int i = 0; i < SubmarineInfo.SavedSubmarines.Count(); i++)
|
||||
{
|
||||
SubmarineInfo subInfo = SubmarineInfo.SavedSubmarines.ElementAt(i);
|
||||
if (subInfo.IsVanillaSubmarine() && subInfo.IsCampaignCompatible)
|
||||
{
|
||||
campaignSubs.Add(SubmarineInfo.SavedSubmarines.ElementAt(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
GameMain.NetLobbyScreen.CampaignSubmarines = campaignSubs;
|
||||
|
||||
started = true;
|
||||
|
||||
GameAnalyticsManager.AddDesignEvent("GameServer:Start");
|
||||
@@ -835,6 +808,9 @@ namespace Barotrauma.Networking
|
||||
case ClientPacketHeader.CREW:
|
||||
ReadCrewMessage(inc, connectedClient);
|
||||
break;
|
||||
case ClientPacketHeader.MEDICAL:
|
||||
ReadMedicalMessage(inc, connectedClient);
|
||||
break;
|
||||
case ClientPacketHeader.READY_CHECK:
|
||||
ReadyCheck.ServerRead(inc, connectedClient);
|
||||
break;
|
||||
@@ -879,16 +855,16 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
else if (entity is Character character)
|
||||
{
|
||||
errorStr = "Missing character " + character.Name + " (event id " + eventID.ToString() + ", entity id " + entityID.ToString() + ").";
|
||||
errorStrNoName = "Missing character " + character.SpeciesName + "(event id " + eventID.ToString() + ", entity id " + entityID.ToString() + ").";
|
||||
errorStr = $"Missing character {character.Name} (event id {eventID}, entity id {entityID}).";
|
||||
errorStrNoName = $"Missing character {character.SpeciesName} (event id {eventID}, entity id {entityID}).";
|
||||
}
|
||||
else if (entity is Item item)
|
||||
{
|
||||
errorStr = errorStrNoName = "Missing item " + item.Name + " (event id " + eventID.ToString() + ", entity id " + entityID.ToString() + ").";
|
||||
errorStr = errorStrNoName = $"Missing item {item.Name}, sub: {item.Submarine?.Info?.Name ?? "none"} (event id {eventID}, entity id {entityID}).";
|
||||
}
|
||||
else
|
||||
{
|
||||
errorStr = errorStrNoName = "Missing entity " + entity.ToString() + " (event id " + eventID.ToString() + ", entity id " + entityID.ToString() + ").";
|
||||
errorStr = errorStrNoName = $"Missing entity {entity}, sub: {entity.Submarine?.Info?.Name ?? "none"} (event id {eventID}, entity id {entityID}).";
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1234,6 +1210,14 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadMedicalMessage(IReadMessage inc, Client sender)
|
||||
{
|
||||
if (GameMain.GameSession?.Campaign is MultiPlayerCampaign mpCampaign)
|
||||
{
|
||||
mpCampaign.MedicalClinic.ServerRead(inc, sender);
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadReadyToSpawnMessage(IReadMessage inc, Client sender)
|
||||
{
|
||||
sender.SpectateOnly = inc.ReadBoolean() && (serverSettings.AllowSpectating || sender.Connection == OwnerConnection);
|
||||
@@ -1861,24 +1845,6 @@ namespace Barotrauma.Networking
|
||||
outmsg.Write(GameMain.NetLobbyScreen.SelectedShuttle.Name);
|
||||
outmsg.Write(GameMain.NetLobbyScreen.SelectedShuttle.MD5Hash.ToString());
|
||||
|
||||
List<int> campaignSubIndices = new List<int>();
|
||||
if (GameMain.NetLobbyScreen.SelectedMode == GameModePreset.MultiPlayerCampaign)
|
||||
{
|
||||
IReadOnlyList<SubmarineInfo> subList = GameMain.NetLobbyScreen.GetSubList();
|
||||
for (int i = 0; i < subList.Count; i++)
|
||||
{
|
||||
if (GameMain.NetLobbyScreen.CampaignSubmarines.Contains(subList[i]))
|
||||
{
|
||||
campaignSubIndices.Add(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
outmsg.Write((UInt16)campaignSubIndices.Count);
|
||||
foreach (int campaignSubIndex in campaignSubIndices)
|
||||
{
|
||||
outmsg.Write((UInt16)campaignSubIndex);
|
||||
}
|
||||
|
||||
outmsg.Write(serverSettings.Voting.AllowSubVoting);
|
||||
outmsg.Write(serverSettings.Voting.AllowModeVoting);
|
||||
|
||||
@@ -2166,7 +2132,6 @@ namespace Barotrauma.Networking
|
||||
else
|
||||
{
|
||||
SendStartMessage(roundStartSeed, GameMain.NetLobbyScreen.LevelSeed, GameMain.GameSession, connectedClients, false);
|
||||
|
||||
GameMain.GameSession.StartRound(GameMain.NetLobbyScreen.LevelSeed, serverSettings.SelectedLevelDifficulty);
|
||||
Log("Game mode: " + selectedMode.Name, ServerLog.MessageType.ServerMessage);
|
||||
Log("Submarine: " + selectedSub.Name, ServerLog.MessageType.ServerMessage);
|
||||
@@ -2186,8 +2151,7 @@ namespace Barotrauma.Networking
|
||||
yield return CoroutineStatus.Failure;
|
||||
}
|
||||
|
||||
MissionMode missionMode = GameMain.GameSession.GameMode as MissionMode;
|
||||
bool missionAllowRespawn = missionMode == null || !missionMode.Missions.Any(m => !m.AllowRespawn);
|
||||
bool missionAllowRespawn = !(GameMain.GameSession.GameMode is MissionMode missionMode) || !missionMode.Missions.Any(m => !m.AllowRespawn);
|
||||
bool isOutpost = campaign != null && campaign.NextLevel?.Type == LevelData.LevelType.Outpost;
|
||||
|
||||
if (serverSettings.AllowRespawn && missionAllowRespawn)
|
||||
@@ -2263,7 +2227,7 @@ namespace Barotrauma.Networking
|
||||
characterInfos.Add(client.CharacterInfo);
|
||||
if (client.CharacterInfo.Job == null || client.CharacterInfo.Job.Prefab != client.AssignedJob.First)
|
||||
{
|
||||
client.CharacterInfo.Job = new Job(client.AssignedJob.First, client.AssignedJob.Second);
|
||||
client.CharacterInfo.Job = new Job(client.AssignedJob.First, Rand.RandSync.Unsynced, client.AssignedJob.Second);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2475,7 +2439,7 @@ namespace Barotrauma.Networking
|
||||
msg.Write(serverSettings.LockAllDefaultWires);
|
||||
msg.Write(serverSettings.AllowRagdollButton);
|
||||
msg.Write(serverSettings.AllowLinkingWifiToChat);
|
||||
msg.Write(serverSettings.UseRespawnShuttle);
|
||||
msg.Write(serverSettings.UseRespawnShuttle || (gameStarted && respawnManager.UsingShuttle));
|
||||
msg.Write((byte)serverSettings.LosMode);
|
||||
msg.Write(includesFinalize); msg.WritePadBits();
|
||||
|
||||
@@ -3372,14 +3336,40 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
public void IncrementStat(Character character, string achievementIdentifier, int amount)
|
||||
{
|
||||
achievementIdentifier = achievementIdentifier.ToLowerInvariant();
|
||||
foreach (Client client in connectedClients)
|
||||
{
|
||||
if (client.Character == character)
|
||||
{
|
||||
IncrementStat(client, achievementIdentifier, amount);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void GiveAchievement(Client client, string achievementIdentifier)
|
||||
{
|
||||
if (client.GivenAchievements.Contains(achievementIdentifier)) return;
|
||||
if (client.GivenAchievements.Contains(achievementIdentifier)) { return; }
|
||||
client.GivenAchievements.Add(achievementIdentifier);
|
||||
|
||||
IWriteMessage msg = new WriteOnlyMessage();
|
||||
msg.Write((byte)ServerPacketHeader.ACHIEVEMENT);
|
||||
msg.Write(achievementIdentifier);
|
||||
msg.Write(0);
|
||||
|
||||
serverPeer.Send(msg, client.Connection, DeliveryMethod.Reliable);
|
||||
}
|
||||
|
||||
public void IncrementStat(Client client, string achievementIdentifier, int amount)
|
||||
{
|
||||
if (client.GivenAchievements.Contains(achievementIdentifier)) { return; }
|
||||
|
||||
IWriteMessage msg = new WriteOnlyMessage();
|
||||
msg.Write((byte)ServerPacketHeader.ACHIEVEMENT);
|
||||
msg.Write(achievementIdentifier);
|
||||
msg.Write(amount);
|
||||
|
||||
serverPeer.Send(msg, client.Connection, DeliveryMethod.Reliable);
|
||||
}
|
||||
@@ -3733,7 +3723,7 @@ namespace Barotrauma.Networking
|
||||
if (assignedPlayerCount[jobPrefab] >= jobPrefab.MaxNumber) { continue; }
|
||||
|
||||
var variant = Rand.Range(0, jobPrefab.Variants, Rand.RandSync.Server);
|
||||
unassignedBots[0].Job = new Job(jobPrefab, variant);
|
||||
unassignedBots[0].Job = new Job(jobPrefab, Rand.RandSync.Server, variant);
|
||||
assignedPlayerCount[jobPrefab]++;
|
||||
unassignedBots.Remove(unassignedBots[0]);
|
||||
canAssign = true;
|
||||
@@ -3756,7 +3746,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
var job = remainingJobs.GetRandom();
|
||||
var variant = Rand.Range(0, job.Variants);
|
||||
c.Job = new Job(job, variant);
|
||||
c.Job = new Job(job, Rand.RandSync.Unsynced, variant);
|
||||
assignedPlayerCount[c.Job.Prefab]++;
|
||||
}
|
||||
}
|
||||
@@ -3842,16 +3832,6 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (GameMain.NetLobbyScreen.SelectedSub != null) { serverSettings.SelectedSubmarine = GameMain.NetLobbyScreen.SelectedSub.Name; }
|
||||
if (GameMain.NetLobbyScreen.SelectedShuttle != null) { serverSettings.SelectedShuttle = GameMain.NetLobbyScreen.SelectedShuttle.Name; }
|
||||
if (GameMain.NetLobbyScreen.CampaignSubmarines != null)
|
||||
{
|
||||
string submarinesString = string.Empty;
|
||||
for (int i = 0; i < GameMain.NetLobbyScreen.CampaignSubmarines.Count; i++)
|
||||
{
|
||||
submarinesString += GameMain.NetLobbyScreen.CampaignSubmarines[i].Name + ServerSettings.SubmarineSeparatorChar;
|
||||
}
|
||||
submarinesString.Trim(ServerSettings.SubmarineSeparatorChar);
|
||||
serverSettings.CampaignSubmarines = submarinesString;
|
||||
}
|
||||
|
||||
serverSettings.SaveSettings();
|
||||
|
||||
|
||||
@@ -351,7 +351,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
if (campaign?.GetClientCharacterData(c) == null || c.CharacterInfo.Job == null)
|
||||
{
|
||||
c.CharacterInfo.Job = new Job(c.AssignedJob.First, c.AssignedJob.Second);
|
||||
c.CharacterInfo.Job = new Job(c.AssignedJob.First, Rand.RandSync.Unsynced, c.AssignedJob.Second);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,21 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
partial class ServerSettings
|
||||
{
|
||||
partial class NetPropertyData
|
||||
{
|
||||
private object lastSyncedValue;
|
||||
public UInt16 LastUpdateID { get; private set; }
|
||||
|
||||
public void SyncValue()
|
||||
{
|
||||
if (!PropEquals(lastSyncedValue, Value))
|
||||
{
|
||||
LastUpdateID = (UInt16)(GameMain.NetLobbyScreen.LastUpdateID);
|
||||
lastSyncedValue = Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static readonly string ClientPermissionsFile = "Data" + Path.DirectorySeparatorChar + "clientpermissions.xml";
|
||||
public static readonly char SubmarineSeparatorChar = '|';
|
||||
|
||||
@@ -35,20 +50,25 @@ namespace Barotrauma.Networking
|
||||
LoadClientPermissions();
|
||||
}
|
||||
|
||||
private void WriteNetProperties(IWriteMessage outMsg)
|
||||
private void WriteNetProperties(IWriteMessage outMsg, Client c)
|
||||
{
|
||||
outMsg.Write((UInt16)netProperties.Keys.Count);
|
||||
foreach (UInt32 key in netProperties.Keys)
|
||||
{
|
||||
outMsg.Write(key);
|
||||
netProperties[key].Write(outMsg);
|
||||
var property = netProperties[key];
|
||||
property.SyncValue();
|
||||
if (property.LastUpdateID > c.LastRecvLobbyUpdate)
|
||||
{
|
||||
outMsg.Write(key);
|
||||
netProperties[key].Write(outMsg);
|
||||
}
|
||||
}
|
||||
outMsg.Write((UInt32)0);
|
||||
}
|
||||
|
||||
public void ServerAdminWrite(IWriteMessage outMsg, Client c)
|
||||
{
|
||||
c.LastSentServerSettingsUpdate = LastPropertyUpdateId;
|
||||
WriteNetProperties(outMsg);
|
||||
WriteNetProperties(outMsg, c);
|
||||
WriteMonsterEnabled(outMsg);
|
||||
BanList.ServerAdminWrite(outMsg, c);
|
||||
Whitelist.ServerAdminWrite(outMsg, c);
|
||||
@@ -79,8 +99,11 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
WriteExtraCargo(outMsg);
|
||||
}
|
||||
|
||||
WriteHiddenSubs(outMsg);
|
||||
|
||||
if (requiredFlags.HasFlag(NetFlags.HiddenSubs))
|
||||
{
|
||||
WriteHiddenSubs(outMsg);
|
||||
}
|
||||
|
||||
if (c.HasPermission(Networking.ClientPermissions.ManageSettings)
|
||||
&& !NetIdUtils.IdMoreRecentOrMatches(c.LastRecvServerSettingsUpdate, LastPropertyUpdateId))
|
||||
@@ -164,6 +187,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
ReadHiddenSubs(incMsg);
|
||||
changed |= true;
|
||||
UpdateFlag(NetFlags.HiddenSubs);
|
||||
}
|
||||
|
||||
if (flags.HasFlag(NetFlags.Misc))
|
||||
|
||||
@@ -32,26 +32,6 @@ namespace Barotrauma
|
||||
set { selectedShuttle = value; lastUpdateID++; }
|
||||
}
|
||||
|
||||
[Obsolete("TODO: this list shouldn't exist, the client should just use the visible subs list instead")]
|
||||
public List<SubmarineInfo> CampaignSubmarines
|
||||
{
|
||||
get
|
||||
{
|
||||
return campaignSubmarines;
|
||||
}
|
||||
set
|
||||
{
|
||||
campaignSubmarines = value;
|
||||
lastUpdateID++;
|
||||
if (GameMain.NetworkMember?.ServerSettings != null)
|
||||
{
|
||||
GameMain.NetworkMember.ServerSettings.ServerDetailsChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<SubmarineInfo> campaignSubmarines;
|
||||
|
||||
public GameModePreset[] GameModes { get; }
|
||||
|
||||
private int selectedModeIndex;
|
||||
|
||||
Reference in New Issue
Block a user