class protect_otvet
Класс для хранения результатов проверки лицензии, полученных с сервера
Сообщите нам, если считаете, что материал размещён без разрешения.
Обращение по товару «protect.mqh» отправится на рассмотрение. Укажите контакт для ответа и опишите причину.
EA Protect — это библиотека для платформы MetaTrader, обеспечивающая защиту и лицензирование экспертных советников и индикаторов. Библиотека реализует онлайн-проверку лицензий через HTTP-запросы к серверу, привязку к оборудованию по HWID, а также поддержку токеновых лицензий для аккаунтов и VPS.
Основной класс CProtect управляет процессом проверки: инициализирует конфигурацию, отправляет запросы на сервер с данными об аккаунте и продукте, получает ответ, проверяет статус лицензии и отображает результат на графике. Класс protect_config отвечает за хранение настроек, загрузку резервных серверов, управление токенами и инициализацию ключей.
Класс CDrawStatus обеспечивает визуальное отображение статуса защиты на графике — отображает индикатор-значок с информацией о лицензии, цвет которого меняется в зависимости от статуса. Класс protect_otvet хранит результаты проверки лицензии, полученные с сервера.
Библиотека поддерживает работу как на MQL4, так и на MQL5, включает механизм шифрования данных лицензии и возможность обхода резервных серверов при недоступности основного адреса.
Классов: 4 · методов: 25 · конструкторов: 1 · деструкторов: 0 · отдельных функций: 23
class protect_otvet
Класс для хранения результатов проверки лицензии, полученных с сервера
class protect_config
Класс конфигурации защиты, хранит настройки, ключи и параметры лицензирования
class CDrawStatus
Класс для отображения статуса защиты на графике в виде графического объекта
class CProtect
Основной класс защиты, управляющий проверкой лицензии, шифрованием и отображением статуса
DWORD InternetAttemptConnect(DWORD dwReserved)
Класс-ответ сервера, содержащий статус, HWID, информацию об ошибках и параметры лицензии
HINTERNET InternetOpenW(LPCTSTR lpszAgent, DWORD dwAccessType, LPCTSTR lpszProxyName, LPCTSTR lpszProxyBypass, DWORD dwFlags)
Класс конфигурации защиты с параметрами сервера, ключами и текстовыми сообщениями
HINTERNET InternetConnectW(HINTERNET hInternet, LPCTSTR lpszServerName, INTERNET_PORT nServerPort, LPCTSTR lpszUsername, LPCTSTR lpszPassword, DWORD dwService, DWORD dwFlags, DWORD_PTR dwContext)
Класс отображения статуса защиты на графике с цветовой индикацией
HINTERNET HttpOpenRequestW(HINTERNET hConnect, LPCTSTR lpszVerb, LPCTSTR lpszObjectName, LPCTSTR lpszVersion, LPCTSTR lpszReferer, int lplpszAcceptTypes, uint dwFlags, DWORD_PTR dwContext)
Основной класс защиты Expert Advisor, обеспечивающий лицензирование и проверку
BOOL HttpSendRequestW(HINTERNET hRequest, LPCTSTR lpszHeaders, DWORD dwHeadersLength, LPVOID lpOptional[], DWORD dwOptionalLength)
Класс-ответ сервера, содержащий результаты проверки лицензии и метаданные
HINTERNET InternetOpenUrlW(HINTERNET hInternet, LPCTSTR lpszUrl, LPCTSTR lpszHeaders, DWORD dwHeadersLength, uint dwFlags, DWORD_PTR dwContext)
Класс конфигурации, хранящий все параметры и настройки системы защиты
BOOL InternetReadFile(HINTERNET hFile, LPVOID lpBuffer[], DWORD dwNumberOfBytesToRead, LPDWORD lpdwNumberOfBytesRead)
Класс визуального отображения статуса лицензии на графике торгового терминала
BOOL InternetCloseHandle(HINTERNET hInternet)
Основной класс, управляющий всем процессом защиты и лицензирования советника
BOOL InternetSetOptionW(HINTERNET hInternet, DWORD dwOption, LPDWORD lpBuffer, DWORD dwBufferLength)
Получает текущий статус проверки лицензии, при необходимости обновляя данные с сервера
BOOL InternetQueryOptionW(HINTERNET hInternet, DWORD dwOption, LPDWORD lpBuffer, LPDWORD lpdwBufferLength)
Возвращает токен лицензии из результата последней проверки
int InternetOpenW(string&,int,string&,string&,int)
Возвращает текущий интервал опроса сервера в секундах
int InternetOpenUrlW(int,string&,string&,uint,uint,uint)
Виртуальный метод для дополнительных действий при инициализации защиты
int InternetCloseHandle(int)
Запускает проверку лицензии, инициализирует конфигурацию, таймер и отображение статуса
int InternetReadFile(int,uchar &arr[],int ic,int &iarr[])
Останавливает защиту, деактивирует таймер и очищает графические объекты
bool DeleteUrlCacheEntry(string url)
Виртуальный метод для дополнительных действий при каждом тике таймера
double AccountBalance()
Основной обработчик таймера: выполняет опрос сервера, проверку лицензии и обновление статуса
double AccountEquity()
Обрабатывает события графика, включая клики по статусу и перезапуск проверки
double AccountMargin()
Обрабатывает событие перезапуска проверки от другого графика
double AccountFreeMargin()
Возвращает имя графического объекта индикатора статуса на графике
string AccountCurrency()
Шифрует переданные данные лицензии и сохраняет результат в файл
string SystemDriveSerialNumber()
Выполняет HTTP GET-запрос к серверу для получения данных о лицензии
string IntToHexString(int integer_number)
Читает ключ лицензии из файла по указанному имени
string md5(const string value)
Записывает ключ лицензии в файл по указанному имени, удаляя предыдущий файл при наличии
bool Load(string &sresult)
Разбирает строку ответа сервера и заполняет поля данных о лицензии
protect_config()
Конструктор класса конфигурации, инициализирует адреса серверов и параметры по умолчанию
void protect_init()
Выполняет начальную инициализацию параметров конфигурации
void LoadServersBypass()
Загружает список резервных серверов из файла для обхода при недоступности основного адреса
void OnInit()
Инициализирует данные аккаунта, сервера и генерирует ключи на основе HWID
void LoadToken()
Загружает токен лицензии из файла для аккаунта или HWID
void SaveToken(bool m_bcheck)
Сохраняет или удаляет токен лицензии в зависимости от типа и результата проверки
bool DelToken(string name)
Удаляет файл токена по указанному имени
void DrawStatusCircle(string sname,string _sLicense,bool bbcheck,string sURL_ADD,string sTEXT_URL_ERRORS,string sEA,string sOrderID,string sKey,int ix_label,int iy_label)
Отрисовывает на графике индикатор-значок статуса лицензии с настройкой позиции и цвета
bool GetStatus()
Возвращает текущий статус проверки лицензии, при необходимости запускает повторный опрос
string GetToken()
Возвращает токен лицензии из результата проверки
long GetTimeout()
Возвращает текущий интервал опроса сервера в секундах
void do_action_OnInit()
Виртуальный метод, вызываемый при инициализации для дополнительных действий
bool OnInit(protect_config &econfig)
Инициализирует защиту: настраивает параметры, запускает таймер и проверяет лицензию
void OnDeinit()
Деинициализирует защиту, останавливает таймер и очищает объекты на графике
void do_action_OnTimer()
Виртуальный метод, вызываемый при каждом таймерном тике для дополнительных действий
void OnTimer()
Основной обработчик таймера: проверяет лицензию на сервере, обрабатывает ответ и обновляет статус
void OnChartEvent(const int id, const long& lparam, const double& dparam, const string& sparam)
Обрабатывает события графика, включая клики по индикатору статуса и перезапуск проверки
void OnRestart(long lparam,double id,string sparam)
Обрабатывает событие перезапуска от другого графика, сбрасывая таймер опроса
string GetStatusName()
Возвращает имя графического объекта статуса на графике
void Crypt(const string sText)
Шифрует данные лицензии и сохраняет их в файл по указанному ключу
string GET(string sURL_ADD,string sgetUrl,string headers)
Выполняет HTTP GET-запрос к серверу для проверки лицензии, поддерживая MQL4 и MQL5
string GetKey(string name)
Читает зашифрованный ключ лицензии из файла по указанному имени
bool SetKey(string name,const string skey)
Сохраняет зашифрованный ключ лицензии в файл
bool DelKey(string name)
Удаляет файл с ключом лицензии по указанному имени
long TimeKey(string name)
Возвращает дату последней модификации файла ключа для контроля актуальности данных
/*
специальная версия для trading-shop.ru
для использования разработчиками в магазине
*/
/*
в начале кода подключаем и настраиваем на ID товара. ID берем из вкладки Дополнительно при создании товара, либо в EA Protect - Продукты
const int PRODUCT_ID=3265;//Index Scalper PRO MT4
const string VERSION="3.50"; //номер версии при обновлении меняем тоже, это на будущее когда будет доступна првоерка версий и обновления
#include <EA_Protect/Protect.mqh>
SHOW_LICENSE_PARAMS
PROTECT_CREATE
----
Данные макросы нужно встроить в указаные функции.
PROTECT_INIT - в функцию OnInit, инициализация
PROTECT_DEINIT в функцию OnDeinit, деинициализация
PROTECT_EVENT в функцию OnChartEvent, прием сообщений внутренних и резервный таймер
PROTECT_TIMER в функцию OnTimer, опрос по таймеру данных с сайта
статус защиты в любом месте можно получить через переменную PROTECT_STATUS
возвращает true - если все в порядке или false если проблемы. Статус при опросах пишет в журнал.
После компиляции компилируем дополнительно с помощью защиты от MQL5 Сервис - MQL5 Cloud Protector - это обязательно делать необходимо.
void OnTimer() { PROTECT_TIMER }
void OnChartEvent(const int id,const long& lparam,const double& dparam,const string& sparam){PROTECT_EVENT}
На сайт загружать все в архиве zip
желательно в архиве чтобы было все по папкам
MQL4 / MQL5
Experts
Indicators
*/
#ifndef __CPROTECT__
#define __CPROTECT__ sovetnikov_net_protect
#property strict
#include <EA_Protect\defines.mqh>
#include <EA_Protect\Draw.mqh>
#include <EA_Protect\Bcrypt.mqh>
#include <EA_Protect\Time.mqh>
#define RESTART_PROTECT CHARTEVENT_CUSTOM+321
#ifndef LICENSE_OFF
#define SHOW_LICENSE_PARAMS input string LicenseKey=""; //LicenseKey
#endif
#define READURL_BUFFER_SIZE 1024
#define LICENSE_ACCOUNT 1
#define LICENSE_VPS 2
#define SERVERS_FILE_NAME "servers-protect.ini"
#ifdef IS_INDICATOR
#ifndef WININET_API_LIB
#define HINTERNET int
#define BOOL int
#define INTERNET_PORT int
#define DWORD int
#define DWORD_PTR int
#define LPDWORD int&
#define LPVOID uchar&
#define LPCTSTR string&
#endif
#import "wininet.dll"
DWORD InternetAttemptConnect(DWORD dwReserved);
HINTERNET InternetOpenW(LPCTSTR lpszAgent, DWORD dwAccessType, LPCTSTR lpszProxyName, LPCTSTR lpszProxyBypass, DWORD dwFlags);
HINTERNET InternetConnectW(HINTERNET hInternet, LPCTSTR lpszServerName, INTERNET_PORT nServerPort, LPCTSTR lpszUsername, LPCTSTR lpszPassword, DWORD dwService, DWORD dwFlags, DWORD_PTR dwContext);
HINTERNET HttpOpenRequestW(HINTERNET hConnect, LPCTSTR lpszVerb, LPCTSTR lpszObjectName, LPCTSTR lpszVersion, LPCTSTR lpszReferer, int /*LPCTSTR* */ lplpszAcceptTypes, uint/*DWORD*/ dwFlags, DWORD_PTR dwContext);
BOOL HttpSendRequestW(HINTERNET hRequest, LPCTSTR lpszHeaders, DWORD dwHeadersLength, LPVOID lpOptional[], DWORD dwOptionalLength);
HINTERNET InternetOpenUrlW(HINTERNET hInternet, LPCTSTR lpszUrl, LPCTSTR lpszHeaders, DWORD dwHeadersLength, uint/*DWORD*/ dwFlags, DWORD_PTR dwContext);
BOOL InternetReadFile(HINTERNET hFile, LPVOID lpBuffer[], DWORD dwNumberOfBytesToRead, LPDWORD lpdwNumberOfBytesRead);
BOOL InternetCloseHandle(HINTERNET hInternet);
BOOL InternetSetOptionW(HINTERNET hInternet, DWORD dwOption, LPDWORD lpBuffer, DWORD dwBufferLength);
BOOL InternetQueryOptionW(HINTERNET hInternet, DWORD dwOption, LPDWORD lpBuffer, LPDWORD lpdwBufferLength);
#import
#else
int InternetOpenW(string&,int,string&,string&,int) {return 0;}
int InternetOpenUrlW(int,string&,string&,uint,uint,uint) {return 0;}
int InternetCloseHandle(int) {return 0;}
int InternetReadFile(int,uchar &arr[],int ic,int &iarr[]) {return 0;}
bool DeleteUrlCacheEntry(string url) {return false;}
#endif
#ifdef __MQL5__
#ifndef __MQL4__TO__MQL5__
double AccountBalance()
{
return AccountInfoDouble(ACCOUNT_BALANCE);
}
double AccountEquity()
{
return AccountInfoDouble(ACCOUNT_EQUITY);
}
double AccountMargin()
{
return AccountInfoDouble(ACCOUNT_MARGIN);
}
double AccountFreeMargin()
{
return AccountInfoDouble(ACCOUNT_MARGIN_FREE);
}
string AccountCurrency()
{
return AccountInfoString(ACCOUNT_CURRENCY);
}
#endif
#endif
string SystemDriveSerialNumber()
{
string sVolumeSerialNumber="1234-4321";
#ifndef LICENSE_OFF
sVolumeSerialNumber=md5(IntegerToString(AccountInfoInteger(ACCOUNT_LOGIN)));
if(!IsTesting() && !IsOptimization())
{
if(FileIsExist("hwid.ini",FILE_COMMON))
{
int ihwid=FileOpen("hwid.ini",FILE_READ|FILE_SHARE_READ|FILE_COMMON|FILE_ANSI);
if(ihwid!=INVALID_HANDLE)
{
sVolumeSerialNumber=FileReadString(ihwid);
FileClose(ihwid);
}
}
else
{
int ihwid=FileOpen("hwid.ini",FILE_WRITE|FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_COMMON|FILE_ANSI);
if(ihwid!=INVALID_HANDLE)
{
FileWriteString(ihwid,sVolumeSerialNumber);
FileClose(ihwid);
}
}
}
#endif
return sVolumeSerialNumber;
}
string IntToHexString(int integer_number)
{
string hex_string="00000000";
int value,shift=28;
for(int i=0; i<8; i++)
{
value=(integer_number>>shift)&0x0F;
if(value<10)
StringSetCharacter(hex_string,i,ushort(value+'0'));
else
StringSetCharacter(hex_string,i,ushort((value-10)+'A'));
shift-=4;
}
return(hex_string);
}
string md5(const string value)
{
const string EMPTY_MD5 = "d41d8cd98f00b204e9800998ecf8427e";
if(value == "")
{
return EMPTY_MD5;
}
uchar result[];
const uchar key[1]= {*};
uchar data[];
StringToCharArray(value, data, 0, StringLen(value));
CryptEncode(CRYPT_HASH_MD5, data, key, result);
string resultStr = "";
for(int i = 0; i < ArraySize(result); i++)
{
resultStr = resultStr + StringFormat("%02x", result[i]);
}
ArrayFree(result);
ArrayFree(data);
return resultStr;
}
#ifndef LICENSE_OFF
#define PROTECT_CREATE protect_config config;\
CProtect protect;
#ifdef LICENSE_PANEL
#define PROTECT_INIT config.product_id=PRODUCT_ID;\
config.version=VERSION;\
config.admin_id=ADMIN_ID;\
config.token=LicenseKey;\
protect.OnInit(config);
#else
#define PROTECT_INIT config.product_id=PRODUCT_ID;\
config.version=VERSION;\
config.token=LicenseKey;\
protect.OnInit(config);
#endif
#define PROTECT_DEINIT protect.OnDeinit();
#define PROTECT_EVENT protect.OnChartEvent(id,lparam,dparam,sparam);
#define PROTECT_TIMER if(config.product_id==0 || config.lAccount==0) {config.protect_init();PROTECT_INIT} protect.OnTimer();
#define PROTECT_STATUS protect.GetStatus()
#else
#define PROTECT_CREATE
#define PROTECT_INIT
#define PROTECT_DEINIT
#define PROTECT_TIMER
#define PROTECT_EVENT
#define SHOW_LICENSE_PARAMS
#define PROTECT_STATUS true
#endif
bool g_bWWW=false;
class protect_otvet
{
public:
string status;
string hwid;
int hardware;
long dateend;
int product_id;
int ban;
string errors;
string message;
int token_mode; //тип лицензии впс или счет
long order_id; //номер заказа
long timeout;
/*
noerrors - нет ошибок, нормальная работа
invalid - неверный счет
demo - добавлен новый демо счет
hardware - исчерпали железо
expired - время вышло
partner - партнерский счет
ban - бан
timeout - частота повторных опросов в минутах!
*/
bool Load(string &sresult)
{
string sRet[];
int isize=string_explode(";",sresult,sRet);
if(isize>=8)
{
status=sRet[0];
hwid=sRet[1];
hardware=(int)StringToInteger(sRet[2]);
dateend=(long)StringToInteger(sRet[3]);
product_id=(int)StringToInteger(sRet[4]);
int admin_id=(int)StringToInteger(sRet[5]);
ban=(int)StringToInteger(sRet[6]);
errors=sRet[7];
if(isize>8)
message=sRet[8];
if(isize>9)
token_mode=(int)StringToInteger(sRet[*]);
if(isize>10)
order_id=(long)StringToInteger(sRet[10]);
if(isize>11)
timeout=(long)StringToInteger(sRet[11]);
ArrayFree(sRet);
return true;
}
ArrayFree(sRet);
return false;
}
};
class protect_config
{
public:
string private_key; //приватный ключ (генериться автоматически)
string public_key; //публичный ключ и он же имя файла защиты, если hardware защита иначе имя формируеться как номер счета.имя советника
ulong lAccount; //номер счета (число)
string sAccount; //номер счета на котором запустили
string HWID; //HWID хеш
string sAccountON,sAccountOFF;
string token; //для защиты по железу нужно выдавать ключ (выдается при привязке к железу)
int token_mode; //инициализируется при загрузке данных, нужно для бэкапа ключа
int product_id; //идентификатор продукта (выдаеться при создании продукта)
int admin_id; //ид админа если связка с панелью (для совместимости) 0- не используеся
string version; //версия продукта
long order_id; //номер заказа если по лицензии (получаем с сайта)
string terminal;
string server;
string fio;
string sURL_ADD;//адрес сайта который надо добавить в WebRequest
string sURL_CHECK; //скрипт проверки счетов
string sEA; //имя скрипта
long iTimeout; //частота опроса
bool bTester; //разрешение работы в тестере
bool bDebug; //режим отладки
string sTEXT_VALID_KEY;
string sTEXT_VALID_TIME_KEY;
string sTEXT_EMPTY_KEY;
string sTEXT_INVALID_KEY;
string sTEXT_EXPERIED;
string sTEXT_PARTNER_KEY;
string sTEXT_TESTING_NO;
string sTEXT_TESTING_ON;
string sTEXT_DEMO; //строка для демо режима
string sTEXT_DEMO_END; //окончание демо режима.
string sTEXT_BAN; //счет заблокирован
string sTEXT_ACTIVATION; //кол-во активаций (формат)
string sTEXT_WEBREQUEST; //ошибка
string sTEXT_ORDER; //Номер заказа
string sTEXT_KEY; //ключ
string sTEXT_RENT_KEY;
string sTEXT_EXPERIED_1DAY; //истекает лицензия через 1 день
string sTEXT_URL_ERRORS;
string sURL_CHECK_SERVERS[10];
int iURL_CHECK_SERVERS;
protect_config()
{
sURL_ADD="";
#ifndef LICENSE_PANEL
sURL_CHECK="";
#else
sURL_ADD="";
sURL_CHECK="";
sTEXT_URL_ERRORS="";
#endif
protect_init();
}
void protect_init()
{
iURL_CHECK_SERVERS=-1;
for(int i=0; i<ArraySize(sURL_CHECK_SERVERS); i++)
{
sURL_CHECK_SERVERS[i]="";
}
sEA=WindowExpertName();
HWID="";
private_key="********************************"; //должен совпадать с ключем на сайте проверки
token="";//токен дл работы по железу
product_id=0;
order_id=0;
iTimeout=900;//900
bTester=true; //разрешаем работать в тестере
bDebug=false;
token_mode=*;
#ifdef __MQL5__
terminal="MT5";
#else
terminal="MT4";
#endif
lAccount=AccountInfoInteger(ACCOUNT_LOGIN);
sAccount=IntegerToString(lAccount);
server=AccountInfoString(ACCOUNT_SERVER);
fio=AccountInfoString(ACCOUNT_NAME);
sTEXT_VALID_KEY= "Activated successfully. ";
sTEXT_VALID_TIME_KEY= "Activated successfully. Time experied %s";
sTEXT_INVALID_KEY= "Invalid license. Contact the seller.";
sTEXT_EXPERIED ="Time experied is %s.\nPurchase a license in the store or contact the seller.";
sTEXT_PARTNER_KEY= "Activated successfully for partner.";
sTEXT_TESTING_NO="Blocking testing and optimization.";
sTEXT_TESTING_ON="Testing.";
sTEXT_BAN="EA blocked. Contact the seller.";
sTEXT_EMPTY_KEY="EA blocked. Contact the seller.";
sTEXT_ACTIVATION="Activated successfully. Inactive activations left %d";
sTEXT_WEBREQUEST="Click for update.";
sTEXT_ORDER="Order #%lld ";
sTEXT_KEY="Key: %s\n";
sTEXT_RENT_KEY="%s Rend %s";
sTEXT_URL_ERRORS="trading-shop.ru/errors";
sTEXT_EXPERIED_1DAY ="The working time will expire in a one day.\nPurchase a license in the store or contact the seller.";
if(TerminalInfoString(TERMINAL_LANGUAGE)=="Russian")
{
sTEXT_VALID_KEY= "Активирован и работает.";
sTEXT_VALID_TIME_KEY= "Активирован и работает до указанной даты. Дата окончания работы %s";
sTEXT_INVALID_KEY= "Неверная лицензия. Свяжитесь с продавцом.";
sTEXT_EXPERIED ="Не работает. Истек пробный период до %s.\nПриобретите лицензию или обратитесь к продавцу.";
sTEXT_PARTNER_KEY= "Активирована партнёрская версия.";
sTEXT_TESTING_NO="Заблокировано тестирование и оптимизация.";
sTEXT_TESTING_ON="Тестер стратегий разрешен.";
sTEXT_BAN="Блокировка. Обратитесь к продавцу.";
sTEXT_EMPTY_KEY="Блокировка. Неверный ключ.";
sTEXT_ACTIVATION="Работает. Осталось неактивных активаций %d";
sTEXT_WEBREQUEST="Нажмите для обновления.";
sTEXT_ORDER="Заказ #%lld ";
sTEXT_KEY="Ключ: %s\n";
sTEXT_RENT_KEY="%s Аренда %s";
sTEXT_EXPERIED_1DAY ="Время работы истекает через один день.\nПриобретите лицензию в магазине или свяжитесь с продавцом.";
}
}
void LoadServersBypass()
{
if(FileIsExist(SERVERS_FILE_NAME,FILE_COMMON))
{
int hf=FileOpen(SERVERS_FILE_NAME,FILE_READ|FILE_UNICODE|FILE_SHARE_READ|FILE_COMMON|FILE_ANSI);
int i=0;
if(hf!=INVALID_HANDLE)
{
while(!FileIsEnding(hf) && !IsStopped() && i<10)
{
string surl=FileReadString(hf); //читаем построчно
if(StringFind(surl,"https://")==0 || StringFind(surl,"http://")==0)
{
sURL_CHECK_SERVERS[i]=surl;
PrintFormat("Load server bypass(%d): %s",i+1,sURL_CHECK_SERVERS[i]);
i++;
}
}
FileClose(hf);
}
}
else
{
int hf=FileOpen(SERVERS_FILE_NAME,FILE_WRITE|FILE_UNICODE|FILE_SHARE_READ|FILE_COMMON);
int i=0;
if(hf!=INVALID_HANDLE)
{
FileSeek(hf,0,SEEK_SET);
FileWriteString(hf,"Input servers for bypass in format: or "); //сохраняем резервный в файл
FileWriteString(hf,"Sample: "); //сохраняем резервный в файл
FileClose(hf);
}
}
}
void OnInit()
{
// код доступен только после оплаты
}
void LoadToken()
{
if(!IsTesting() && !IsOptimization() && lAccount>0)
{
string sFileTokenAccount=StringFormat("*********",sAccount,WindowExpertName());
string sFileTokenHWID=StringFormat("*********",HWID,WindowExpertName());
if(token=="" && FileIsExist(sFileTokenAccount,FILE_COMMON))
{
int ihwid=FileOpen(sFileTokenAccount,FILE_READ|FILE_SHARE_READ|FILE_COMMON|FILE_ANSI);
if(ihwid!=INVALID_HANDLE)
{
token=FileReadString(ihwid);
FileClose(ihwid);
}
}
if(token=="" && FileIsExist(sFileTokenHWID,FILE_COMMON))
{
int ihwid=FileOpen(sFileTokenHWID,FILE_READ|FILE_SHARE_READ|FILE_COMMON|FILE_ANSI);
if(ihwid!=INVALID_HANDLE)
{
token=FileReadString(ihwid);
FileClose(ihwid);
}
}
}
}
void SaveToken(bool m_bcheck) //забэкапим токен в зависимости от типа лицензии
{
if(!IsTesting() && !IsOptimization() && lAccount>0)
{
string sFileTokenAccount=StringFormat("*********",sAccount,WindowExpertName());
string sFileTokenHWID=StringFormat("*********",HWID,WindowExpertName());
if(StringLen(token)>=3)
{
if(token_mode==LICENSE_ACCOUNT)
{
if(m_bcheck)
{
int ihwid=FileOpen(sFileTokenAccount,FILE_WRITE|FILE_SHARE_READ|FILE_COMMON|FILE_ANSI);
if(ihwid!=INVALID_HANDLE)
{
FileWriteString(ihwid,token); //бэкапим
FileClose(ihwid);
}
}
else
{
DelToken(sFileTokenAccount);
}
}
if(token_mode==LICENSE_VPS)
{
if(m_bcheck)
{
int ihwid=FileOpen(sFileTokenHWID,FILE_WRITE|FILE_SHARE_READ|FILE_COMMON|FILE_ANSI);
if(ihwid!=INVALID_HANDLE)
{
FileWriteString(ihwid,token); //бэкапим
FileClose(ihwid);
}
}
else
{
DelToken(sFileTokenHWID);
}
}
}
}
}
bool DelToken(string name)
{
if(name==NULL || name=="")
return false;
if(FileIsExist(name,FILE_COMMON))
{
ResetLastError();
token="";
return FileDelete(name,FILE_COMMON);
}
return false;
}
};
class CDrawStatus: public CEAProtect_DrawPos
{
public:
virtual void DrawStatusCircle(string sname,string _sLicense,bool bbcheck,string sURL_ADD,string sTEXT_URL_ERRORS,string sEA,string sOrderID,string sKey,int ix_label,int iy_label)
{
static color clRoute=clrRed;
if(bbcheck)
{
clRoute=clrLime;
}
else
{
if(clRoute==clrLime)
clRoute=clrRed;
}
if((IsTesting() && IsVisualMode()) || (!IsTesting() && !IsOptimization()))
{
/*
список индикаторов
у них есть индекс.
имя - по имени можно определить есть ли в наличии объект
он должен только свой позиционировать на графике.
но при этом все должны индикаторы видеть одинакого.
с 0 ищем
нашли по имени
*/
string obj=getObjName(sname);
if(ObjectFind(0,obj)==-1)
{
ObjectCreate(0,obj,OBJ_LABEL,0,0,0);
for(int i=0; i<ObjectsTotal(0,-1,-1); i++)
{
string sobj=ObjectName(0,i);
if(obj==sobj)
continue;
if(ObjectGetInteger(0,sobj,OBJPROP_TYPE)==OBJ_LABEL)
{
if(StringFind(sobj,"_status",0)>0 &&
StringFind(sobj,"protect_",0)==0)
{
ix_label+=24;
}
}
}
SetCorner(0,sname,CORNER_LEFT_LOWER);
ObjectSetInteger(0,obj,OBJPROP_XDISTANCE,ix_label);
ObjectSetInteger(0,obj,OBJPROP_YDISTANCE,iy_label);
SetSelectable(0,sname,false);
}
if(ObjectFind(0,obj)!=-1)
{
SetText(0,sname,CharToString(108),clRoute,"Wingdings",24);
string _sDebug="";
if(!bbcheck)
{
bool bDLL=(bool)MQLInfoInteger(MQL_DLLS_ALLOWED);
bool bTrade=(bool)MQLInfoInteger(MQL_TRADE_ALLOWED);
bool bWWW=g_bWWW;
if(TerminalInfoString(TERMINAL_LANGUAGE)=="Russian")
{
_sDebug="";
if(!bDLL)
_sDebug=StringFormat("%s\nDLL - не разрешены",_sDebug);
if(!bTrade)
_sDebug=StringFormat("%s\nТорговля - выключена",_sDebug);
if(!bWWW)
_sDebug=StringFormat("%s\nWebRequest - выключен",_sDebug);
}
else
{
_sDebug="";
if(!bDLL)
_sDebug=StringFormat("%s\nDLL - failed",_sDebug);
if(!bTrade)
_sDebug=StringFormat("%s\nAutoTrading - off",_sDebug);
if(!bWWW)
_sDebug=StringFormat("%s\nWebRequest - failed",_sDebug);
}
_sDebug=StringFormat("%s\n%s",_sDebug,sTEXT_URL_ERRORS);
}
string stooltip=StringFormat("%s\n%s%s\n%s%s%s",sURL_ADD,sOrderID,sEA,sKey,_sLicense,_sDebug);
#ifdef __LIB_GUI__
ObjectSetString(0,obj,OBJPROP_TOOLTIP,stooltip);
#else
SetTooltip(0,sname,stooltip);
#endif
}
if(clRoute==clrRed)
clRoute=clrGold;
else
if(clRoute==clrGold)
clRoute=clrRed;
}
}
};
class CProtect
{
protected:
protect_config configs;
protect_otvet otvet;
CTimerProtect m_timer; //таймер
CBcrypt m_crypt; //криптошифр
CDrawStatus m_status; //отобразим
bool m_bClickStatus; //если надо на клик статуса сделать своё действие, то используем эту переменную для првоерки
string sLicense,sLicenseLast,sOrderID,sKey;
bool bSendBlocked;
bool bSendTrialEnd;
bool bSendMessage;
bool bSendTrial1Day;
bool bcheck;
long iHardware; //флаг что проверять по кол-ву активаций (онлайн)
int ix_label,iy_label;
ulong newid;
bool bTesting;
public:
datetime m_lastpost;
bool GetStatus()
{
if((long)(TimeGMT()-m_lastpost)>=configs.iTimeout)
{
this.OnTimer();
}
return bcheck;
}
string GetToken()
{
return otvet.status; //вернем токен
}
long GetTimeout()
{
return configs.iTimeout; //seconds
}
virtual void do_action_OnInit()
{
}
bool OnInit(protect_config &econfig)
{
// код доступен только после оплаты
}
void OnDeinit()
{
m_timer.OnDeinit(); //деактивируем таймер
m_status.OnDeinit();
}
virtual void do_action_OnTimer()
{
}
void OnTimer()
{
#ifndef IS_INDICATOR
if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)==false)
{
m_timer.OnTimer();
return; //ждем подключения к серверу
}
#endif
if(TerminalInfoInteger(TERMINAL_CONNECTED)==false || AccountInfoInteger(ACCOUNT_LOGIN)==0 || IsStopped())
{
m_timer.OnTimer();
return; //ждем подключения к серверу
}
if(configs.lAccount!=AccountInfoInteger(ACCOUNT_LOGIN))
{
configs.lAccount=AccountInfoInteger(ACCOUNT_LOGIN);
configs.sAccount=IntegerToString(configs.lAccount);
if(configs.lAccount==0)
{
PrintFormat("Protect EA: Error Init Account %lld",AccountInfoInteger(ACCOUNT_LOGIN));
m_timer.OnTimer();
return;
}
}
string sKEY="";
#ifdef LICENSE_OFF
sLicense=configs.sTEXT_VALID_KEY;
bcheck=true;
m_timer.OnTimer();
return;//проверка лицензии выключена
#endif
if(bTesting)
{
if(!configs.bTester)
sLicense=configs.sTEXT_TESTING_NO;
else
sLicense=configs.sTEXT_TESTING_ON;
if(configs.bTester)
bcПоказано первые 50% кода (символов: 35157)
Купите тариф с пакетом открытий или войдите, если тариф уже есть. Открытый файл останется в вашем кабинете навсегда.
На этой странице откроется полный исходный код файла вместо ознакомительного фрагмента.
Зачем нужен email? После подтверждения оплаты файл сохранится в кабинете на этот email. Если аккаунта ещё нет, мы создадим его и пришлём ссылку для задания пароля. Если аккаунт уже есть, покупка добавится в него. Укажите адрес, к которому у вас есть доступ.
Чтобы оформить заказ, введите email и перейдите к оплате.