public void Save() { if ((HighLogic.LoadedScene == GameScenes.FLIGHT) && (FlightGlobals.fetch.activeVessel != null)) { if (FlightGlobals.fetch.activeVessel.loaded && !FlightGlobals.fetch.activeVessel.packed) { if (FlightGlobals.fetch.activeVessel.situation != Vessel.Situations.FLYING) { savedVessel = new ConfigNode(); ProtoVessel tempVessel = new ProtoVessel(FlightGlobals.fetch.activeVessel); tempVessel.Save(savedVessel); savedSubspace = new Subspace(); savedSubspace.planetTime = Planetarium.GetUniversalTime(); savedSubspace.serverClock = TimeSyncer.fetch.GetServerClock(); savedSubspace.subspaceSpeed = 1f; ScreenMessages.PostScreenMessage("Quicksaved!", 3f, ScreenMessageStyle.UPPER_CENTER); } else { ScreenMessages.PostScreenMessage("Cannot quicksave - Active vessel is in flight!", 3f, ScreenMessageStyle.UPPER_CENTER); } } else { ScreenMessages.PostScreenMessage("Cannot quicksave - Active vessel is not loaded!", 3f, ScreenMessageStyle.UPPER_CENTER); } } else { ScreenMessages.PostScreenMessage("Cannot quicksave - Not in flight!", 3f, ScreenMessageStyle.UPPER_CENTER); } }
private static void SaveSubspace(int subspaceID, Subspace subspace) { string subspaceFile = Path.Combine(Server.universeDirectory, "subspace.txt"); using (StreamWriter sw = new StreamWriter(subspaceFile)) { sw.WriteLine("#Incorrectly editing this file will cause weirdness. If there is any errors, the universe time will be reset."); sw.WriteLine("#This file can only be edited if the server is stopped."); sw.WriteLine("#Each variable is on a new line. They are subspaceID, server clock (from DateTime.UtcNow.Ticks), universe time, and subspace speed."); sw.WriteLine(subspaceID); sw.WriteLine(subspace.serverClock); sw.WriteLine(subspace.planetTime); sw.WriteLine(subspace.subspaceSpeed); } }
private static void HandleWarpControl(ClientObject client, byte[] messageData) { ServerMessage newMessage = new ServerMessage(); newMessage.type = ServerMessageType.WARP_CONTROL; newMessage.data = messageData; using (MessageReader mr = new MessageReader(messageData, false)) { WarpMessageType warpType = (WarpMessageType)mr.Read<int>(); string fromPlayer = mr.Read<string>(); if (fromPlayer == client.playerName) { if (warpType == WarpMessageType.NEW_SUBSPACE) { int newSubspaceID = mr.Read<int>(); if (subspaces.ContainsKey(newSubspaceID)) { DarkLog.Debug("Kicked for trying to create an existing subspace"); SendConnectionEnd(client, "Kicked for trying to create an existing subspace"); return; } else { Subspace newSubspace = new Subspace(); newSubspace.serverClock = mr.Read<long>(); newSubspace.planetTime = mr.Read<double>(); newSubspace.subspaceSpeed = mr.Read<float>(); subspaces.Add(newSubspaceID, newSubspace); client.subspace = newSubspaceID; SaveLatestSubspace(); } } if (warpType == WarpMessageType.CHANGE_SUBSPACE) { client.subspace = mr.Read<int>(); } if (warpType == WarpMessageType.REPORT_RATE) { int reportedSubspace = mr.Read<int>(); if (client.subspace != reportedSubspace) { DarkLog.Debug("Warning, setting client " + client.playerName + " to subspace " + client.subspace); client.subspace = reportedSubspace; } float newSubspaceRate = mr.Read<float>(); client.subspaceRate = newSubspaceRate; foreach (ClientObject otherClient in clients) { if (otherClient.authenticated && otherClient.subspace == reportedSubspace) { if (newSubspaceRate > otherClient.subspaceRate) { newSubspaceRate = otherClient.subspaceRate; } } } if (newSubspaceRate < 0.3f) { newSubspaceRate = 0.3f; } if (newSubspaceRate > 1f) { newSubspaceRate = 1f; } //Relock the subspace if the rate is more than 3% out of the average if (Math.Abs(subspaces[reportedSubspace].subspaceSpeed - newSubspaceRate) > 0.03f) { UpdateSubspace(reportedSubspace); subspaces[reportedSubspace].subspaceSpeed = newSubspaceRate; ServerMessage relockMessage = new ServerMessage(); relockMessage.type = ServerMessageType.WARP_CONTROL; using (MessageWriter mw = new MessageWriter()) { mw.Write<int>((int)WarpMessageType.RELOCK_SUBSPACE); mw.Write<string>(Settings.settingsStore.consoleIdentifier); mw.Write<int>(reportedSubspace); mw.Write<long>(subspaces[reportedSubspace].serverClock); mw.Write<double>(subspaces[reportedSubspace].planetTime); mw.Write<float>(subspaces[reportedSubspace].subspaceSpeed); relockMessage.data = mw.GetMessageBytes(); } SaveLatestSubspace(); //DarkLog.Debug("Subspace " + client.subspace + " locked to " + newSubspaceRate + "x speed."); SendToClient(client, relockMessage, true); SendToAll(client, relockMessage, true); } } } else { DarkLog.Debug(client.playerName + " tried to send an update for " + fromPlayer + ", kicking."); SendConnectionEnd(client, "Kicked for sending an update for another player"); return; } } SendToAll(client, newMessage, true); }
private static void LoadSavedSubspace() { try { using (StreamReader sr = new StreamReader(subspaceFile)) { //Ignore the comment line. string firstLine = ""; while (firstLine.StartsWith("#") || String.IsNullOrEmpty(firstLine)) { firstLine = sr.ReadLine().Trim(); } Subspace savedSubspace = new Subspace(); int subspaceID = Int32.Parse(firstLine); savedSubspace.serverClock = Int64.Parse(sr.ReadLine().Trim()); savedSubspace.planetTime = Double.Parse(sr.ReadLine().Trim()); savedSubspace.subspaceSpeed = Single.Parse(sr.ReadLine().Trim()); subspaces.Add(subspaceID, savedSubspace); } } catch { DarkLog.Debug("Creating new subspace lock file"); Subspace newSubspace = new Subspace(); newSubspace.serverClock = DateTime.UtcNow.Ticks; newSubspace.planetTime = 100d; newSubspace.subspaceSpeed = 1f; subspaces.Add(0, newSubspace); SaveSubspace(0, newSubspace); } }
public void LockNewSubspace(int subspaceID, long serverTime, double planetariumTime, float subspaceSpeed) { if (!subspaces.ContainsKey(subspaceID)) { Subspace newSubspace = new Subspace(); newSubspace.serverClock = serverTime; newSubspace.planetTime = planetariumTime; newSubspace.subspaceSpeed = subspaceSpeed; subspaces.Add(subspaceID, newSubspace); } DarkLog.Debug("Subspace " + subspaceID + " locked to server, time: " + planetariumTime); }
public Subspace GetSubspace(int subspaceID) { Subspace ss = new Subspace(); if (subspaces.ContainsKey(subspaceID)) { ss.serverClock = subspaces[subspaceID].serverClock; ss.planetTime = subspaces[subspaceID].planetTime; ss.subspaceSpeed = subspaces[subspaceID].subspaceSpeed; } return ss; }
private static void HandleNewSubspace(ClientObject client, long serverClock, double planetTime, float subspaceSpeed) { lock (createLock) { DarkLog.Debug("Create subspace"); //Create subspace Subspace newSubspace = new Subspace(); newSubspace.serverClock = serverClock; newSubspace.planetTime = planetTime; newSubspace.subspaceSpeed = subspaceSpeed; subspaces.Add(freeID, newSubspace); //Create message ServerMessage newMessage = new ServerMessage(); newMessage.type = ServerMessageType.WARP_CONTROL; using (MessageWriter mw = new MessageWriter()) { mw.Write<int>((int)WarpMessageType.NEW_SUBSPACE); mw.Write<int>(freeID); mw.Write<long>(serverClock); mw.Write<double>(planetTime); mw.Write<float>(subspaceSpeed); newMessage.data = mw.GetMessageBytes(); } //Tell all clients about the new subspace ClientHandler.SendToAll(null, newMessage, true); //Send the client to that subspace if (Settings.settingsStore.warpMode == WarpMode.MCW_FORCE || Settings.settingsStore.warpMode == WarpMode.MCW_VOTE || Settings.settingsStore.warpMode == WarpMode.MCW_LOWEST) { SendSetSubspaceToAll(freeID); } else { SendSetSubspace(client, freeID); } freeID++; //Save to disk SaveLatestSubspace(); } }
private static void HandleWarpControl(ClientObject client, byte[] messageData) { ServerMessage newMessage = new ServerMessage(); newMessage.type = ServerMessageType.WARP_CONTROL; newMessage.data = messageData; using (MessageReader mr = new MessageReader(messageData, false)) { WarpMessageType warpType = (WarpMessageType)mr.Read<int>(); string fromPlayer = mr.Read<string>(); if (fromPlayer == client.playerName) { if (warpType == WarpMessageType.NEW_SUBSPACE) { int newSubspaceID = mr.Read<int>(); if (subspaces.ContainsKey(newSubspaceID)) { DarkLog.Debug("Kicked for trying to create an existing subspace"); SendConnectionEnd(client, "Kicked for trying to create an existing subspace"); return; } else { Subspace newSubspace = new Subspace(); newSubspace.serverClock = mr.Read<long>(); newSubspace.planetTime = mr.Read<double>(); newSubspace.subspaceSpeed = mr.Read<float>(); subspaces.Add(newSubspaceID, newSubspace); client.subspace = newSubspaceID; SaveLatestSubspace(); } } if (warpType == WarpMessageType.CHANGE_SUBSPACE) { client.subspace = mr.Read<int>(); } if (warpType == WarpMessageType.REPORT_RATE) { int reportedSubspace = mr.Read<int>(); if (reportedSubspace == client.subspace) { float newSubspaceRateTotal = mr.Read<float>(); int newSubspaceRateCount = 1; foreach (ClientObject otherClient in clients) { if (otherClient.authenticated && otherClient.subspace == reportedSubspace) { newSubspaceRateTotal += otherClient.subspaceRate; newSubspaceRateCount++; } } float newAverageRate = newSubspaceRateTotal / (float)newSubspaceRateCount; if (newAverageRate < 0.5f) { newAverageRate = 0.5f; } if (newAverageRate > 1f) { newAverageRate = 1f; } //Relock the subspace if the rate is more than 3% out of the average //DarkLog.Debug("New average rate: " + newAverageRate + " for subspace " + client.subspace); if (Math.Abs(subspaces[reportedSubspace].subspaceSpeed - newAverageRate) > 0.03f) { //New time = Old time + (seconds since lock * subspace rate) long newServerClockTime = DateTime.UtcNow.Ticks; float timeSinceLock = (DateTime.UtcNow.Ticks - subspaces[client.subspace].serverClock) / 10000000f; double newPlanetariumTime = subspaces[client.subspace].planetTime + (timeSinceLock * subspaces[client.subspace].subspaceSpeed); subspaces[client.subspace].serverClock = newServerClockTime; subspaces[client.subspace].planetTime = newPlanetariumTime; subspaces[client.subspace].subspaceSpeed = newAverageRate; ServerMessage relockMessage = new ServerMessage(); relockMessage.type = ServerMessageType.WARP_CONTROL; using (MessageWriter mw = new MessageWriter()) { mw.Write<int>((int)WarpMessageType.RELOCK_SUBSPACE); mw.Write<string>(Settings.settingsStore.consoleIdentifier); mw.Write<int>(client.subspace); mw.Write<long>(DateTime.UtcNow.Ticks); mw.Write<double>(newPlanetariumTime); mw.Write<float>(newAverageRate); relockMessage.data = mw.GetMessageBytes(); } SaveLatestSubspace(); DarkLog.Debug("Subspace " + client.subspace + " locked to " + newAverageRate + "x speed."); SendToClient(client, relockMessage, true); SendToAll(client, relockMessage, true); } } } } else { DarkLog.Debug(client.playerName + " tried to send an update for " + fromPlayer + ", kicking."); SendConnectionEnd(client, "Kicked for sending an update for another player"); return; } } SendToAll(client, newMessage, true); }
public double GetUniverseTime(Subspace subspace) { long realTimeSinceLock = GetServerClock() - subspace.serverClock; double realTimeSinceLockSeconds = realTimeSinceLock / 10000000d; double adjustedTimeSinceLockSeconds = realTimeSinceLockSeconds * subspace.subspaceSpeed; return subspace.planetTime + adjustedTimeSinceLockSeconds; }
public void LockTemporarySubspace(long serverClock, double planetTime, float subspaceSpeed) { Subspace tempSubspace = new Subspace(); tempSubspace.serverClock = serverClock; tempSubspace.planetTime = planetTime; tempSubspace.subspaceSpeed = subspaceSpeed; lockedSubspace = tempSubspace; }
public void AddNewSubspace(int subspaceID, long serverTime, double planetariumTime, float subspaceSpeed) { Subspace newSubspace = new Subspace(); newSubspace.serverClock = serverTime; newSubspace.planetTime = planetariumTime; newSubspace.subspaceSpeed = subspaceSpeed; subspaces[subspaceID] = newSubspace; if (currentSubspace == subspaceID) { LockSubspace(currentSubspace); } DarkLog.Debug("Subspace " + subspaceID + " locked to server, time: " + planetariumTime); }