Unstable 0.17.5.0
This commit is contained in:
+1
-1
@@ -129,7 +129,7 @@ namespace Barotrauma
|
||||
|
||||
public void ApplyWalletData(Character character)
|
||||
{
|
||||
character.Wallet = new Wallet(WalletData);
|
||||
character.Wallet = new Wallet(Option<Character>.Some(character), WalletData);
|
||||
}
|
||||
|
||||
public XElement Save()
|
||||
|
||||
+116
-132
@@ -135,7 +135,7 @@ namespace Barotrauma
|
||||
DebugConsole.NewMessage("Saved campaigns:", Color.White);
|
||||
for (int i = 0; i < saveFiles.Length; i++)
|
||||
{
|
||||
DebugConsole.NewMessage(" " + i + ". " + saveFiles[i], Color.White);
|
||||
DebugConsole.NewMessage(" " + i + ". " + saveFiles[i].FilePath, Color.White);
|
||||
}
|
||||
DebugConsole.ShowQuestionPrompt("Select a save file to load (0 - " + (saveFiles.Length - 1) + "):", (string selectedSave) =>
|
||||
{
|
||||
@@ -148,7 +148,7 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
LoadCampaign(saveFiles[saveIndex]);
|
||||
LoadCampaign(saveFiles[saveIndex].FilePath);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -166,28 +166,13 @@ namespace Barotrauma
|
||||
/// <summary>
|
||||
/// There is a client-side implementation of the method in <see cref="CampaignMode"/>
|
||||
/// </summary>
|
||||
public bool AllowedToEndRound(Client client)
|
||||
{
|
||||
//allow ending the round if the client has permissions, is the owner, the only client in the server,
|
||||
//or if no-one has permissions
|
||||
return
|
||||
client.HasPermission(ClientPermissions.ManageRound) ||
|
||||
client.HasPermission(ClientPermissions.ManageCampaign) ||
|
||||
GameMain.Server.ConnectedClients.Count == 1 ||
|
||||
IsOwner(client) ||
|
||||
GameMain.Server.ConnectedClients.None(c =>
|
||||
c.InGame && (IsOwner(c) || c.HasPermission(ClientPermissions.ManageRound) || c.HasPermission(ClientPermissions.ManageCampaign)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// There is a client-side implementation of the method in <see cref="CampaignMode"/>
|
||||
/// </summary>
|
||||
public bool AllowedToManageCampaign(Client client, ClientPermissions permissions = ClientPermissions.ManageCampaign)
|
||||
public bool AllowedToManageCampaign(Client client, ClientPermissions permissions)
|
||||
{
|
||||
//allow managing the campaign if the client has permissions, is the owner, or the only client in the server,
|
||||
//or if no-one has management permissions
|
||||
return
|
||||
client.HasPermission(permissions) ||
|
||||
client.HasPermission(ClientPermissions.ManageCampaign) ||
|
||||
GameMain.Server.ConnectedClients.Count == 1 ||
|
||||
IsOwner(client) ||
|
||||
GameMain.Server.ConnectedClients.None(c => c.InGame && (IsOwner(c) || c.HasPermission(permissions)));
|
||||
@@ -519,7 +504,7 @@ namespace Barotrauma
|
||||
walletsToCheck.Clear();
|
||||
walletsToCheck.Add(0, Bank);
|
||||
|
||||
foreach (Character character in Mission.GetSalaryEligibleCrew())
|
||||
foreach (Character character in GameSession.GetSessionCrewCharacters(CharacterType.Player))
|
||||
{
|
||||
walletsToCheck.Add(character.ID, character.Wallet);
|
||||
}
|
||||
@@ -715,107 +700,102 @@ namespace Barotrauma
|
||||
purchasedItemSwaps.Add(new PurchasedItemSwap(itemToRemove, itemToInstall));
|
||||
}
|
||||
|
||||
bool allowedToManageCampaign = AllowedToManageCampaign(sender);
|
||||
if (AllowedToManageCampaign(sender))
|
||||
Location location = Map.CurrentLocation;
|
||||
int hullRepairCost = location?.GetAdjustedMechanicalCost(HullRepairCost) ?? HullRepairCost;
|
||||
int itemRepairCost = location?.GetAdjustedMechanicalCost(ItemRepairCost) ?? ItemRepairCost;
|
||||
int shuttleRetrieveCost = location?.GetAdjustedMechanicalCost(ShuttleReplaceCost) ?? ShuttleReplaceCost;
|
||||
Wallet personalWallet = GetWallet(sender);
|
||||
|
||||
if (purchasedHullRepairs != PurchasedHullRepairs)
|
||||
{
|
||||
Location location = Map.CurrentLocation;
|
||||
int hullRepairCost = location?.GetAdjustedMechanicalCost(HullRepairCost) ?? HullRepairCost;
|
||||
int itemRepairCost = location?.GetAdjustedMechanicalCost(ItemRepairCost) ?? ItemRepairCost;
|
||||
int shuttleRetrieveCost = location?.GetAdjustedMechanicalCost(ShuttleReplaceCost) ?? ShuttleReplaceCost;
|
||||
Wallet personalWallet = GetWallet(sender);
|
||||
|
||||
if (purchasedHullRepairs != PurchasedHullRepairs)
|
||||
switch (purchasedHullRepairs)
|
||||
{
|
||||
switch (purchasedHullRepairs)
|
||||
{
|
||||
case true when personalWallet.CanAfford(hullRepairCost):
|
||||
personalWallet.Deduct(hullRepairCost);
|
||||
PurchasedHullRepairs = true;
|
||||
GameAnalyticsManager.AddMoneySpentEvent(hullRepairCost, GameAnalyticsManager.MoneySink.Service, "hullrepairs");
|
||||
break;
|
||||
case false:
|
||||
PurchasedHullRepairs = false;
|
||||
personalWallet.Refund(hullRepairCost);
|
||||
break;
|
||||
}
|
||||
case true when personalWallet.CanAfford(hullRepairCost):
|
||||
personalWallet.Deduct(hullRepairCost);
|
||||
PurchasedHullRepairs = true;
|
||||
GameAnalyticsManager.AddMoneySpentEvent(hullRepairCost, GameAnalyticsManager.MoneySink.Service, "hullrepairs");
|
||||
break;
|
||||
case false:
|
||||
PurchasedHullRepairs = false;
|
||||
personalWallet.Refund(hullRepairCost);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (purchasedItemRepairs != PurchasedItemRepairs)
|
||||
if (purchasedItemRepairs != PurchasedItemRepairs)
|
||||
{
|
||||
switch (purchasedItemRepairs)
|
||||
{
|
||||
switch (purchasedItemRepairs)
|
||||
{
|
||||
case true when personalWallet.CanAfford(itemRepairCost):
|
||||
personalWallet.Deduct(itemRepairCost);
|
||||
PurchasedItemRepairs = true;
|
||||
GameAnalyticsManager.AddMoneySpentEvent(itemRepairCost, GameAnalyticsManager.MoneySink.Service, "devicerepairs");
|
||||
break;
|
||||
case false:
|
||||
PurchasedItemRepairs = false;
|
||||
personalWallet.Refund(itemRepairCost);
|
||||
break;
|
||||
}
|
||||
case true when personalWallet.CanAfford(itemRepairCost):
|
||||
personalWallet.Deduct(itemRepairCost);
|
||||
PurchasedItemRepairs = true;
|
||||
GameAnalyticsManager.AddMoneySpentEvent(itemRepairCost, GameAnalyticsManager.MoneySink.Service, "devicerepairs");
|
||||
break;
|
||||
case false:
|
||||
PurchasedItemRepairs = false;
|
||||
personalWallet.Refund(itemRepairCost);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (purchasedLostShuttles != PurchasedLostShuttles)
|
||||
if (purchasedLostShuttles != PurchasedLostShuttles)
|
||||
{
|
||||
if (GameMain.GameSession?.SubmarineInfo != null && GameMain.GameSession.SubmarineInfo.LeftBehindSubDockingPortOccupied)
|
||||
{
|
||||
if (GameMain.GameSession?.SubmarineInfo != null && GameMain.GameSession.SubmarineInfo.LeftBehindSubDockingPortOccupied)
|
||||
{
|
||||
GameMain.Server.SendDirectChatMessage(TextManager.FormatServerMessage("ReplaceShuttleDockingPortOccupied"), sender, ChatMessageType.MessageBox);
|
||||
}
|
||||
else if (purchasedLostShuttles && personalWallet.TryDeduct(shuttleRetrieveCost))
|
||||
{
|
||||
PurchasedLostShuttles = true;
|
||||
GameAnalyticsManager.AddMoneySpentEvent(shuttleRetrieveCost, GameAnalyticsManager.MoneySink.Service, "retrieveshuttle");
|
||||
}
|
||||
else if (!purchasedItemRepairs)
|
||||
{
|
||||
PurchasedLostShuttles = false;
|
||||
personalWallet.Refund(shuttleRetrieveCost);
|
||||
}
|
||||
GameMain.Server.SendDirectChatMessage(TextManager.FormatServerMessage("ReplaceShuttleDockingPortOccupied"), sender, ChatMessageType.MessageBox);
|
||||
}
|
||||
|
||||
if (currentLocIndex < Map.Locations.Count && Map.AllowDebugTeleport)
|
||||
else if (purchasedLostShuttles && personalWallet.TryDeduct(shuttleRetrieveCost))
|
||||
{
|
||||
Map.SetLocation(currentLocIndex);
|
||||
PurchasedLostShuttles = true;
|
||||
GameAnalyticsManager.AddMoneySpentEvent(shuttleRetrieveCost, GameAnalyticsManager.MoneySink.Service, "retrieveshuttle");
|
||||
}
|
||||
else if (!purchasedItemRepairs)
|
||||
{
|
||||
PurchasedLostShuttles = false;
|
||||
personalWallet.Refund(shuttleRetrieveCost);
|
||||
}
|
||||
}
|
||||
|
||||
if (currentLocIndex < Map.Locations.Count && Map.AllowDebugTeleport)
|
||||
{
|
||||
Map.SetLocation(currentLocIndex);
|
||||
}
|
||||
|
||||
if (AllowedToManageCampaign(sender, ClientPermissions.ManageMap))
|
||||
{
|
||||
Map.SelectLocation(selectedLocIndex == UInt16.MaxValue ? -1 : selectedLocIndex);
|
||||
if (Map.SelectedLocation == null) { Map.SelectRandomLocation(preferUndiscovered: true); }
|
||||
if (Map.SelectedConnection != null) { Map.SelectMission(selectedMissionIndices); }
|
||||
CheckTooManyMissions(Map.CurrentLocation, sender);
|
||||
}
|
||||
|
||||
bool allowedToUseStore = AllowedToManageCampaign(sender, ClientPermissions.CampaignStore);
|
||||
if (allowedToManageCampaign || allowedToUseStore || AllowedToManageCampaign(sender, ClientPermissions.BuyItems))
|
||||
|
||||
var prevBuyCrateItems = new Dictionary<Identifier, List<PurchasedItem>>(CargoManager.ItemsInBuyCrate);
|
||||
foreach (var store in prevBuyCrateItems)
|
||||
{
|
||||
var prevBuyCrateItems = new Dictionary<Identifier, List<PurchasedItem>>(CargoManager.ItemsInBuyCrate);
|
||||
foreach (var store in prevBuyCrateItems)
|
||||
foreach (var item in store.Value)
|
||||
{
|
||||
foreach (var item in store.Value)
|
||||
{
|
||||
CargoManager.ModifyItemQuantityInBuyCrate(store.Key, item.ItemPrefab, -item.Quantity, sender);
|
||||
}
|
||||
}
|
||||
foreach (var store in buyCrateItems)
|
||||
{
|
||||
foreach (var item in store.Value)
|
||||
{
|
||||
CargoManager.ModifyItemQuantityInBuyCrate(store.Key, item.ItemPrefab, item.Quantity, sender);
|
||||
}
|
||||
}
|
||||
var prevPurchasedItems = new Dictionary<Identifier, List<PurchasedItem>>(CargoManager.PurchasedItems);
|
||||
foreach (var store in prevPurchasedItems)
|
||||
{
|
||||
CargoManager.SellBackPurchasedItems(store.Key, store.Value);
|
||||
}
|
||||
foreach (var store in purchasedItems)
|
||||
{
|
||||
CargoManager.PurchaseItems(store.Key, store.Value, false, sender);
|
||||
CargoManager.ModifyItemQuantityInBuyCrate(store.Key, item.ItemPrefab, -item.Quantity, sender);
|
||||
}
|
||||
}
|
||||
foreach (var store in buyCrateItems)
|
||||
{
|
||||
foreach (var item in store.Value)
|
||||
{
|
||||
CargoManager.ModifyItemQuantityInBuyCrate(store.Key, item.ItemPrefab, item.Quantity, sender);
|
||||
}
|
||||
}
|
||||
var prevPurchasedItems = new Dictionary<Identifier, List<PurchasedItem>>(CargoManager.PurchasedItems);
|
||||
foreach (var store in prevPurchasedItems)
|
||||
{
|
||||
CargoManager.SellBackPurchasedItems(store.Key, store.Value);
|
||||
}
|
||||
foreach (var store in purchasedItems)
|
||||
{
|
||||
CargoManager.PurchaseItems(store.Key, store.Value, false, sender);
|
||||
}
|
||||
|
||||
bool allowedToSellSubItems = AllowedToManageCampaign(sender, ClientPermissions.SellSubItems);
|
||||
if (allowedToManageCampaign || allowedToUseStore || allowedToSellSubItems)
|
||||
if (allowedToSellSubItems)
|
||||
{
|
||||
var prevSubSellCrateItems = new Dictionary<Identifier, List<PurchasedItem>>(CargoManager.ItemsInSellFromSubCrate);
|
||||
foreach (var store in prevSubSellCrateItems)
|
||||
@@ -834,7 +814,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
bool allowedToSellInventoryItems = AllowedToManageCampaign(sender, ClientPermissions.SellInventoryItems);
|
||||
if (allowedToManageCampaign || allowedToUseStore || (allowedToSellInventoryItems && allowedToSellSubItems))
|
||||
if (allowedToSellInventoryItems && allowedToSellSubItems)
|
||||
{
|
||||
// for some reason CargoManager.SoldItem is never cleared by the server, I've added a check to SellItems that ignores all
|
||||
// sold items that are removed so they should be discarded on the next message
|
||||
@@ -867,37 +847,34 @@ namespace Barotrauma
|
||||
bool predicate(SoldItem i) => allowedToSellInventoryItems != (i.Origin == SoldItem.SellOrigin.Character);
|
||||
}
|
||||
|
||||
if (allowedToManageCampaign)
|
||||
foreach (var (prefab, category, _) in purchasedUpgrades)
|
||||
{
|
||||
foreach (var (prefab, category, _) in purchasedUpgrades)
|
||||
{
|
||||
UpgradeManager.PurchaseUpgrade(prefab, category, client: sender);
|
||||
UpgradeManager.PurchaseUpgrade(prefab, category, client: sender);
|
||||
|
||||
// unstable logging
|
||||
int price = prefab.Price.GetBuyprice(UpgradeManager.GetUpgradeLevel(prefab, category), Map?.CurrentLocation);
|
||||
int level = UpgradeManager.GetUpgradeLevel(prefab, category);
|
||||
GameServer.Log($"SERVER: Purchased level {level} {category.Identifier}.{prefab.Identifier} for {price}", ServerLog.MessageType.ServerMessage);
|
||||
}
|
||||
foreach (var purchasedItemSwap in purchasedItemSwaps)
|
||||
// unstable logging
|
||||
int price = prefab.Price.GetBuyprice(UpgradeManager.GetUpgradeLevel(prefab, category), Map?.CurrentLocation);
|
||||
int level = UpgradeManager.GetUpgradeLevel(prefab, category);
|
||||
GameServer.Log($"SERVER: Purchased level {level} {category.Identifier}.{prefab.Identifier} for {price}", ServerLog.MessageType.ServerMessage);
|
||||
}
|
||||
foreach (var purchasedItemSwap in purchasedItemSwaps)
|
||||
{
|
||||
if (purchasedItemSwap.ItemToInstall == null)
|
||||
{
|
||||
if (purchasedItemSwap.ItemToInstall == null)
|
||||
{
|
||||
UpgradeManager.CancelItemSwap(purchasedItemSwap.ItemToRemove);
|
||||
}
|
||||
else
|
||||
{
|
||||
UpgradeManager.PurchaseItemSwap(purchasedItemSwap.ItemToRemove, purchasedItemSwap.ItemToInstall, client: sender);
|
||||
}
|
||||
UpgradeManager.CancelItemSwap(purchasedItemSwap.ItemToRemove);
|
||||
}
|
||||
foreach (Item item in Item.ItemList)
|
||||
else
|
||||
{
|
||||
if (item.PendingItemSwap != null && !purchasedItemSwaps.Any(it => it.ItemToRemove == item))
|
||||
{
|
||||
UpgradeManager.CancelItemSwap(item);
|
||||
item.PendingItemSwap = null;
|
||||
}
|
||||
UpgradeManager.PurchaseItemSwap(purchasedItemSwap.ItemToRemove, purchasedItemSwap.ItemToInstall, client: sender);
|
||||
}
|
||||
}
|
||||
foreach (Item item in Item.ItemList)
|
||||
{
|
||||
if (item.PendingItemSwap != null && !purchasedItemSwaps.Any(it => it.ItemToRemove == item))
|
||||
{
|
||||
UpgradeManager.CancelItemSwap(item);
|
||||
item.PendingItemSwap = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ServerReadMoney(IReadMessage msg, Client sender)
|
||||
@@ -907,19 +884,26 @@ namespace Barotrauma
|
||||
switch (transfer.Sender)
|
||||
{
|
||||
case Some<ushort> { Value: var id }:
|
||||
|
||||
if (id != sender.CharacterID && !AllowedToManageCampaign(sender)) { return; }
|
||||
if (id != sender.CharacterID && !AllowedToManageCampaign(sender, ClientPermissions.ManageMoney)) { return; }
|
||||
|
||||
Wallet wallet = GetWalletByID(id);
|
||||
if (wallet is InvalidWallet) { return; }
|
||||
|
||||
TransferMoney(wallet);
|
||||
break;
|
||||
|
||||
case None<ushort> _:
|
||||
if (!AllowedToManageCampaign(sender)) { return; }
|
||||
|
||||
TransferMoney(Bank);
|
||||
if (!AllowedToManageCampaign(sender, ClientPermissions.ManageMoney))
|
||||
{
|
||||
if (transfer.Receiver is Some<ushort> { Value: var receiverId } && receiverId == sender.CharacterID)
|
||||
{
|
||||
GameMain.Server?.Voting.StartTransferVote(sender, null, transfer.Amount, sender);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
TransferMoney(Bank);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -952,10 +936,10 @@ namespace Barotrauma
|
||||
{
|
||||
NetWalletSetSalaryUpdate update = INetSerializableStruct.Read<NetWalletSetSalaryUpdate>(msg);
|
||||
|
||||
if (!AllowedToManageCampaign(sender)) { return; }
|
||||
if (!AllowedToManageCampaign(sender, ClientPermissions.ManageMoney)) { return; }
|
||||
|
||||
Character targetCharacter = Character.CharacterList.FirstOrDefault(c => c.ID == update.Target);
|
||||
targetCharacter?.Wallet.SetRewardDistrubiton(update.NewRewardDistribution);
|
||||
targetCharacter?.Wallet.SetRewardDistribution(update.NewRewardDistribution);
|
||||
}
|
||||
|
||||
public void ServerReadCrew(IReadMessage msg, Client sender)
|
||||
@@ -994,7 +978,7 @@ namespace Barotrauma
|
||||
List<CharacterInfo> hiredCharacters = new List<CharacterInfo>();
|
||||
CharacterInfo firedCharacter = null;
|
||||
|
||||
if (location != null && AllowedToManageCampaign(sender))
|
||||
if (location != null && AllowedToManageCampaign(sender, ClientPermissions.ManageHires))
|
||||
{
|
||||
if (fireCharacter)
|
||||
{
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Barotrauma
|
||||
private struct RateLimitInfo
|
||||
{
|
||||
public int Requests;
|
||||
public const int MaxRequests = 5;
|
||||
public const int MaxRequests = 10;
|
||||
public DateTimeOffset Expiry;
|
||||
}
|
||||
|
||||
|
||||
@@ -130,6 +130,8 @@ namespace Barotrauma.Networking
|
||||
KarmaManager.SelectPreset(serverSettings.KarmaPreset);
|
||||
serverSettings.SetPassword(password);
|
||||
|
||||
Voting = new Voting();
|
||||
|
||||
ownerKey = ownKey;
|
||||
|
||||
ownerSteamId = steamId;
|
||||
@@ -383,23 +385,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
TraitorManager?.Update(deltaTime);
|
||||
|
||||
if (serverSettings.Voting.VoteRunning)
|
||||
{
|
||||
Voting.SubVote.Timer += deltaTime;
|
||||
|
||||
if (Voting.SubVote.Timer >= serverSettings.SubmarineVoteTimeout)
|
||||
{
|
||||
// Do not take unanswered into account for total
|
||||
if (SubmarineVoteYesCount / (float)(SubmarineVoteYesCount + SubmarineVoteNoCount) >= serverSettings.SubmarineVoteRequiredRatio)
|
||||
{
|
||||
SwitchSubmarine();
|
||||
}
|
||||
else
|
||||
{
|
||||
serverSettings.Voting.StopSubmarineVote(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
Voting.Update(deltaTime);
|
||||
|
||||
bool isCrewDead =
|
||||
connectedClients.All(c => c.Character == null || c.Character.IsDead || c.Character.IsIncapacitated);
|
||||
@@ -1073,7 +1059,7 @@ namespace Barotrauma.Networking
|
||||
ChatMessage.ServerRead(inc, c);
|
||||
break;
|
||||
case ClientNetObject.VOTE:
|
||||
serverSettings.Voting.ServerRead(inc, c);
|
||||
Voting.ServerRead(inc, c);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
@@ -1220,7 +1206,7 @@ namespace Barotrauma.Networking
|
||||
entityEventManager.Read(inc, c);
|
||||
break;
|
||||
case ClientNetObject.VOTE:
|
||||
serverSettings.Voting.ServerRead(inc, c);
|
||||
Voting.ServerRead(inc, c);
|
||||
break;
|
||||
case ClientNetObject.SPECTATING_POS:
|
||||
c.SpectatePos = new Vector2(inc.ReadSingle(), inc.ReadSingle());
|
||||
@@ -1309,17 +1295,11 @@ namespace Barotrauma.Networking
|
||||
var mpCampaign = GameMain.GameSession?.GameMode as MultiPlayerCampaign;
|
||||
if (command == ClientPermissions.ManageRound && mpCampaign != null)
|
||||
{
|
||||
if (!mpCampaign.AllowedToEndRound(sender))
|
||||
{
|
||||
return;
|
||||
}
|
||||
//do nothing, ending campaign rounds is checked in more detail below
|
||||
}
|
||||
else if (command == ClientPermissions.ManageCampaign && mpCampaign != null)
|
||||
{
|
||||
if (!mpCampaign.AllowedToManageCampaign(sender))
|
||||
{
|
||||
return;
|
||||
}
|
||||
//do nothing, campaign permissions are checked in more detail in MultiplayerCampaign.ServerRead
|
||||
}
|
||||
else if (!sender.HasPermission(command))
|
||||
{
|
||||
@@ -1381,21 +1361,26 @@ namespace Barotrauma.Networking
|
||||
bool end = inc.ReadBoolean();
|
||||
if (end)
|
||||
{
|
||||
bool save = inc.ReadBoolean();
|
||||
if (gameStarted)
|
||||
if (mpCampaign == null ||
|
||||
mpCampaign.AllowedToManageCampaign(sender, ClientPermissions.ManageRound) ||
|
||||
mpCampaign.AllowedToManageCampaign(sender, ClientPermissions.ManageCampaign))
|
||||
{
|
||||
Log("Client \"" + GameServer.ClientLogName(sender) + "\" ended the round.", ServerLog.MessageType.ServerMessage);
|
||||
if (mpCampaign != null && Level.IsLoadedOutpost && save)
|
||||
bool save = inc.ReadBoolean();
|
||||
if (gameStarted)
|
||||
{
|
||||
mpCampaign.SavePlayers();
|
||||
GameMain.GameSession.SubmarineInfo = new SubmarineInfo(GameMain.GameSession.Submarine);
|
||||
SaveUtil.SaveGame(GameMain.GameSession.SavePath);
|
||||
Log("Client \"" + GameServer.ClientLogName(sender) + "\" ended the round.", ServerLog.MessageType.ServerMessage);
|
||||
if (mpCampaign != null && Level.IsLoadedOutpost && save)
|
||||
{
|
||||
mpCampaign.SavePlayers();
|
||||
GameMain.GameSession.SubmarineInfo = new SubmarineInfo(GameMain.GameSession.Submarine);
|
||||
SaveUtil.SaveGame(GameMain.GameSession.SavePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
save = false;
|
||||
}
|
||||
EndGame(wasSaved: save);
|
||||
}
|
||||
else
|
||||
{
|
||||
save = false;
|
||||
}
|
||||
EndGame(wasSaved: save);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1403,14 +1388,17 @@ namespace Barotrauma.Networking
|
||||
bool continueCampaign = inc.ReadBoolean();
|
||||
if (mpCampaign != null && mpCampaign.GameOver || continueCampaign)
|
||||
{
|
||||
MultiPlayerCampaign.LoadCampaign(GameMain.GameSession.SavePath);
|
||||
if (mpCampaign.AllowedToManageCampaign(sender, ClientPermissions.ManageCampaign) || mpCampaign.AllowedToManageCampaign(sender, ClientPermissions.ManageMap))
|
||||
{
|
||||
MultiPlayerCampaign.LoadCampaign(GameMain.GameSession.SavePath);
|
||||
}
|
||||
}
|
||||
else if (!gameStarted && !initiatedStartGame)
|
||||
{
|
||||
Log("Client \"" + ClientLogName(sender) + "\" started the round.", ServerLog.MessageType.ServerMessage);
|
||||
StartGame();
|
||||
}
|
||||
else if (mpCampaign != null)
|
||||
else if (mpCampaign != null && (mpCampaign.AllowedToManageCampaign(sender, ClientPermissions.ManageCampaign) || mpCampaign.AllowedToManageCampaign(sender, ClientPermissions.ManageMap)))
|
||||
{
|
||||
var availableTransition = mpCampaign.GetAvailableTransition(out _, out _);
|
||||
//don't force location if we've teleported
|
||||
@@ -1473,34 +1461,20 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (GameMain.NetLobbyScreen.GameModes[modeIndex].Identifier == "multiplayercampaign")
|
||||
{
|
||||
string[] saveFiles = SaveUtil.GetSaveFiles(SaveUtil.SaveType.Multiplayer, includeInCompatible: false).ToArray();
|
||||
for (int i = 0; i < saveFiles.Length; i++)
|
||||
{
|
||||
XDocument doc = SaveUtil.LoadGameSessionDoc(saveFiles[i]);
|
||||
if (doc?.Root != null)
|
||||
{
|
||||
saveFiles[i] =
|
||||
string.Join(";",
|
||||
saveFiles[i].Replace(';', ' '),
|
||||
doc.Root.GetAttributeStringUnrestricted("submarine", ""),
|
||||
doc.Root.GetAttributeStringUnrestricted("savetime", ""),
|
||||
doc.Root.GetAttributeStringUnrestricted("selectedcontentpackages", ""));
|
||||
}
|
||||
}
|
||||
|
||||
const int MaxSaves = 255;
|
||||
var saveInfos = SaveUtil.GetSaveFiles(SaveUtil.SaveType.Multiplayer, includeInCompatible: false);
|
||||
IWriteMessage msg = new WriteOnlyMessage();
|
||||
msg.Write((byte)ServerPacketHeader.CAMPAIGN_SETUP_INFO);
|
||||
msg.Write((UInt16)saveFiles.Count());
|
||||
foreach (string saveFile in saveFiles)
|
||||
msg.Write((byte)Math.Min(saveInfos.Count, MaxSaves));
|
||||
for (int i = 0; i < saveInfos.Count && i < MaxSaves; i++)
|
||||
{
|
||||
msg.Write(saveFile);
|
||||
msg.Write(saveInfos[i]);
|
||||
}
|
||||
|
||||
serverPeer.Send(msg, sender.Connection, DeliveryMethod.Reliable);
|
||||
}
|
||||
break;
|
||||
case ClientPermissions.ManageCampaign:
|
||||
(GameMain.GameSession.GameMode as MultiPlayerCampaign)?.ServerRead(inc, sender);
|
||||
mpCampaign?.ServerRead(inc, sender);
|
||||
break;
|
||||
case ClientPermissions.ConsoleCommands:
|
||||
{
|
||||
@@ -1900,8 +1874,8 @@ namespace Barotrauma.Networking
|
||||
outmsg.Write(selectedShuttle.Name);
|
||||
outmsg.Write(selectedShuttle.MD5Hash.ToString());
|
||||
|
||||
outmsg.Write(serverSettings.Voting.AllowSubVoting);
|
||||
outmsg.Write(serverSettings.Voting.AllowModeVoting);
|
||||
outmsg.Write(serverSettings.AllowSubVoting);
|
||||
outmsg.Write(serverSettings.AllowModeVoting);
|
||||
|
||||
outmsg.Write(serverSettings.VoiceChatEnabled);
|
||||
|
||||
@@ -2036,9 +2010,9 @@ namespace Barotrauma.Networking
|
||||
SubmarineInfo selectedShuttle = GameMain.NetLobbyScreen.SelectedShuttle;
|
||||
|
||||
SubmarineInfo selectedSub;
|
||||
if (serverSettings.Voting.AllowSubVoting)
|
||||
if (serverSettings.AllowSubVoting)
|
||||
{
|
||||
selectedSub = serverSettings.Voting.HighestVoted<SubmarineInfo>(VoteType.Sub, connectedClients);
|
||||
selectedSub = Voting.HighestVoted<SubmarineInfo>(VoteType.Sub, connectedClients);
|
||||
if (selectedSub == null) { selectedSub = GameMain.NetLobbyScreen.SelectedSub; }
|
||||
}
|
||||
else
|
||||
@@ -2051,7 +2025,7 @@ namespace Barotrauma.Networking
|
||||
return false;
|
||||
}
|
||||
|
||||
GameModePreset selectedMode = serverSettings.Voting.HighestVoted<GameModePreset>(VoteType.Mode, connectedClients);
|
||||
GameModePreset selectedMode = Voting.HighestVoted<GameModePreset>(VoteType.Mode, connectedClients);
|
||||
if (selectedMode == null) { selectedMode = GameMain.NetLobbyScreen.SelectedMode; }
|
||||
|
||||
if (selectedMode == null)
|
||||
@@ -2455,11 +2429,8 @@ namespace Barotrauma.Networking
|
||||
|
||||
yield return CoroutineStatus.Running;
|
||||
|
||||
if (GameMain.Server?.ServerSettings?.Voting != null)
|
||||
{
|
||||
GameMain.Server.ServerSettings.Voting.ResetVotes(GameMain.Server.ConnectedClients);
|
||||
}
|
||||
|
||||
Voting?.ResetVotes(GameMain.Server.ConnectedClients);
|
||||
|
||||
GameMain.GameScreen.Select();
|
||||
|
||||
Log("Round started.", ServerLog.MessageType.ServerMessage);
|
||||
@@ -3233,23 +3204,24 @@ namespace Barotrauma.Networking
|
||||
serverPeer.Send(msg, transfer.Connection, DeliveryMethod.ReliableOrdered);
|
||||
}
|
||||
|
||||
public void UpdateVoteStatus()
|
||||
public void UpdateVoteStatus(bool checkActiveVote = true)
|
||||
{
|
||||
if (connectedClients.Count == 0) return;
|
||||
if (connectedClients.Count == 0) { return; }
|
||||
|
||||
if (serverSettings.Voting.VoteRunning)
|
||||
if (checkActiveVote && Voting.ActiveVote != null)
|
||||
{
|
||||
int yes = GameMain.Server.ConnectedClients.Count(c => c.InGame && c.GetVote<int>(Voting.ActiveVote.VoteType) == 2);
|
||||
int no = GameMain.Server.ConnectedClients.Count(c => c.InGame && c.GetVote<int>(Voting.ActiveVote.VoteType) == 1);
|
||||
int max = GameMain.Server.ConnectedClients.Count(c => c.InGame);
|
||||
// Required ratio cannot be met
|
||||
if (SubmarineVoteNoCount / (float)SubmarineVoteMax > 1f - serverSettings.SubmarineVoteRequiredRatio)
|
||||
if (no / (float)max > 1f - serverSettings.VoteRequiredRatio)
|
||||
{
|
||||
serverSettings.Voting.StopSubmarineVote(false);
|
||||
return; // Update will be re-sent via StopSubmarineVote
|
||||
Voting.ActiveVote.Finish(Voting, passed: false);
|
||||
}
|
||||
else if (SubmarineVoteYesCount / (float)SubmarineVoteMax >= serverSettings.SubmarineVoteRequiredRatio)
|
||||
else if (yes / max >= serverSettings.VoteRequiredRatio)
|
||||
{
|
||||
SwitchSubmarine();
|
||||
return; // Update will be re-sent via StopSubmarineVote
|
||||
}
|
||||
Voting.ActiveVote.Finish(Voting, passed: true);
|
||||
}
|
||||
}
|
||||
|
||||
Client.UpdateKickVotes(connectedClients);
|
||||
@@ -3279,10 +3251,12 @@ namespace Barotrauma.Networking
|
||||
|
||||
SendVoteStatus(connectedClients);
|
||||
|
||||
if (serverSettings.Voting.AllowEndVoting && EndVoteMax > 0 &&
|
||||
((float)EndVoteCount / (float)EndVoteMax) >= serverSettings.EndVoteRequiredRatio)
|
||||
int endVoteCount = ConnectedClients.Count(c => c.HasSpawned && c.GetVote<bool>(VoteType.EndRound));
|
||||
int endVoteMax = GameMain.Server.ConnectedClients.Count(c => c.HasSpawned);
|
||||
if (serverSettings.AllowEndVoting && endVoteMax > 0 &&
|
||||
((float)endVoteCount / (float)endVoteMax) >= serverSettings.EndVoteRequiredRatio)
|
||||
{
|
||||
Log("Ending round by votes (" + EndVoteCount + "/" + (EndVoteMax - EndVoteCount) + ")", ServerLog.MessageType.ServerMessage);
|
||||
Log("Ending round by votes (" + endVoteCount + "/" + (endVoteMax - endVoteCount) + ")", ServerLog.MessageType.ServerMessage);
|
||||
EndGame(wasSaved: false);
|
||||
}
|
||||
}
|
||||
@@ -3294,7 +3268,7 @@ namespace Barotrauma.Networking
|
||||
IWriteMessage msg = new WriteOnlyMessage();
|
||||
msg.Write((byte)ServerPacketHeader.UPDATE_LOBBY);
|
||||
msg.Write((byte)ServerNetObject.VOTE);
|
||||
serverSettings.Voting.ServerWrite(msg);
|
||||
Voting.ServerWrite(msg);
|
||||
msg.Write((byte)ServerNetObject.END_OF_MESSAGE);
|
||||
|
||||
foreach (var c in recipients)
|
||||
@@ -3303,11 +3277,13 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
private void SwitchSubmarine()
|
||||
public void SwitchSubmarine()
|
||||
{
|
||||
SubmarineInfo targetSubmarine = Voting.SubVote.Sub;
|
||||
VoteType voteType = Voting.SubVote.VoteType;
|
||||
Client starter = Voting.SubVote.VoteStarter;
|
||||
if (!(Voting.ActiveVote is Voting.SubmarineVote subVote)) { return; }
|
||||
|
||||
SubmarineInfo targetSubmarine = subVote.Sub;
|
||||
VoteType voteType = Voting.ActiveVote.VoteType;
|
||||
Client starter = Voting.ActiveVote.VoteStarter;
|
||||
int deliveryFee = 0;
|
||||
|
||||
switch (voteType)
|
||||
@@ -3318,7 +3294,7 @@ namespace Barotrauma.Networking
|
||||
GameMain.GameSession.PurchaseSubmarine(targetSubmarine, starter);
|
||||
break;
|
||||
case VoteType.SwitchSub:
|
||||
deliveryFee = Voting.SubVote.DeliveryFee;
|
||||
deliveryFee = subVote.DeliveryFee;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
@@ -3326,10 +3302,10 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (voteType != VoteType.PurchaseSub)
|
||||
{
|
||||
SubmarineInfo newSub = GameMain.GameSession.SwitchSubmarine(targetSubmarine, deliveryFee, starter);
|
||||
GameMain.GameSession.SwitchSubmarine(targetSubmarine, deliveryFee, starter);
|
||||
}
|
||||
|
||||
serverSettings.Voting.StopSubmarineVote(true);
|
||||
Voting.StopSubmarineVote(true);
|
||||
}
|
||||
|
||||
public void UpdateClientPermissions(Client client)
|
||||
|
||||
@@ -312,8 +312,8 @@ namespace Barotrauma.Networking
|
||||
|
||||
AutoRestart = doc.Root.GetAttributeBool("autorestart", false);
|
||||
|
||||
Voting.AllowSubVoting = SubSelectionMode == SelectionMode.Vote;
|
||||
Voting.AllowModeVoting = ModeSelectionMode == SelectionMode.Vote;
|
||||
AllowSubVoting = SubSelectionMode == SelectionMode.Vote;
|
||||
AllowModeVoting = ModeSelectionMode == SelectionMode.Vote;
|
||||
|
||||
selectedLevelDifficulty = doc.Root.GetAttributeFloat("LevelDifficulty", 20.0f);
|
||||
GameMain.NetLobbyScreen.SetLevelDifficulty(selectedLevelDifficulty);
|
||||
|
||||
@@ -7,59 +7,161 @@ namespace Barotrauma
|
||||
{
|
||||
partial class Voting
|
||||
{
|
||||
public bool AllowSubVoting
|
||||
public interface IVote
|
||||
{
|
||||
get { return allowSubVoting; }
|
||||
set { allowSubVoting = value; }
|
||||
}
|
||||
public bool AllowModeVoting
|
||||
{
|
||||
get { return allowModeVoting; }
|
||||
set { allowModeVoting = value; }
|
||||
}
|
||||
public Client VoteStarter { get; }
|
||||
public VoteType VoteType { get; }
|
||||
public float Timer { get; set; }
|
||||
|
||||
public struct SubmarineVote
|
||||
public VoteState State { get; set; }
|
||||
|
||||
public void Finish(Voting voting, bool passed);
|
||||
}
|
||||
|
||||
public class SubmarineVote : IVote
|
||||
{
|
||||
public Client VoteStarter;
|
||||
public Client VoteStarter { get; }
|
||||
public VoteType VoteType { get; }
|
||||
public float Timer { get; set; }
|
||||
|
||||
public VoteState State { get; set; }
|
||||
|
||||
public SubmarineInfo Sub;
|
||||
public VoteType VoteType;
|
||||
public float Timer;
|
||||
public int DeliveryFee;
|
||||
public VoteState State;
|
||||
|
||||
public SubmarineVote(Client starter, SubmarineInfo subInfo, int deliveryFee, VoteType voteType)
|
||||
{
|
||||
Sub = subInfo;
|
||||
DeliveryFee = deliveryFee;
|
||||
VoteType = voteType;
|
||||
State = VoteState.Started;
|
||||
VoteStarter = starter;
|
||||
}
|
||||
|
||||
public void Finish(Voting voting, bool passed)
|
||||
{
|
||||
if (passed)
|
||||
{
|
||||
GameMain.Server?.SwitchSubmarine();
|
||||
}
|
||||
voting.StopSubmarineVote(passed);
|
||||
}
|
||||
}
|
||||
|
||||
public static SubmarineVote SubVote;
|
||||
public static IVote ActiveVote;
|
||||
|
||||
public class TransferVote : IVote
|
||||
{
|
||||
public Client VoteStarter { get; }
|
||||
public VoteType VoteType { get; }
|
||||
public float Timer { get; set; }
|
||||
|
||||
public VoteState State { get; set; }
|
||||
|
||||
//null = bank
|
||||
public readonly Client From, To;
|
||||
public readonly int TransferAmount;
|
||||
|
||||
public TransferVote(Client starter, Client from, int transferAmount, Client to)
|
||||
{
|
||||
VoteStarter = starter;
|
||||
From = from;
|
||||
To = to;
|
||||
TransferAmount = transferAmount;
|
||||
State = VoteState.Started;
|
||||
VoteType = VoteType.TransferMoney;
|
||||
}
|
||||
|
||||
public void Finish(Voting voting, bool passed)
|
||||
{
|
||||
if (passed)
|
||||
{
|
||||
Wallet fromWallet = From == null ? (GameMain.GameSession.GameMode as MultiPlayerCampaign)?.Bank : From.Character?.Wallet;
|
||||
if (fromWallet.TryDeduct(TransferAmount))
|
||||
{
|
||||
Wallet toWallet = To == null ? (GameMain.GameSession.GameMode as MultiPlayerCampaign)?.Bank : To.Character?.Wallet;
|
||||
toWallet.Give(TransferAmount);
|
||||
}
|
||||
}
|
||||
voting.StopMoneyTransferVote(passed);
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly Queue<IVote> pendingVotes = new Queue<IVote>();
|
||||
|
||||
private void StartSubmarineVote(SubmarineInfo subInfo, VoteType voteType, Client sender)
|
||||
{
|
||||
SubVote.Sub = subInfo;
|
||||
SubVote.DeliveryFee = voteType == VoteType.SwitchSub ? GameMain.GameSession.Map.DistanceToClosestLocationWithOutpost(GameMain.GameSession.Map.CurrentLocation, out Location endLocation) : 0;
|
||||
SubVote.VoteType = voteType;
|
||||
SubVote.State = VoteState.Started;
|
||||
SubVote.VoteStarter = sender;
|
||||
VoteRunning = true;
|
||||
var subVote = new SubmarineVote(
|
||||
sender,
|
||||
subInfo,
|
||||
voteType == VoteType.SwitchSub ? GameMain.GameSession.Map.DistanceToClosestLocationWithOutpost(GameMain.GameSession.Map.CurrentLocation, out Location endLocation) : 0,
|
||||
voteType);
|
||||
StartOrEnqueueVote(subVote);
|
||||
sender.SetVote(voteType, 2);
|
||||
GameMain.Server.UpdateVoteStatus(checkActiveVote: false);
|
||||
}
|
||||
|
||||
public void StopSubmarineVote(bool passed)
|
||||
{
|
||||
VoteRunning = false;
|
||||
SubVote.State = passed ? VoteState.Passed : VoteState.Failed;
|
||||
if (!(ActiveVote is SubmarineVote)) { return; }
|
||||
StopActiveVote(passed);
|
||||
}
|
||||
|
||||
GameMain.Server.UpdateVoteStatus();
|
||||
public void StopMoneyTransferVote(bool passed)
|
||||
{
|
||||
if (!(ActiveVote is TransferVote)) { return; }
|
||||
StopActiveVote(passed);
|
||||
}
|
||||
|
||||
public void StopActiveVote(bool passed)
|
||||
{
|
||||
ActiveVote.State = passed ? VoteState.Passed : VoteState.Failed;
|
||||
GameMain.Server.UpdateVoteStatus(checkActiveVote: false);
|
||||
|
||||
GameMain.NetworkMember.SubmarineVoteYesCount = GameMain.NetworkMember.SubmarineVoteNoCount = GameMain.NetworkMember.SubmarineVoteMax = 0;
|
||||
for (int i = 0; i < GameMain.NetworkMember.ConnectedClients.Count; i++)
|
||||
{
|
||||
GameMain.NetworkMember.ConnectedClients[i].SetVote(SubVote.VoteType, 0);
|
||||
GameMain.NetworkMember.ConnectedClients[i].SetVote(ActiveVote.VoteType, 0);
|
||||
}
|
||||
|
||||
SubVote.Sub = null;
|
||||
SubVote.DeliveryFee = 0;
|
||||
SubVote.VoteType = VoteType.Unknown;
|
||||
SubVote.Timer = 0.0f;
|
||||
SubVote.State = VoteState.None;
|
||||
SubVote.VoteStarter = null;
|
||||
ActiveVote = null;
|
||||
if (pendingVotes.Any())
|
||||
{
|
||||
ActiveVote = pendingVotes.Dequeue();
|
||||
}
|
||||
}
|
||||
|
||||
public void StartTransferVote(Client starter, Client from, int transferAmount, Client to)
|
||||
{
|
||||
StartOrEnqueueVote(new TransferVote(starter, from, transferAmount, to));
|
||||
starter.SetVote(VoteType.TransferMoney, 2);
|
||||
GameMain.Server.UpdateVoteStatus(checkActiveVote: false);
|
||||
}
|
||||
|
||||
private void StartOrEnqueueVote(IVote vote)
|
||||
{
|
||||
if (ActiveVote == null)
|
||||
{
|
||||
ActiveVote = vote;
|
||||
}
|
||||
else
|
||||
{
|
||||
pendingVotes.Enqueue(vote);
|
||||
}
|
||||
}
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
if (ActiveVote == null) { return; }
|
||||
|
||||
ActiveVote.Timer += deltaTime;
|
||||
|
||||
if (ActiveVote.Timer >= GameMain.NetworkMember.ServerSettings.VoteTimeout)
|
||||
{
|
||||
// Do not take unanswered into account for total
|
||||
int yes = GameMain.Server.ConnectedClients.Count(c => c.InGame && c.GetVote<int>(ActiveVote.VoteType) == 2);
|
||||
int no = GameMain.Server.ConnectedClients.Count(c => c.InGame && c.GetVote<int>(ActiveVote.VoteType) == 1);
|
||||
ActiveVote.Finish(this, passed: yes / (float)(yes + no) >= GameMain.NetworkMember.ServerSettings.VoteRequiredRatio);
|
||||
}
|
||||
}
|
||||
|
||||
public void ServerRead(IReadMessage inc, Client sender)
|
||||
@@ -97,10 +199,6 @@ namespace Barotrauma
|
||||
case VoteType.EndRound:
|
||||
if (!sender.HasSpawned) { return; }
|
||||
sender.SetVote(voteType, inc.ReadBoolean());
|
||||
|
||||
GameMain.NetworkMember.EndVoteCount = GameMain.Server.ConnectedClients.Count(c => c.HasSpawned && c.GetVote<bool>(VoteType.EndRound));
|
||||
GameMain.NetworkMember.EndVoteMax = GameMain.Server.ConnectedClients.Count(c => c.HasSpawned);
|
||||
|
||||
break;
|
||||
case VoteType.Kick:
|
||||
byte kickedClientID = inc.ReadByte();
|
||||
@@ -126,24 +224,34 @@ namespace Barotrauma
|
||||
case VoteType.PurchaseAndSwitchSub:
|
||||
case VoteType.PurchaseSub:
|
||||
case VoteType.SwitchSub:
|
||||
case VoteType.TransferMoney:
|
||||
bool startVote = inc.ReadBoolean();
|
||||
if (startVote)
|
||||
{
|
||||
string subName = inc.ReadString();
|
||||
SubmarineInfo subInfo = SubmarineInfo.SavedSubmarines.FirstOrDefault(s => s.Name == subName);
|
||||
if (GameMain.GameSession?.Campaign is MultiPlayerCampaign campaign && (campaign.CanPurchaseSub(subInfo, sender) || GameMain.GameSession.IsSubmarineOwned(subInfo)))
|
||||
if (voteType == VoteType.TransferMoney)
|
||||
{
|
||||
StartSubmarineVote(subInfo, voteType, sender);
|
||||
int amount = inc.ReadInt32();
|
||||
int fromClientId = inc.ReadByte();
|
||||
int toClientId = inc.ReadByte();
|
||||
pendingVotes.Enqueue(new TransferVote(sender,
|
||||
GameMain.Server.ConnectedClients.Find(c => c.ID == fromClientId),
|
||||
amount,
|
||||
GameMain.Server.ConnectedClients.Find(c => c.ID == toClientId)));
|
||||
}
|
||||
else
|
||||
{
|
||||
string subName = inc.ReadString();
|
||||
SubmarineInfo subInfo = SubmarineInfo.SavedSubmarines.FirstOrDefault(s => s.Name == subName);
|
||||
if (GameMain.GameSession?.Campaign is MultiPlayerCampaign campaign && (campaign.CanPurchaseSub(subInfo, sender) || GameMain.GameSession.IsSubmarineOwned(subInfo)))
|
||||
{
|
||||
StartSubmarineVote(subInfo, voteType, sender);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sender.SetVote(voteType, (int)inc.ReadByte());
|
||||
}
|
||||
|
||||
GameMain.Server.SubmarineVoteYesCount = GameMain.Server.ConnectedClients.Count(c => c.GetVote<int>(SubVote.VoteType) == 2);
|
||||
GameMain.Server.SubmarineVoteNoCount = GameMain.Server.ConnectedClients.Count(c => c.GetVote<int>(SubVote.VoteType) == 1);
|
||||
GameMain.Server.SubmarineVoteMax = GameMain.Server.ConnectedClients.Count(c => c.InGame);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -154,10 +262,10 @@ namespace Barotrauma
|
||||
|
||||
public void ServerWrite(IWriteMessage msg)
|
||||
{
|
||||
if (GameMain.Server == null) return;
|
||||
if (GameMain.Server == null) { return; }
|
||||
|
||||
msg.Write(allowSubVoting);
|
||||
if (allowSubVoting)
|
||||
msg.Write(GameMain.Server.ServerSettings.AllowSubVoting);
|
||||
if (GameMain.Server.ServerSettings.AllowSubVoting)
|
||||
{
|
||||
IReadOnlyDictionary<SubmarineInfo, int> voteList = GetVoteCounts<SubmarineInfo>(VoteType.Sub, GameMain.Server.ConnectedClients);
|
||||
msg.Write((byte)voteList.Count);
|
||||
@@ -167,8 +275,8 @@ namespace Barotrauma
|
||||
msg.Write(vote.Key.Name);
|
||||
}
|
||||
}
|
||||
msg.Write(AllowModeVoting);
|
||||
if (allowModeVoting)
|
||||
msg.Write(GameMain.Server.ServerSettings.AllowModeVoting);
|
||||
if (GameMain.Server.ServerSettings.AllowModeVoting)
|
||||
{
|
||||
IReadOnlyDictionary<GameModePreset, int> voteList = GetVoteCounts<GameModePreset>(VoteType.Mode, GameMain.Server.ConnectedClients);
|
||||
msg.Write((byte)voteList.Count);
|
||||
@@ -178,60 +286,78 @@ namespace Barotrauma
|
||||
msg.Write(vote.Key.Identifier);
|
||||
}
|
||||
}
|
||||
msg.Write(AllowEndVoting);
|
||||
if (AllowEndVoting)
|
||||
msg.Write(GameMain.Server.ServerSettings.AllowEndVoting);
|
||||
if (GameMain.Server.ServerSettings.AllowEndVoting)
|
||||
{
|
||||
msg.Write((byte)GameMain.Server.ConnectedClients.Count(c => c.HasSpawned && c.GetVote<bool>(VoteType.EndRound)));
|
||||
msg.Write((byte)GameMain.Server.ConnectedClients.Count(c => c.HasSpawned));
|
||||
}
|
||||
|
||||
msg.Write(AllowVoteKick);
|
||||
msg.Write(GameMain.Server.ServerSettings.AllowVoteKick);
|
||||
|
||||
msg.Write((byte)SubVote.State);
|
||||
if (SubVote.State != VoteState.None)
|
||||
msg.Write((byte)(ActiveVote?.State ?? VoteState.None));
|
||||
if (ActiveVote != null)
|
||||
{
|
||||
msg.Write((byte)SubVote.VoteType);
|
||||
|
||||
if (SubVote.VoteType != VoteType.Unknown)
|
||||
{
|
||||
var yesClients = GameMain.Server.ConnectedClients.FindAll(c => c.GetVote<int>(SubVote.VoteType) == 2);
|
||||
msg.Write((byte)ActiveVote.VoteType);
|
||||
if (ActiveVote.State != VoteState.None && ActiveVote.VoteType != VoteType.Unknown)
|
||||
{
|
||||
var yesClients = GameMain.Server.ConnectedClients.FindAll(c => c.InGame && c.GetVote<int>(ActiveVote.VoteType) == 2);
|
||||
msg.Write((byte)yesClients.Count);
|
||||
foreach (Client c in yesClients)
|
||||
{
|
||||
msg.Write(c.ID);
|
||||
}
|
||||
|
||||
var noClients = GameMain.Server.ConnectedClients.FindAll(c => c.GetVote<int>(SubVote.VoteType) == 1);
|
||||
var noClients = GameMain.Server.ConnectedClients.FindAll(c => c.InGame && c.GetVote<int>(ActiveVote.VoteType) == 1);
|
||||
msg.Write((byte)noClients.Count);
|
||||
foreach (Client c in noClients)
|
||||
{
|
||||
msg.Write(c.ID);
|
||||
}
|
||||
|
||||
msg.Write((byte)GameMain.Server.SubmarineVoteMax);
|
||||
msg.Write((byte)GameMain.Server.ConnectedClients.Count(c => c.InGame));
|
||||
|
||||
switch (SubVote.State)
|
||||
switch (ActiveVote.State)
|
||||
{
|
||||
case VoteState.Started:
|
||||
msg.Write(SubVote.Sub.Name);
|
||||
msg.Write(SubVote.VoteStarter.ID);
|
||||
msg.Write((byte)GameMain.Server.ServerSettings.SubmarineVoteTimeout);
|
||||
msg.Write(ActiveVote.VoteStarter.ID);
|
||||
msg.Write((byte)GameMain.Server.ServerSettings.VoteTimeout);
|
||||
|
||||
switch (ActiveVote.VoteType)
|
||||
{
|
||||
case VoteType.PurchaseSub:
|
||||
case VoteType.PurchaseAndSwitchSub:
|
||||
case VoteType.SwitchSub:
|
||||
msg.Write((ActiveVote as SubmarineVote).Sub.Name);
|
||||
break;
|
||||
case VoteType.TransferMoney:
|
||||
var transferVote = (ActiveVote as TransferVote);
|
||||
msg.Write(transferVote.From?.ID ?? 0);
|
||||
msg.Write(transferVote.To?.ID ?? 0);
|
||||
msg.Write(transferVote.TransferAmount);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case VoteState.Running:
|
||||
// Nothing specific
|
||||
break;
|
||||
case VoteState.Passed:
|
||||
case VoteState.Failed:
|
||||
msg.Write(SubVote.State == VoteState.Passed);
|
||||
msg.Write(SubVote.Sub.Name);
|
||||
if (SubVote.State == VoteState.Passed)
|
||||
msg.Write(ActiveVote.State == VoteState.Passed);
|
||||
switch (ActiveVote.VoteType)
|
||||
{
|
||||
msg.Write((short)SubVote.DeliveryFee);
|
||||
case VoteType.PurchaseSub:
|
||||
case VoteType.PurchaseAndSwitchSub:
|
||||
case VoteType.SwitchSub:
|
||||
msg.Write((ActiveVote as SubmarineVote).Sub.Name);
|
||||
msg.Write((short)(ActiveVote as SubmarineVote).DeliveryFee);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var readyClients = GameMain.Server.ConnectedClients.FindAll(c => c.GetVote<bool>(VoteType.StartRound));
|
||||
msg.Write((byte)readyClients.Count);
|
||||
|
||||
@@ -192,7 +192,7 @@ namespace Barotrauma
|
||||
public override void Select()
|
||||
{
|
||||
base.Select();
|
||||
GameMain.Server.ServerSettings.Voting.ResetVotes(GameMain.Server.ConnectedClients);
|
||||
GameMain.Server.Voting.ResetVotes(GameMain.Server.ConnectedClients);
|
||||
if (SelectedMode != GameModePreset.MultiPlayerCampaign && GameMain.GameSession?.GameMode is CampaignMode && Selected == this)
|
||||
{
|
||||
GameMain.GameSession = null;
|
||||
|
||||
Reference in New Issue
Block a user