This commit is contained in:
Evil Factory
2022-04-28 12:36:24 -03:00
91 changed files with 1140 additions and 491 deletions
@@ -63,8 +63,9 @@ namespace Barotrauma
{
msg.Write(Job.Prefab.Identifier);
msg.Write((byte)Job.Variant);
msg.Write((byte)Job.Skills.Count);
foreach (Skill skill in Job.Skills)
var skills = Job.GetSkills();
msg.Write((byte)skills.Count());
foreach (Skill skill in skills)
{
msg.Write(skill.Identifier);
msg.Write(skill.Level);
@@ -434,8 +434,9 @@ namespace Barotrauma
}
else
{
msg.Write((byte)Info.Job.Skills.Count);
foreach (Skill skill in Info.Job.Skills)
var skills = Info.Job.GetSkills();
msg.Write((byte)skills.Count());
foreach (Skill skill in skills)
{
msg.Write(skill.Identifier);
msg.Write(skill.Level);
@@ -2470,7 +2470,7 @@ namespace Barotrauma
if (isMax) { level = 100; }
if (skillIdentifier == "all")
{
foreach (Skill skill in character.Info.Job.Skills)
foreach (Skill skill in character.Info.Job.GetSkills())
{
character.Info.SetSkillLevel(skill.Identifier, level);
}
@@ -2531,30 +2531,10 @@ namespace Barotrauma
#if DEBUG
commands.Add(new Command("spamevents", "A debug command that creates a ton of entity events.", (string[] args) =>
{
/*foreach (Item item in Item.ItemList)
foreach (Item item in Item.ItemList)
{
foreach (ItemComponent component in item.Components)
{
if (component is IServerSerializable)
{
GameMain.Server.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.ComponentState, item.GetComponentIndex(component) });
}
var itemContainer = item.GetComponent<ItemContainer>();
if (itemContainer != null)
{
GameMain.Server.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.InventoryState, 0 });
}
GameMain.Server.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.Status });
}
}
foreach (Character c in Character.CharacterList)
{
GameMain.Server.CreateEntityEvent(c, new object[] { NetEntityEvent.Type.Status });
}*/
foreach (Hull hull in Hull.HullList)
{
GameMain.Server.CreateEntityEvent(hull);
item.TryCreateServerEventSpam();
item.CreateStatusEvent();
}
foreach (Structure wall in Structure.WallList)
{
@@ -35,7 +35,7 @@ namespace Barotrauma
int itemValue = sellValues[item.ItemPrefab];
if (store.Balance < itemValue || item.Removed) { continue; }
store.Balance += itemValue;
campaign.GetWallet(client).TryDeduct(itemValue);
campaign.TryPurchase(client, itemValue);
storeSpecificItems.Remove(item);
}
}
@@ -178,6 +178,14 @@ namespace Barotrauma
GameMain.Server.ConnectedClients.None(c => c.InGame && (IsOwner(c) || c.HasPermission(permissions)));
}
public bool AllowedToManageWallets(Client client)
{
return
client.HasPermission(ClientPermissions.ManageCampaign) ||
client.HasPermission(ClientPermissions.ManageMoney) ||
IsOwner(client);
}
public void SaveExperiencePoints(Client client)
{
ClearSavedExperiencePoints(client);
@@ -430,7 +438,7 @@ namespace Barotrauma
}
public bool CanPurchaseSub(SubmarineInfo info, Client client)
=> GetWallet(client).CanAfford(info.Price) && GetCampaignSubs().Contains(info);
=> CanAfford(info.Price, client) && GetCampaignSubs().Contains(info);
private readonly List<CharacterCampaignData> discardedCharacters = new List<CharacterCampaignData>();
public void DiscardClientCharacterData(Client client)
@@ -755,8 +763,8 @@ namespace Barotrauma
{
switch (purchasedHullRepairs)
{
case true when personalWallet.CanAfford(hullRepairCost):
personalWallet.Deduct(hullRepairCost);
case true when GetBalance(sender) >= hullRepairCost:
TryPurchase(sender, hullRepairCost);
PurchasedHullRepairs = true;
GameAnalyticsManager.AddMoneySpentEvent(hullRepairCost, GameAnalyticsManager.MoneySink.Service, "hullrepairs");
break;
@@ -771,8 +779,8 @@ namespace Barotrauma
{
switch (purchasedItemRepairs)
{
case true when personalWallet.CanAfford(itemRepairCost):
personalWallet.Deduct(itemRepairCost);
case true when GetBalance(sender) >= itemRepairCost:
TryPurchase(sender, itemRepairCost);
PurchasedItemRepairs = true;
GameAnalyticsManager.AddMoneySpentEvent(itemRepairCost, GameAnalyticsManager.MoneySink.Service, "devicerepairs");
break;
@@ -789,7 +797,7 @@ namespace Barotrauma
{
GameMain.Server.SendDirectChatMessage(TextManager.FormatServerMessage("ReplaceShuttleDockingPortOccupied"), sender, ChatMessageType.MessageBox);
}
else if (purchasedLostShuttles && personalWallet.TryDeduct(shuttleRetrieveCost))
else if (purchasedLostShuttles && TryPurchase(sender, shuttleRetrieveCost))
{
PurchasedLostShuttles = true;
GameAnalyticsManager.AddMoneySpentEvent(shuttleRetrieveCost, GameAnalyticsManager.MoneySink.Service, "retrieveshuttle");
@@ -972,7 +980,7 @@ namespace Barotrauma
switch (transfer.Sender)
{
case Some<ushort> { Value: var id }:
if (id != sender.CharacterID && !AllowedToManageCampaign(sender, ClientPermissions.ManageMoney)) { return; }
if (id != sender.CharacterID && !AllowedToManageWallets(sender)) { return; }
Wallet wallet = GetWalletByID(id);
if (wallet is InvalidWallet) { return; }
@@ -980,7 +988,7 @@ namespace Barotrauma
TransferMoney(wallet);
break;
case None<ushort> _:
if (!AllowedToManageCampaign(sender, ClientPermissions.ManageMoney))
if (!AllowedToManageWallets(sender))
{
if (transfer.Receiver is Some<ushort> { Value: var receiverId } && receiverId == sender.CharacterID)
{
@@ -1025,7 +1033,7 @@ namespace Barotrauma
{
NetWalletSetSalaryUpdate update = INetSerializableStruct.Read<NetWalletSetSalaryUpdate>(msg);
if (!AllowedToManageCampaign(sender, ClientPermissions.ManageMoney)) { return; }
if (!AllowedToManageWallets(sender)) { return; }
Character targetCharacter = Character.CharacterList.FirstOrDefault(c => c.ID == update.Target);
targetCharacter?.Wallet.SetRewardDistribution(update.NewRewardDistribution);
@@ -1231,6 +1239,45 @@ namespace Barotrauma
}
}
public override bool TryPurchase(Client client, int price)
{
Wallet wallet = GetWallet(client);
if (!AllowedToManageWallets(client))
{
return wallet.TryDeduct(price);
}
int balance = wallet.Balance;
if (balance >= price)
{
return wallet.TryDeduct(price);
}
if (balance + Bank.Balance >= price)
{
int remainder = price - balance;
if (balance > 0) { wallet.Deduct(balance); }
Bank.Deduct(remainder);
return true ;
}
return false;
}
public override int GetBalance(Client client = null)
{
if (client is null) { return 0; }
Wallet wallet = GetWallet(client);
if (!AllowedToManageWallets(client))
{
return wallet.Balance;
}
return wallet.Balance + Bank.Balance;
}
public override void Save(XElement element)
{
element.Add(new XAttribute("campaignid", CampaignID));
@@ -1,17 +0,0 @@
using Barotrauma.Networking;
namespace Barotrauma.Items.Components
{
partial class OutpostTerminal : ItemComponent, IClientSerializable, IServerSerializable
{
public void ServerEventRead(IReadMessage msg, Client c)
{
}
public void ServerEventWrite(IWriteMessage msg, Client c, NetEntityEvent.IData extraData = null)
{
}
}
}
@@ -188,11 +188,10 @@ namespace Barotrauma.Items.Components
//already connected, no need to do anything
if (Connections[i].Wires.Contains(newWire)) { continue; }
Connections[i].TryAddLink(newWire);
newWire.Connect(Connections[i], true, true);
Connections[i].TryAddLink(newWire);
var otherConnection = newWire.OtherConnection(Connections[i]);
if (otherConnection == null)
{
GameServer.Log(GameServer.CharacterLogName(c.Character) + " connected a wire to " +
@@ -79,6 +79,7 @@ namespace Barotrauma
Vector2? worldPosition = applyStatusEffectEventData.WorldPosition;
Character targetCharacter = applyStatusEffectEventData.TargetCharacter;
if (targetCharacter != null && targetCharacter.Removed) { targetCharacter = null; }
byte targetLimbIndex = targetLimb != null && targetCharacter != null ? (byte)Array.IndexOf(targetCharacter.AnimController.Limbs, targetLimb) : (byte)255;
msg.WriteRangedInteger((int)actionType, 0, Enum.GetValues(typeof(ActionType)).Length - 1);
@@ -372,5 +373,20 @@ namespace Barotrauma
if (!ic.ValidateEventData(eventData)) { throw new Exception($"Component event creation failed: {typeof(T).Name}.{nameof(ItemComponent.ValidateEventData)} returned false"); }
GameMain.Server.CreateEntityEvent(this, eventData);
}
#if DEBUG
public void TryCreateServerEventSpam()
{
if (GameMain.Server == null) { return; }
foreach (ItemComponent ic in components)
{
if (!(ic is IServerSerializable)) { continue; }
var eventData = new ComponentStateEventData(ic, ic.ServerGetEventData());
if (!ic.ValidateEventData(eventData)) { continue; }
GameMain.Server.CreateEntityEvent(this, eventData);
}
}
#endif
}
}
@@ -160,10 +160,14 @@ namespace Barotrauma.Networking
return Connection.EndpointMatches(endPoint);
}
public void SetPermissions(ClientPermissions permissions, List<DebugConsole.Command> permittedConsoleCommands)
public void SetPermissions(ClientPermissions permissions, IEnumerable<DebugConsole.Command> permittedConsoleCommands)
{
this.Permissions = permissions;
this.PermittedConsoleCommands = new List<DebugConsole.Command>(permittedConsoleCommands);
this.PermittedConsoleCommands.Clear();
foreach (var command in permittedConsoleCommands)
{
this.PermittedConsoleCommands.Add(command);
}
}
public void GivePermission(ClientPermissions permission)
@@ -15,11 +15,14 @@ namespace Barotrauma
if (GameMain.Server == null || spawnOrRemove?.Entity == null) { return; }
GameMain.Server.CreateEntityEvent(this, spawnOrRemove);
if (spawnOrRemove.Entity is Character { Info: { } } character)
if (spawnOrRemove is SpawnEntity)
{
foreach (var statKey in character.Info.SavedStatValues.Keys)
if (spawnOrRemove.Entity is Character { Info: { } } character && !character.Removed)
{
GameMain.NetworkMember.CreateEntityEvent(character, new Character.UpdatePermanentStatsEventData(statKey));
foreach (var statKey in character.Info.SavedStatValues.Keys)
{
GameMain.NetworkMember.CreateEntityEvent(character, new Character.UpdatePermanentStatsEventData(statKey));
}
}
}
}
@@ -286,7 +286,10 @@ namespace Barotrauma.Networking
if (newClient.Connection == OwnerConnection && OwnerConnection != null)
{
newClient.GivePermission(ClientPermissions.All);
newClient.PermittedConsoleCommands.AddRange(DebugConsole.Commands);
foreach (var command in DebugConsole.Commands)
{
newClient.PermittedConsoleCommands.Add(command);
}
SendConsoleMessage("Granted all permissions to " + newClient.Name + ".", newClient);
}
@@ -1239,16 +1242,6 @@ namespace Barotrauma.Networking
}
}
#warning TODO: remove this later
/*private IEnumerable<object> RoundRestartLoop()
{
yield return new WaitForSeconds(8.0f);
EndGame();
yield return new WaitForSeconds(8.0f);
StartGame();
yield return CoroutineStatus.Success;
}*/
private void ReadCrewMessage(IReadMessage inc, Client sender)
{
if (GameMain.GameSession?.Campaign is MultiPlayerCampaign mpCampaign)
@@ -1407,10 +1400,16 @@ namespace Barotrauma.Networking
bool continueCampaign = inc.ReadBoolean();
if (mpCampaign != null && mpCampaign.GameOver || continueCampaign)
{
if (mpCampaign.AllowedToManageCampaign(sender, ClientPermissions.ManageCampaign) || mpCampaign.AllowedToManageCampaign(sender, ClientPermissions.ManageMap))
if (gameStarted)
{
SendDirectChatMessage("Cannot continue the campaign from the previous save (round already running).", sender, ChatMessageType.Error);
break;
}
else if (mpCampaign.AllowedToManageCampaign(sender, ClientPermissions.ManageCampaign) || mpCampaign.AllowedToManageCampaign(sender, ClientPermissions.ManageMap))
{
MultiPlayerCampaign.LoadCampaign(GameMain.GameSession.SavePath);
}
}
else if (!gameStarted && !initiatedStartGame)
{
@@ -364,6 +364,13 @@ namespace Barotrauma.Networking
break;
}
#if DEBUG
netPeerConfiguration.SimulatedDuplicatesChance = GameMain.Server.SimulatedDuplicatesChance;
netPeerConfiguration.SimulatedMinimumLatency = GameMain.Server.SimulatedMinimumLatency;
netPeerConfiguration.SimulatedRandomLatency = GameMain.Server.SimulatedRandomLatency;
netPeerConfiguration.SimulatedLoss = GameMain.Server.SimulatedLoss;
#endif
NetOutgoingMessage lidgrenMsg = netServer.CreateMessage();
byte[] msgData = new byte[msg.LengthBytes];
msg.PrepareForSending(ref msgData, compressPastThreshold, out bool isCompressed, out int length);
@@ -541,7 +541,7 @@ namespace Barotrauma.Networking
public static void ReduceCharacterSkills(CharacterInfo characterInfo)
{
if (characterInfo?.Job == null) { return; }
foreach (Skill skill in characterInfo.Job.Skills)
foreach (Skill skill in characterInfo.Job.GetSkills())
{
var skillPrefab = characterInfo.Job.Prefab.Skills.Find(s => skill.Identifier == s.Identifier);
if (skillPrefab == null) { continue; }
@@ -466,7 +466,7 @@ namespace Barotrauma.Networking
}
ClientPermissions permissions = Networking.ClientPermissions.None;
List<DebugConsole.Command> permittedCommands = new List<DebugConsole.Command>();
HashSet<DebugConsole.Command> permittedCommands = new HashSet<DebugConsole.Command>();
if (clientElement.Attribute("preset") == null)
{
@@ -513,7 +513,7 @@ namespace Barotrauma.Networking
else
{
permissions = preset.Permissions;
permittedCommands = preset.PermittedCommands.ToList();
permittedCommands = preset.PermittedCommands.ToHashSet();
}
}
@@ -577,15 +577,15 @@ namespace Barotrauma.Networking
foreach (string line in lines)
{
string[] separatedLine = line.Split('|');
if (separatedLine.Length < 3) continue;
if (separatedLine.Length < 3) { continue; }
string name = string.Join("|", separatedLine.Take(separatedLine.Length - 2));
string ip = separatedLine[separatedLine.Length - 2];
ClientPermissions permissions = Networking.ClientPermissions.None;
ClientPermissions permissions;
if (Enum.TryParse(separatedLine.Last(), out permissions))
{
ClientPermissions.Add(new SavedClientPermission(name, ip, permissions, new List<DebugConsole.Command>()));
ClientPermissions.Add(new SavedClientPermission(name, ip, permissions, new HashSet<DebugConsole.Command>()));
}
}
}