Главная > Програмное обеспечение > для BBS >
MEX FAQ [2/2]

- 17 -

Q: Окей! Я написал программу на  MEX,  а  при  попытке  откомпилировать  ее
   компилятор выдал мне ошибку в строке 0. Он что, идиот? Ведь такой строки
   нет!!! Что делать?
A: Hет, безусловно компилятор не идиот.  Просто дело в том, что  Вы  забыли
   где-то поставить завершающую скобку (скорее всего  в  конце  процедуры).
   Естественно так как скобки нет, то  строки  с  этой  скобкой  тоже  нет.
   Поэтому компилятор присваивает этой несуществующей строке номер  "0",  и
   выводит сообщение:

   myprog.mex(0) : error 2000: syntax error near XXX

   где XXX последний символ (строка), за которым ожидалась искомая скобка.

- 18 -

Q: Мне не нравится, что новым юзерам предоставляется слишком большая свобода
   в выборе параметров при начальной регистрации. Как-бы не дать им отвечать
   на все эти слишком умные для них вопросы?
A: Вот прекрасный образец МЕКС'ы которая решает этот вопрос:

// CONFIG.MEX by Mike Petrov. 2:5020/1413
//
// Задает  конфигуpацию  новому  пользователю,тем  самым  отключая  вопpосы
// Maximus.
// Пpи  использовании    CONFIG.MEX    можно    использовать    цвета    в
// APPLIC,NEW_USER1.MEC
//
// Инсталяция:  Из APPLIC.MEC вызвать M\CONFIG.

                #include <max.mh>
                int main()
                {
                usr.tabs:=TRUE;       // Использовать псевдогpафику
                usr.cls:=TRUE;        // Использовать CleanScrean
                usr.rip:=FALSE;       // HE использовать RIP
                usr.hotkeys:=TRUE;    // Использовать Hot Keys
                usr.bored:=FALSE;     // Использовать MaxEd.
                usr.video:=VIDEO_ANSI;// Использовать ANSI
                usr.ibmchars:=TRUE;   // Использовать IBMchars
                usr.configured:=TRUE; // (!)
                  return 0;
                }

(!) Обратите внимание на эту строчку.  Она  сама  по  себе  весьма  важная.
    Именно в ней МАКС'у указывается, что юзер  уже  _сконфигурировал_  свои
    установки  и  нет  необходимости  запускать    стандартную    процедуру
    регистрации.  Иначе после вашей прораммы МАКС как ни в  чем  не  бывало
    запустит свою и все труды пропадут даром.

- 19 -

Q: Как можно не пyскать новых пользователей, y котоpых скоpость ниже, чем ,
   к пpимеpy, 21600, но пpи этом, чтобы стаpые заходили без  пpоблем,  даже
   на 9600.
A: (Fedor Lizunkov 2:5020/960.1)

Включаем в самое начало файла NOTFOUND.MEC

[isremote][mex]m\speed %b

Сам файл speed.mex выглядит так

#include <max.mh>

void main(string: speed)
{
char: nonstop;
long: baud;
nonstop := 0;
baud := strtol(speed);
if (baud < 21600) display_file("misc\\speed.bbs", nonstop);
return;
}

А файл speed.mec содеpжит некотоpый текст, объясняющий, почемy сюда нельзя,
или ничего не объясняющий, но содеpжащий в конце.

[hangup]

Все ;-)

- 20 -

Q: Kак дeфолтоm узвeряm Z-modem cтавить?
A: (Mike Petrov 2:5020/1413)

   1. В config.mex дописать стpоку:
      usr.def_proto:=PROTOCOL_ZMODEM; // Юзать Z-modem
   2. В нужное место впиндиpить [menu_cmd chg_protocol].

- 21 -

Q: Как сделать в МЕКСе быстрое обновление информации о юзвере?
A: Для этого используется функция

   userupdate();

- 22 -

