private void ParseFriendsList(string friendsList) { /* Sanitize the XML, it can break if over 40 friends long or so. */ int count = 0; //Logger.Debug("Before xml extract:" + friendsList); string xmlData = friendsList.Substring(friendsList.IndexOf("<", StringComparison.Ordinal) + friendsList.Length); Logger.Debug("Parsing XML buffer."); try { XDocument xdoc = XDocument.Parse(friendsList); Logger.Debug("Successful XML parse."); XElement rettest = xdoc.Element("OK"); if (rettest != null) { XElement xElement = xdoc.Element("OK"); if (xElement != null) Logger.Debug("Last friendslist action: " + xElement.Value); } IEnumerable<XElement> friends = xdoc.Descendants("item"); foreach (XElement friend in friends) { /* string preencode = Regex.Replace(friend.Element("name").Value, ".{2}", "\\x$0"); */ XElement xElement = friend.Element("name"); if (xElement != null) { byte[] byteenc = StringToByteArray(xElement.Value); //appendStatus("Friend:" + System.Text.Encoding.UTF8.GetString(byteenc)); count++; XElement element = friend.Element("pending"); if (element != null && element.Value == "1") { AppendStatus("Pending invite from CMDR " + Encoding.UTF8.GetString(byteenc) + "detected!"); if (Encoding.UTF8.GetString(byteenc) == MyClient.ClientName) { MyClient.Self.FriendRequest = RequestState.Recieved; AppendStatus("FR is from our client. Notifying Dispatch."); TPAMessage frmsg = new TPAMessage { action = "FriendRequest:update", data = new Dictionary<string, string> { {"FRReceived", "true"}, {"RatID", "abcdef1234567890"}, {"RescueID", "abcdef1234567890"} } }; _apworker.SendTpaMessage(frmsg); } } } } /* Check the OK status field, which can contain useful information on successful FRs. */ foreach (XElement element in xdoc.Descendants()) { if (element.Name != "OK") continue; XElement xElement1 = xdoc.Element("data"); if (xElement1 != null) { XElement element1 = xElement1.Element("OK"); if (element1 != null) Logger.Debug("Return code: " + element1.Value); } var xElement = xdoc.Element("data"); if (xElement != null) { var o = xElement.Element("OK"); if (o != null && (!o.Value.Contains("Invitation accepted"))) continue; } AppendStatus("Friend request accepted."); MyClient.Self.FriendRequest = RequestState.Accepted; } //AppendStatus("Parsed " + count + " friends in FRXML."); //Spammy! } catch (XmlException ex) { Logger.Fatal("XML Parsing exception - Probably netlog overflow. " + ex.Message); } catch (Exception ex) { Logger.Fatal("XML Parsing exception:" + ex.Message); _tc.TrackException(ex); } }
private void ParseWingInvite(string wingInvite) { Logger.Debug("Raw xmlData: " + wingInvite); try { XDocument xdoc = XDocument.Parse(wingInvite); Logger.Debug("Successful XML parse."); //voice.Speak("Wing invite detected."); IEnumerable<XElement> wing = xdoc.Descendants("commander"); foreach (XElement wingdata in wing) { XElement xElement = wingdata.Element("name"); if (xElement != null) { byte[] byteenc = StringToByteArray(xElement.Value); AppendStatus("Wingmember:" + Encoding.UTF8.GetString(byteenc)); if (_myrescue != null) { if (Encoding.UTF8.GetString(byteenc).ToLower() == _myrescue.Client.ToLower()) { AppendStatus("This data matches our current client! Storing information..."); XElement element = wingdata.Element("id"); if (element != null) MyClient.ClientId = element.Value; AppendStatus("Wingmember IP data:" + xdoc.Element("connectionDetails")); string wingIPPattern = "IP4NAT:([0-9.]+):\\d+\\,"; Match wingMatch = Regex.Match(wingInvite, wingIPPattern, RegexOptions.IgnoreCase); if (wingMatch.Success) { AppendStatus("Successful IP data match: " + wingMatch.Groups[1]); MyClient.ClientIp = wingMatch.Groups[1].Value; } /* If the friend request matches the client name, store his session ID. */ XElement o = wingdata.Element("commander_id"); if (o != null) MyClient.ClientId = o.Value; XElement xElement1 = wingdata.Element("session_runid"); if (xElement1 != null) MyClient.SessionId = xElement1.Value; MyClient.Self.WingRequest = RequestState.Recieved; TPAMessage wrmsg = new TPAMessage { action = "WingRequest:update", data = new Dictionary<string, string> { {"WRReceived", "true"}, {"RatID", "abcdef1234567890"}, {"RescueID", "abcdef1234567890"} } }; _apworker.SendTpaMessage(wrmsg); } } } } } catch (Exception ex) { Logger.Fatal("Error in parseWingInvite: " + ex.Message); _tc.TrackException(ex); } }
private void fueledButton_Click(object sender, RoutedEventArgs e) { if (MyClient.Rescue == null || MyPlayer.RatId.FirstOrDefault()==null) { Logger.Debug("Null rescue or RatID, not doin' nothing."); return; } TPAMessage fuelmsg = new TPAMessage {action = "Fueled:update"}; fuelmsg.data.Add("RatID", MyPlayer.RatId.FirstOrDefault()); fuelmsg.data.Add("RescueID", MyClient.Rescue.id); if (Equals(FueledButton.Background, Brushes.Red)) { AppendStatus("Reporting fueled status, requesting paperwork link..."); FueledButton.Background = Brushes.Green; fuelmsg.data.Add("Fueled", "true"); /* image.Source = new BitmapImage(RatTracker_WPF.Properties.Resources.yellow_light); */ } else { AppendStatus("Fueled status now negative."); FueledButton.Background = Brushes.Red; fuelmsg.data.Add("Fueled", "false"); } _apworker.SendTpaMessage(fuelmsg); }
private async void button1_Click(object sender, RoutedEventArgs e) { Logger.Debug("Begin TPA Jump Call..."); _myrescue = (Datum) RescueGrid.SelectedItem; if (_myrescue == null) { AppendStatus("Null myrescue! Failing."); return; } if (_myrescue != null && _myrescue.id == null) { Logger.Debug("Rescue ID is null!"); return; } if (_myrescue.Client == null) { AppendStatus("Null client."); return; } if (_myrescue.System == null) { AppendStatus("Null system."); return; } Logger.Debug("Null tests completed"); AppendStatus("Tracking rescue. System: " + _myrescue.System + " Client: " + _myrescue.Client); MyClient = new ClientInfo { ClientName = _myrescue.Client, Rescue = _myrescue, ClientSystem = _myrescue.System }; Logger.Debug("Client info loaded:"+MyClient.ClientName+" in "+MyClient.ClientSystem); _overlay?.SetCurrentClient(MyClient); ClientDistance distance = await GetDistanceToClient(MyClient.ClientSystem); //ClientDistance distance = new ClientDistance {Distance = 500}; AppendStatus("Sending jumps to IRC..."); Logger.Debug("Constructing TPA message..."); var jumpmessage = new TPAMessage(); Logger.Debug("Setting action."); jumpmessage.action = "CallJumps:update"; jumpmessage.applicationId = "0xDEADBEEF"; Logger.Debug("Set appID"); Logger.Debug("Constructing TPA for "+_myrescue.id+" with "+_myplayer.RatId.First()); jumpmessage.data = new Dictionary<string, string> { {"CallJumps", Math.Ceiling(distance.Distance/_myplayer.JumpRange).ToString(CultureInfo.InvariantCulture)}, {"RescueID", _myrescue.id}, {"RatID", _myplayer.RatId.FirstOrDefault()}, {"Lightyears", distance.Distance.ToString(CultureInfo.InvariantCulture)}, {"SourceCertainty", distance.SourceCertainty}, {"DestinationCertainty", distance.TargetCertainty} }; Logger.Debug("Sending TPA message"); _apworker.SendTpaMessage(jumpmessage); }
private void bcnButton_Click(object sender, RoutedEventArgs e) { RatState ratState = GetRatStateForButton(sender, BcnButton, BcnButtonCopy, BcnButtonCopy1); TPAMessage frmsg = new TPAMessage {data = new Dictionary<string, string>()}; if (MyClient?.Rescue != null) { frmsg.action = "BeaconSpotted:update"; frmsg.data.Add("RatID", MyPlayer.RatId.FirstOrDefault()); frmsg.data.Add("RescueID", MyClient.Rescue.id); } if (ratState.Beacon==false) { AppendStatus("Sending Beacon acknowledgement."); frmsg.data.Add("BeaconSpotted", "true"); } else { AppendStatus("Cancelling Beacon status."); frmsg.data.Add("BeaconSpotted", "false"); } if (frmsg.action != null && ratState.FriendRequest != RequestState.Recieved) { _apworker.SendTpaMessage(frmsg); } ratState.Beacon = !ratState.Beacon; }
private void instButton_Click(object sender, RoutedEventArgs e) { RatState ratState = GetRatStateForButton(sender, InstButton, InstButtonCopy, InstButtonCopy1); TPAMessage frmsg = new TPAMessage {data = new Dictionary<string, string>()}; if (MyClient?.Rescue != null) { frmsg.action = "InstanceSuccessful:update"; frmsg.data.Add("RatID", MyPlayer.RatId.FirstOrDefault()); frmsg.data.Add("RescueID", MyClient.Rescue.id); } if (ratState.InInstance==false) { AppendStatus("Sending Good Instance message."); frmsg.data.Add("InstanceSuccessful", "true"); } else { AppendStatus("Cancelling Good instance message."); frmsg.data.Add("InstanceSuccessful", "false"); } if (frmsg.action != null && ratState.FriendRequest != RequestState.Recieved) { _apworker.SendTpaMessage(frmsg); } ratState.InInstance = !ratState.InInstance; }
private void wrButton_Click(object sender, RoutedEventArgs e) { RatState ratState = GetRatStateForButton(sender, WrButton, WrButtonCopy, WrButtonCopy1); TPAMessage frmsg = new TPAMessage {data = new Dictionary<string, string>()}; if (MyClient?.Rescue != null) { frmsg.action = "WingRequest:update"; frmsg.data.Add("RatID", MyPlayer.RatId.FirstOrDefault()); frmsg.data.Add("RescueID", MyClient.Rescue.id); } switch (ratState.WingRequest) { case RequestState.NotRecieved: ratState.WingRequest = RequestState.Recieved; break; case RequestState.Recieved: AppendStatus("Sending Wing Request acknowledgement."); frmsg.data.Add("WingRequest", "true"); ratState.WingRequest = RequestState.Accepted; break; case RequestState.Accepted: ratState.WingRequest = RequestState.NotRecieved; AppendStatus("Cancelled WR status."); frmsg.data.Add("WingRequest", "false"); break; default: throw new ArgumentOutOfRangeException(); } if (frmsg.action != null && ratState.WingRequest != RequestState.Recieved) { _apworker.SendTpaMessage(frmsg); } }
private void sysButton_Click(object sender, RoutedEventArgs e) { RatState ratState = GetRatStateForButton(sender, SysButton, SysButtonCopy, SysButtonCopy1); TPAMessage frmsg = new TPAMessage {data = new Dictionary<string, string>()}; if (MyClient?.Rescue != null) { frmsg.action = "SysArrived:update"; frmsg.data.Add("RatID", MyPlayer.RatId.FirstOrDefault()); frmsg.data.Add("RescueID", MyClient.Rescue.id); } if (ratState.InSystem==false) { AppendStatus("Sending System acknowledgement."); frmsg.data.Add("ArrivedSystem", "true"); } else { AppendStatus("Cancelling System status."); frmsg.data.Add("ArrivedSystem", "false"); } if (frmsg.action != null) { _apworker.SendTpaMessage(frmsg); } ratState.InSystem = !ratState.InSystem; }
private void UpdateButton_Click(object sender, RoutedEventArgs e) { // No more of this testing bull, let's actually send the updated system now. if (MyClient==null) { Logger.Debug("No current rescue, ignoring system update request."); return; } TPAMessage systemmessage = new TPAMessage { action = "ClientSystem:update", data = new Dictionary<string, string> { {"SystemName", SystemName.Text}, {"RatID", _myplayer.RatId.FirstOrDefault()}, {"RescueID", MyClient.Rescue.id} } }; _apworker.SendTpaMessage(systemmessage); }
private void DutyButton_Click(object sender, RoutedEventArgs e) { if (MyPlayer.OnDuty == false) { Button.Content = "On Duty"; MyPlayer.OnDuty = true; _watcher.EnableRaisingEvents = true; AppendStatus("Started watching for events in netlog."); Button.Background = Brushes.Green; StopNetLog = false; _threadLogWatcher = new Thread(NetLogWatcher) {Name = "Netlog watcher"}; _threadLogWatcher.Start(); } else { Button.Content = "Off Duty"; MyPlayer.OnDuty = false; _watcher.EnableRaisingEvents = false; AppendStatus("\nStopped watching for events in netlog."); Button.Background = Brushes.Red; StopNetLog = true; } try { TPAMessage dutymessage = new TPAMessage { action = "OnDuty:update", data = new Dictionary<string, string> { {"OnDuty", MyPlayer.OnDuty.ToString()}, {"RatID", _myplayer.RatId.FirstOrDefault()}, {"currentSystem", MyPlayer.CurrentSystem} } }; // _apworker.SendTpaMessage(dutymessage); // Disabled while testing, it's spammy. } catch (Exception ex) { Logger.Fatal("Exception in sendTPAMessage: " + ex.Message); _tc.TrackException(ex); } }
private async void TriggerSystemChange(string value) { Dispatcher disp = Dispatcher; if (value == MyPlayer.CurrentSystem) { return; // Already know we're in that system, thanks. } MyPlayer.CurrentSystem = value; try { _tc.TrackEvent("SystemChange"); using (HttpClient client = new HttpClient()) { UriBuilder content = new UriBuilder(EdsmUrl + "systems?sysname=" + value + "&coords=1") {Port = -1}; NameValueCollection query = HttpUtility.ParseQueryString(content.Query); content.Query = query.ToString(); HttpResponseMessage response = await client.GetAsync(content.ToString()); response.EnsureSuccessStatusCode(); string responseString = await response.Content.ReadAsStringAsync(); IEnumerable<EdsmSystem> m = JsonConvert.DeserializeObject<IEnumerable<EdsmSystem>>(responseString); EdsmSystem firstsys = m.FirstOrDefault(); // EDSM should return the closest lexical match as the first element. Trust that - for now. if (firstsys != null && firstsys.Name == value) { if (firstsys.Coords == default(EdsmCoords)) Logger.Debug("Got a match on " + firstsys.Name + " but it has no coords."); else Logger.Debug("Got definite match in first pos, disregarding extra hits:" + firstsys.Name + " X:" + firstsys.Coords.X + " Y:" + firstsys.Coords.Y + " Z:" + firstsys.Coords.Z); //AppendStatus("Got M:" + firstsys.name + " X:" + firstsys.coords.x + " Y:" + firstsys.coords.y + " Z:" + firstsys.coords.z); if (_myTravelLog == null) { _myTravelLog=new Collection<TravelLog>(); } _myTravelLog.Add(new TravelLog() {System = firstsys, LastVisited = DateTime.Now}); Logger.Debug("Added system to TravelLog."); // Should we add systems even if they don't exist in EDSM? Maybe submit them? } if (_myrescue != null) { if (_myrescue.System == value) { AppendStatus("Arrived in client system. Notifying dispatch."); Logger.Info("Sending 3PA sys+ message!"); TPAMessage sysmsg = new TPAMessage { action = "SysArrived:update", data = new Dictionary<string, string> { {"SysArrived", "true"}, {"RatID", _myplayer.RatId.FirstOrDefault()}, {"RescueID", _myrescue.id} } }; _apworker.SendTpaMessage(sysmsg); MyClient.Self.InSystem = true; } } await disp.BeginInvoke(DispatcherPriority.Normal, (Action) (() => SystemNameLabel.Content = value)); if (responseString.Contains("-1")) { await disp.BeginInvoke(DispatcherPriority.Normal, (Action) (() => SystemNameLabel.Foreground = Brushes.Red)); } else { await disp.BeginInvoke(DispatcherPriority.Normal, (Action) (() => SystemNameLabel.Foreground = Brushes.Orange)); } if (responseString.Contains("coords")) { await disp.BeginInvoke(DispatcherPriority.Normal, (Action) (() => SystemNameLabel.Foreground = Brushes.Green)); if (firstsys != null) { Logger.Debug("Getting distance from fuelum to " + firstsys.Name); double distance = await CalculateEdsmDistance("Fuelum", firstsys.Name); distance = Math.Round(distance, 2); await disp.BeginInvoke(DispatcherPriority.Normal, (Action) (() => DistanceLabel.Content = distance + "LY from Fuelum")); } } } } catch (Exception ex) { Logger.Fatal("Exception in triggerSystemChange: " + ex.Message); _tc.TrackException(ex); } }
private void ParseLine(string line) { try { if (string.IsNullOrEmpty(line)) { Logger.Error("ParseLine was passed a null or empty line. This should not happen!"); return; } // string reMatchSystem = ".*?(System:).*?\\(((?:[^)]+)).*?\\)"; // Pre-1.6/2.1 style const string reMatchSystem = ".*?(System:)\"(.*)?\".*?\\(((?:[^)]+)).*?\\)"; Match match = Regex.Match(line, reMatchSystem, RegexOptions.IgnoreCase); if (match.Success) { if (match.Groups[2].Value == _myplayer.CurrentSystem) return; TriggerSystemChange(match.Groups[2].Value); } const string reMatchPlayer = "\\{.+\\} (\\d+) x (\\d+).*\\(\\(([0-9.]+):\\d+\\)\\)Name (.+)$"; Match frmatch = Regex.Match(line, reMatchPlayer, RegexOptions.IgnoreCase); if (frmatch.Success) { Logger.Debug("PlayerMatch parsed"); if (_scState == "Normalspace" && _myrescue!=null) { AppendStatus("Successful ID match in normal space. Sending good instance."); MyClient.Self.InInstance = true; TPAMessage instmsg = new TPAMessage { action = "InstanceSuccessful:update", data = new Dictionary<string, string> { {"RatID", _myplayer.RatId.ToString()}, {"InstanceSuccessful", "true"}, {"RescueID", _myrescue.id} } }; _apworker.SendTpaMessage(instmsg); } AppendStatus("Successful identity match! ID: " + frmatch.Groups[1] + " IP:" + frmatch.Groups[3]); } const string reMatchNat = @"RxRoute:(\d+)+ Comp:(\d)\[IP4NAT:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})+:(\d{1,5}),(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})+:(\d{1,5}),(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})+:(\d{1,5}),(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})+:(\d{1,5}),(\d),(\d),(\d),(\d{1,4})\]\[Relay:"; Match natmatch = Regex.Match(line, reMatchNat, RegexOptions.IgnoreCase); if (natmatch.Success) { Logger.Debug("Found NAT datapoint for runID " + natmatch.Groups[1] + ": " + natmatch.Groups[11]); NatType clientnat = (NatType) Enum.Parse(typeof (NatType), match.Groups[11].Value); switch (clientnat) { case NatType.Blocked: _tc.TrackMetric("ClientNATBlocked", 1); break; case NatType.Unknown: _tc.TrackMetric("ClientNATUnknown", 1); break; case NatType.Open: _tc.TrackMetric("ClientNATOpen", 1); break; case NatType.FullCone: _tc.TrackMetric("ClientNATFullCone", 1); break; case NatType.Failed: _tc.TrackMetric("ClientNATFailed", 1); break; case NatType.SymmetricUdp: _tc.TrackMetric("ClientNATSymmetricUDP", 1); break; case NatType.Restricted: _tc.TrackMetric("ClientNATRestricted", 1); break; case NatType.Symmetric: _tc.TrackMetric("ClientNATSymmetric", 1); break; } _tc.Flush(); } const string reMatchStats = "machines=(\\d+)&numturnlinks=(\\d+)&backlogtotal=(\\d+)&backlogmax=(\\d+)&avgsrtt=(\\d+)&loss=([0-9]*(?:\\.[0-9]*)+)&&jit=([0-9]*(?:\\.[0-9]*)+)&act1=([0-9]*(?:\\.[0-9]*)+)&act2=([0-9]*(?:\\.[0-9]*)+)"; Match statmatch = Regex.Match(line, reMatchStats, RegexOptions.IgnoreCase); if (statmatch.Success) { Logger.Info("Updating connection statistics."); ConnInfo.Srtt = int.Parse(statmatch.Groups[5].Value); ConnInfo.Loss = float.Parse(statmatch.Groups[6].Value); ConnInfo.Jitter = float.Parse(statmatch.Groups[7].Value); ConnInfo.Act1 = float.Parse(statmatch.Groups[8].Value); ConnInfo.Act2 = float.Parse(statmatch.Groups[9].Value); Dispatcher disp = Dispatcher; disp.BeginInvoke(DispatcherPriority.Normal, (Action) (() => ConnectionStatus.Text = "SRTT: " + Conninfo.Srtt + " Jitter: " + Conninfo.Jitter + " Loss: " + Conninfo.Loss + " In: " + Conninfo.Act1 + " Out: " + Conninfo.Act2)); } if (line.Contains("</data>")) { Logger.Debug("End of FriendsXML, send buffer to friendsparser."); _xmlparselist += line; ParseFriendsList(_xmlparselist); return; } if (line.Contains("<item>")) { Logger.Debug("Appending xml item to parselist."); _xmlparselist += line; return; } if (line.Contains("<data>")) { Logger.Debug("Startline for FriendsXML, initialize XML buffer"); _xmlparselist = ""; _xmlparselist += line; return; } if (line.Contains("<FriendWingInvite>")) { Logger.Debug("Wing invite detected, parsing..."); ParseWingInvite(line); } if (line.Contains("JoinSession:WingSession:") && line.Contains(MyClient.ClientIp)) { Logger.Debug("Prewing communication underway..."); } if (line.Contains("TalkChannelManager::OpenOutgoingChannelTo") && line.Contains(MyClient.ClientIp)) { AppendStatus("Wing established, opening voice comms."); //voice.Speak("Wing established."); MyClient.Self.WingRequest = RequestState.Accepted; } if (line.Contains("ListenResponse->Listening (SUCCESS: User has responded via local talkchannel)")) { AppendStatus("Voice communications established."); } if (line.Contains("NormalFlight") && _scState == "Supercruise") { _scState = "Normalspace"; Logger.Debug("Drop to normal space detected."); //voice.Speak("Dropping to normal space."); } if (line.Contains("Supercruise") && _scState == "Normalspace") { _scState = "Supercruise"; Logger.Debug("Entering supercruise."); //voice.Speak("Entering supercruise."); } if (line.Contains("JoinSession:BeaconSession") && line.Contains(MyClient.ClientIp)) { AppendStatus("Client's Beacon in sight."); MyClient.Self.Beacon = true; if (_myrescue != null) { TPAMessage bcnmsg = new TPAMessage { action = "BeaconSpotted:update", data = new Dictionary<string, string> { {"BeaconSpotted", "true"}, {"RatID", _myplayer.RatId.ToString()}, {"RescueID", _myrescue.id} } }; _apworker.SendTpaMessage(bcnmsg); } } } catch (Exception ex) { Logger.Debug("Exception in ParseLine: " + ex.Message + "@"+ex.Source +":"+ ex.Data); _tc.TrackException(ex); } }
public void SendTpaMessage(TPAMessage message) { if (Ws == null) { Logger.Debug("Attempt to send TPA message over uninitialized WS connection!"); return; } message.data.Add("platform", "PC"); message.applicationId = Properties.Settings.Default.AppID; string json = JsonConvert.SerializeObject(message); Logger.Debug("Serialized TPA data: " + json); Ws.Send(json); }