S
Познакомьтесь с пентестом веб-приложений на практике в нашем новом бесплатном курсе
ЗаписьЖурналаРегистрации("Загрузка статистики звонков",УровеньЖурналаРегистрации.Информация,,,);
ПараметрыСоединенияСОктелл = Новый ПараметрыСоединенияВнешнегоИсточникаДанных;
ПараметрыСоединенияСОктелл.СтрокаСоединения= "
|DRIVER={SQL Server Native Client 10.0};
|SERVER=OKTELLSERVER;
|DATABASE=oktell;
|UID=sa;
|PWD=123qweasdzxc;";
ВнешниеИсточникиДанных.OKTELL.УстановитьОбщиеПараметрыСоединения(ПараметрыСоединенияСОктелл);
ЗапросПроект=Новый Запрос;
ЗапросПроект.Текст="ВЫБРАТЬ
| RZ_СоответствиеТелефонов.Проект
|ИЗ
| РегистрСведений.RZ_СоответствиеТелефонов КАК RZ_СоответствиеТелефонов
|ГДЕ
| RZ_СоответствиеТелефонов.Телефон = &Поток";
НомераИЛинии=Новый ТаблицаЗначений;
Запрос=Новый Запрос;
Запрос.Текст="ВЫБРАТЬ
| dbo_A_ServerStreams.Name КАК Name,
| dbo_A_ServerExtLines.ID КАК ID
|ИЗ
| ВнешнийИсточникДанных.OKTELL.Таблица.dbo_A_ServerExtLines КАК dbo_A_ServerExtLines
| ЛЕВОЕ СОЕДИНЕНИЕ ВнешнийИсточникДанных.OKTELL.Таблица.dbo_A_ServerStreams КАК dbo_A_ServerStreams
| ПО dbo_A_ServerExtLines.StreamId = dbo_A_ServerStreams.Id
|
|УПОРЯДОЧИТЬ ПО
| Name";
ДанныеОбЛиниях=Запрос.Выполнить().Выгрузить();
Запрос.Текст="ВЫБРАТЬ РАЗЛИЧНЫЕ
| ТаблицаЗвонков.Id КАК ИдентификаторЗаписи,
| ТаблицаЗвонков.IdChain КАК ИдентификаторЦепочки,
| ТаблицаЗвонков.TimeStart КАК ДатаНачала,
| ТаблицаЗвонков.TimeStop КАК ДатаОкончания,
| ТаблицаЗвонков.ANumberDialed,
| ТаблицаЗвонков.ReasonStart,
| ТаблицаЗвонков.AOutNumber,
| ТаблицаЗвонков.BLineNum,
| ТаблицаЗвонков.ALineNum,
| ТаблицаЗвонков.BOutNumber,
| ТаблицаЗвонков.IsRecorded,
| ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, РАЗНОСТЬДАТ(ТаблицаЗвонков.TimeStart, ТаблицаЗвонков.TimeStop, СЕКУНДА)) КАК ВремяСоединения,
| ВЫБОР
| КОГДА СписокПропущенных.Id ЕСТЬ NULL
| ТОГДА ВЫБОР
| КОГДА ТаблицаЗвонков.ReasonStart = 2
| И СписокПереключений.КоличествоЗаписей = 1
| И ТаблицаЗвонков.BLineNum = ""IVR""
| И РАЗНОСТЬДАТ(ТаблицаЗвонков.TimeStart, ТаблицаЗвонков.TimeStop, СЕКУНДА) <= 10
| ТОГДА ИСТИНА
| ИНАЧЕ ЛОЖЬ
| КОНЕЦ
| ИНАЧЕ ИСТИНА
| КОНЕЦ КАК Пропущен,
| ТаблицаЗвонков.AUserId,
| ТаблицаЗвонков.BUserId,
| ТаблицаЗвонков.ALineId,
| ТаблицаЗвонков.BLineId
|ИЗ
| ВнешнийИсточникДанных.OKTELL.Таблица.dbo_A_Stat_Connections_1x1 КАК ТаблицаЗвонков
| ЛЕВОЕ СОЕДИНЕНИЕ ВнешнийИсточникДанных.OKTELL.Таблица.dbo_A_Stat_MissedCalls КАК СписокПропущенных
| ПО ТаблицаЗвонков.IdChain = СписокПропущенных.IdChain
| ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ РАЗЛИЧНЫЕ
| dbo_A_Stat_Connections_1x1.IdChain КАК IdChain,
| КОЛИЧЕСТВО(РАЗЛИЧНЫЕ dbo_A_Stat_Connections_1x1.Id) КАК КоличествоЗаписей
| ИЗ
| ВнешнийИсточникДанных.OKTELL.Таблица.dbo_A_Stat_Connections_1x1 КАК dbo_A_Stat_Connections_1x1
|
| СГРУППИРОВАТЬ ПО
| dbo_A_Stat_Connections_1x1.IdChain) КАК СписокПереключений
| ПО ТаблицаЗвонков.IdChain = СписокПереключений.IdChain
|ГДЕ
| ТаблицаЗвонков.TimeStop МЕЖДУ &ДатаВремяНачало И &ДатаВремяКонец";
Запрос.УстановитьПараметр("ДатаВремяНачало",ТекущаяДата()-780);
Запрос.УстановитьПараметр("ДатаВремяКонец",ТекущаяДата());
ВнешниеИсточникиДанных.OKTELL.УстановитьСоединение();
РезультатЗапроса=Запрос.Выполнить().Выгрузить();
ВнешниеИсточникиДанных.OKTELL.РазорватьСоединение();
ТаблицаЗвонковНаЗапись=Новый ТаблицаЗначений;
ТаблицаЗвонковНаЗапись.Колонки.Добавить("ИдентификаторЦепочки");
ТаблицаЗвонковНаЗапись.Колонки.Добавить("ИдентификаторЗаписи");
ТаблицаЗвонковНаЗапись.Колонки.Добавить("ДатаНачала");
ТаблицаЗвонковНаЗапись.Колонки.Добавить("ВремяСоединения");
ТаблицаЗвонковНаЗапись.Колонки.Добавить("ДатаОкончания");
ТаблицаЗвонковНаЗапись.Колонки.Добавить("Набрано");
ТаблицаЗвонковНаЗапись.Колонки.Добавить("idЗвонящего");
ТаблицаЗвонковНаЗапись.Колонки.Добавить("idОтвечающего");
ТаблицаЗвонковНаЗапись.Колонки.Добавить("Пропущен");
ТаблицаЗвонковНаЗапись.Колонки.Добавить("НаправлениеВызова");
ТаблицаЗвонковНаЗапись.Колонки.Добавить("НомерА");
ТаблицаЗвонковНаЗапись.Колонки.Добавить("НомерБ");
ТаблицаЗвонковНаЗапись.Колонки.Добавить("Линия");
ТаблицаЗвонковНаЗапись.Колонки.Добавить("Поток");
ТаблицаЗвонковНаЗапись.Колонки.Добавить("Проект");
ТаблицаЗвонковНаЗапись.Колонки.Добавить("Записан");
Для Каждого Звонок Из РезультатЗапроса Цикл
ЕстьТакаяЗапись=НайтиТакоеДвижениеЗвонка(Звонок.ИдентификаторЗаписи);
Если ЕстьТакаяЗапись Тогда
Продолжить;
КонецЕсли;
РегЖурнал= ТаблицаЗвонковНаЗапись.Добавить();
РегЖурнал.ИдентификаторЦепочки= Звонок.ИдентификаторЦепочки;
РегЖурнал.ИдентификаторЗаписи= Звонок.ИдентификаторЗаписи;
РегЖурнал.ДатаНачала= Звонок.ДатаНачала;
РегЖурнал.ВремяСоединения= Звонок.ВремяСоединения;
РегЖурнал.ДатаОкончания= Звонок.ДатаОкончания;
РегЖурнал.Набрано= Звонок.ANumberDialed;
РегЖурнал.idЗвонящего= СокрЛП(Звонок.AUserId);
РегЖурнал.idОтвечающего= СокрЛП(Звонок.BUserId);
РегЖурнал.Пропущен= Звонок.Пропущен;
Флаг = Звонок.ReasonStart;
Если Флаг = 2 Тогда
РегЖурнал.НаправлениеВызова=Перечисления.RZ_НаправлениеВызова.Входящий;
РегЖурнал.НомерА= Звонок.AOutNumber;
РегЖурнал.НомерБ= Звонок.BLineNum;
ЛинияУстановка= Звонок.ALineNum;
ДанныеПотокаЛиния=ДанныеОбЛиниях.Найти(Звонок.ALineId,"ID");
Если ДанныеПотокаЛиния=Неопределено Тогда
ДанныеПотокаЛиния="74955043639";
Иначе
ДанныеПотокаЛиния=ДанныеПотокаЛиния.Name;
КонецЕсли;
НазваниеПотока=ДанныеПотокаЛиния;
ИначеЕсли Флаг = 3 Тогда
РегЖурнал.НаправлениеВызова=Перечисления.RZ_НаправлениеВызова.Исходящий;
РегЖурнал.НомерА= Звонок.ALineNum;
РегЖурнал.НомерБ= Звонок.BOutNumber;
ЛинияУстановка= Звонок.BLineNum;
ДанныеПотокаЛиния=ДанныеОбЛиниях.Найти(Звонок.BLineId,"ID");
Если ДанныеПотокаЛиния=Неопределено Тогда
ДанныеПотокаЛиния="74955043639";
Иначе
ДанныеПотокаЛиния=ДанныеПотокаЛиния.Name;
КонецЕсли;
НазваниеПотока=ДанныеПотокаЛиния;
иначе
РегЖурнал.НаправлениеВызова= Перечисления.RZ_НаправлениеВызова.Внутренний;
РегЖурнал.НомерА= Звонок.ALineNum;
РегЖурнал.НомерБ= Звонок.BLineNum;
НазваниеПотока="74955043639";
ЛинияУстановка= "SYS";
КонецЕсли;
РегЖурнал.Линия= ЛинияУстановка;
ПотокСправочник=Справочники.RZ_Телефоны.НайтиПоНаименованию(СокрЛП(НазваниеПотока));
Если НЕ ЗначениеЗаполнено(ПотокСправочник) Тогда
Если (Флаг=2) И (СокрЛП(Звонок.ANumberDialed)="IVR") Тогда
НазваниеПотока=СокрЛП(Звонок.ANumberDialed);
КонецЕсли;
ПотокСправочник=Справочники.RZ_Телефоны.НайтиПоНаименованию(СокрЛП(НазваниеПотока));
КонецЕсли;
РегЖурнал.Поток=ПотокСправочник;
ПроектЗапроса=Справочники.Проекты.ПустаяСсылка();
ЗапросПроект.УстановитьПараметр("Поток",ПотокСправочник);
ПроектЗапроса=ЗапросПроект.Выполнить().Выгрузить();
Если ПроектЗапроса.Количество()>0 Тогда
ПроектЗапроса=ПроектЗапроса[0].Проект;
Иначе
ПроектЗапроса=Справочники.Проекты.ПустаяСсылка();
КонецЕсли;
РегЖурнал.Проект=ПроектЗапроса;
РегЖурнал.Записан= ?(Звонок.IsRecorded= 1, Истина, Ложь);
КонецЦикла;
ПараметрыСоединенияСОктелл = Новый ПараметрыСоединенияВнешнегоИсточникаДанных;
ПараметрыСоединенияСОктелл.ИмяПользователя="sa";
ПараметрыСоединенияСОктелл.Пароль="123qweasdzxc";
ПараметрыСоединенияСОктелл.СУБД="MSSQLServer";
//ПараметрыСоединенияСОктелл.АутентификацияОС=Ложь;
ПараметрыСоединенияСОктелл.СтрокаСоединения= "
|DRIVER={SQL Server Native Client 10.0};
|SERVER=OKTELLSERVER;
|DATABASE=oktell;
|UID=sa;
|PWD=123qweasdzxc;";
ВнешниеИсточникиДанных.OKTELL.УстановитьОбщиеПараметрыСоединения(ПараметрыСоединенияСОктелл);
ЗапросПроект=Новый Запрос;
ЗапросПроект.Текст="ВЫБРАТЬ
| RZ_СоответствиеТелефонов.Проект
|ИЗ
| РегистрСведений.RZ_СоответствиеТелефонов КАК RZ_СоответствиеТелефонов
|ГДЕ
| RZ_СоответствиеТелефонов.Телефон = &Поток";
НомераИЛинии=Новый ТаблицаЗначений;
Запрос=Новый Запрос;
Запрос.Текст="ВЫБРАТЬ
| dbo_A_ServerStreams.Name КАК Name,
| dbo_A_ServerExtLines.ID КАК ID
|ИЗ
| ВнешнийИсточникДанных.OKTELL.Таблица.dbo_A_ServerExtLines КАК dbo_A_ServerExtLines
| ЛЕВОЕ СОЕДИНЕНИЕ ВнешнийИсточникДанных.OKTELL.Таблица.dbo_A_ServerStreams КАК dbo_A_ServerStreams
| ПО dbo_A_ServerExtLines.StreamId = dbo_A_ServerStreams.Id
|
|УПОРЯДОЧИТЬ ПО
| Name";
ДанныеОбЛиниях=Запрос.Выполнить().Выгрузить();
ЗапросПереключения=Новый Запрос("ВЫБРАТЬ
| dbo_A_Stat_Connections_1x1.IdChain КАК Поток,
| КОЛИЧЕСТВО(РАЗЛИЧНЫЕ dbo_A_Stat_Connections_1x1.Id) КАК Количество
|ИЗ
| ВнешнийИсточникДанных.OKTELL.Таблица.dbo_A_Stat_Connections_1x1 КАК dbo_A_Stat_Connections_1x1
|ГДЕ
| dbo_A_Stat_Connections_1x1.IdChain В(&Потоки)
|
|СГРУППИРОВАТЬ ПО
| dbo_A_Stat_Connections_1x1.IdChain");
ЗапросПроаущенные=Новый Запрос("");
Запрос.Текст="ВЫБРАТЬ РАЗЛИЧНЫЕ
| ТаблицаЗвонков.Id КАК ИдентификаторЗаписи,
| ТаблицаЗвонков.IdChain КАК ИдентификаторЦепочки,
| ТаблицаЗвонков.TimeStart КАК ДатаНачала,
| ТаблицаЗвонков.TimeStop КАК ДатаОкончания,
| ТаблицаЗвонков.ANumberDialed КАК ANumberDialed,
| ТаблицаЗвонков.ReasonStart КАК ReasonStart,
| ТаблицаЗвонков.AOutNumber КАК AOutNumber,
| ТаблицаЗвонков.BLineNum КАК BLineNum,
| ТаблицаЗвонков.ALineNum КАК ALineNum,
| ТаблицаЗвонков.BOutNumber КАК BOutNumber,
| ТаблицаЗвонков.IsRecorded КАК IsRecorded,
| ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, РАЗНОСТЬДАТ(ТаблицаЗвонков.TimeStart, ТаблицаЗвонков.TimeStop, СЕКУНДА)) КАК ВремяСоединения,
| ТаблицаЗвонков.AUserId КАК AUserId,
| ТаблицаЗвонков.BUserId КАК BUserId,
| ТаблицаЗвонков.ALineId КАК ALineId,
| ТаблицаЗвонков.BLineId КАК BLineId,
| ВЫБОР
| КОГДА СписокПропущенных.Количество ЕСТЬ NULL
| ТОГДА ВЫБОР
| КОГДА ТаблицаЗвонков.ReasonStart = 2
| И ТаблицаЗвонков.BLineNum = ""IVR""
| И РАЗНОСТЬДАТ(ТаблицаЗвонков.TimeStart, ТаблицаЗвонков.TimeStop, СЕКУНДА) <= 10
| ТОГДА 2
| ИНАЧЕ 0
| КОНЕЦ
| ИНАЧЕ 1
| КОНЕЦ КАК Пропущен,
| СписокПропущенных.Количество
|ИЗ
| ВнешнийИсточникДанных.OKTELL.Таблица.dbo_A_Stat_Connections_1x1 КАК ТаблицаЗвонков
| ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
| dbo_A_Stat_MissedCalls.IdChain КАК Поток,
| КОЛИЧЕСТВО(РАЗЛИЧНЫЕ dbo_A_Stat_MissedCalls.Id) КАК Количество
| ИЗ
| ВнешнийИсточникДанных.OKTELL.Таблица.dbo_A_Stat_MissedCalls КАК dbo_A_Stat_MissedCalls
| ГДЕ
| dbo_A_Stat_MissedCalls.TimeStart >= &ДатаВремяНачало
|
| СГРУППИРОВАТЬ ПО
| dbo_A_Stat_MissedCalls.IdChain) КАК СписокПропущенных
| ПО ТаблицаЗвонков.IdChain = СписокПропущенных.Поток
|ГДЕ
| ТаблицаЗвонков.TimeStop >= &ДатаВремяКонец";
Запрос.УстановитьПараметр("ДатаВремяНачало",НачалоДня(ТекущаяДата()));
Запрос.УстановитьПараметр("ДатаВремяКонец",ТекущаяДата()-2400);
ВнешниеИсточникиДанных.OKTELL.УстановитьСоединение();
РезультатЗапроса=Запрос.Выполнить().Выгрузить();
МассивЦепочек = РезультатЗапроса.ВыгрузитьКолонку("ИдентификаторЦепочки");
ЗапросПереключения.УстановитьПараметр("Потоки",МассивЦепочек);
СписокПереключений=ЗапросПереключения.Выполнить().Выгрузить();
ВнешниеИсточникиДанных.OKTELL.РазорватьСоединение();
ТаблицаЗвонковНаЗапись=Новый ТаблицаЗначений;
ТаблицаЗвонковНаЗапись.Колонки.Добавить("ИдентификаторЦепочки");
ТаблицаЗвонковНаЗапись.Колонки.Добавить("ИдентификаторЗаписи");
ТаблицаЗвонковНаЗапись.Колонки.Добавить("ДатаНачала");
ТаблицаЗвонковНаЗапись.Колонки.Добавить("ВремяСоединения");
ТаблицаЗвонковНаЗапись.Колонки.Добавить("ДатаОкончания");
ТаблицаЗвонковНаЗапись.Колонки.Добавить("Набрано");
ТаблицаЗвонковНаЗапись.Колонки.Добавить("idЗвонящего");
ТаблицаЗвонковНаЗапись.Колонки.Добавить("idОтвечающего");
ТаблицаЗвонковНаЗапись.Колонки.Добавить("Пропущен");
ТаблицаЗвонковНаЗапись.Колонки.Добавить("НаправлениеВызова");
ТаблицаЗвонковНаЗапись.Колонки.Добавить("НомерА");
ТаблицаЗвонковНаЗапись.Колонки.Добавить("НомерБ");
ТаблицаЗвонковНаЗапись.Колонки.Добавить("Линия");
ТаблицаЗвонковНаЗапись.Колонки.Добавить("Поток");
ТаблицаЗвонковНаЗапись.Колонки.Добавить("Проект");
ТаблицаЗвонковНаЗапись.Колонки.Добавить("Записан");
Для Каждого Звонок Из РезультатЗапроса Цикл
ЕстьТакаяЗапись=НайтиТакоеДвижениеЗвонка(Звонок.ИдентификаторЗаписи);
Если ЕстьТакаяЗапись Тогда
Продолжить;
КонецЕсли;
РегЖурнал= ТаблицаЗвонковНаЗапись.Добавить();
РегЖурнал.ИдентификаторЦепочки= Звонок.ИдентификаторЦепочки;
РегЖурнал.ИдентификаторЗаписи= Звонок.ИдентификаторЗаписи;
РегЖурнал.ДатаНачала= Звонок.ДатаНачала;
РегЖурнал.ВремяСоединения= Звонок.ВремяСоединения;
РегЖурнал.ДатаОкончания= Звонок.ДатаОкончания;
РегЖурнал.Набрано= Звонок.ANumberDialed;
РегЖурнал.idЗвонящего= СокрЛП(Звонок.AUserId);
РегЖурнал.idОтвечающего= СокрЛП(Звонок.BUserId);
Если Звонок.Пропущен=1 Тогда
РегЖурнал.Пропущен= Истина;
ИНачеЕсли Звонок.Пропущен=0 Тогда
РегЖурнал.Пропущен= Ложь;
ИНачеЕсли Звонок.Пропущен=2 Тогда
ДанныеПереключений=СписокПереключений.Найти(Звонок.ИдентификаторЦепочки,"Поток");
Если ДанныеПереключений=Неопределено Тогда
РегЖурнал.Пропущен= ЛОжь;
ИНаче
Если ДанныеПереключений.Количество=1 Тогда
РегЖурнал.Пропущен= Истина;
ИНаче
РегЖурнал.Пропущен= ЛОжь;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Флаг = Звонок.ReasonStart;
Если Флаг = 2 Тогда
РегЖурнал.НаправлениеВызова=Перечисления.RZ_НаправлениеВызова.Входящий;
РегЖурнал.НомерА= Звонок.AOutNumber;
РегЖурнал.НомерБ= Звонок.BLineNum;
ЛинияУстановка= Звонок.ALineNum;
ДанныеПотокаЛиния=ДанныеОбЛиниях.Найти(Звонок.ALineId,"ID");
Если ДанныеПотокаЛиния=Неопределено Тогда
ДанныеПотокаЛиния="74955043639";
Иначе
ДанныеПотокаЛиния=ДанныеПотокаЛиния.Name;
КонецЕсли;
НазваниеПотока=ДанныеПотокаЛиния;
ИначеЕсли Флаг = 3 Тогда
РегЖурнал.НаправлениеВызова=Перечисления.RZ_НаправлениеВызова.Исходящий;
РегЖурнал.НомерА= Звонок.ALineNum;
РегЖурнал.НомерБ= Звонок.BOutNumber;
ЛинияУстановка= Звонок.BLineNum;
ДанныеПотокаЛиния=ДанныеОбЛиниях.Найти(Звонок.BLineId,"ID");
Если ДанныеПотокаЛиния=Неопределено Тогда
ДанныеПотокаЛиния="74955043639";
Иначе
ДанныеПотокаЛиния=ДанныеПотокаЛиния.Name;
КонецЕсли;
НазваниеПотока=ДанныеПотокаЛиния;
иначе
РегЖурнал.НаправлениеВызова= Перечисления.RZ_НаправлениеВызова.Внутренний;
РегЖурнал.НомерА= Звонок.ALineNum;
РегЖурнал.НомерБ= Звонок.BLineNum;
НазваниеПотока="74955043639";
ЛинияУстановка= "SYS";
КонецЕсли;
РегЖурнал.Линия= ЛинияУстановка;
ПотокСправочник=Справочники.RZ_Телефоны.НайтиПоНаименованию(СокрЛП(НазваниеПотока));
Если НЕ ЗначениеЗаполнено(ПотокСправочник) Тогда
Если (Флаг=2) И (СокрЛП(Звонок.ANumberDialed)="IVR") Тогда
НазваниеПотока=СокрЛП(Звонок.ANumberDialed);
КонецЕсли;
ПотокСправочник=Справочники.RZ_Телефоны.НайтиПоНаименованию(СокрЛП(НазваниеПотока));
КонецЕсли;
РегЖурнал.Поток=ПотокСправочник;
ПроектЗапроса=Справочники.Проекты.ПустаяСсылка();
ЗапросПроект.УстановитьПараметр("Поток",ПотокСправочник);
ПроектЗапроса=ЗапросПроект.Выполнить().Выгрузить();
Если ПроектЗапроса.Количество()>0 Тогда
ПроектЗапроса=ПроектЗапроса[0].Проект;
Иначе
ПроектЗапроса=Справочники.Проекты.ПустаяСсылка();
КонецЕсли;
РегЖурнал.Проект=ПроектЗапроса;
РегЖурнал.Записан= ?(Звонок.IsRecorded= 1, Истина, Ложь);
КонецЦикла;
Я уже отписал что решил сам! +рабочая интеграция с ОКТЕЛОМ (берите кому надо)Нет, ты скажи: ты искренне надеешься, что кто-то ответит на такой вопрос?
Во-первых: так в чем же проблема?
Во-вторых: ты еще пару страниц добавь - до конца даже никто не полистает.
Я всегда разбираюсь вовсем до конца, время правда трачу кучу. Разместил на форуме с расчетом что пойдет быстрее - не фига.Вар, вот честно, а не пробовал ли хоть раз в проблеме разобраться до конца, а не постить косой десяток страниц, где первый пост - куча никому не нужного сейчас кода без вопроса внятного, а второй пост - "ура, я сам решил"? Ей богу, аки вирус 10 ответов ниочем. Сделал что-то выдающееся - тебе сюда
Обучение наступательной кибербезопасности в игровой форме. Начать игру!