proboard/MENU.CPP

767 lines
21 KiB
C++
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#define Use_MsgBase
#define INCLUDE_REGIS
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <dos.h>
#include <stdlib.h>
#include "proboard.hpp"
struct MenuItem : public _MenuItem
{
bool checkAccess() const;
};
bool
MenuItem::checkAccess() const
{
if(!check_access(access.minLevel , access.flags , access.flagsNot))
return FALSE;
if(access.maxLevel && user.level > access.maxLevel)
return FALSE;
int age = -1;
if(user.birthDate.ok())
age = Date(TODAY).age(user.birthDate);
if(access.minAge || access.maxAge)
{
if(age < 0)
return FALSE;
if((access.minAge && age < access.minAge) || (access.maxAge && age > access.maxAge))
return FALSE;
}
if(access.minTimeLeft && timer.left() < access.minTimeLeft)
return FALSE;
if(access.minTimeOnline && timer.online() < access.minTimeOnline)
return FALSE;
if(!access.timeFrame.enabled())
return FALSE;
if(access.sex)
{
if(!user.sex)
return FALSE;
if(user.sex == SEX_MALE)
{
if(access.sex == 2)
return FALSE;
}
if(user.sex == SEX_FEMALE)
{
if(access.sex == 1)
return FALSE;
}
}
dword speed = io.baud;
if(speed < 1)
speed = 38400L;
if(access.minSpeed && speed < access.minSpeed)
return FALSE;
if(access.maxSpeed && speed > access.maxSpeed)
return FALSE;
if(access.nodes[(node_number-1)/8] & (1 << ((node_number-1) & 7)))
return FALSE;
return TRUE;
}
typedef char *str;
#define MAX_MENUSTACK 100
static
class menu_stack
{
str *menus;
int sp;
public:
menu_stack()
{
menus = new str[MAX_MENUSTACK];
for(int i=0;i<MAX_MENUSTACK;i++) menus[i] = new char[9];
sp=0;
}
~menu_stack()
{
for(int i=0;i<MAX_MENUSTACK;i++) delete [] menus[i];
delete [] menus;
}
void clear() { sp=0; }
void push(char *m) { if(sp<MAX_MENUSTACK) strcpy(menus[sp++],m); }
void pop(char *m) { if(sp>0) strcpy(m,menus[--sp]); }
} mstack;
void
logoff(char *data)
{
if(data==NULL || data[0]!='/') io.cls();
run_sdkfile("/I GOODBYE");
showansascrip("GOODBYE");
run_sdkfile("/I GOODBYE2");
LOG("User logged off");
if(io.baud) sleep(2);
exit_proboard();
}
static void
gotomenu(char *data)
{
String param[4];
char newmenu[20];
static int reg_counter = 0;
if(reg_counter++ == 10)
{
CHECK_REG();
reg_counter = 0;
}
int n=parse_data(data,param);
for(int i=0;i<n;i++)
{
if(param[i][0]=='/')
{
switch(toupper(param[i][1]))
{
case 'M': {
MsgArea ma;
if(param[i][3]=='+')
{
for(int i=user.msgArea+1;i<=user.msgArea+MsgArea::highAreaNum();i++)
{
int area = ((i-1)%MsgArea::highAreaNum())+1;
if(!ma.read(area) || !check_access(ma.readLevel,ma.readFlags,ma.readFlagsNot)) continue;
user.msgArea = area;
break;
}
break;
}
if(param[i][3]=='-')
{
for(int i=user.msgArea+MsgArea::highAreaNum()-1;i>=user.msgArea;i--)
{
int area = ((i-1)%MsgArea::highAreaNum())+1;
if(!ma.read(area) || !check_access(ma.readLevel,ma.readFlags,ma.readFlagsNot)) continue;
user.msgArea = area;
break;
}
break;
}
user.msgArea =atoi(&(param[i][3]));
break;
}
case 'F': {
FileArea fa;
if(param[i][3]=='+')
{
for(int i=user.fileArea+1;i<=user.fileArea+FileArea::highAreaNum();i++)
{
int area = ((i-1)%FileArea::highAreaNum())+1;
if(!fa.read(area) || !check_access(fa.level,fa.flags,fa.flagsNot)) continue;
user.fileArea = area;
break;
}
break;
}
if(param[i][3]=='-')
{
for(int i=user.fileArea+FileArea::highAreaNum()-1;i>=user.fileArea;i--)
{
int area = ((i-1)%FileArea::highAreaNum())+1;
if(!fa.read(area) || !check_access(fa.level,fa.flags,fa.flagsNot)) continue;
user.fileArea = area;
break;
}
break;
}
user.fileArea=atoi(&(param[i][3]));
break;
}
case 'P': {
char s[20];
io << '\n' << S_ENTER_MENU_PASSWORD;
io.read(s,15,READMODE_PWD);
io << "\n\xFF";
if(!s[0]) return;
if(strcmpl(&(param[i][3]),s))
{
LOG(1,"Wrong password for menu <%s> : %s",newmenu,strupr(s));
io << '\n' << S_ACCESS_DENIED << "\n\n" << S_PRESS_ENTER_TO_CONTINUE;
return;
}
}
break;
}
}
else strcpy(newmenu,param[i]);
}
strcpy(curmenu,newmenu);
menuchanged = TRUE;
}
static void
gosubmenu(char *data)
{
mstack.push(curmenu);
gotomenu(data);
if(!menuchanged) mstack.pop(curmenu);
}
static void
prevmenu(char *)
{
mstack.pop(curmenu);
menuchanged = TRUE;
}
static void
gotomenu_clear(char *data)
{
mstack.clear();
gotomenu(data);
}
#define MAX_ITEMS 255
struct menu_item
{
union {
char type;
char highlight;
};
unsigned level;
AccessFlags flags;
char string[76];
char key;
char data[81];
byte color;
byte attr;
};
const byte MNU_RIP_SHOW_REMOTE = 1;
const byte MNU_RIP_HIDE_LOCAL = 2;
const byte MNU_RIP_NO_RESET = 4;
static void nofunction(char *) {}
void (*menufunctions[])(char *) =
{
(void (*)(char *)) nofunction, // function 0 -> niets!! raar maar waar
(void (*)(char *)) gotomenu, // function 1 -> goto menu
(void (*)(char *)) gosubmenu, // function 2 -> gosub menu
(void (*)(char *)) prevmenu, // function 3 -> previous menu
(void (*)(char *)) gotomenu_clear, // function 4 -> clear stack and goto menu
showansasc, // function 5 -> show ans/asc file
(void (*)(char *)) change_state, // function 6 -> change state (!!)
(void (*)(char *)) shell, // function 7 -> shell
(void (*)(char *)) version_info, // function 8 -> version information
(void (*)(char *)) logoff, // function 9 -> logoff
(void (*)(char *)) usage_graph, // function 10 -> system usage graph by hour
(void (*)(char *)) pagesysop, // function 11 -> Chat request
(void (*)(char *)) questionnaire, // function 12 -> questionnaire
(void (*)(char *)) user_list, // function 13 -> user list
(void (*)(char *)) time_stat, // function 14 -> time info
(void (*)(char *)) view_ans_wait, // function 15 -> View ans/asc and wait
(void (*)(char *)) city_change, // function 16 -> change city
(void (*)(char *)) password_change, // function 17 -> change password
(void (*)(char *)) lines_change, // function 18 -> change screen size
(void (*)(char *)) cls_toggle, // function 19 -> toggle clearscreen
(void (*)(char *)) pause_toggle, // function 20 -> toggle more prompt
(void (*)(char *)) ansi_toggle, // function 21 -> toggle ANSI graphics
(void (*)(char *)) mailcheck, // function 22 -> check for mail
(void (*)(char *)) readmsg, // function 23 -> read messages
(void (*)(char *)) scan_msg, // function 24 -> scan messages
(void (*)(char *)) qscan_msg, // function 25 -> qscan messages
(void (*)(char *)) days_graph, // function 26 -> usage graph by day
(void (*)(char *)) writemsg, // function 27 -> write a message
(void (*)(char *)) combined_select, // function 28 -> combined boards select
(void (*)(char *)) weeks_graph, // function 29 -> usage graph per week
(void (*)(char *)) raw_dir, // function 30 -> show directory
(void (*)(char *)) list_files, // function 31 -> list files
(void (*)(char *)) download, // function 32 -> download a file
(void (*)(char *)) upload, // function 33 -> upload a file
(void (*)(char *)) list_archive, // function 34 -> view archive
(void (*)(char *)) keyword_search, // function 35 -> keyword search
(void (*)(char *)) filename_search, // function 36 -> filename search
(void (*)(char *)) new_files, // function 37 -> show new files
(void (*)(char *)) view_file, // function 38 -> view a file
(void (*)(char *)) view_named_file, // function 39 -> display named file
(void (*)(char *)) nofunction, // function 40 -> display ans/asc w/hotkeys
(void (*)(char *)) fsed_toggle, // function 41 -> toggle fs-editor
(void (*)(char *)) hotkey_toggle, // function 42 -> toggle hotkeys
(void (*)(char *)) clearmarked, // function 43 -> clear marked messages
(void (*)(char *)) combined_clear, // function 44 -> reset combined boards
(void (*)(char *)) view_file_wait, // function 45 -> display textfile and wait
(void (*)(char *)) change_access, // function 46 -> Change Access (flags/level)
(void (*)(char *)) logentry, // function 47 -> make a log entry
(void (*)(char *)) tops, // function 48 -> Tops
(void (*)(char *)) set_msgarea, // function 49 -> Set msg-area
(void (*)(char *)) show_users_online,// function 50 -> show users online
(void (*)(char *)) lastcallers, // function 51 -> list last callers
(void (*)(char *)) usereditor, // function 52 -> toggle no-disturb
(void (*)(char *)) multichat, // function 53 -> multi-line chat
(void (*)(char *)) set_filearea, // function 54 -> Set File Area
(void (*)(char *)) view_gif, // function 55 -> View GIF type
(void (*)(char *)) ibm_toggle, // function 56 -> Toggle IBM chars
(void (*)(char *)) phone_change, // function 57 -> Change phone #
(void (*)(char *)) dataphone_change, // function 58 -> Change data phone #
(void (*)(char *)) handle_change, // function 59 -> Change handle
(void (*)(char *)) run_sdkfile, // function 60 -> Load a ProBoard SDK File
(void (*)(char *)) bulletin, // function 61 -> Show bulletin
(void (*)(char *)) toggle_avatar, // function 62 -> Toggle AVT/0
(void (*)(char *)) toggle_avtplus, // function 63 -> Toggle AVT/0+
(void (*)(char *)) show_graph, // function 64 -> Show general usage graph
(void (*)(char *)) showansascrip, // function 65 -> Show ANS/ASC/RIP w/hotkeys
(void (*)(char *)) ripfont_change, // function 66 -> Change RIP font
(void (*)(char *)) rip_toggle, // function 67 -> Toggle RIP graphics
(void (*)(char *)) edit_taglist, // function 68 -> Edit file tags
(void (*)(char *)) select_language, // function 69 -> Select a language
(void (*)(char *)) change_dateformat,// function 70 -> Change date format
(void (*)(char *)) change_address, // function 71 -> Change address
(void (*)(char *)) change_faxphone, // function 72 -> Change fax phone
(void (*)(char *)) change_country, // function 73 -> Change country
(void (*)(char *)) change_default_protocol, // function 74 -> Change default protocol
(void (*)(char *)) select_msggroup, // function 75 -> Select message area group
(void (*)(char *)) select_filegroup // function 76 -> Select file area group
};
static void _near
execute_function(MenuItem *item)
{
rip_reset();
if( item->function>4
&& item->function != 23
&& item->function != 32
&& item->function != 33
&& !(item->attr & MNU_RIP_NO_RESET))
{
rip_textmode();
}
if(item->attr & MENU_PASSWORD)
{
char s[20];
io << '\n' << S_ENTER_SELECTION_PASSWORD;
io.read(s,15,READMODE_PWD);
io << "\n\xFF";
if(!s[0]) return;
if(stricmp(item->password,s))
{
LOG(1,"Wrong password in menu <%s>",(char *)curmenu);
io << '\n' << S_ACCESS_DENIED << "\n\n" << S_PRESS_ENTER_TO_CONTINUE;
return;
}
}
(*menufunctions[item->function])(replace_stringvars(item->data));
}
static char * near
colorstring(char col)
{
char cols[] = { 0,4,2,6,1,5,3,7 };
String s;
static char str[30];
str[0]=0;
char fg=col&7;
char bg=(col&0x70)>>4;
char bright=!(col&8);
if(avatar)
{
fg = cols[fg];
bg = cols[bg];
s << char(22) << char(1) << char(fg|(bg<<4)|(bright?8:0));
strcpy(str,s);
return str;
}
if(!ansi_mode) return str;
s="[";
if(bright) s << "1;";
else s << "0;";
s << form("3%d;4%dm",fg,bg);
strcpy(str,s);
return str;
}
static String near
translate_menutext(char *s,byte color,byte highlight,bool prompt)
{
String str;
bool high = FALSE;
if(*s == ';') return "";
if(*s == '\0') return "\n";
str << colorstring(color);
for(;*s;s++)
{
char c = *s;
switch(c)
{
case '^': high = !high;
if(high)
str << colorstring(highlight);
else
str << colorstring(color);
break;
case '~': str << "@<TMLEFT>@";
break;
case '`': str << "@<CURMSGAREA>@";
break;
case '@': if(*(s+1)=='<' || (*(s-1))=='>')
str << '@';
else
str << "@<CURFILEAREA>@";
break;
case '\\': c = *(s+1);
if(c>='1' && c<='7')
{
str << char(c - '0');
s++;
continue;
}
if(c=='0')
{
str << colorstring(color);
s++;
continue;
}
c = '\\';
default : str << c;
}
}
if(!prompt)
{
if(str[str.len()-1] == ';') str[str.len()-1] = '\0';
else str << '\n';
}
return replace_stringvars(str);
}
static bool
menu_show_at_all(MenuItem *item , _MenuFile *prompt)
{
return
( (item->attr & MNU_RIP_SHOW_REMOTE)
|| !(item->attr & MNU_RIP_HIDE_LOCAL)
|| !rip_mode
|| !prompt->attr
);
}
static bool
menu_show_local(MenuItem *item , _MenuFile *prompt)
{
return
(
!(item->attr & MNU_RIP_HIDE_LOCAL)
|| !rip_mode
|| !prompt->attr
);
}
static bool
menu_show_remote(MenuItem *item , _MenuFile *prompt)
{
return (
(item->attr & MNU_RIP_SHOW_REMOTE)
|| !rip_mode
|| !prompt->attr
);
}
void
menu_processor()
{
int i,j;
char hotkeys[MAX_ITEMS];
File f;
_MenuFile *menufile = NULL;
MenuItem **items = NULL;
int numallocated = 0;
int numitems = 0;
int glob_numitems = 0;
menufile = new _MenuFile;
strcpy(curmenu,"TOP");
for(;;)
{
LOG(3,"Menu: %s",curmenu);
menuchanged = FALSE;
updatemenu = FALSE;
if(f.open(FileName(cfg.mnupath,"GLOBAL.PBM")))
{
glob_numitems = int((f.len() - sizeof(_MenuFile)) / sizeof(MenuItem));
f.close();
}
if(!f.open(FileName(cfg.mnupath,curmenu,".PBM")))
{
if(!strcmpl(curmenu,"TOP")) fatalerror("NO TOP MENU");
mstack.clear();
LOG("ERROR: Menu %s not found!",curmenu);
strcpy(curmenu,"TOP");
continue;
}
if(items != NULL)
{
for(i=0;i<numallocated;i++)
delete items[i];
delete [] items;
}
numitems=int((f.len() - sizeof(_MenuFile)) / sizeof(MenuItem));
items = new MenuItem *[numitems + glob_numitems];
for(i=0;i<numitems+glob_numitems;i++)
items[i] = new MenuItem;
numallocated = i;
f.read(menufile,sizeof(_MenuFile));
for(i=0;i<numitems;i++)
f.read(items[i],sizeof(MenuItem));
f.close();
if(f.open(FileName(cfg.mnupath,"GLOBAL.PBM")))
{
f.seek(sizeof(_MenuFile));
for(i=numitems;i<numitems+glob_numitems;i++)
f.read(items[i],sizeof(MenuItem));
f.close();
numitems += glob_numitems;
}
for(i=0,j=0;i<numitems;i++)
if(items[i]->checkAccess())
if(items[i]->hotKey>13 && items[i]->function)
hotkeys[j++] = toupper(items[i]->hotKey);
hotkeys[j++]='\r';
hotkeys[j++]=';';
hotkeys[j]=0;
for(;;)
{
char k;
again:
if(updatemenu) break;
rip_reset();
k=toupper(comstack.pollnext());
if(strchr(hotkeys,k) && k!=13 && k)
{
k=toupper(comstack.getnext());
for(i=0;i<numitems;i++)
if(k==items[i]->hotKey && items[i]->checkAccess())
{
if(!stack_mode) io << k << "\n\xFF";
execute_function(items[i]);
if(menuchanged) break;
}
if(menuchanged) break;
io << "\n\xFF";
continue;
}
io.disablestop();
io << "\n\f\xFF";
if(menufile->attr)
show_rip(menufile->RIPname,FALSE);
for(i=0;i<numitems;i++)
{
if(!items[i]->checkAccess())
continue;
if(items[i]->function==40)
{
if(menu_show_at_all(items[i],menufile))
{
if(!menu_show_local(items[i],menufile)) io.show_local = FALSE;
if(!menu_show_remote(items[i],menufile)) io.show_remote = FALSE;
k=showansasc(replace_stringvars(items[i]->data),hotkeys);
io.show_local = TRUE;
io.show_remote = TRUE;
if(k>2)
{
io << " \7" << k << "\n\xFF";
for(int j=0;j<numitems;j++)
if(items[j]->hotKey==k && items[j]->checkAccess())
{
if(items[j]->function) execute_function(items[j]);
if(menuchanged) break;
}
if(menuchanged) break;
goto again;
}
}
}
else if(items[i]->hotKey==1)
{
if(items[i]->function == 5 || items[i]->function == 38)
{
if(menu_show_at_all(items[i],menufile))
{
if(!menu_show_local(items[i],menufile)) io.show_local = FALSE;
if(!menu_show_remote(items[i],menufile)) io.show_remote = FALSE;
execute_function(items[i]);
io.show_local = TRUE;
io.show_remote = TRUE;
}
}
else
{
execute_function(items[i]);
}
if(menuchanged) break;
}
k=0;
if(menu_show_at_all(items[i],menufile))
{
if(!menu_show_local(items[i],menufile)) io.show_local = FALSE;
if(!menu_show_remote(items[i],menufile)) io.show_remote = FALSE;
k = io.send(translate_menutext(items[i]->text,
items[i]->color,
menufile->highlight,
FALSE),
hotkeys);
io.show_local = TRUE;
io.show_remote = TRUE;
}
if(k==1) break;
if(k>1)
{
io << " \7" << k << "\n\xFF";
for(int j=0;j<numitems;j++)
if(items[j]->hotKey==k && items[j]->checkAccess())
{
if(items[j]->function) execute_function(items[j]);
if(menuchanged) break;
}
if(menuchanged) break;
goto again;
}
}
if(menuchanged) break;
io << '\n' << translate_menutext(menufile->prompt, // hidden constructor
menufile->color,
menufile->highlight,
TRUE);
if(!stack_mode) k=io.wait(hotkeys);
if(k==';') io << "> ";
if(k==';' || stack_mode)
{
if(k==';' || !strchr(hotkeys,k) || !k)
{
comstack.clear();
char command[60];
io.read(command,59,READMODE_NOFIELD);
if(!command[0]) { command[0]='\r'; command[1]=0; }
io << "\n\xFF";
k=toupper(command[0]);
if(!strchr(hotkeys,k)) k='\r';
else comstack.parse(&command[1]);
}
}
for(i=0;i<numitems;i++)
if(k==items[i]->hotKey && items[i]->checkAccess())
{
if(!stack_mode) io << k << "\n\xFF";
execute_function(items[i]);
if(menuchanged) break;
}
if(menuchanged) break;
io << "\n\xFF";
}
}
}