diff --git a/KMPClientMain.cs b/KMPClientMain.cs index 1143c3a..6f692cc 100644 --- a/KMPClientMain.cs +++ b/KMPClientMain.cs @@ -841,10 +841,11 @@ static void handleMessage(KMPCommon.ServerMessageID id, byte[] data) { String server_version = encoder.GetString(data, 8, server_version_length); clientID = KMPCommon.intFromBytes(data, 8 + server_version_length); - gameManager.gameMode = KMPCommon.intFromBytes(data, 12 + server_version_length); - int kmpModControl_length = KMPCommon.intFromBytes(data, 16 + server_version_length); + gameManager.gameMode = KMPCommon.intFromBytes(data, 12 + server_version_length); + gameManager.numberOfShips = KMPCommon.intFromBytes(data, 16 + server_version_length); + int kmpModControl_length = KMPCommon.intFromBytes(data, 20 + server_version_length); kmpModControl_bytes = new byte[kmpModControl_length]; - Array.Copy(data, 20 + server_version_length, kmpModControl_bytes, 0, kmpModControl_length); + Array.Copy(data, 24 + server_version_length, kmpModControl_bytes, 0, kmpModControl_length); SetMessage("Handshake received. Server version: " + server_version); } } diff --git a/KMPManager.cs b/KMPManager.cs index 99ab5bb..46e44ea 100644 --- a/KMPManager.cs +++ b/KMPManager.cs @@ -153,6 +153,7 @@ public struct VesselStatusInfo public static object interopInQueueLock = new object(); + public int numberOfShips = 0; public int gameMode = 0; //0=Sandbox, 1=Career public bool gameCheatsEnabled = false; //Allow built-in KSP cheats public bool gameArrr = false; //Allow private vessels to be taken if other user can successfully dock manually @@ -183,6 +184,7 @@ public struct VesselStatusInfo private const int SYNC_TIME_VALID_COUNT = 4; //Number of SYNC_TIME's to receive until time is valid. private const int MAX_TIME_SYNC_HISTORY = 10; //The last 10 SYNC_TIME's are used for the offset filter. private ScreenMessage skewMessage; + private ScreenMessage vesselLoadedMessage; private Queue vesselUpdateQueue = new Queue(); private Queue newVesselUpdateQueue = new Queue(); @@ -258,6 +260,7 @@ public struct VesselStatusInfo private Vessel lastEVAVessel = null; private bool showServerSync = false; private bool inGameSyncing = false; + private List vesselUpdatesLoaded = new List(); private bool configRead = false; @@ -359,7 +362,16 @@ public void updateStep() if (syncing) { ScreenMessages.PostScreenMessage("Synchronizing universe, please wait...",1f,ScreenMessageStyle.UPPER_CENTER); - ScreenMessages.PostScreenMessage("Loaded vessels: " + FlightGlobals.Vessels.Count,0.04f,ScreenMessageStyle.UPPER_RIGHT); + if (vesselLoadedMessage != null) { + vesselLoadedMessage.duration = 0f; + } + if (!inGameSyncing) { + if (numberOfShips != 0) { + vesselLoadedMessage = ScreenMessages.PostScreenMessage("Loaded vessels: " + vesselUpdatesLoaded.Count + "/" + numberOfShips + " (" + (vesselUpdatesLoaded.Count * 100 / numberOfShips) + "%)",1f,ScreenMessageStyle.UPPER_RIGHT); + } + } else { + vesselLoadedMessage = ScreenMessages.PostScreenMessage("Loaded vessels: " + FlightGlobals.Vessels.Count,1f,ScreenMessageStyle.UPPER_RIGHT); + } } if (!isInFlight && HighLogic.LoadedScene == GameScenes.TRACKSTATION) @@ -2668,6 +2680,10 @@ private void addRemoteVessel(ProtoVessel protovessel, Guid vessel_id, KMPVessel if (protovessel.vesselType == VesselType.Flag) { Invoke("ClearFlagLock", 5f); } + if (!vesselUpdatesLoaded.Contains(vessel_id)) + { + vesselUpdatesLoaded.Add(vessel_id); + } Vector3 newWorldPos = Vector3.zero, newOrbitVel = Vector3.zero; bool setTarget = false, wasLoaded = false, wasActive = false; Vessel oldVessel = null; @@ -3547,6 +3563,9 @@ private void SkewTime () double currentErrorMs = Math.Round (currentError * 1000, 2); if (Math.Abs (currentError) > 5) { + if (skewMessage != null) { + skewMessage.duration = 0f; + } if (isInFlight) { krakensBaneWarp(skewTargetTick + timeFromLastSyncSecondsAdjusted); } else { @@ -4447,7 +4466,8 @@ private void connectionWindow(int windowID) HighLogic.CurrentGame.Title = "KMP"; HighLogic.CurrentGame.Description = "Kerbal Multi Player session"; HighLogic.CurrentGame.flagURL = "KMP/Flags/default"; - + vesselUpdatesLoaded.Clear(); + if (gameMode == 1) //Career mode HighLogic.CurrentGame.Mode = Game.Modes.CAREER; diff --git a/KMPServer/Server.cs b/KMPServer/Server.cs index c129a03..7052460 100644 --- a/KMPServer/Server.cs +++ b/KMPServer/Server.cs @@ -885,6 +885,35 @@ private void countShipsServerCommand(bool bList = false) } + private int countShipsInDatabase() + { + var universeDB = KMPServer.Server.universeDB; + if (settings.useMySQL) { + universeDB = new MySqlConnection(settings.mySQLConnString); + universeDB.Open(); + } + DbCommand cmd = universeDB.CreateCommand(); + String sql = "SELECT vu.UpdateMessage, v.ProtoVessel, v.Guid" + + " FROM kmpVesselUpdate vu" + + " INNER JOIN kmpVessel v ON v.Guid = vu.Guid AND v.Destroyed != 1" + + " INNER JOIN kmpSubspace s ON s.ID = vu.Subspace" + + " INNER JOIN" + + " (SELECT vu.Guid, MAX(s.LastTick) AS LastTick" + + " FROM kmpVesselUpdate vu" + + " INNER JOIN kmpSubspace s ON s.ID = vu.Subspace" + + " GROUP BY vu.Guid) t ON t.Guid = vu.Guid AND t.LastTick = s.LastTick;"; + cmd.CommandText = sql; + DbDataReader reader = cmd.ExecuteReader(); + int count = 0; + while (reader.Read()) + { + count++; + } + reader.Dispose(); + if (settings.useMySQL) universeDB.Close(); + return count; + } + private void listShipsServerCommand() { countShipsServerCommand(true); @@ -2934,7 +2963,7 @@ private void sendHandshakeMessage(Client cl) byte[] version_bytes = encoder.GetBytes(KMPCommon.PROGRAM_VERSION); - byte[] data_bytes = new byte[version_bytes.Length + 20 + kmpModControl.Length + 1]; + byte[] data_bytes = new byte[version_bytes.Length + 24 + kmpModControl.Length + 1]; //Write net protocol version KMPCommon.intToBytes(KMPCommon.NET_PROTOCOL_VERSION).CopyTo(data_bytes, 0); @@ -2947,12 +2976,15 @@ private void sendHandshakeMessage(Client cl) //Write client ID KMPCommon.intToBytes(cl.clientIndex).CopyTo(data_bytes, 8 + version_bytes.Length); - - //Write gameMode + + //Write gameMode KMPCommon.intToBytes(settings.gameMode).CopyTo(data_bytes, 12 + version_bytes.Length); - - KMPCommon.intToBytes(kmpModControl.Length).CopyTo(data_bytes, 16 + version_bytes.Length); - kmpModControl.CopyTo(data_bytes, 20 + version_bytes.Length); + + //Write number of ships in initial sync + KMPCommon.intToBytes(countShipsInDatabase()).CopyTo(data_bytes, 16 + version_bytes.Length); + + KMPCommon.intToBytes(kmpModControl.Length).CopyTo(data_bytes, 20 + version_bytes.Length); + kmpModControl.CopyTo(data_bytes, 24 + version_bytes.Length); cl.queueOutgoingMessage(KMPCommon.ServerMessageID.HANDSHAKE, data_bytes); }