private void HandleMCWLowestInput(bool startWarpKey, bool stopWarpKey) { int newRequestIndex = requestIndex; bool newRequestPhysWarp = requestPhysWarp; if (startWarpKey) { if (requestIndex == 0) { newRequestPhysWarp = GameSettings.MODIFIER_KEY.GetKey(); } float[] physRates = TimeWarp.fetch.physicsWarpRates; float[] warpRates = TimeWarp.fetch.warpRates; newRequestIndex++; if (newRequestPhysWarp && newRequestIndex >= physRates.Length) { newRequestIndex = physRates.Length - 1; } if (!newRequestPhysWarp && newRequestIndex >= warpRates.Length) { newRequestIndex = warpRates.Length - 1; } } if (stopWarpKey) { newRequestIndex--; if (newRequestIndex < 0) { newRequestIndex = 0; } if (newRequestIndex == 0) { newRequestPhysWarp = false; } } if ((newRequestIndex != requestIndex) || (newRequestPhysWarp != requestPhysWarp)) { requestIndex = newRequestIndex; requestPhysWarp = newRequestPhysWarp; PlayerWarpRate newWarpRate = new PlayerWarpRate(); newWarpRate.isPhysWarp = requestPhysWarp; newWarpRate.rateIndex = requestIndex; newWarpRate.planetTime = Planetarium.GetUniversalTime(); newWarpRate.serverClock = timeSyncer.GetServerClock(); clientWarpList[dmpSettings.playerName] = newWarpRate; DarkLog.Debug("Warp request change: " + requestIndex + ", physwarp: " + requestPhysWarp); using (MessageWriter mw = new MessageWriter()) { mw.Write <int>((int)WarpMessageType.CHANGE_WARP); mw.Write <bool>(requestPhysWarp); mw.Write <int>(requestIndex); mw.Write <long>(timeSyncer.GetServerClock()); mw.Write <double>(Planetarium.GetUniversalTime()); networkWorker.SendWarpMessage(mw.GetMessageBytes()); } } }
private void HandleChangeWarp(string fromPlayer, bool isPhysWarp, int newRate, long serverClock, double planetTime) { if (warpMode != WarpMode.NONE) { if (clientWarpList.ContainsKey(fromPlayer)) { clientWarpList[fromPlayer].isPhysWarp = isPhysWarp; clientWarpList[fromPlayer].rateIndex = newRate; clientWarpList[fromPlayer].serverClock = serverClock; clientWarpList[fromPlayer].planetTime = planetTime; } else { PlayerWarpRate newPlayerWarpRate = new PlayerWarpRate(); newPlayerWarpRate.isPhysWarp = isPhysWarp; newPlayerWarpRate.rateIndex = newRate; newPlayerWarpRate.serverClock = serverClock; newPlayerWarpRate.planetTime = planetTime; clientWarpList.Add(fromPlayer, newPlayerWarpRate); } } }
private void SetTimeFromWarpEntry(PlayerWarpRate masterWarpRate) { float[] warpRates = null; if (masterWarpRate.isPhysWarp) { TimeWarp.fetch.Mode = TimeWarp.Modes.LOW; warpRates = TimeWarp.fetch.physicsWarpRates; } else { TimeWarp.fetch.Mode = TimeWarp.Modes.HIGH; warpRates = TimeWarp.fetch.warpRates; } if (TimeWarp.WarpMode != TimeWarp.Modes.LOW && masterWarpRate.isPhysWarp) { TimeWarp.fetch.Mode = TimeWarp.Modes.LOW; } if (TimeWarp.WarpMode != TimeWarp.Modes.HIGH && !masterWarpRate.isPhysWarp) { TimeWarp.fetch.Mode = TimeWarp.Modes.HIGH; } //Set warp if (TimeWarp.CurrentRateIndex != masterWarpRate.rateIndex) { TimeWarp.SetRate(masterWarpRate.rateIndex, true); } //Set clock long serverClockDiff = timeSyncer.GetServerClock() - masterWarpRate.serverClock; double secondsDiff = serverClockDiff / 10000000d; double newTime = masterWarpRate.planetTime + (warpRates[masterWarpRate.rateIndex] * secondsDiff); Planetarium.SetUniversalTime(newTime); }
private void Update() { //Switch to new subspace if told to - this needs to be before the workerEnabled check as it fires during the initial sync if (newSetSubspace != -1) { DarkLog.Debug("Sent to subspace: " + newSetSubspace); timeSyncer.LockSubspace(newSetSubspace); newSetSubspace = -1; } if (!workerEnabled) { return; } //Reset warp if we need to CheckWarp(); //Process new warp messages ProcessWarpMessages(); //Write the screen message if needed if ((Client.realtimeSinceStartup - lastScreenMessageCheck) > SCREEN_MESSAGE_UPDATE_INTERVAL) { lastScreenMessageCheck = Client.realtimeSinceStartup; UpdateScreenMessage(); } //Send a CHANGE_WARP message if needed if ((warpMode == WarpMode.MCW_FORCE) || (warpMode == WarpMode.MCW_VOTE) || (warpMode == WarpMode.SUBSPACE) || warpMode == WarpMode.SUBSPACE_SIMPLE) { if (!clientWarpList.ContainsKey(dmpSettings.playerName)) { clientWarpList[dmpSettings.playerName] = new PlayerWarpRate(); } PlayerWarpRate ourRate = clientWarpList[dmpSettings.playerName]; if ((ourRate.rateIndex != TimeWarp.CurrentRateIndex) || (ourRate.isPhysWarp != (TimeWarp.WarpMode == TimeWarp.Modes.LOW))) { ourRate.isPhysWarp = (TimeWarp.WarpMode == TimeWarp.Modes.LOW); ourRate.rateIndex = TimeWarp.CurrentRateIndex; ourRate.serverClock = timeSyncer.GetServerClock(); ourRate.planetTime = Planetarium.GetUniversalTime(); using (MessageWriter mw = new MessageWriter()) { mw.Write <int>((int)WarpMessageType.CHANGE_WARP); mw.Write <bool>(ourRate.isPhysWarp); mw.Write <int>(ourRate.rateIndex); mw.Write <long>(ourRate.serverClock); mw.Write <double>(ourRate.planetTime); networkWorker.SendWarpMessage(mw.GetMessageBytes()); } } } if ((Client.realtimeSinceStartup - lastWarpSet) > WARP_SET_THROTTLE) { //Follow the warp master into warp if needed (MCW_FORCE/MCW_VOTE) if (warpMode == WarpMode.MCW_FORCE || warpMode == WarpMode.MCW_VOTE) { if ((warpMaster != "") && (warpMaster != dmpSettings.playerName)) { if (clientWarpList.ContainsKey(warpMaster)) { //Get master warp rate PlayerWarpRate masterWarpRate = clientWarpList[warpMaster]; SetTimeFromWarpEntry(masterWarpRate); lastWarpSet = Client.realtimeSinceStartup; } else { TimeWarp.SetRate(0, true); } } } if (warpMode == WarpMode.MCW_LOWEST) { if ((warpMaster != "") && clientWarpList.ContainsKey(warpMaster)) { //Get master warp rate PlayerWarpRate masterWarpRate = clientWarpList[warpMaster]; SetTimeFromWarpEntry(masterWarpRate); lastWarpSet = Client.realtimeSinceStartup; } } } //Report our timeSyncer skew if ((Client.realtimeSinceStartup - lastReportRate) > REPORT_SKEW_RATE_INTERVAL && timeSyncer.locked) { lastReportRate = Client.realtimeSinceStartup; using (MessageWriter mw = new MessageWriter()) { mw.Write <int>((int)WarpMessageType.REPORT_RATE); mw.Write <float>(timeSyncer.requestedRate); networkWorker.SendWarpMessage(mw.GetMessageBytes()); } } //Handle warp keys HandleInput(); }
private void UpdateScreenMessage() { if (warpMode == WarpMode.MCW_FORCE || warpMode == WarpMode.MCW_VOTE) { if (warpMaster != "") { int timeLeft = (int)(controllerExpireTime - Client.realtimeSinceStartup); if (warpMaster != dmpSettings.playerName) { DisplayMessage(warpMaster + " currently has warp control (timeout " + timeLeft + "s)", 1f); } else { DisplayMessage("You have warp control, press '<' while not in warp to release (timeout " + timeLeft + "s)", 1f); } } else { if (voteMaster != "") { int timeLeft = (int)(voteExpireTime - Client.realtimeSinceStartup); if (voteMaster == dmpSettings.playerName) { DisplayMessage("Waiting for vote replies... Yes: " + voteYesCount + ", No: " + voteNoCount + ", Needed: " + voteNeededCount + " (" + timeLeft + "s left)", 1f); } else { if (voteSent) { DisplayMessage("Voted! (Yes: " + voteYesCount + ", No: " + voteNoCount + ", Timeout: " + timeLeft + "s)", 1f); } else { DisplayMessage(voteMaster + " has started a warp vote, reply with '<' for no or '>' for yes (Yes: " + voteYesCount + ", No: " + voteNoCount + ", Timeout: " + timeLeft + "s)", 1f); } } } } } if (warpMode == WarpMode.MCW_LOWEST) { string fastestPlayer = GetFastestWarpingPlayer(); float ourRate = GetRateAtIndex(requestIndex, requestPhysWarp); string displayMessage = String.Empty; if (fastestPlayer != null && fastestPlayer != dmpSettings.playerName && clientWarpList.ContainsKey(fastestPlayer)) { PlayerWarpRate fastestRate = clientWarpList[fastestPlayer]; displayMessage += "\n" + fastestPlayer + " is requesting rate " + GetRateAtIndex(fastestRate.rateIndex, fastestRate.isPhysWarp) + "x"; } if (ourRate > 1f) { displayMessage += "\nWe are requesting rate: " + ourRate + "x"; } if (warpMaster != null && clientWarpList.ContainsKey(warpMaster)) { PlayerWarpRate currentWarpRate = clientWarpList[warpMaster]; float currentRate = GetRateAtIndex(currentWarpRate.rateIndex, currentWarpRate.isPhysWarp); displayMessage += "\nCurrent warp rate: " + currentRate + "x"; } if (displayMessage != String.Empty) { DisplayMessage(displayMessage, 1f); } } if (warpMode == WarpMode.SUBSPACE_SIMPLE) { int mostAdvancedSubspace = timeSyncer.GetMostAdvancedSubspace(); int ourSubspace = timeSyncer.currentSubspace; canSubspaceSimpleWarp = true; if ((ourSubspace != -1) && (mostAdvancedSubspace != ourSubspace)) { canSubspaceSimpleWarp = false; double deltaSeconds = timeSyncer.GetUniverseTime(mostAdvancedSubspace) - timeSyncer.GetUniverseTime(ourSubspace); DisplayMessage("Press '>' to warp " + Math.Round(deltaSeconds) + "s into the future", 1f); } } }
private void HandleWarpMessage(byte[] messageData) { using (MessageReader mr = new MessageReader(messageData, false)) { WarpMessageType messageType = (WarpMessageType)mr.Read <int>(); string fromPlayer = mr.Read <string>(); switch (messageType) { case WarpMessageType.REQUEST_VOTE: { if (warpMode == WarpMode.MCW_VOTE) { if (voteMaster == "") { voteMaster = fromPlayer; } else { //Freak out and tell everyone to reset their warp votes - This can happen if 2 clients start a vote at the exact same time. ReleaseWarpMaster(); } } } break; case WarpMessageType.REPLY_VOTE: { if (warpMode == WarpMode.MCW_VOTE) { if (voteMaster == Settings.fetch.playerName && warpMaster == "") { if (!voteList.ContainsKey(fromPlayer)) { bool vote = mr.Read <bool>(); DarkLog.Debug(fromPlayer + " voted " + vote); voteList.Add(fromPlayer, vote); } voteNoCount = 0; voteYesCount = 0; foreach (KeyValuePair <string, bool> vote in voteList) { if (vote.Value) { voteYesCount++; } else { voteNoCount++; } } //We have enough votes if (voteYesCount >= voteNeededCount) { //Vote has passed. warpMasterOwnerTime = UnityEngine.Time.realtimeSinceStartup; warpMaster = Settings.fetch.playerName; using (MessageWriter mw = new MessageWriter()) { mw.Write <int>((int)WarpMessageType.SET_CONTROLLER); mw.Write <string>(Settings.fetch.playerName); mw.Write <string>(Settings.fetch.playerName); NetworkWorker.fetch.SendWarpMessage(mw.GetMessageBytes()); } } //We have enough votes if (voteNoCount >= voteFailedCount) { //Vote has failed. ReleaseWarpMaster(); DisplayMessage("Vote failed!", 5f); } } } } break; case WarpMessageType.SET_CONTROLLER: { if (warpMode == WarpMode.MCW_FORCE || warpMode == WarpMode.MCW_VOTE || warpMode == WarpMode.MCW_LOWEST) { string newController = mr.Read <string>(); warpMaster = newController; if (warpMode == WarpMode.MCW_FORCE && newController == "") { warpMasterOwnerTime = 0f; } if (warpMode == WarpMode.MCW_VOTE && newController == "") { TimeWarp.SetRate(0, true); CancelVote(); } } } break; case WarpMessageType.CHANGE_WARP: { if (warpMode == WarpMode.MCW_FORCE || warpMode == WarpMode.MCW_VOTE || warpMode == WarpMode.MCW_LOWEST || warpMode == WarpMode.SUBSPACE) { bool newPhysWarp = mr.Read <bool>(); int newRateIndex = mr.Read <int>(); if (clientWarpList.ContainsKey(fromPlayer)) { clientWarpList[fromPlayer].isPhysWarp = newPhysWarp; clientWarpList[fromPlayer].rateIndex = newRateIndex; } else { PlayerWarpRate newPlayerWarpRate = new PlayerWarpRate(); newPlayerWarpRate.isPhysWarp = newPhysWarp; newPlayerWarpRate.rateIndex = newRateIndex; clientWarpList.Add(fromPlayer, newPlayerWarpRate); } //DarkLog.Debug(fromPlayer + " warp rate changed, Physwarp: " + newPhysWarp + ", Index: " + newRateIndex); } } break; case WarpMessageType.NEW_SUBSPACE: { int newSubspaceID = mr.Read <int>(); long serverTime = mr.Read <long>(); double planetariumTime = mr.Read <double>(); float gameSpeed = mr.Read <float>(); TimeSyncer.fetch.LockNewSubspace(newSubspaceID, serverTime, planetariumTime, gameSpeed); if (((warpMode == WarpMode.MCW_VOTE) || (warpMode == WarpMode.MCW_FORCE)) && (warpMaster == fromPlayer)) { TimeSyncer.fetch.LockSubspace(newSubspaceID); } if (!TimeSyncer.fetch.locked && TimeSyncer.fetch.currentSubspace == newSubspaceID) { TimeSyncer.fetch.LockSubspace(newSubspaceID); } } break; case WarpMessageType.CHANGE_SUBSPACE: { int changeSubspaceID = mr.Read <int>(); clientSubspaceList[fromPlayer] = changeSubspaceID; } break; case WarpMessageType.RELOCK_SUBSPACE: { if (fromPlayer == "Server") { int subspaceID = mr.Read <int>(); long serverTime = mr.Read <long>(); double planetariumTime = mr.Read <double>(); float gameSpeed = mr.Read <float>(); TimeSyncer.fetch.RelockSubspace(subspaceID, serverTime, planetariumTime, gameSpeed); } } break; case WarpMessageType.REPORT_RATE: { //Not interested in subspace. mr.Read <int>(); clientSkewList[fromPlayer] = mr.Read <float>(); } break; default: { DarkLog.Debug("Unhandled WARP_MESSAGE type: " + messageType); break; } } } }
private void Update() { if (!workerEnabled) { return; } //Reset warp if we need to CheckWarp(); //Process new warp messages ProcessWarpMessages(); //Write the screen message if needed if ((UnityEngine.Time.realtimeSinceStartup - lastScreenMessageCheck) > SCREEN_MESSAGE_UPDATE_INTERVAL) { lastScreenMessageCheck = UnityEngine.Time.realtimeSinceStartup; UpdateScreenMessage(); } //Send a CHANGE_WARP message if needed if ((warpMode == WarpMode.MCW_FORCE) || (warpMode == WarpMode.MCW_VOTE) || (warpMode == WarpMode.SUBSPACE) || warpMode == WarpMode.SUBSPACE_SIMPLE) { if (!clientWarpList.ContainsKey(Settings.fetch.playerName)) { clientWarpList[Settings.fetch.playerName] = new PlayerWarpRate(); } PlayerWarpRate ourRate = clientWarpList[Settings.fetch.playerName]; if ((ourRate.rateIndex != TimeWarp.CurrentRateIndex) || (ourRate.isPhysWarp != (TimeWarp.WarpMode == TimeWarp.Modes.LOW))) { ourRate.isPhysWarp = (TimeWarp.WarpMode == TimeWarp.Modes.LOW); ourRate.rateIndex = TimeWarp.CurrentRateIndex; ourRate.serverClock = TimeSyncer.fetch.GetServerClock(); ourRate.planetTime = Planetarium.GetUniversalTime(); using (MessageWriter mw = new MessageWriter()) { mw.Write <int>((int)WarpMessageType.CHANGE_WARP); mw.Write <bool>(ourRate.isPhysWarp); mw.Write <int>(ourRate.rateIndex); mw.Write <long>(ourRate.serverClock); mw.Write <double>(ourRate.planetTime); NetworkWorker.fetch.SendWarpMessage(mw.GetMessageBytes()); } } } if ((UnityEngine.Time.realtimeSinceStartup - lastWarpSet) > WARP_SET_THROTTLE) { //Follow the warp master into warp if needed (MCW_FORCE/MCW_VOTE) if (warpMode == WarpMode.MCW_FORCE || warpMode == WarpMode.MCW_VOTE) { if ((warpMaster != "") && (warpMaster != Settings.fetch.playerName)) { if (clientWarpList.ContainsKey(warpMaster)) { //Get master warp rate PlayerWarpRate masterWarpRate = clientWarpList[warpMaster]; SetTimeFromWarpEntry(masterWarpRate); lastWarpSet = UnityEngine.Time.realtimeSinceStartup; } else { TimeWarp.SetRate(0, true); } } } if (warpMode == WarpMode.MCW_LOWEST) { if ((warpMaster != "") && clientWarpList.ContainsKey(warpMaster)) { //Get master warp rate PlayerWarpRate masterWarpRate = clientWarpList[warpMaster]; SetTimeFromWarpEntry(masterWarpRate); lastWarpSet = UnityEngine.Time.realtimeSinceStartup; } } } //Report our timeSyncer skew if ((UnityEngine.Time.realtimeSinceStartup - lastReportRate) > REPORT_SKEW_RATE_INTERVAL && TimeSyncer.fetch.locked) { lastReportRate = UnityEngine.Time.realtimeSinceStartup; using (MessageWriter mw = new MessageWriter()) { mw.Write <int>((int)WarpMessageType.REPORT_RATE); mw.Write <float>(TimeSyncer.fetch.requestedRate); NetworkWorker.fetch.SendWarpMessage(mw.GetMessageBytes()); } } //Handle warp keys HandleInput(); }