/// <summary> /// 判断本任务以及所有子任务是否完毕 /// 如果完毕则通知父页 /// </summary> /// <param name="snifferManager"></param> public void PageDone(SnifferManager snifferManager) { //snifferManager?.OnPageDoneEventHandler(this); //if (this.Config.Plug != null) // this.Config.Plug.OnPageDoneEventHandler(this); //所有子页已完成,则标注已完成状态 if (SubPages.All(x => x.Done && x.SnifferState == SnifferState.Complate)) { SnifferState = SnifferState.Complate; } if (ParentPage == null) { if (SubPages.All(x => x.Done && x.SnifferState == SnifferState.Complate)) { //触发顶级页采集完毕事件 snifferManager?.OnRootPageDoneEventHandler(this, snifferManager.Context); if (this.Config.Plug != null) { this.Config.Plug.OnRootPageDoneEventHandler(this, snifferManager.Context); } } } else { //当前页以及当前页的所有子页完毕 if (SnifferState == SnifferState.Complate) { if (Config.PageType == PageType.DetailPage) { //当前详细页以及详细页内容采集完毕 snifferManager?.OnDetailPageDoneEventHandler(this as DetailPage, snifferManager.Context); if (this.Config.Plug != null) { this.Config.Plug.OnDetailPageDoneEventHandler(this as DetailPage, snifferManager.Context); } } else { //列表页以及所有子页采集完毕 snifferManager?.OnListPageDoneEventHandler(this as ListPage, snifferManager.Context); if (this.Config.Plug != null) { this.Config.Plug.OnListPageDoneEventHandler(this as ListPage, snifferManager.Context); } } //触发父页 PageDone ParentPage.PageDone(snifferManager); } } }
public static string ToHuman(this SnifferState state) { switch (state) { case SnifferState.IN_MENUS: return("Browsing the menus"); case SnifferState.SONG_ENDING: return("Song ending"); case SnifferState.SONG_PLAYING: return("Playing a song"); case SnifferState.SONG_SELECTED: return("Preparing to play a song"); case SnifferState.SONG_STARTING: return("Song starting"); default: return(""); } }
/// <summary> /// Update the state of the sniffer /// </summary> private void UpdateState() { //Super complex state machine of state transitions switch (currentState) { case SnifferState.IN_MENUS: if (currentMemoryReadout.songTimer != 0) { currentState = SnifferState.SONG_SELECTED; } break; case SnifferState.SONG_SELECTED: if (currentMemoryReadout.songTimer == 0) { currentState = SnifferState.SONG_STARTING; } //If we somehow missed some states, skip to SONG_PLAYING //Or if the user reset if (currentMemoryReadout.songTimer > 1) { currentState = SnifferState.SONG_PLAYING; } break; case SnifferState.SONG_STARTING: if (currentMemoryReadout.songTimer > 0) { currentState = SnifferState.SONG_PLAYING; } break; case SnifferState.SONG_PLAYING: //Allow 5 seconds of error margin on song ending if (currentMemoryReadout.songTimer >= currentCDLCDetails.songLength - 5) { currentState = SnifferState.SONG_ENDING; } //If the timer goes to 0, the user must have quit if (currentMemoryReadout.songTimer == 0) { currentState = SnifferState.IN_MENUS; } break; case SnifferState.SONG_ENDING: if (currentMemoryReadout.songTimer == 0) { currentState = SnifferState.IN_MENUS; } break; default: break; } //Force state to IN_MENUS if the current song details are not valid if (!currentCDLCDetails.IsValid()) { currentState = SnifferState.IN_MENUS; } //If state changed if (currentState != previousState) { //Invoke event OnStateChanged?.Invoke(this, new OnStateChangedArgs() { oldState = previousState, newState = currentState }); //Remember previous state previousState = currentState; if (Logger.logStateMachine) { Logger.Log("Current state: {0}", currentState.ToString()); } } }
private void Sniffer_OnStateChanged(object sender, OnStateChangedArgs e) { State = e.newState; UpdatePresence(); }
internal void UpdatePresence() { //Construct rich presence var rp = new RichPresence(); rp.Assets = new Assets(); rp.Assets.LargeImageKey = "rocksmith"; rp.Assets.LargeImageText = "Rocksmith 2014 Remastered"; //If we have a valid song and are playing a song if ((songdetails != null && readout != null) && (state == SnifferState.SONG_STARTING || state == SnifferState.SONG_PLAYING || state == SnifferState.SONG_ENDING)) { //Get the arrangement based on the arrangement id var arrangement = songdetails.arrangements.FirstOrDefault(x => x.arrangementID == readout.arrangementID); //Add song name rp.Details = $"Playing {songdetails.songName}"; //Add artist name rp.State = $"by {songdetails.artistName}"; //Set song timer rp.Timestamps = new Timestamps(DateTime.UtcNow, DateTime.UtcNow.AddSeconds(songdetails.songLength - readout.songTimer)); //Calculate accuracy float accuracy = readout.noteData.Accuracy; string accuracyText = FormattableString.Invariant($"{accuracy:F2}%"); //Set accuracy as text for arrangement icon rp.Assets.SmallImageText = accuracyText; if (readout.mode == RSMode.SCOREATTACK) { var sand = (ScoreAttackNoteData)readout.noteData; rp.Assets.SmallImageText = $"{FormattableString.Invariant($"{sand.CurrentScore:n0}")} x{sand.CurrentMultiplier} | {rp.Assets.SmallImageText}"; if (sand.FailedPhrases > 0) { rp.Assets.SmallImageText = $"{new string('X', sand.FailedPhrases)} | {rp.Assets.SmallImageText}"; } } //When we got the arrangement if (arrangement != null) { //Set arrangement icon rp.Assets.SmallImageKey = arrangement.type.ToLower(); //Try to get section var section = arrangement.sections.LastOrDefault(x => x.startTime < readout.songTimer); //If we got a section if (section != null) { //Add section to small image text rp.Assets.SmallImageText = $"{section.name} | {rp.Assets.SmallImageText}"; } } } else { rp.Details = "Browsing Menus"; if (readout != null) { string gameStage = readout.gameStage.ToLowerInvariant().Trim(); string state = ""; if (gameStage.StartsWith("main")) { state = "Main Menu"; } else if (gameStage.StartsWith("las")) { state = "Learn A Song"; } else if (gameStage.StartsWith("sm")) { state = "Session Mode"; } else if (gameStage.StartsWith("nsp")) { state = "Nonstop Play"; } else if (gameStage.StartsWith("sa")) { state = "Score Attack"; } else if (gameStage.StartsWith("guitarcade") || gameStage.StartsWith("gc_games")) { state = "Guitarcade"; } else if (gameStage.StartsWith("gcade")) { rp.Details = "Playing Guitarcade"; state = ""; if (gcadeGames.ContainsKey(readout.songID)) { state = gcadeGames[readout.songID]; } } else if (gameStage.StartsWith("ge_")) { state = "Lessons"; } else if (gameStage.StartsWith("mp_")) { state = "Multiplayer"; } else if (gameStage.StartsWith("shop")) { state = "Shop"; } rp.State = state; } rp.Timestamps = new Timestamps(appStartTime); } client.SetPresence(rp); }
private void Sniffer_OnStateChanged(object sender, RockSnifferLib.Events.OnStateChangedArgs e) { state = e.newState; UpdatePresence(); }
public void Device_OnPacketArrival(object sender, CaptureEventArgs capture) { // skip packets which are obviously too small if (capture.Packet.Data.Length < 42) { return; } // skip none-UDP packets (TCP, ICMP,...) else if (capture.Packet.Data[0x17] != 0x11) { return; } string sourceIpAddress = capture.Packet.Data.Length < 29 ? string.Empty : $"{(uint)capture.Packet.Data[26]}.{(uint)capture.Packet.Data[27]}.{(uint)capture.Packet.Data[28]}.{(uint)capture.Packet.Data[29]}"; string destinationIpAddress = capture.Packet.Data.Length < 33 ? string.Empty : $"{(uint)capture.Packet.Data[30]}.{(uint)capture.Packet.Data[31]}.{(uint)capture.Packet.Data[32]}.{(uint)capture.Packet.Data[33]}"; switch (_snifferState) { case SnifferState.WaitingForDrone: // an other interface could already have found the ip-address // but this interface hasn't been shutdown yet if (!string.IsNullOrEmpty(_operatorIpAddress)) { return; } // as we have no clue what the operator ip is, we // need to wrap the bytes into a UDP-Packet and // extract the source and destination ip-address // if we the packet isn't drone-related, skip if (destinationIpAddress != DRONE_IP_ADDRESS && sourceIpAddress != DRONE_IP_ADDRESS) { return; } // the very first packet could be either from the drone // or from the operator. Thus, if it is from the drone, // we require to switch SRC and DEST, as the following // code expects an operator as a SRC address. if (sourceIpAddress == DRONE_IP_ADDRESS) { sourceIpAddress = destinationIpAddress; destinationIpAddress = DRONE_IP_ADDRESS; } IPAddress sourceIpAddr = IPAddress.Parse(sourceIpAddress); // ignore network and broadcast packets + ignore non-local packets if (sourceIpAddr.GetAddressBytes()[3] == 0) { return; } else if (sourceIpAddr.GetAddressBytes()[3] == Convert.ToInt16(255)) { return; } else if (!sourceIpAddress.StartsWith("192.168")) { return; } // ignore our own ip address var localAddresses = Dns.GetHostEntry(Dns.GetHostName()) .AddressList.Where(a => a.AddressFamily == AddressFamily.InterNetwork) .Select(s => s.ToString()).ToList(); if (localAddresses.Contains(sourceIpAddress)) { return; } // drone has been found. We require to do following actions: // 1. remember the operator's ip-address // 2. switch the local state to 'PacketSniffing' // 3. notify any possible subscribers about our accomplishment // 4. reroute this packet to the subscribers, as this is our first valid packet // 5. stop listening on all other interfaces var networkInformation = new DjiNetworkInformation(sourceIpAddress, DRONE_IP_ADDRESS, NetworkStatus.Connected); Trace.TraceInformation($"Interface {capture.Device?.Name ?? "Simulation"} detected possible drone interaction {sourceIpAddress} -> {destinationIpAddress}"); _operatorIpAddress = networkInformation.OperatorIpAddress; _snifferState = SnifferState.PacketSniffing; _networkInformationReceivedSource?.Raise(capture, networkInformation); Device_OnPacketArrival(sender, capture); Task.Run(() => { var irrelevantDevices = _captureDevices.Where(cp => cp != capture.Device).ToList(); for (int index = 0; index < irrelevantDevices.Count; index++) { ShutdownInterface(irrelevantDevices[index]); } }); break; case SnifferState.PacketSniffing: // ignore all none-dji related network packets if ((destinationIpAddress != DRONE_IP_ADDRESS && destinationIpAddress != _operatorIpAddress) || (sourceIpAddress != DRONE_IP_ADDRESS && sourceIpAddress != _operatorIpAddress)) { return; } // determine based on the sender who sent the packet var participant = sourceIpAddress == DRONE_IP_ADDRESS ? Participant.Drone : Participant.Operator; var networkPacket = new NetworkPacket(participant, sourceIpAddress, destinationIpAddress, capture.Packet); _networkPackets.Enqueue(networkPacket); _networkFrameAvailable.Set(); break; default: throw new ApplicationException($"{nameof(SnifferState)} hasn't been implemented yet"); } }