Release v0.15.12.0

This commit is contained in:
Joonas Rikkonen
2021-10-27 18:50:57 +03:00
parent bf95e82d80
commit 234fb6bc06
450 changed files with 26042 additions and 10457 deletions
@@ -1,12 +1,4 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Barotrauma.IO;
using System.IO.Pipes;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Win32.SafeHandles;
using System.IO.Pipes;
namespace Barotrauma.Networking
{
@@ -1181,6 +1181,10 @@ namespace Barotrauma.Networking
{
c.Character.ServerRead(objHeader, inc, c);
}
else
{
DebugConsole.AddWarning($"Received character inputs from a client who's not controlling a character ({c.Name}).");
}
break;
case ClientNetObject.ENTITY_STATE:
entityEventManager.Read(inc, c);
@@ -1318,7 +1322,7 @@ namespace Barotrauma.Networking
Log("Client \"" + GameServer.ClientLogName(sender) + "\" ended the round.", ServerLog.MessageType.ServerMessage);
if (mpCampaign != null && Level.IsLoadedOutpost)
{
mpCampaign.SaveInventories();
mpCampaign.SavePlayers();
GameMain.GameSession.SubmarineInfo = new SubmarineInfo(GameMain.GameSession.Submarine);
SaveUtil.SaveGame(GameMain.GameSession.SavePath);
}
@@ -2354,8 +2358,16 @@ namespace Barotrauma.Networking
characterData.ApplyHealthData(spawnedCharacter);
characterData.ApplyOrderData(spawnedCharacter);
spawnedCharacter.GiveIdCardTags(mainSubWaypoints[i]);
spawnedCharacter.LoadTalents();
characterData.HasSpawned = true;
}
if (GameMain.GameSession?.GameMode is MultiPlayerCampaign mpCampaign && spawnedCharacter.Info != null)
{
spawnedCharacter.Info.SetExperience(Math.Max(spawnedCharacter.Info.ExperiencePoints, mpCampaign.GetSavedExperiencePoints(teamClients[i])));
mpCampaign.ClearSavedExperiencePoints(teamClients[i]);
}
spawnedCharacter.OwnerClientEndPoint = teamClients[i].Connection.EndPointString;
spawnedCharacter.OwnerClientName = teamClients[i].Name;
}
@@ -2366,6 +2378,8 @@ namespace Barotrauma.Networking
spawnedCharacter.TeamID = teamID;
spawnedCharacter.GiveJobItems(mainSubWaypoints[i]);
spawnedCharacter.GiveIdCardTags(mainSubWaypoints[i]);
// talents are only avilable for players in online sessions, but modders or someone else might want to have them loaded anyway
spawnedCharacter.LoadTalents();
}
}
@@ -2431,6 +2445,7 @@ namespace Barotrauma.Networking
roundStartTime = DateTime.Now;
startGameCoroutine = null;
yield return CoroutineStatus.Success;
}
@@ -2455,6 +2470,7 @@ namespace Barotrauma.Networking
msg.Write(serverSettings.AllowRespawn && missionAllowRespawn);
msg.Write(serverSettings.AllowDisguises);
msg.Write(serverSettings.AllowRewiring);
msg.Write(serverSettings.AllowFriendlyFire);
msg.Write(serverSettings.LockAllDefaultWires);
msg.Write(serverSettings.AllowRagdollButton);
msg.Write(serverSettings.UseRespawnShuttle);
@@ -2619,8 +2635,8 @@ namespace Barotrauma.Networking
}
}
Submarine.Unload();
entityEventManager.Clear();
Submarine.Unload();
GameMain.NetLobbyScreen.Select();
Log("Round ended.", ServerLog.MessageType.ServerMessage);
@@ -3145,28 +3161,19 @@ namespace Barotrauma.Networking
public void SendOrderChatMessage(OrderChatMessage message)
{
if (message.Sender == null || message.Sender.SpeechImpediment >= 100.0f) { return; }
//ChatMessageType messageType = ChatMessage.CanUseRadio(message.Sender) ? ChatMessageType.Radio : ChatMessageType.Default;
//check which clients can receive the message and apply distance effects
foreach (Client client in ConnectedClients)
{
string modifiedMessage = message.Text;
if (message.Sender != null &&
client.Character != null && !client.Character.IsDead)
if (message.Sender != null && client.Character != null && !client.Character.IsDead)
{
//too far to hear the msg -> don't send
if (!client.Character.CanHearCharacter(message.Sender)) { continue; }
}
SendDirectChatMessage(new OrderChatMessage(message.Order, message.OrderOption, message.OrderPriority, message.TargetEntity, message.TargetCharacter, message.Sender), client);
}
string myReceivedMessage = message.Text;
if (!string.IsNullOrWhiteSpace(myReceivedMessage))
if (!string.IsNullOrWhiteSpace(message.Text))
{
AddChatMessage(new OrderChatMessage(message.Order, message.OrderOption, message.OrderPriority, myReceivedMessage, message.TargetEntity, message.TargetCharacter, message.Sender));
AddChatMessage(new OrderChatMessage(message.Order, message.OrderOption, message.OrderPriority, message.Text, message.TargetEntity, message.TargetCharacter, message.Sender));
}
}
@@ -3462,15 +3469,15 @@ namespace Barotrauma.Networking
}
catch (Exception e)
{
//gender = Gender.Male;
//race = Race.White;
//headSpriteId = 0;
DebugConsole.Log("Received invalid characterinfo from \"" + sender.Name + "\"! { " + e.Message + " }");
}
int hairIndex = message.ReadByte();
int beardIndex = message.ReadByte();
int moustacheIndex = message.ReadByte();
int faceAttachmentIndex = message.ReadByte();
Color skinColor = message.ReadColorR8G8B8();
Color hairColor = message.ReadColorR8G8B8();
Color facialHairColor = message.ReadColorR8G8B8();
List<Pair<JobPrefab, int>> jobPreferences = new List<Pair<JobPrefab, int>>();
int count = message.ReadByte();
@@ -3487,6 +3494,9 @@ namespace Barotrauma.Networking
sender.CharacterInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, sender.Name);
sender.CharacterInfo.RecreateHead(headSpriteId, race, gender, hairIndex, beardIndex, moustacheIndex, faceAttachmentIndex);
sender.CharacterInfo.SkinColor = skinColor;
sender.CharacterInfo.HairColor = hairColor;
sender.CharacterInfo.FacialHairColor = facialHairColor;
if (jobPreferences.Count > 0)
{
@@ -3786,7 +3796,7 @@ namespace Barotrauma.Networking
return preferredClient;
}
public void UpdateMissionState(Mission mission, int state)
public void UpdateMissionState(Mission mission)
{
foreach (var client in connectedClients)
{
@@ -3794,7 +3804,7 @@ namespace Barotrauma.Networking
msg.Write((byte)ServerPacketHeader.MISSION);
int missionIndex = GameMain.GameSession.GetMissionIndex(mission);
msg.Write((byte)(missionIndex == -1 ? 255: missionIndex));
msg.Write((ushort)state);
mission?.ServerWrite(msg);
serverPeer.Send(msg, client.Connection, DeliveryMethod.Reliable);
}
}
@@ -518,14 +518,22 @@ namespace Barotrauma
AdjustKarma(character, karmaIncrease, "Repaired item");
}
public void OnReactorOverHeating(Character character, float deltaTime)
public void OnReactorOverHeating(Item reactor, Character character, float deltaTime)
{
AdjustKarma(character, -ReactorOverheatKarmaDecrease * deltaTime, "Caused reactor to overheat");
if (reactor?.Submarine == null || character == null) { return; }
if (reactor.Submarine.TeamID == CharacterTeamType.FriendlyNPC || reactor.Submarine.TeamID == character.TeamID)
{
AdjustKarma(character, -ReactorOverheatKarmaDecrease * deltaTime, "Caused reactor to overheat");
}
}
public void OnReactorMeltdown(Character character)
public void OnReactorMeltdown(Item reactor, Character character)
{
AdjustKarma(character, -ReactorMeltdownKarmaDecrease, "Caused a reactor meltdown");
if (reactor?.Submarine == null || character == null) { return; }
if (reactor.Submarine.TeamID == CharacterTeamType.FriendlyNPC || reactor.Submarine.TeamID == character.TeamID)
{
AdjustKarma(character, -ReactorMeltdownKarmaDecrease, "Caused a reactor meltdown");
}
}
public void OnExtinguishingFire(Character character, float deltaTime)
@@ -44,11 +44,11 @@ namespace Barotrauma.Networking
class ServerEntityEventManager : NetEntityEventManager
{
private List<ServerEntityEvent> events;
private readonly List<ServerEntityEvent> events;
//list of unique events (i.e. !IsDuplicate) created during the round
//used for syncing clients who join mid-round
private List<ServerEntityEvent> uniqueEvents;
private readonly List<ServerEntityEvent> uniqueEvents;
private UInt16 lastSentToAll;
private UInt16 lastSentToAnyone;
@@ -90,11 +90,11 @@ namespace Barotrauma.Networking
}
}
private List<BufferedEvent> bufferedEvents;
private readonly List<BufferedEvent> bufferedEvents;
private UInt16 ID;
private GameServer server;
private readonly GameServer server;
private double lastEventCountHighWarning;
@@ -8,6 +8,11 @@ namespace Barotrauma.Networking
{
partial class RespawnManager : Entity, IServerSerializable
{
/// <summary>
/// How much skills drop towards the job's default skill levels when respawning midround in the campaign
/// </summary>
const float SkillReductionOnCampaignMidroundRespawn = 0.75f;
private DateTime despawnTime;
private float shuttleEmptyTimer;
@@ -284,6 +289,8 @@ namespace Barotrauma.Networking
partial void RespawnCharactersProjSpecific(Vector2? shuttlePos)
{
respawnedCharacters.Clear();
var respawnSub = RespawnShuttle ?? Submarine.MainSub;
MultiPlayerCampaign campaign = GameMain.GameSession.GameMode as MultiPlayerCampaign;
@@ -300,7 +307,7 @@ namespace Barotrauma.Networking
if (matchingData != null && !matchingData.HasSpawned)
{
c.CharacterInfo = matchingData.CharacterInfo;
}
}
//all characters are in Team 1 in game modes/missions with only one team.
//if at some point we add a game mode with multiple teams where respawning is possible, this needs to be reworked
@@ -355,8 +362,28 @@ namespace Barotrauma.Networking
characterInfos[i].ClearCurrentOrders();
var character = Character.Create(characterInfos[i], shuttleSpawnPoints[i].WorldPosition, characterInfos[i].Name, isRemotePlayer: !bot, hasAi: bot);
bool forceSpawnInMainSub = false;
if (!bot && campaign != null)
{
var matchingData = campaign?.GetClientCharacterData(clients[i]);
if (matchingData != null)
{
if (!matchingData.HasSpawned)
{
forceSpawnInMainSub = true;
}
else
{
ReduceCharacterSkills(characterInfos[i]);
}
}
}
var character = Character.Create(characterInfos[i], (forceSpawnInMainSub ? mainSubSpawnPoints[i] : shuttleSpawnPoints[i]).WorldPosition, characterInfos[i].Name, isRemotePlayer: !bot, hasAi: bot);
character.TeamID = CharacterTeamType.Team1;
character.LoadTalents();
respawnedCharacters.Add(character);
if (bot)
{
@@ -364,6 +391,12 @@ namespace Barotrauma.Networking
}
else
{
if (GameMain.GameSession?.GameMode is MultiPlayerCampaign mpCampaign && character.Info != null)
{
character.Info.SetExperience(Math.Max(character.Info.ExperiencePoints, mpCampaign.GetSavedExperiencePoints(clients[i])));
mpCampaign.ClearSavedExperiencePoints(clients[i]);
}
//tell the respawning client they're no longer a traitor
if (GameMain.Server.TraitorManager?.Traitors != null && clients[i].Character != null)
{
@@ -455,6 +488,17 @@ namespace Barotrauma.Networking
}
}
public static void ReduceCharacterSkills(CharacterInfo characterInfo)
{
if (characterInfo?.Job == null) { return; }
foreach (Skill skill in characterInfo.Job.Skills)
{
var skillPrefab = characterInfo.Job.Prefab.Skills.Find(s => skill.Prefab == s);
if (skillPrefab == null) { continue; }
skill.Level = MathHelper.Lerp(skill.Level, skillPrefab.LevelRange.X, SkillReductionOnCampaignMidroundRespawn);
}
}
public void ServerWrite(IWriteMessage msg, Client c, object[] extraData = null)
{
msg.WriteRangedInteger((int)CurrentState, 0, Enum.GetNames(typeof(State)).Length);
@@ -163,9 +163,7 @@ namespace Barotrauma.Networking
RadiationEnabled = incMsg.ReadBoolean();
int maxMissionCount = MaxMissionCount + incMsg.ReadByte() - 1;
if (maxMissionCount < CampaignSettings.MinMissionCountLimit) maxMissionCount = CampaignSettings.MaxMissionCountLimit;
if (maxMissionCount > CampaignSettings.MaxMissionCountLimit) maxMissionCount = CampaignSettings.MinMissionCountLimit;
MaxMissionCount = maxMissionCount;
MaxMissionCount = MathHelper.Clamp(maxMissionCount, CampaignSettings.MinMissionCountLimit, CampaignSettings.MaxMissionCountLimit);
changed |= true;
}
@@ -267,7 +265,7 @@ namespace Barotrauma.Networking
"192-255",
"384-591",
"1024-1279",
"19968-40959","13312-19903","131072-15043983","15043985-173791","173824-178207","178208-183983","63744-64255","194560-195103" //CJK
"19968-21327","21329-40959","13312-19903","131072-173791","173824-178207","178208-183983","63744-64255","194560-195103" //CJK
};
string[] allowedClientNameCharsStr = doc.Root.GetAttributeStringArray("AllowedClientNameChars", defaultAllowedClientNameChars);
@@ -92,7 +92,7 @@ namespace Barotrauma
case VoteType.Mode:
string modeIdentifier = inc.ReadString();
GameModePreset mode = GameModePreset.List.Find(gm => gm.Identifier == modeIdentifier);
if (!mode.Votable) { break; }
if (mode == null || !mode.Votable) { break; }
sender.SetVote(voteType, mode);
break;
case VoteType.EndRound: