using MDS.Controls; using MDS.DataModels; using MDS.Units; using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Configuration; using System.Data; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Media.Animation; namespace MDS { /// /// Логика взаимодействия для App.xaml /// public partial class App : Application, INotifyPropertyChanged { public enum Mode { Demo, Study, Training, Exam, Quiz}; private static string _client; private static string _workplace; private static bool _checker; public static bool Checker { set { if (value != _checker) { _checker = value; } } get { return _checker; } } private static ObservableCollection _clients = new ObservableCollection(); public static ObservableCollection Clients { get { return _clients; } } public static Frame MainFrame; private static TelnetDotNet Telnet; public static Assembly CurrentDevice; private static ObservableCollection _units; public static ObservableCollection Units { get { return _units; } private set { if (value != _units) { _units = value; } } } private static Mode _currentMode; public static Mode CurrentMode { get { return _currentMode; } set { if (value != _currentMode) { _currentMode = value; } } } private static Random rand = new Random(); public static Random Rand { get { return rand; } } private static Tutorial activeTutorial; public static Tutorial ActiveTutorial { get { return activeTutorial; } set { if (value != activeTutorial) { activeTutorial = value; if(activeTutorial.RandValues!=null) { foreach(var val in activeTutorial.RandValues) { val.Min = RandVarReplace(val.Min, activeTutorial.RandValues); val.Max = RandVarReplace(val.Max, activeTutorial.RandValues); val.Value = Rand.Next(int.Parse(val.Min), int.Parse(val.Max)); if (val.Mod != 0) val.Value = val.Value - val.Value % val.Mod; } } activeTutorial.ExamDescription = RandVarReplace(activeTutorial.ExamDescription, activeTutorial.RandValues); foreach (var step in activeTutorial.Steps) { step.Title = RandVarReplace(step.Title, activeTutorial.RandValues); step.Command = RandVarReplace(step.Command, activeTutorial.RandValues); if(step.Conditions!=null) { foreach(var cond in step.Conditions) cond.Value = RandVarReplace(cond.Value, activeTutorial.RandValues); } } } } } public static string RandVarReplace(string text, List values) { string output = text; if (values != null) { for (int i = 0; i < values.Count(); i++) output = output.Replace("[" + i + "]", values[i].Value.ToString()); } return output; } public static Window TutorialWindow; public App() { Units = new ObservableCollection(); Telnet = new TelnetDotNet(); Telnet.MessageRecieved += Telnet_MessageRecieved; Current.Exit += Current_Exit; } void Current_Exit(object sender, ExitEventArgs e) { Telnet.Close(); } public static void StartDemo(string workplace) { Task.Run(() => { Current.Dispatcher.BeginInvoke(new Action(() => { MainFrame.Content = Activator.CreateInstance(CurrentDevice.GetType(workplace), Mode.Demo.ToString()); })); }); } public static void Start(string workplace) { Task.Run(() => { Current.Dispatcher.BeginInvoke(new Action(() => { try { MainFrame.Content = Activator.CreateInstance(CurrentDevice.GetType(workplace), CurrentMode.ToString()); } catch(Exception) { MainFrame.Content = Activator.CreateInstance(CurrentDevice.GetType(workplace)); } switch (CurrentMode) { case Mode.Study: TutorialWindow = new TutorialWindow(); TutorialWindow.Topmost = true; TutorialWindow.Show(); break; case Mode.Exam: TutorialWindow = new ExamWindow(); TutorialWindow.Topmost = true; TutorialWindow.Show(); break; } })); }); } public static void PrepareControls() { if (ActiveTutorial != null && ActiveTutorial.PrepareControls != null) { foreach (var control in ActiveTutorial.PrepareControls) { CheckBox chkBox = FindChild(Current.MainWindow, control) as CheckBox; if (chkBox != null) { chkBox.IsChecked = !chkBox.IsChecked; } else { try { //TODO: програмное нажатие кнопки (App.MainFrame.Content as BaseFrame).prepareElement(control); } catch (Exception) { } } } } } public static void Stop() { if (TutorialWindow != null) TutorialWindow.Close(); Telnet.Close(); Current.Dispatcher.BeginInvoke(new Action(() => { if (App.Current.MainWindow.WindowStyle == WindowStyle.None) { App.Current.MainWindow.WindowStyle = WindowStyle.SingleBorderWindow; App.Current.MainWindow.ResizeMode = ResizeMode.CanResize; App.Current.MainWindow.WindowStartupLocation = WindowStartupLocation.CenterScreen; App.Current.MainWindow.WindowState = WindowState.Normal; App.Current.MainWindow.Hide(); App.Current.MainWindow.Show(); } MainFrame.Source = new Uri("MenuPage.xaml", UriKind.RelativeOrAbsolute); })); foreach (var u in Units) u.Dispose(); Units.Clear(); } public static bool BroadcastMessage(string Message, bool FromTelnet) { if (Message != null) { bool MessageAccepted = false; foreach (Unit unit in Units) { if (unit.RecieveMessage(Message)) { MessageAccepted = true; } } if (Telnet.IsConnected && !FromTelnet) { Telnet.Send(Message); } if (CurrentMode == Mode.Exam || CurrentMode == Mode.Study) { if (ActiveTutorial.CurrentStep != null && ActiveTutorial.CurrentStep.Command != null) { if (Message.Contains(ActiveTutorial.CurrentStep.Command)) { if (ActiveTutorial.CurrentStep.Conditions != null && ActiveTutorial.CurrentStep.Conditions.Count > 0) { foreach (var cond in ActiveTutorial.CurrentStep.Conditions) { object unit = App.Units.FirstOrDefault(u => u.Name == cond.UnitName); if (unit != null) { string[] path = cond.Path.Split('/'); PropertyInfo propertyInfo = null; object property = unit; Type type = unit.GetType(); foreach (var segment in path) { if (segment[0] == '[') { if (!segment.Contains('=')) { int index; int.TryParse(segment.Substring(1, segment.Length - 2), out index); int i = 0; foreach (var element in property as IEnumerable) { if (index == i) { property = element; break; } i++; } } else { int eqSignPos = segment.IndexOf('='); string key = segment.Substring(1, eqSignPos - 1); string value = segment.Substring(eqSignPos + 1, segment.Length - eqSignPos - 2); foreach (var element in property as IEnumerable) { PropertyInfo elemInfo = element.GetType().GetProperty(key); if (elemInfo.GetValue(element).ToString() == value) { property = element; break; } } } } else { propertyInfo = type.GetProperty(segment); if (propertyInfo != null) property = propertyInfo.GetValue(property); } if (property == null) break; type = property.GetType(); } if (cond.Tolerance != 0) { if (Math.Abs(double.Parse(property.ToString()) - double.Parse(cond.Value)) <= cond.Tolerance) cond.IsMet = true; } else { if (property != null) { switch (type.Name) { case "bool": if (((bool)property == true && cond.Value == "True") || ((bool)property == false && cond.Value == "False")) cond.IsMet = true; break; default: if (property.ToString() == (cond.Value)) cond.IsMet = true; break; } } } } } if (ActiveTutorial.CurrentStep.Conditions.Where(c => c.IsMet).Count() == ActiveTutorial.CurrentStep.Conditions.Count()) TutorialStepCompleted(); } else TutorialStepCompleted(); } } } return MessageAccepted; } else { return false; } } private static void TutorialStepCompleted() { ActiveTutorial.NextStep(); } public static void Connect(string Server, string Client, string Workplace) { _client = Client; _workplace = Workplace; Telnet.Connected += Telnet_Connected; Telnet.Connect(Server, 27027); } static void Telnet_Connected(object sender, EventArgs e) { Telnet.Send(String.Format("Connect {0} {1}", _client, _workplace)); App.Current.Dispatcher.BeginInvoke(new Action(() => Start(_workplace))); } public static void StartServer(int Port) { Telnet.StartServer(Port); } static void Telnet_MessageRecieved(object sender, string e) { if (e != null) { String[] Comms = e.Split('\n'); List Commands = new List(Comms); Commands.Sort(); foreach (string command in Commands) { if (command != String.Empty) { String[] Message = command.Split(' '); switch (Message[0]) { case "Connect": //TODO if (Checker == true && Telnet.ClientSocket == null) { string[] MessageSplitted = {""}; MessageSplitted = Message[2].Split(new string[] { "Big" }, StringSplitOptions.None); if (MessageSplitted.Length < 2) { MessageSplitted = Message[2].Split(new string[] { "Small" }, StringSplitOptions.None); } if (Message[2].Contains("OperatorPage")) { int op_counter = 0; if (MainFrame.Content.ToString().Contains("OperatorPage")) op_counter += 1; foreach (Client imposter in Clients) if (imposter.Workspace.Contains("OperatorPage")) op_counter += 1; if (op_counter < 2) Clients.Add(new Client(Message[1], Message[2])); else Telnet.Send(String.Format("You are impostor {0}", Message[1])); } else { if(!MainFrame.Content.ToString().Contains(MessageSplitted[1])) { foreach (Client imposter in Clients) if (imposter.Workspace == Message[2]) { Telnet.Send(String.Format("You are impostor {0}", Message[1])); break; } Clients.Add(new Client(Message[1], Message[2])); } else Telnet.Send(String.Format("You are impostor {0}", Message[1])); } } else Clients.Add(new Client(Message[1], Message[2])); break; case "You": if (Message[3] == Telnet.ClientSocket.LocalEndPoint.ToString().Split(':')[0]) { App.Stop(); MessageBox.Show("Server closed connection", "Closed", MessageBoxButton.OK, MessageBoxImage.Information); } else { foreach (Client impostor in Clients) { if (Message[3] == impostor.IPAddress) { Clients.Remove(impostor); } } } break; default: if(command != "CommonInfoArrayNotif 53 0") BroadcastMessage(command, true); break; } } } } } public static DependencyObject FindChild(DependencyObject parent, string name) { if (parent == null || string.IsNullOrEmpty(name)) return null; if (parent is FrameworkElement && (parent as FrameworkElement).Name == name) return parent; DependencyObject result = null; if (parent is FrameworkElement) (parent as FrameworkElement).ApplyTemplate(); int childrenCount = VisualTreeHelper.GetChildrenCount(parent); for (int i = 0; i < childrenCount; i++) { var child = VisualTreeHelper.GetChild(parent, i); result = FindChild(child, name); if (result != null) break; } return result; } public static double GetAngle(double x, double y) { if (x == 0) { if (y > 0) return 180; else return 0; } else { if (x > 0 && y < 0) return 90 - Math.Atan(Math.Abs(y) / x) * 180 / Math.PI; if (x > 0 && y >= 0) return Math.Atan(y / x) * 180 / Math.PI + 90; if (x < 0 && y >= 0) return -Math.Atan(y / Math.Abs(x)) * 180 / Math.PI + 270; if (x < 0 && y < 0) return Math.Atan(Math.Abs(y) / Math.Abs(x)) * 180 / Math.PI + 270; } return 0; } #region INotify public event PropertyChangedEventHandler PropertyChanged; public void NotifyPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } #endregion } }