Unstable 0.17.5.0
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user