The server can start the game
This commit is contained in:
@@ -637,20 +637,6 @@ namespace Barotrauma
|
|||||||
if (!(c.AIController is EnemyAIController)) continue;
|
if (!(c.AIController is EnemyAIController)) continue;
|
||||||
c.AddDamage(CauseOfDeath.Damage, 10000.0f, null);
|
c.AddDamage(CauseOfDeath.Damage, 10000.0f, null);
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case "sendrandomdata":
|
|
||||||
int messageCount = 1;
|
|
||||||
|
|
||||||
if (commands.Length > 1) int.TryParse(commands[1], out messageCount);
|
|
||||||
|
|
||||||
for (int i = 0; i < messageCount; i++)
|
|
||||||
{
|
|
||||||
if (GameMain.Server != null)
|
|
||||||
{
|
|
||||||
GameMain.Server.SendRandomData();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "netstats":
|
case "netstats":
|
||||||
if (GameMain.Server == null) return;
|
if (GameMain.Server == null) return;
|
||||||
|
|||||||
@@ -513,12 +513,87 @@ namespace Barotrauma.Networking
|
|||||||
case ServerPacketHeader.UPDATE_LOBBY:
|
case ServerPacketHeader.UPDATE_LOBBY:
|
||||||
ReadLobbyUpdate(inc);
|
ReadLobbyUpdate(inc);
|
||||||
break;
|
break;
|
||||||
|
case ServerPacketHeader.QUERY_STARTGAME:
|
||||||
|
string subName = inc.ReadString();
|
||||||
|
string subHash = inc.ReadString();
|
||||||
|
|
||||||
|
string shuttleName = inc.ReadString();
|
||||||
|
string shuttleHash = inc.ReadString();
|
||||||
|
|
||||||
|
NetOutgoingMessage readyToStartMsg = client.CreateMessage();
|
||||||
|
readyToStartMsg.Write((byte)ClientPacketHeader.RESPONSE_STARTGAME);
|
||||||
|
|
||||||
|
readyToStartMsg.Write(
|
||||||
|
GameMain.NetLobbyScreen.TrySelectSub(subName, subHash, GameMain.NetLobbyScreen.SubList) &&
|
||||||
|
GameMain.NetLobbyScreen.TrySelectSub(shuttleName, shuttleHash, GameMain.NetLobbyScreen.ShuttleList.ListBox));
|
||||||
|
|
||||||
|
client.SendMessage(readyToStartMsg, NetDeliveryMethod.ReliableUnordered);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case ServerPacketHeader.STARTGAME:
|
||||||
|
startGameCoroutine = GameMain.ShowLoading(StartGame(inc), false);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IEnumerable<object> StartGame(NetIncomingMessage inc)
|
||||||
|
{
|
||||||
|
if (Character != null) Character.Remove();
|
||||||
|
|
||||||
|
endVoteTickBox.Selected = false;
|
||||||
|
|
||||||
|
int seed = inc.ReadInt32();
|
||||||
|
string levelSeed = inc.ReadString();
|
||||||
|
|
||||||
|
int missionTypeIndex = inc.ReadByte();
|
||||||
|
|
||||||
|
string subName = inc.ReadString();
|
||||||
|
string subHash = inc.ReadString();
|
||||||
|
|
||||||
|
string shuttleName = inc.ReadString();
|
||||||
|
string shuttleHash = inc.ReadString();
|
||||||
|
|
||||||
|
string modeName = inc.ReadString();
|
||||||
|
|
||||||
|
bool respawnAllowed = inc.ReadBoolean();
|
||||||
|
|
||||||
|
GameModePreset gameMode = GameModePreset.list.Find(gm => gm.Name == modeName);
|
||||||
|
|
||||||
|
if (gameMode == null)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError("Game mode ''" + modeName + "'' not found!");
|
||||||
|
yield return CoroutineStatus.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GameMain.NetLobbyScreen.TrySelectSub(subName, subHash, GameMain.NetLobbyScreen.SubList))
|
||||||
|
{
|
||||||
|
yield return CoroutineStatus.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GameMain.NetLobbyScreen.TrySelectSub(shuttleName, shuttleHash, GameMain.NetLobbyScreen.ShuttleList.ListBox))
|
||||||
|
{
|
||||||
|
yield return CoroutineStatus.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rand.SetSyncedSeed(seed);
|
||||||
|
|
||||||
|
GameMain.GameSession = new GameSession(GameMain.NetLobbyScreen.SelectedSub, "", gameMode, Mission.MissionTypes[missionTypeIndex]);
|
||||||
|
GameMain.GameSession.StartShift(levelSeed);
|
||||||
|
|
||||||
|
if (respawnAllowed) respawnManager = new RespawnManager(this, GameMain.NetLobbyScreen.SelectedShuttle);
|
||||||
|
|
||||||
|
gameStarted = true;
|
||||||
|
|
||||||
|
endVoteTickBox.Visible = Voting.AllowEndVoting && myCharacter != null;
|
||||||
|
|
||||||
|
GameMain.GameScreen.Select();
|
||||||
|
|
||||||
|
yield return CoroutineStatus.Success;
|
||||||
|
}
|
||||||
|
|
||||||
private void ReadLobbyUpdate(NetIncomingMessage inc)
|
private void ReadLobbyUpdate(NetIncomingMessage inc)
|
||||||
{
|
{
|
||||||
ServerNetObject objHeader;
|
ServerNetObject objHeader;
|
||||||
|
|||||||
@@ -368,29 +368,7 @@ namespace Barotrauma.Networking
|
|||||||
switch (inc.MessageType)
|
switch (inc.MessageType)
|
||||||
{
|
{
|
||||||
case NetIncomingMessageType.Data:
|
case NetIncomingMessageType.Data:
|
||||||
if (banList.IsBanned(inc.SenderEndPoint.Address.ToString()))
|
ReadDataMessage(inc);
|
||||||
{
|
|
||||||
KickClient(inc.SenderConnection,true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ClientPacketHeader header = (ClientPacketHeader)inc.ReadByte();
|
|
||||||
switch (header)
|
|
||||||
{
|
|
||||||
case ClientPacketHeader.REQUEST_AUTH:
|
|
||||||
ClientAuthRequest(inc.SenderConnection);
|
|
||||||
break;
|
|
||||||
case ClientPacketHeader.REQUEST_INIT:
|
|
||||||
ClientInitRequest(inc);
|
|
||||||
break;
|
|
||||||
case ClientPacketHeader.UPDATE_LOBBY:
|
|
||||||
ClientReadLobby(inc);
|
|
||||||
break;
|
|
||||||
case ClientPacketHeader.UPDATE_INGAME:
|
|
||||||
//TODO
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case NetIncomingMessageType.StatusChanged:
|
case NetIncomingMessageType.StatusChanged:
|
||||||
switch (inc.SenderConnection.Status)
|
switch (inc.SenderConnection.Status)
|
||||||
@@ -427,8 +405,8 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
@@ -498,6 +476,40 @@ namespace Barotrauma.Networking
|
|||||||
refreshMasterTimer = DateTime.Now + refreshMasterInterval;
|
refreshMasterTimer = DateTime.Now + refreshMasterInterval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ReadDataMessage(NetIncomingMessage inc)
|
||||||
|
{
|
||||||
|
if (banList.IsBanned(inc.SenderEndPoint.Address.ToString()))
|
||||||
|
{
|
||||||
|
KickClient(inc.SenderConnection, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientPacketHeader header = (ClientPacketHeader)inc.ReadByte();
|
||||||
|
switch (header)
|
||||||
|
{
|
||||||
|
case ClientPacketHeader.REQUEST_AUTH:
|
||||||
|
ClientAuthRequest(inc.SenderConnection);
|
||||||
|
break;
|
||||||
|
case ClientPacketHeader.REQUEST_INIT:
|
||||||
|
ClientInitRequest(inc);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ClientPacketHeader.RESPONSE_STARTGAME:
|
||||||
|
var connectedClient = connectedClients.Find(c => c.Connection == inc.SenderConnection);
|
||||||
|
if (connectedClient != null)
|
||||||
|
{
|
||||||
|
connectedClient.ReadyToStart = inc.ReadBoolean();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ClientPacketHeader.UPDATE_LOBBY:
|
||||||
|
ClientReadLobby(inc);
|
||||||
|
break;
|
||||||
|
case ClientPacketHeader.UPDATE_INGAME:
|
||||||
|
//TODO
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void SparseUpdate()
|
private void SparseUpdate()
|
||||||
{
|
{
|
||||||
//if (gameStarted)
|
//if (gameStarted)
|
||||||
@@ -703,11 +715,117 @@ namespace Barotrauma.Networking
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//CoroutineManager.StartCoroutine(WaitForPlayersReady(selectedSub, selectedShuttle, selectedMode), "WaitForPlayersReady");
|
CoroutineManager.StartCoroutine(InitiateStartGame(selectedSub, selectedShuttle, selectedMode), "InitiateStartGame");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IEnumerable<object> InitiateStartGame(Submarine selectedSub, Submarine selectedShuttle, GameModePreset selectedMode)
|
||||||
|
{
|
||||||
|
GameMain.NetLobbyScreen.StartButton.Enabled = false;
|
||||||
|
|
||||||
|
NetOutgoingMessage msg = server.CreateMessage();
|
||||||
|
msg.Write((byte)ServerPacketHeader.QUERY_STARTGAME);
|
||||||
|
|
||||||
|
msg.Write(selectedSub.Name);
|
||||||
|
msg.Write(selectedSub.MD5Hash.Hash);
|
||||||
|
|
||||||
|
msg.Write(selectedShuttle.Name);
|
||||||
|
msg.Write(selectedShuttle.MD5Hash.Hash);
|
||||||
|
|
||||||
|
connectedClients.ForEach(c => c.ReadyToStart = false);
|
||||||
|
|
||||||
|
server.SendMessage(msg, connectedClients.Select(c => c.Connection).ToList(), NetDeliveryMethod.ReliableUnordered, 0);
|
||||||
|
|
||||||
|
//give the clients a few seconds to request missing sub/shuttle files before starting the round
|
||||||
|
float waitForResponseTimer = 3.0f;
|
||||||
|
while (connectedClients.Any(c => !c.ReadyToStart) && waitForResponseTimer > 0.0f)
|
||||||
|
{
|
||||||
|
waitForResponseTimer -= CoroutineManager.UnscaledDeltaTime;
|
||||||
|
yield return CoroutineStatus.Running;
|
||||||
|
}
|
||||||
|
|
||||||
|
//todo: wait until file transfers are finished/cancelled
|
||||||
|
|
||||||
|
GameMain.ShowLoading(StartGame(selectedSub, selectedShuttle, selectedMode), false);
|
||||||
|
|
||||||
|
yield return CoroutineStatus.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerable<object> StartGame(Submarine selectedSub, Submarine selectedShuttle, GameModePreset selectedMode)
|
||||||
|
{
|
||||||
|
Item.Spawner.Clear();
|
||||||
|
Item.Remover.Clear();
|
||||||
|
|
||||||
|
GameMain.NetLobbyScreen.StartButton.Enabled = false;
|
||||||
|
|
||||||
|
GUIMessageBox.CloseAll();
|
||||||
|
|
||||||
|
//AssignJobs(connectedClients);
|
||||||
|
|
||||||
|
roundStartSeed = DateTime.Now.Millisecond;
|
||||||
|
Rand.SetSyncedSeed(roundStartSeed);
|
||||||
|
|
||||||
|
GameMain.GameSession = new GameSession(selectedSub, "", selectedMode, Mission.MissionTypes[GameMain.NetLobbyScreen.MissionTypeIndex]);
|
||||||
|
GameMain.GameSession.StartShift(GameMain.NetLobbyScreen.LevelSeed);
|
||||||
|
|
||||||
|
GameServer.Log("Starting a new round...", Color.Cyan);
|
||||||
|
GameServer.Log("Submarine: " + selectedSub.Name, Color.Cyan);
|
||||||
|
GameServer.Log("Game mode: " + selectedMode.Name, Color.Cyan);
|
||||||
|
GameServer.Log("Level seed: " + GameMain.NetLobbyScreen.LevelSeed, Color.Cyan);
|
||||||
|
|
||||||
|
if (AllowRespawn) respawnManager = new RespawnManager(this, selectedShuttle);
|
||||||
|
|
||||||
|
var startMessage = CreateStartMessage(roundStartSeed, Submarine.MainSub, GameMain.GameSession.gameMode.Preset);
|
||||||
|
server.SendMessage(startMessage, connectedClients.Select(c => c.Connection).ToList(), NetDeliveryMethod.ReliableUnordered, 0);
|
||||||
|
|
||||||
|
yield return CoroutineStatus.Running;
|
||||||
|
|
||||||
|
//UpdateCrewFrame();
|
||||||
|
|
||||||
|
//TraitorManager = null;
|
||||||
|
//if (TraitorsEnabled == YesNoMaybe.Yes ||
|
||||||
|
// (TraitorsEnabled == YesNoMaybe.Maybe && Rand.Range(0.0f, 1.0f) < 0.5f))
|
||||||
|
//{
|
||||||
|
// TraitorManager = new TraitorManager(this);
|
||||||
|
//}
|
||||||
|
|
||||||
|
GameMain.GameScreen.Cam.TargetPos = Vector2.Zero;
|
||||||
|
GameMain.GameScreen.Select();
|
||||||
|
|
||||||
|
AddChatMessage("Press TAB to chat. Use ''r;'' to talk through the radio.", ChatMessageType.Server);
|
||||||
|
|
||||||
|
GameMain.NetLobbyScreen.StartButton.Enabled = true;
|
||||||
|
|
||||||
|
gameStarted = true;
|
||||||
|
|
||||||
|
yield return CoroutineStatus.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
private NetOutgoingMessage CreateStartMessage(int seed, Submarine selectedSub, GameModePreset selectedMode)
|
||||||
|
{
|
||||||
|
NetOutgoingMessage msg = server.CreateMessage();
|
||||||
|
msg.Write((byte)ServerPacketHeader.STARTGAME);
|
||||||
|
|
||||||
|
msg.Write(seed);
|
||||||
|
|
||||||
|
msg.Write(GameMain.NetLobbyScreen.LevelSeed);
|
||||||
|
|
||||||
|
msg.Write((byte)GameMain.NetLobbyScreen.MissionTypeIndex);
|
||||||
|
|
||||||
|
msg.Write(selectedSub.Name);
|
||||||
|
msg.Write(selectedSub.MD5Hash.Hash);
|
||||||
|
|
||||||
|
msg.Write(GameMain.NetLobbyScreen.SelectedShuttle.Name);
|
||||||
|
msg.Write(GameMain.NetLobbyScreen.SelectedShuttle.MD5Hash.Hash);
|
||||||
|
|
||||||
|
msg.Write(selectedMode.Name);
|
||||||
|
|
||||||
|
msg.Write(AllowRespawn);
|
||||||
|
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
public void EndGame()
|
public void EndGame()
|
||||||
{
|
{
|
||||||
if (!gameStarted) return;
|
if (!gameStarted) return;
|
||||||
@@ -1135,15 +1253,6 @@ namespace Barotrauma.Networking
|
|||||||
GameMain.Server.log.WriteLine(line, color);
|
GameMain.Server.log.WriteLine(line, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// sends some random data to the clients
|
|
||||||
/// use for debugging purposes
|
|
||||||
/// </summary>
|
|
||||||
public void SendRandomData()
|
|
||||||
{
|
|
||||||
//NO DON'T DO THIS WHY
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Disconnect()
|
public override void Disconnect()
|
||||||
{
|
{
|
||||||
banList.Save();
|
banList.Save();
|
||||||
|
|||||||
@@ -11,27 +11,32 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
enum ClientPacketHeader
|
enum ClientPacketHeader
|
||||||
{
|
{
|
||||||
REQUEST_AUTH, //ask the server if a password is needed, if so we'll get nonce for encryption
|
REQUEST_AUTH, //ask the server if a password is needed, if so we'll get nonce for encryption
|
||||||
REQUEST_INIT, //ask the server to give you initialization
|
REQUEST_INIT, //ask the server to give you initialization
|
||||||
UPDATE_LOBBY, //update state in lobby
|
UPDATE_LOBBY, //update state in lobby
|
||||||
UPDATE_INGAME, //update state ingame while alive
|
UPDATE_INGAME, //update state ingame while alive
|
||||||
|
|
||||||
|
RESPONSE_STARTGAME //tell the server whether you're ready to start
|
||||||
}
|
}
|
||||||
enum ClientNetObject
|
enum ClientNetObject
|
||||||
{
|
{
|
||||||
END_OF_MESSAGE, //self-explanatory
|
END_OF_MESSAGE, //self-explanatory
|
||||||
SYNC_IDS, //ids of the last changes the client knows about
|
SYNC_IDS, //ids of the last changes the client knows about
|
||||||
CHAT_MESSAGE, //also self-explanatory
|
CHAT_MESSAGE, //also self-explanatory
|
||||||
VOTE, //you get the idea
|
VOTE, //you get the idea
|
||||||
CHARACTER_INPUT,
|
CHARACTER_INPUT,
|
||||||
ITEM_INTERACTION
|
ITEM_INTERACTION
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ServerPacketHeader
|
enum ServerPacketHeader
|
||||||
{
|
{
|
||||||
AUTH_RESPONSE, //tell the player if they require a password to log in
|
AUTH_RESPONSE, //tell the player if they require a password to log in
|
||||||
AUTH_FAILURE, //the server won't authorize player yet, however connection is still alive
|
AUTH_FAILURE, //the server won't authorize player yet, however connection is still alive
|
||||||
UPDATE_LOBBY, //update state in lobby (votes and chat messages)
|
UPDATE_LOBBY, //update state in lobby (votes and chat messages)
|
||||||
UPDATE_INGAME, //update state ingame while alive (character input and chat messages)
|
UPDATE_INGAME, //update state ingame while alive (character input and chat messages)
|
||||||
|
|
||||||
|
QUERY_STARTGAME, //ask the clients whether they're ready to start
|
||||||
|
STARTGAME //start a new round
|
||||||
}
|
}
|
||||||
enum ServerNetObject
|
enum ServerNetObject
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user