using System; using System.Collections.Generic; using System.Windows.Forms; using System.IO; using DBAccessPluginNamespace; namespace VisualPascalABCPlugins { //имя класса *_VisualPascalABCPlugin public class VisualPascalABCPlugin_TeacherControlPlugin : IExtendedVisualPascalABCPlugin { private const string LabelEntered = "Авторизация: "; private const string LabelNotEntered = "Авторизация: вход не выполнен"; public static string StringsPrefix = "VPP_REGISTER_AND_CONTROL_PLUGIN_"; IVisualEnvironmentCompiler VisualEnvironmentCompiler; IWorkbench Workbench; //private TeacherControlForm RegisterForm = new TeacherControlForm(); // старая форма авторизации //private LoginForm RegisterFormNew = new LoginForm(); // новая форма авторизации // User SiteAccessProvider User; private PluginGUIItem Item; public string Name { get => "Teacher Control Plugin"; } public string Version { get => "0.1"; } public string Copyright { get => "Copyright © 2021-2024 by Stanislav Mikhalkovich"; } public string Login = null; public string Password = null; public LoginForm loginForm; public ToolStripMenuItem menuItem = null; public ToolStripButton toolStripButton = null; // public string AuthFileFullName = ""; public bool IsMechmath; public VisualPascalABCPlugin_TeacherControlPlugin(IWorkbench Workbench) { this.Workbench = Workbench; VisualEnvironmentCompiler = Workbench.VisualEnvironmentCompiler; User = new SiteAccessProvider(); if (IsLightPTInWorkingDirectory()) { IsMechmath = System.Environment.MachineName.ToLower().StartsWith("mil8a-"); User.ServAddr = "https://air.mmcs.sfedu.ru/pascalabc"; loginForm = new LoginForm(this); } // RegisterForm.VisualEnvironmentCompiler = VisualEnvironmentCompiler; // Пока форма регистрации никак не связана с компилятором // Регистрация обработчика this.Workbench.ServiceContainer.RunService.Starting += RunStartingHandler; this.Workbench.ServiceContainer.RunService.ChangeArgsBeforeRun += ChangeArgsBeforeRunHandler; //Workbench.ServiceContainer.BuildService.BeforeCompile += BeforeCompileHandler; } public void Execute() { loginForm.SiteProvider = User; loginForm.ShowDialog(); // OK никогда не будет } public void AddMessage(string text) { Workbench.CompilerConsoleWindow.AddTextToCompilerMessages(text + Environment.NewLine); } public void AddMessage(Exception e) => AddMessage(e.ToString()); public string WorkingDirectory() { var FileName = Workbench.ServiceContainer.DocumentService.CurrentCodeFileDocument.FileName; return System.IO.Path.GetDirectoryName(FileName); } public string FullLightPTName() { var WorkingDir = WorkingDirectory(); var lightptname = Path.Combine(WorkingDir, "lightpt.dat"); if (File.Exists(lightptname)) return lightptname; return ""; } public bool IsLightPTInWorkingDirectory() { var WorkingDir = WorkingDirectory(); var lightptname = Path.Combine(WorkingDir, "lightpt.dat"); return File.Exists(lightptname); } public /*async*/ void TryLogin(string login, string pass) { // Гасим все исключения try { var answer = User.Login("", login, pass); if (answer.Result == "Success") { loginForm.ChangeControlsAfterLogin(login); var Rating = User.GetRating("", login, pass); loginForm.SetRating(Rating.Result); } } catch (Exception e) { AddMessage(e); } } public string FullAuthNameFromNETDisk() { var AuthFileFullName = ""; try { foreach (var drive in System.IO.DriveInfo.GetDrives()) { if (drive.DriveType != System.IO.DriveType.Network) continue; // Проверять, что диск сетевой!!! Для несетевых - нет! var auth = System.IO.Path.Combine(drive.Name, "auth.dat"); if (System.IO.File.Exists(auth)) AuthFileFullName = auth; } } catch (Exception) { } // Тут исключение быть не может и даже если, то неинформативно return AuthFileFullName; } public string FullAuthNameFromWorkingDirOrParent() { var AuthFileFullName = ""; try { var WorkingDir = WorkingDirectory(); var auth = Path.Combine(WorkingDir, "auth.dat"); var exists = false; if (File.Exists(auth)) // искать auth в текущей папке. Если нет, то exists = true; else { auth = Path.Combine(WorkingDir, "..", "auth.dat"); // искать auth в папке на уровень выше if (File.Exists(auth)) exists = true; } if (exists) // то в auth - его путь Преобразуем его в полный путь { var fi = new System.IO.FileInfo(auth); AuthFileFullName = fi.FullName; } } catch (Exception) { } return AuthFileFullName; } public string CalcAuthFullName() { var AuthFileFullName = ""; // На мехмате - проверяю все диски на предмет существования в корне файла auth.dat if (IsMechmath) AuthFileFullName = FullAuthNameFromNETDisk(); else // Это домашний компьютер AuthFileFullName = FullAuthNameFromWorkingDirOrParent(); return AuthFileFullName; } public void InitItems(List MenuItems, List ToolBarItems) { Item = new PluginGUIItem(StringsPrefix + "NAME", StringsPrefix + "DESCRIPTION", loginForm.PluginImage.Image, loginForm.PluginImage.BackColor, Execute); MenuItems.Add(Item); ToolBarItems.Add(Item); } public void GetGUI(List MenuItems, List ToolBarItems) { // Для студентов: если в рабочем каталоге нет lightpt.dat, то кнопки не появляются // На самом деле надо еще проверять диск P: - точнее, сетевой диск с определенной меткой (например, в его корне лежит файл auth.dat // if (!File.Exists(Path.Combine(WorkingDir,'lightpt.dat')) // return; // Scan disks // Find NET disk with auth.dat in root // if not - return //var WorkingDirectory = Workbench.VisualEnvironmentCompiler.Compiler.CompilerOptions.SourceFileDirectory; // При ручной авторизации - сохранение // Мехмат: auth сохраняется в корень сетевого диска // Дома: auth сохраняется в папке на уровень выше текущей. Если это невозможно, то в текущей папке. // Если это диск C, то тоже не сохранять и тогда сохранять в текущей // При запуске кнопки плагина показываются // Дома: всегда у тех, у кого установлен плагин // Мехмат: при наличии lightpt в текущей папке или при наличии auth.dat в корне сетевого диска !!! //if (!IsMechmath) // дома - всегда // InitItems(MenuItems, ToolBarItems); //else // это мехмат // SSM 20/06/22 Решил включить плагин в инсталлят и показывать кнопки только если есть lightpt.dat в текущем // или auth.dat в корне сетевого - убрал это 11.07.23 - только если при запуске lightpt.dat в текущем!!! { if (IsLightPTInWorkingDirectory()) // если lightpt.dat существует в текущем InitItems(MenuItems, ToolBarItems); /*else { var AuthFileFullName = FullAuthNameFromNETDisk(); if (AuthFileFullName != "") // если auth.dat существует в корне сетевого диска InitItems(MenuItems, ToolBarItems); }*/ } } public void AfterAddInGUI() { if (Item == null) // Если не показали кнопки, то нет смысла в дальнейших действиях - плагин неактивен { AddMessage("TeacherControlPlugin deactivated"); // Не выполнено условие LightPTExists || AuthExists return; } menuItem = (ToolStripMenuItem)Item.menuItem; toolStripButton = (ToolStripButton)Item.toolStripButton; // При запуске auth.dat ищется и делается попытка авторизации: // Мехмат: в корне сетевого диска (только!). Если находится, делается попытка авторизации // Дома: в текущей папке. Если нет, ищется в папке на уровень выше. Если находится, делается попытка авторизации // При этом на мехмате не ищется lightpt.dat в текущем // Версия. Разрешить на мехмате автоматически авторизоваться если заходим из папки с lightpt.dat // А если его нет, то ищем auth в корне сетевого // Последовательность поиска auth.dat на мехмате: // В текущем, на уровень выше (только если в текущем есть lightpt) и на сетевом try { // Попытка автоматического входа // AuthFileFullName для мехмата был запомнен в GetGUI // SSM 11/07/23 - нет, AuthFileFullName для мехмата отдельно теперь не перевычисляется для простоты!!! // Нет - только на мехмате. Заполнить если дома!!! // Думаю, здесь всё надо перевычислить. Начать с текущего, потом на уровень выше и потом в корень сетевого диска // !!! НАДО ТУТ ИСКАТЬ lightpt.dat в текущем!!! var AuthFileFullName = ""; if (IsLightPTInWorkingDirectory()) // Только если lightPT.dat в текущем, ищем auth.dat в текущем или выше AuthFileFullName = FullAuthNameFromWorkingDirOrParent(); /*if (AuthFileFullName == "" && IsMechmath) { AuthFileFullName = FullAuthNameFromNETDisk(); }*/ if (AuthFileFullName != "") { //var ss = File.ReadAllLines(AuthFileFullName); var ss = TeacherPluginUtils.ReadLoginPassFromAuth(AuthFileFullName); if (ss.Length >= 2) { var login = ss[0]; var pass = ss[1]; // В TryLogin может быть исключение, которое не перехватывается этим кодом, т.к.в другом потоке System.Threading.Tasks.Task.Run(() => TryLogin(login, pass)); } } } catch (Exception e) { AddMessage(e); // И тут уже вывести причину. Она только в ReadLoginPassFromAuth может быть } } private void RunStartingHandler(string filename) { } private void ChangeArgsBeforeRunHandler(ref string args) { if (Item == null) // если нет кнопок с человечком, то в глобальную базу писаться не будет в принципе! return; args += " " + loginForm.Authorized.ToString(); if (loginForm.Authorized) // Параметр Текст программы добавляется только если зарегистрирован { var FileName = Workbench.ServiceContainer.DocumentService.CurrentCodeFileDocument.FileName; var text = Workbench.VisualEnvironmentCompiler.StandartCompiler.GetSourceFileText(FileName); if (text.Length > 5000) text = text.Substring(0, 5000); text = text.Replace("\\\"", "\\ \""); text = text.Replace("\"", "\\\""); args += " " + "\"" + text + "\""; } } } }