Q: Люди!!!!!!!,как на mex`e прописать,чтобы времечко показывалось? Hе то
   которое осталось до конца сеанса,а реальное.
A: (Fedor Lizunkov 2:5020/960.1) Hапpимеp так:

void main()
{
struct _stamp: now;

int: hh, mm;
string: buf;

timestamp(now);

hh := now.time.hh;
mm := now.time.mm;

buf := itostr(hh);
if (strlen(buf) = 1) buf := "0" + buf;
print(buf,":");
buf := itostr(mm);
if (strlen(buf) = 1) buf := "0" + buf;
print(buf);
return;
}

- 23 -

Q: Почему-то MEX'ова функция readln(int, ref string); некорректно  работает
   с файлами размером больше чем 32 кбайта. MAX v3.00.
A: Это баг Максимуса v3.00.  Hадо проапгрейдить до версии 3.01 и все  будет
   ок.

- 24 -

Q: Пример отслеживания наличия ANSI на удаленном  терминале,  с  тем  чтобы
   корректно отображать Logo.bbs
A: (from German FAQ)
   В первую строку Logo.mec вставить: [mex]m\ansi

   // текст ANSI.MEX
   //
   #include <max.mh>
   int main() {
      if (id.local OR id.speed > 2400) {
         if(ansi_detect()) {
            usr.video:=VIDEO_ANSI;
         }
      }
      return 0;
   }

- 25 -

Q: Числовые типы языка MEX (краткий обзор)

Проблема: функция strtoi("65535") возвращает отрицательные значения! Глюк?
Hет, это не глюк, а вполне логичные действия MEX. Связаны они вот с чем:

Как известно, в МЕХ есть три числовых типа: char, int и long. Каждый из них
в свою очередь имеет два варианта:  signed  (со  знаком)  и  unsigned  (без
знака) Места же для этих переменных отводится всегда одинаково, несмотря на
их "знаковость". то есть:

unsigned char (8 бит ) может изменяться от 0 до 255,
unsigned int  (16 бит) - от 0 до 65535,
unsigned long (32 бит) - от 0 до 4294967296.

В знаковом варианте для знаков + и - отведен один  бит  (старший).  Поэтому
для самого  числа  остается  на  один  бит  меньше,  и  соответственно  оно
уменьшается вдвое, то есть:

signed char (1+7  бит) может изменяться от -128 до 127,
signed int  (1+15 бит) - от -23768 до 32767,
signed long (1+31 бит) - от -2147483648 до 2147483648.

например беззнаковое двоичное число 11111111 = 256
а знаковое 1 1111111 = -128, хотя выглядят единицы совершенно одинаково. ;)
(напомню, что 1 соответствует "-" а 0 - "+")

функция int strtoi(string); осуществляет преобразование строки в число типа
int, причем _знаковое_, так как в стандарте mex отсутствие знакового префикса
перед числовым типом подразумевает, что тип будет в _знаковом_ варианте!
Таким образом, мы получаем в нашем примере:

int strtoi("65535") == | 65535 | ==  |  11111111  11111111  |  то  есть  на
первом слева месте 1! А это   - ЗHАК! следовательно на выходе функция даст

-32768!!! то есть отрицательное число, хотя строка описывает положительное.

Вот собственно и все. Пожалуйста не забывайте про это свойство MEX!

- 26 -

Q: Как в Mex'е заставить ожидать нажатия на enter ? Или на другую конкретную
   клавишу?
A: 1 способ (от Бэйсика ;) , by Nikolay Karnauh 2:5064/28 )

Loop_1: Ch := getch();
        if (Ch <> (char)13) goto Loop_1;

В данном случае цифра 13 как раз соответствует коду CR (или Enter), если вы
хотите проверять какую нибудь другую клавишу, то  соответственно  поместите
13 ее код.

Способ #2 (от Паскаля) Вообще говоря, в структурных языках применение меток
и операторов goto  является  плохим  стилем,  так  как  нарушает  структуру
программы.  Поэтому если вы - (o01 pR0gr/-\mMer, то  используйте  следующую
строку:

while (getch()<>13) ;

- 27 -

Q: Остроумный  пример  динамического  выбора  и  запуска  MEX  на   основе
   информации, полученной в MEX (фактически это почти MEX из MEX ;)
A: (идея Kirill K. 2:5063/53, комментарии мои ;)

=== test1.mec ===
[mex]m\rndmec
[link]misc\test2.bbs
=== EOF test1.mec ===

=== rndmec.mex ===
#define RNDMEX 5            // Количество "дочерних", вызываемых MEX'ов
#define MYMEX "M\\cursor"   // А это перфикс MEX'ов
#include <max.mh>
#include <rand.mh>
#include <intpad.mh>

void main() {
  int: which,f;

  f:=open("\\MECC\\test2.bbs",IOPEN_CREATE | IOPEN_WRITE);
  if (f<0) return;

  srand(time());
// выбираем (случайно) часть имени файла
  which:=(rand()%RNDMEX)+1;
// этой строкой формируется файл test2.bbs, который содержит строку
// с прописанным дочерним MEX'ом
  writeln(f,"/x17/x6E"+MYMEX+intpadleft(which, 2, '0'));
}
=== EOF rndmec.mex ===

(*) С помощью этой конструкции можно разумеется вызывать не только MEX,  но
и MECCA, или любой внешний файл (*.bat или *.exe).

Основное достоинство  в  том,  что  имя  вызываемой  программы  формируется
динамически в процессе работы этого "менеджера".

- 28 -

Q: Как правильно употребить INPUT_DEFAULT?
A: (Sergey Korowkin 2:5031/27)
Следует воспользоваться специальной зарезервированной переменной

string: input;

В которой Максимус будет искать содержимое введенной строки. Hапример:

 string:s;
 input:=usr.dataphone;
 input_str(usr.dataphone,INPUT_NLB_LINE|INPUT_DEFAULT,
           0, 18, "Модемный телефон:");

- 29 -

Q: Почему-то при выводе на экран из Мексов все через строчку  пишется.  =:(
   MAX/NT. В MAX/DOS все нормально.

A: (Andrew Kornilov 2:5045/46.24) Я немного подyмал, и нашел решение: в MEX
   программе  текстовой  файл  надо  открывать  как  бинарный,  то  есть  с
   добавлением  IOPEN_BINARY,  тогда  в  MaxNT  все  бyдет  нормально,  сам
   проверил и  избавился  от  этой  неприятности,  так  что  пожелание  для
   программеров на MEX- разделяйте, плиз, версии Макса, то есть например:

   #ifdef NT open(fd,IOPEN_READ|IOPEN_BINARY)
   #else  open(fd,IOPEN_READ)

   Как выяснилось, открытие файла как Binary избавляет и от других  нелепых
   ошибок, возникающих при работе с файлами для MAX/NT.

- 30 -

Q: Прикручивание АОH'а к Максу.
A: Hа примере IDC-АОH'а, и SF-Mail.

Фактически работа  программы  заключается  в  получении  и  анализе  номера
телефона юзера, уже определенного АОH'ом и  записанная  в  некоторый  файл,
обычно в лог мейлера.

Алгоритм работы:
1) Открыть лог мейлера;
2) Прочитать _последний_ записанный  туда  телефонный  номер  в  переменную
   string : phone;
3) Привести строку с  номером  к  некоему  стандартному  виду  и  отследить
   ситуацию, если номер не определился.
4) Сравнить полученный номер с номерами из badphone.bbs
5) Пропустить или не пропустить юзверя на BBS

Кусок примерного текста программы, обслуживающий лог SF-Mail'а для IDC-AON :

 fd:=open("c:\\bbs\\logs\\sf-mail.log",IOPEN_READ);
 seek(fd,-230,SEEK_END);
// открыли  файл лога _с конца_ и спозиционировались на 230 символов назад,
// то есть  заведомо  дальше  последнего  запомненного  номера  телефона  и
// заведомо  ближе  предпоследнего...  (подбирается  для  каждого   мейлера
// экспериментально или расчитывается).
 s:=""; log("LStartPhoneSel");
 while (strfind(s,"CALLER")=0) readln(fd,s);
// Ищем в логе мейлера строку с подстрокой "CALLER", для IDC это будет
// строка "CALLER`S NUMBER +2ABCDEF1", либо "CALLER`S NUBER ?"
 phone:=substr(s,strfind(s,"CALLER")+17,9);
 close(fd);
 log("LPhone:"+phone);
// Швырнули в MAX.LOG полученный номер телефона (для контроля)
 if ((phone[1]='?') or (phone[2]=' ')) return 2;
// Если номер неопределен, заканчиваем работу.
 phone:=substr(phone,3,6);
 log("LPhoneSel:"+phone);
// Швырнули  в  MAX.LOG  отселектированные  значащие  цифры  номера,    без
// плюсиков и категории абонента, то есть в виде ABCDEF (для 5080 :)
 fd:=open("c:\\bbs\\max\\badphone.bbs",IOPEN_READ);     while
 (readln(fd,s)>0) if (s=phone) {
    userremove(usr);
    log("!Phone found in BLACKLOG:"+phone);
    display_file("Misc\\BlackLog",nonstop);
 }
 close(fd);
// Пощупали телефон на предмет нахождения в черном списке
 if (strfind(usr.xkeys,"T")<>0) {
    log("LLaw User've came. First cycle of protection not activated!");
    return 60;
 }
// Пропустили, если юзер благонадежен и указал правильный номер
 userfindopen("","",tu);
 while(userfindnext(tu)=TRUE)
   if ((tu.phone=phone) and (usr.name<>tu.name))
      display_file("Misc\\DPhone",nonstop);

 if (phone<>usr.phone) {
    log("!Phone Unstable:"+usr.phone);
    display_file("Misc\\BadPhone",nonstop);
    input_str(usr.phone,INPUT_WORD,0,6,"Телефон (6 цифр без дефисов) :");
    if (phone<>usr.phone) {
       log("!Phone Unstable after input:"+usr.phone);
       if (strfind(usr.xkeys,"V")<>0) {
         fd:=open("c:\\bbs\\max\\badphone.bbs",IOPEN_WRITE | IOPEN_APPEND);
         writeln(fd,phone+"\n");
         close(fd);
         usr.priv:=0;
         display_file("Misc\\BadUser",nonstop);
         return 1;
       }
       if (strfind(usr.xkeys,"U")<>0) usr.xkeys:=usr.xkeys+"V";
       else usr.xkeys:=usr.xkeys+"U";
       return 1;
    };
  log("!Phone changed to correct after input:"+usr.phone);
// Здесь если юзер попался хитрый, ему было дадено  три  попытки  исправить
// ситуацию и ввести нормальный номер... это кстати полезно  еще  и  если
// не дай бог был просто сбой в работе АОH'а
 } else usr.xkeys:=usr.xkeys+"T"; return 0; }
// если все ок, присваиваем юзеру ключик "благонадежности"

============================================================================
 Уважаемые коллеги!  Если  в  обнаружили  в  данном  документе  ошибку  или
 неточные, устаревшие сведения; если вам  хочется  сделать  добавление  или
 исправление в тексте FAQа, пожалуйста напишите об этом мне - нетмейлом на
                            2:5080/78.6@FidoNet

Большое спасибо всем, приславшим поправки, дополнения и советы.
Hа данный момент это:
Mike Petrov 2:5020/1413
Fedor Lizunkov 2:5020/960
Kirill K. 2:5063/53

Отдельное спасибо:
George Jot'у (2:5080/52.56) за его советы при настройке МАКСа

Lanius Corp. за прекрасную BBS - MAXIMUS.


                     Автор этого текста - Alex Shiloff, 2:5080/152@FidoNet


Страница 1 2 <<< Предыдущая


Украинская Баннерная Сеть

Главная  Алфавитный индекс  Справка  Добавить FAQ  E-mail
Новости  Поиск по сайту

Copyright © 2001 - 2003 Olexandr Slobodyan.
Сайт создан в системе uCoz