/// <summary> /// This is a hot path. Runs at the completion interpolation, and attempts to find/reconstruct the next suitable frame for interpolation. /// </summary> public Frame DetermineAndPrepareNextFrame(bool svrWaitingForTeleportConfirm) { // buffer is empty, no point looking for any frames - we need to extrapolate the next frame if (validFrameMask == 0) { DebugX.Log(!DebugX.logInfo ? null : //Debug.Log( (Time.time + " NST " + nst.NstId + " " + nst.name + " <color=red><b> empty buffer, copying current frame to </b></color>" + NextFrame.frameid + " \n curr: " + currentFrame)); ExtrapolateNextFrame(svrWaitingForTeleportConfirm); return(NextFrame); } extrapolationCount = 0; // First see if there is a future frame ready - ignoring late arrivles that may have backfilled behind the current frame Frame nextValid = GetFirstFutureValidFrame(); // if not see if there is an older frame that arrived late, if so we will jump back to that as current if (nextValid == null) { nextValid = GetOldestPastValidFrame() ?? GetOldestValidFrame(); // The only valid frames are only in the past, we need to jump back to the oldest to get our current frame in a better ballpark if (nextValid != null) { //Debug.Log( DebugX.Log(!DebugX.logInfo ? null : (Time.time + " NST " + nst.NstId + " " + nst.name + " <color=red><b> Skipping back to frame </b></color> " + nextValid.frameid + " from current frame " + CurrentIndex)); nextValid.CompletePosition(currentFrame); return(nextValid); } } // Find out how far in the future the next valid frame is, need to know this for the reconstruction lerp. int stepsFromLast = CountFrames(CurrentIndex, nextValid.frameid); // The next frame is the next valid... not much thinking required... just use it. if (stepsFromLast == 1) { InvalidateOldFrames(NextFrame); // LIKELY UNEEDED NextFrame.CompletePosition(currentFrame); return(NextFrame); } // if next frame on the buffer is a couple ahead of current, jump forward if (stepsFromLast > jumpForwardThreshold) { //Debug.Log( DebugX.Log(!DebugX.logInfo ? null : ("<color=red><b>Jumping forward frame(s) </b></color>")); InvalidateOldFrames(nextValid); nextValid.CompletePosition(currentFrame); return(nextValid); } //All other cases we Reconstruct missing next frame using the current frame and a future frame Frame next = NextFrame; //Debug.Log( DebugX.Log(!DebugX.logInfo ? null : (Time.time + " NST:" + nst.NstId + " <color=black><b>Reconstructing missing packet " + next.frameid + " </b></color> \n" + currentFrame.compPos + "\n" + nextValid.compPos)); next.state = currentFrame.state; float t = 1f / stepsFromLast; nextValid.CompletePosition(currentFrame); Vector3 lerpedPos = Vector3.Lerp(currentFrame.rootPos, nextValid.rootPos, t); float lerpedStartTime = Mathf.Lerp(currentFrame.packetArriveTime, nextValid.packetArriveTime, t); next.ModifyFrame(currentFrame.updateType, currentFrame.rootBitCullLevel, lerpedPos, GenericX.NULL, lerpedStartTime); DebugX.Log(!DebugX.logInfo ? null : (Time.time + "fid" + next.frameid + " <color=red><b> RECONSTRUCT ELEMENTS </b></color> " + next.RootRot + " " + currentFrame.RootRot + " " + nextValid.RootRot)); // Notify all interested components that they need to reconstruct a missing frame (elements and such) foreach (INstOnReconstructMissing callbacks in nst.iNstOnReconstructMissing) { callbacks.OnReconstructMissing(next, currentFrame, nextValid, t, svrWaitingForTeleportConfirm); } return(next); }
public WWCPImporter <T> LoadForwardingDataFromFile() { lock (_EVSEOperators) { var CurrentDirectory = Directory.GetCurrentDirectory(); var ConfigFilename = Directory.EnumerateFiles(CurrentDirectory). Select(file => file.Remove(0, CurrentDirectory.Length + 1)). Where(file => file.StartsWith(_ConfigFilenamePrefix)). OrderByDescending(file => file). FirstOrDefault(); var InputFile = ConfigFilename != null ? ConfigFilename : ConfigFilenamePrefix + ".json"; if (File.Exists(InputFile)) { #region Try to read JSON from file... JObject JSONConfig; try { JSONConfig = JObject.Parse(File.ReadAllText(InputFile)); } catch (Exception) { throw new ApplicationException("Could not read '" + InputFile + "'!"); } #endregion try { foreach (var CurrentRoamingNetwork in JSONConfig) { var CurrentRoamingNetworkId = RoamingNetwork_Id.Parse(CurrentRoamingNetwork.Key); var CurrenteVSEOperator = _EVSEOperators. Where(evseoperator => evseoperator.RoamingNetwork.Id == CurrentRoamingNetworkId). FirstOrDefault(); if (CurrenteVSEOperator == null) { throw new ApplicationException("Could not find any EVSE operator for roaming network '" + CurrentRoamingNetworkId + "'!"); } var CurrentRoamingNetworkJObject = CurrentRoamingNetwork.Value as JObject; if (CurrentRoamingNetworkJObject != null) { foreach (var ChargingStationGroups in CurrentRoamingNetworkJObject) { switch (ChargingStationGroups.Key.ToLower()) { #region ValidChargingStations case "validchargingstations": (ChargingStationGroups.Value as JObject).GetEnumerator(). ConsumeAll(). OrderBy(KVP => KVP.Key). ForEach(StationConfig => { ChargingStation_Id ChargingStationId = null; if (ChargingStation_Id.TryParse(StationConfig.Key, out ChargingStationId)) { JToken JSONToken2; String PhoneNumber = null; var CurrentSettings = StationConfig.Value as JObject; #region PhoneNumber if (CurrentSettings.TryGetValue("PhoneNumber", out JSONToken2)) { PhoneNumber = JSONToken2.Value <String>(); } #endregion #region AdminStatus var AdminStatus = ChargingStationAdminStatusType.Operational; if (CurrentSettings.TryGetValue("Adminstatus", out JSONToken2)) { if (!Enum.TryParse <ChargingStationAdminStatusType>(JSONToken2.Value <String>(), true, out AdminStatus)) { DebugX.Log("Invalid admin status '" + JSONToken2.Value <String>() + "' for charging station '" + ChargingStationId.ToString() + "'!"); } } #endregion #region Group if (CurrentSettings.TryGetValue("Group", out JSONToken2)) { var JV = JSONToken2 as JValue; var JA = JSONToken2 as JArray; var GroupList = JV != null ? new String[] { JV.Value <String>() } : JA != null ? JA.AsEnumerable().Select(v => v.Value <String>()) : null; if (GroupList != null) { foreach (var GroupId in GroupList) { CurrenteVSEOperator. GetOrCreateChargingStationGroup(ChargingStationGroup_Id.Parse(CurrenteVSEOperator.Id, GroupId)). Add(ChargingStationId); } } } #endregion if (!_AllForwardingInfos.ContainsKey(ChargingStationId)) { _AllForwardingInfos.Add(ChargingStationId, new ImporterForwardingInfo( OnChangedCallback: SendOnForwardingChanged, EVSEOperators: _EVSEOperators, StationId: ChargingStationId, StationName: "", StationServiceTag: "", StationAddress: new Address(), StationGeoCoordinate: null, PhoneNumber: PhoneNumber, AdminStatus: AdminStatus, Created: DateTime.Now, OutOfService: true, ForwardedToEVSEOperator: CurrenteVSEOperator) ); } } }); break; #endregion } } } } } catch (Exception e) { DebugX.Log("LoadForwardingDataFromFile failed: " + e.Message); } } else { throw new ApplicationException("Config file '" + _ConfigFilenamePrefix + "' does not exist!"); } } return(this); }
/// <summary> /// Apply the TRS matrix to a transform. Any axes not included in the Crusher are left as is. /// </summary> public void Apply(Matrix matrix) { DebugX.LogError(transformMissingError, !defaultTransform, true); Apply(defaultTransform, matrix); }
/// <summary> /// Reads update headers for each NST frame update in the incoming bitstream, and passes the bitstream to that NST to read out its /// update information. /// </summary> /// <param name="mirror">True if this is the server, and this is the incoming bitstream. Tells the server that the outstream /// needs to be populated for retransmission to all clients. Also false if this is the server running its own outgoing update.</param> public static void ReceiveUpdate(ref UdpBitStream bitstream, ref UdpBitStream outstream, bool mirror, int senderId) { // Create a new bitstream to ensure ptr is at 0. Same data as master though. bitstream.ptr = 0; int frameid = bitstream.ReadInt(6); if (mirror) { outstream.WriteInt(frameid, 6); } bool isOfftick = frameid == 60; // remove this safety once working //TEST int safety = 0; UpdateType updateType; do { safety++; BandwidthUsage.Start(ref bitstream, BandwidthLogType.UpdateRcv); //stop looking when header is EOS bool notEOS = bitstream.ReadBool(); int mirrorUpdateStartPtr = outstream.ptr; BandwidthUsage.AddUsage(ref bitstream, "NotEOS"); if (mirror) { outstream.WriteBool(notEOS); } if (!notEOS) { break; } // First three bits are the msgtype //TODO this might only need to be two updateType = (UpdateType)bitstream.ReadInt(3); BandwidthUsage.AddUsage(ref bitstream, "UpdateType"); int updateBitstreamPos = outstream.ptr; if (mirror) { outstream.WriteInt((int)updateType, 3); } // Next variable is the NstId - get it to know where to send the rest of the bitstream uint nstid = bitstream.ReadUInt(HeaderSettings.single.BitsForNstId); BandwidthUsage.AddUsage(ref bitstream, "NstId"); if (mirror) { outstream.WriteUInt(nstid, HeaderSettings.single.BitsForNstId); } lastNST = NSTTools.GetNstFromId(nstid); BandwidthUsage.SetName(lastNST); int updatelength = bitstream.ReadInt(UPDATELENGTH_BYTE_COUNT_SIZE); if (mirror) { outstream.WriteInt(updatelength, UPDATELENGTH_BYTE_COUNT_SIZE); } BandwidthUsage.AddUsage(ref bitstream, "DataLength"); //Note the starting pos in stream int bodyPtr = bitstream.ptr; // The start pos for modifying update lenght for mirror int mirrorBodyPtr = outstream.ptr; // This mising NST handler is NOT FULLY TESTED. Uses the updatelength value to jump ahead in the bitstream if the NST it is // addressed to doesn't exist for some reason. if (lastNST == null) { //DebugX.LogWarning(!DebugX.logWarnings ? null : DebugX.Log( ("Message for an NST Object " + nstid + " arrived but that object does not exist. (yet/anymore?) This is normal during startup and shutdown.")); // Forward to the next update start in the incoming stream. bitstream.ptr = bodyPtr + (updatelength << 3); // rewind to the EOS marker and pretend this arrival never occured for the outgoing mirror stream. outstream.ptr = mirrorUpdateStartPtr; continue; } // Tell this nst to read its mail. updateType may get modified by server receive for things like teleport. Frame frame = lastNST.ReadUpdate(ref bitstream, ref outstream, frameid, isOfftick, updateType, updatelength, mirror); updateType = frame.updateType; // overwrite the updateType of the server outgoing in case it has changed. if (mirror) { outstream.WriteIntAtPos((int)updateType, 3, updateBitstreamPos); } //Advance ptr to next update in stream by force, in case the last update wasn't read for any reason (such as the NST leaving the game) bitstream.ptr = bodyPtr + (updatelength << 3); // write the update byte length for the mirror (not the same value as the incoming due to server side adjustments) if (mirror) { int holdPos = outstream.ptr; outstream.ptr = mirrorBodyPtr - UPDATELENGTH_BYTE_COUNT_SIZE; // get the bytesused rounded up. int bytes = ((holdPos - mirrorBodyPtr) >> 3) + (((holdPos - mirrorBodyPtr) % 8 == 0) ? 0 : 1); outstream.WriteInt(bytes, UPDATELENGTH_BYTE_COUNT_SIZE); outstream.ptr = mirrorBodyPtr + (bytes << 3); } } while (safety < 100); /// NST updates are finished - any data to append to the master update can go here IntegrityCheck.ReadCheck(ref bitstream, ref outstream, "End of All Update Reads", mirror); MasterRTT.Rcv(ref bitstream, ref outstream, mirror, senderId); BandwidthUsage.AddUsage(ref bitstream, "RTT checks"); // Very last thing... report the bits that were used. This is conditional to the editor only BandwidthUsage.ReportMasterBits(ref bitstream, BandwidthLogType.MasterIn); }
public void Apply(ulong u0, ulong u1, ulong u2, ulong u3, uint u4) { DebugX.LogError(transformMissingError, !defaultTransform, true); Apply(defaultTransform, u0, u1, u2, u3, u4); }
/// <summary> /// Apply the TRS matrix to a transform. Any axes not included in the Crusher are left as is. /// </summary> public void Apply(CompressedMatrix cmatrix) { DebugX.LogError(transformMissingError, !defaultTransform, true); Apply(defaultTransform, cmatrix); }
public void Apply(ulong cvalue) { DebugX.LogError(transformMissingError, !defaultTransform, true); Apply(defaultTransform, cvalue); }
/// <summary> /// Compress the transform of the default gameobject. (Only avavilable if this crusher is serialized in the editor). /// </summary> /// <returns></returns> public CompressedMatrix Compress() { DebugX.LogError(transformMissingError, !defaultTransform, true); return(Compress(defaultTransform)); }
/// <summary> /// Initiate the Library change process. /// </summary> /// <param name="newLib"></param> public static bool ChangeLibraries(NetworkLibrary newLib) { // Don't do anything if the adapters already are correct if (newLib == MasterNetAdapter.NetworkLibrary && newLib == NSTNetAdapter.NetLibrary) { return(true); } if (newLib == NetworkLibrary.PUN && !PUN_Exists) { Debug.LogError("Photon PUN does not appear to be installed (Cannot find the PhotonNetwork assembly). Be sure it is installed from the asset store for this project."); return(false); } if (newLib == NetworkLibrary.PUN2 && !PUN2_Exists) { Debug.LogError("Photon PUN2 does not appear to be installed (Cannot find the PhotonNetwork assembly). Be sure it is installed from the asset store for this project."); return(false); } if (!EditorUtility.DisplayDialog("Change Network Library To " + System.Enum.GetName(typeof(NetworkLibrary), newLib) + "?", "Changing libraries is a very messy brute force operation (you may see compile errors and may need to restart Unity). " + "Did you really want to do this, or are you just poking at things to see what they do?", "Change Library", "Cancel")) { return(false); } Debug.Log("Removing current adapters from game objects for Network Library change ..."); PurgeLibraryReferences(); // Close and reopen the current scene to remove the bugginess of orphaned scripts. var curscene = EditorSceneManager.GetActiveScene(); var curscenepath = curscene.path; if (EditorUtility.DisplayDialog("Save Scene Before Reload?", "Scene must be reloaded to complete the purging of old library adapters. Would you like to save this scene?", "Save Scene", "Don't Save")) { EditorSceneManager.SaveScene(curscene); } // force a scene close to eliminate weirdness EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects, NewSceneMode.Single); if (MasterNetAdapter.NetworkLibrary != newLib) { CopyUncompiledAdapters(newLib); } EditorUtility.DisplayDialog("Touch Nothing!", "Wait for the compiling animation in the bottom right of Unity to stop before doing anything. Touching NST related assets will result in broken scripts and errors.", "I Won't Touch, Promise."); // Flag the need for a deep global find of NSTs and NSTMasters in need of adapters DebugX.LogWarning("Add dependencies pending. Clicking on any NST related object in a scene " + "will trigger the final steps of the transition to " + newLib + ". You may need to select the " + "Player Prefab in the scene or asset folder in order to make it the default player object.", true, true); NetLibrarySettings.Single.dependenciesNeedToBeCheckedEverywhere = true; AssetDatabase.Refresh(); EditorUtility.SetDirty(NetLibrarySettings.single); AssetDatabase.SaveAssets(); return(true); }
/// <summary> /// Send a multi-language Telegram to the given users in their preferred language. /// </summary> /// <param name="Message">The multi-language text of the message.</param> /// <param name="Usernames">An enumeration of usernames.</param> public async Task <IEnumerable <MessageEnvelop> > SendTelegram(I18NString Message, IEnumerable <String> Usernames, ParseMode ParseMode) { #region Initial checks Usernames = Usernames.SafeSelect(username => username?.Trim()). SafeWhere(username => !username.IsNullOrEmpty()). ToArray(); if (Message.IsNullOrEmpty()) { throw new ArgumentNullException(nameof(Message), "The given message must not be null or empty!"); } if (Usernames.IsNullOrEmpty()) { throw new ArgumentNullException(nameof(Usernames), "The given enumeration of usernames must not be null or empty!"); } var responseMessages = new List <MessageEnvelop>(); #endregion var eventTrackingId = EventTracking_Id.New; #region Send OnSendTelegramRequest event var StartTime = Timestamp.Now; try { if (OnSendTelegramRequest != null) { await Task.WhenAll(OnSendTelegramRequest.GetInvocationList(). Cast <OnSendTelegramRequestDelegate>(). Select(e => e(StartTime, this, eventTrackingId, Message, Usernames))). ConfigureAwait(false); } } catch (Exception e) { DebugX.Log(e, nameof(TelegramStore) + "." + nameof(OnSendTelegramRequest)); } #endregion foreach (var username in Usernames) { if (UserByUsername.TryGetValue(username, out TelegramUser User)) { responseMessages.Add(new MessageEnvelop(username, User.ChatId, await TelegramAPI.SendTextMessageAsync( ChatId: User.ChatId, Text: Message[User.PreferredLanguage] ?? Message[Languages.en], ParseMode: ParseMode ))); } else { responseMessages.Add(new MessageEnvelop(username, new Telegram.Bot.Types.Message() { Text = "Unknown Telegram user '" + username + "'!" })); } } #region Send OnSendTelegramResponse event var Endtime = Timestamp.Now; try { if (OnSendTelegramResponse != null) { await Task.WhenAll(OnSendTelegramResponse.GetInvocationList(). Cast <OnSendTelegramResponseDelegate>(). Select(e => e(Endtime, this, eventTrackingId, Message, Usernames, responseMessages, Endtime - StartTime))). ConfigureAwait(false); } } catch (Exception e) { DebugX.Log(e, nameof(TelegramStore) + "." + nameof(OnSendTelegramResponse)); } #endregion return(responseMessages); }
/// <summary> /// Send a Telegram to the given user. /// </summary> /// <param name="Message">The text of the message.</param> /// <param name="Username">The name of the user.</param> public async Task <MessageEnvelop> SendTelegram(String Message, String Username, ParseMode ParseMode) { #region Initial checks Message = Message?.Trim(); Username = Username?.Trim(); if (Message.IsNullOrEmpty()) { throw new ArgumentNullException(nameof(Message), "The given message must not be null or empty!"); } if (Username.IsNullOrEmpty()) { throw new ArgumentNullException(nameof(Username), "The given username must not be null or empty!"); } MessageEnvelop responseMessage; #endregion var eventTrackingId = EventTracking_Id.New; var message = I18NString.Create(Languages.en, Message); var usernames = new String[] { Username }; #region Send OnSendTelegramRequest event var StartTime = Timestamp.Now; try { if (OnSendTelegramRequest != null) { await Task.WhenAll(OnSendTelegramRequest.GetInvocationList(). Cast <OnSendTelegramRequestDelegate>(). Select(e => e(StartTime, this, eventTrackingId, message, usernames))). ConfigureAwait(false); } } catch (Exception e) { DebugX.Log(e, nameof(TelegramStore) + "." + nameof(OnSendTelegramRequest)); } #endregion if (UserByUsername.TryGetValue(Username, out TelegramUser User)) { responseMessage = new MessageEnvelop(Username, User.ChatId, await TelegramAPI.SendTextMessageAsync( ChatId: User.ChatId, Text: Message )); } else { responseMessage = new MessageEnvelop(Username, new Telegram.Bot.Types.Message() { Text = "Unknown Telegram user '" + Username + "'!" }); } #region Send OnSendTelegramResponse event var Endtime = Timestamp.Now; try { if (OnSendTelegramResponse != null) { await Task.WhenAll(OnSendTelegramResponse.GetInvocationList(). Cast <OnSendTelegramResponseDelegate>(). Select(e => e(Endtime, this, eventTrackingId, message, usernames, new MessageEnvelop[] { responseMessage }, Endtime - StartTime))). ConfigureAwait(false); } } catch (Exception e) { DebugX.Log(e, nameof(TelegramStore) + "." + nameof(OnSendTelegramResponse)); } #endregion return(responseMessage); }