summaryrefslogblamecommitdiffstats
path: root/mbbsd/cal.c
blob: 1e939641cc30fb13559b762c09fefbfa4ae79fbd (plain) (tree)
1
                                                     




































































































                                                                           
                             


































                                                                           

                                                              


                                             

                                                               





                                 
                                                               





                         

                                                  
                                                                           

                                                            





















































































































                                                                                       
                                      















                                                                     
                                                                          





                                                 
                                                                     


















                                                                        
                                                                   








































                                                                    


                       





                                                                    
                                  

 
              
                   










                                                        
                              
                                                                
                                              
                                 
                         
                                                                         



                                                                      
                                                                  
                            



























































































































                                                                 
/* $Id: cal.c,v 1.8 2002/05/06 09:17:02 lwms Exp $ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include "config.h"
#include "pttstruct.h"
#include "common.h"
#include "modes.h"
#include "perm.h"
#include "proto.h"

extern struct utmpfile_t *utmpshm;
extern int usernum;

/* 防堵 Multi play */
static int count_multiplay(int unmode) {
    register int i, j;
    register userinfo_t *uentp;
    extern struct utmpfile_t *utmpshm;

    for(i = j = 0; i < USHM_SIZE; i++) {
    uentp = &(utmpshm->uinfo[i]);
    if(uentp->uid == usernum)
        if(uentp->lockmode == unmode)
        j++;
    }
    return j;
}

extern userinfo_t *currutmp;
extern char *ModeTypeTable[];

int lockutmpmode(int unmode, int state) {
    int errorno = 0;
    
    if(currutmp->lockmode)
    errorno = 1;
    else if(count_multiplay(unmode))
    errorno = 2;
    
    if(errorno && !(state == LOCK_THIS && errorno == LOCK_MULTI)) {
    clear();
    move(10,20);
    if(errorno == 1)
        prints("請先離開 %s 才能再 %s ",
           ModeTypeTable[currutmp->lockmode],
           ModeTypeTable[unmode]);
    else 
        prints("抱歉! 您已有其他線相同的ID正在%s",
           ModeTypeTable[unmode]);
    pressanykey();
    return errorno;
    }
    
    setutmpmode(unmode);
    currutmp->lockmode = unmode;
    return 0;
}

int unlockutmpmode() {
    currutmp->lockmode = 0;
    return 0;
}

extern userec_t cuser;
extern userec_t xuser;

/* 使用錢的函數 */
#define VICE_NEW   "vice.new"

/* Heat:發票 */
int vice(int money, char* item) {
    char buf[128];
    unsigned int viceserial=(currutmp->lastact%1000000)*100+rand()%100;
    FILE *fp;
    demoney(-money);
    sprintf(buf, BBSHOME"/home/%c/%s/%s",
        cuser.userid[0], cuser.userid, VICE_NEW);
    fp = fopen(buf, "a");
    if(!fp )
    {return 0;}
   
    fprintf(fp, "%08d\n", viceserial);
    fclose(fp);
    sprintf(buf, "%s 花了%d$ 編號[%08d]",item, money, viceserial);
    mail_id(cuser.userid, buf, "etc/vice.txt", "Ptt經濟部"); 
    return 0;
}

#define lockreturn(unmode, state) if(lockutmpmode(unmode, state)) return 
#define lockreturn0(unmode, state) if(lockutmpmode(unmode, state)) return 0
#define lockbreak(unmode, state) if(lockutmpmode(unmode, state)) break
#define SONGBOOK  "etc/SONGBOOK"
#define OSONGPATH "etc/SONGO"
extern char trans_buffer[];
extern char save_title[];

static int osong(char *defaultid) {
    char destid[IDLEN + 1],buf[200],genbuf[200],filename[256],say[51];
    char receiver[45],ano[2];
    FILE *fp,*fp1;// *fp2;
    fileheader_t mail;
    time_t now;
    int nsongs;
    
    now = time(NULL);
    strcpy(buf, Cdatedate(&now));
    
    lockreturn0(OSONG, LOCK_MULTI);
    
    /* Jaky 一人一天點一首 */
    if(!strcmp(buf, Cdatedate(&cuser.lastsong)) && !HAS_PERM(PERM_SYSOP)) {
    move(22,0);
    outs("你今天已經點過囉,明天再點吧....");
    refresh();
    pressanykey();

    unlockutmpmode();
    return 0;
    }

    if(cuser.money < 200) {
    move(22, 0);
    outs("點歌要200銀唷!....");
    refresh();
    pressanykey();
    unlockutmpmode();
    return 0;
    }
    move(12, 0);
    clrtobot();
    sprintf(buf, "親愛的 %s 歡迎來到歐桑自動點歌系統\n", cuser.userid);
    outs(buf);
    trans_buffer[0] = 0;
    if(!defaultid){
      getdata(13, 0, "要點給誰呢:[可直接按 Enter 先選歌]",
          destid, sizeof(destid), DOECHO);
      while (!destid[0]){
         a_menu("點歌歌本", SONGBOOK,0 );
         clear();
         getdata(13, 0, "要點給誰呢:[可按 Enter 重新選歌]",
             destid, sizeof(destid), DOECHO);
      }
    }
    else
    strcpy(destid,defaultid);

    /* Heat:點歌者匿名功能 */    
    getdata(14,0, "要匿名嗎?[y/n]:", ano, sizeof(ano), DOECHO);
     
    if(!destid[0]) {
    unlockutmpmode();
    return 0;
    }
    
    getdata_str(14, 0, "想要要對他(她)說..:", say,
        sizeof(say), DOECHO, "我愛妳..");
    sprintf(save_title, "%s:%s", (ano[0]=='y')?"匿名者":cuser.userid, say);
    getdata_str(16, 0, "寄到誰的信箱(可用E-mail)?",
        receiver, sizeof(receiver), LCECHO, destid);
    
    if (!trans_buffer[0]){
       outs("\n接著要選歌囉..進入歌本好好的選一首歌吧..^o^");
       pressanykey();    
       a_menu("點歌歌本", SONGBOOK,0 );
    }
    if(!trans_buffer[0] ||  strstr(trans_buffer, "home") ||
       strstr(trans_buffer, "boards") || !(fp = fopen(trans_buffer, "r"))) {
    unlockutmpmode();
    return 0;
    }
    
    strcpy(filename, OSONGPATH);
    
    stampfile(filename, &mail);
    
    unlink(filename);
    
    if(!(fp1 = fopen(filename, "w"))) {
    fclose(fp);
    unlockutmpmode();
    return 0;
    }
    
    strcpy(mail.owner, "點歌機");
    sprintf(mail.title, "◇ %s 點給 %s ", (ano[0]=='y')?"匿名者":cuser.userid, destid);
    mail.savemode = 0;
    
    while(fgets(buf, 200, fp)) {
    char *po;
    if(!strncmp(buf, "標題: ", 6)) {
        clear();
        move(10,10);prints("%s", buf);
        pressanykey();
        fclose(fp);
        unlockutmpmode();
        return 0;
    }
    while((po = strstr(buf, "<~Src~>"))) {
        po[0] = 0;
        sprintf(genbuf,"%s%s%s",buf,(ano[0]=='y')?"匿名者":cuser.userid,po+7);
        strcpy(buf,genbuf);
        }
    while((po = strstr(buf, "<~Des~>"))) {
        po[0] = 0;
        sprintf(genbuf,"%s%s%s",buf,destid,po+7);
        strcpy(buf,genbuf);
        }
    while((po = strstr(buf, "<~Say~>"))) {
        po[0] = 0;
        sprintf(genbuf,"%s%s%s",buf,say,po+7);
        strcpy(buf,genbuf);
        }
    fputs(buf,fp1);
    }
    fclose(fp1);
    fclose(fp);

//    do_append(OSONGMAIL "/.DIR", &mail2, sizeof(mail2));
    
    if(do_append(OSONGPATH "/.DIR", &mail, sizeof(mail)) != -1) {
      cuser.lastsong = time(NULL);
    /* Jaky 超過 500 首歌就開始砍 */
          nsongs=get_num_records(OSONGPATH "/.DIR", sizeof(mail));
      if (nsongs > 500){
        delete_range(OSONGPATH "/.DIR", 1, nsongs-500);
      }
    /* 把第一首拿掉 */
       vice(200, "點歌");
    }
    sprintf(save_title, "%s:%s", (ano[0]=='y')?"匿名者":cuser.userid, say);
    hold_mail(filename, destid);

    if(receiver[0]) {
#ifndef USE_BSMTP
    bbs_sendmail(filename, save_title, receiver);
#else
    bsmtp(filename, save_title, receiver,0);
#endif
    }
    clear();
    outs(
    "\n\n  恭喜您點歌完成囉..\n"
    "  一小時內動態看板會自動重新更新\n"
    "  大家就可以看到您點的歌囉\n\n"
    "  點歌有任何問題可以到Note板的精華區找答案\n"
    "  也可在Note板精華區看到自己的點歌記錄\n"
    "  有任何保貴的意見也歡迎到Note板留話\n"
    "  讓親切的板主為您服務\n");
    pressanykey();
    sortsong();
    topsong();

    unlockutmpmode();
    return 1;
}

int ordersong() {
    osong(NULL);
    return 0;
}

static int inmailbox(int m) {
    passwd_query(usernum, &xuser);
    cuser.exmailbox = xuser.exmailbox + m;
    passwd_update(usernum, &cuser);
    return cuser.exmailbox;
}


extern int b_lines;

#if !HAVE_FREECLOAK
/* 花錢選單 */
int p_cloak() {
    char buf[4];
    getdata(b_lines-1, 0,
        currutmp->invisible ? "確定要現身?[y/N]" : "確定要隱身?[y/N]",
        buf, sizeof(buf), LCECHO);
    if(buf[0] != 'y')
    return 0;
    if(cuser.money >= 19) {
    vice(19, "cloak");
    currutmp->invisible %= 2;
    outs((currutmp->invisible ^= 1) ? MSG_CLOAKED : MSG_UNCLOAK);
    refresh();
    safe_sleep(1);
    }
    return 0;
}
#endif

int p_from() {
    char ans[4];

    getdata(b_lines-2, 0, "確定要改故鄉?[y/N]", ans, sizeof(ans), LCECHO);
    if(ans[0] != 'y')
    return 0;
    reload_money();
    if(cuser.money < 49)
    return 0;
    if(getdata_buf(b_lines-1, 0, "請輸入新故鄉:",
           currutmp->from, sizeof(currutmp->from), DOECHO)) {
    vice(49,"home");
    currutmp->from_alias=0;
    }
    return 0;
}

int p_exmail() {
    char ans[4],buf[200];
    int n;

    if(cuser.exmailbox >= MAX_EXKEEPMAIL) {
    sprintf(buf,"容量最多增加 %d 封,不能再買了。", MAX_EXKEEPMAIL);
    outs(buf);
    refresh();
    return 0;
    }
    sprintf(buf,"您曾增購 %d 封容量,還要再買多少?",
        cuser.exmailbox);
    
    getdata_str(b_lines-2, 0, buf, ans, sizeof(ans), LCECHO, "10");
    
    n = atoi(ans);
    if(!ans[0] || !n)
    return 0;
    if(n + cuser.exmailbox > MAX_EXKEEPMAIL)
    n = MAX_EXKEEPMAIL - cuser.exmailbox;
    reload_money();
    if(cuser.money < n * 1000)
    return 0;
    vice(n * 1000, "mail");
    inmailbox(n);
    return 0;
}

void mail_redenvelop(char* from, char* to, int money, char mode){
    char genbuf[200];
    fileheader_t fhdr;
    time_t now;
    FILE* fp;
    sprintf(genbuf, "home/%c/%s", to[0], to);
    stampfile(genbuf, &fhdr);
    if (!(fp = fopen(genbuf, "w")))
        return;
    now = time(NULL);
    fprintf(fp, "作者: %s\n"
                "標題: 招財進寶\n"
                "時間: %s\n"
                "\033[1;33m親愛的 %s :\n\n\033[m"
                "\033[1;31m    我包給你一個 %d 元的大紅包喔 ^_^\n\n"
                "    禮輕情意重,請笑納...... ^_^\033[m\n"
                , from, ctime(&now), to, money);
    fclose(fp);
    sprintf(fhdr.title, "招財進寶");
    strcpy(fhdr.owner, from);

    if (mode == 'y')
       vedit(genbuf, NA, NULL);
    sprintf(genbuf, "home/%c/%s/.DIR", to[0], to);       
    append_record(genbuf, &fhdr, sizeof(fhdr));
}

/* 計算贈與稅 */
int give_tax(int money)
{
    int i, tax = 0;
    static int tax_bound[] = { 1000000, 100000, 10000, 1000, 0};
    static double tax_rate[] = { 0.4, 0.3, 0.2, 0.1, 0.05 };
    for( i = 0; money < tax_bound[i]; i++ )
        ;
    tax = money * tax_rate[i];
    return tax <= 0 ? 1 : tax;
}

int p_give() {
    int money, tax;
    char id[IDLEN + 1], genbuf[90];
    time_t now = time(0);
    
    move(1,0);
    usercomplete("這位幸運兒的id:", id);
    if(!id[0] || !strcmp(cuser.userid,id) ||
       !getdata(2, 0, "要給多少錢:", genbuf, 7, LCECHO))
    return 0;
    money = atoi(genbuf);
    reload_money();
    if(money > 0 && cuser.money >= money ) {
    tax = give_tax(money);
    if ( money - tax <= 0 ) return 0; /* 繳完稅就沒錢給了 */
        deumoney(searchuser(id), money - tax);
    demoney(-(money - tax ));
    now = time(NULL);
    sprintf(genbuf,"%s\t給%s\t%d\t%s", cuser.userid, id, money - tax,
        ctime(&now));
    log_file(FN_MONEY, genbuf);
    genbuf[0] = 'n';
    getdata(3, 0, "要自行書寫紅包袋嗎?[y/N]", genbuf, 2, LCECHO);
    mail_redenvelop(cuser.userid, id, money - tax, genbuf[0]);
    vice(tax, "贈與稅");
    }
    return 0;
}

int p_sysinfo() {
    char buf[100];
    long int total,used;
    float p;
    
    move(b_lines-1,0);
    clrtoeol();
    cpuload(buf);
    outs("CPU 負荷 : ");
    outs(buf);
    
    p = swapused(&total,&used);
    sprintf(buf, " 虛擬記憶體: %.1f%%(全部:%ldMB 用掉:%ldMB)\n",
        p*100, total >> 20, used >> 20);
    outs(buf);
    pressanykey();
    return 0;
}

/* 小計算機 */
static void ccount(float *a, float b, int cmode) {
    switch(cmode) {
    case 0:
    case 1:
    case 2:
        *a += b;
        break;
    case 3:
        *a -= b;
        break;
    case 4:
        *a *= b;
        break;
    case 5:
        *a /= b;
        break;
    }
}

int cal() {
    float a = 0;
    char flo = 0, ch = 0;
    char mode[6] = {' ','=','+','-','*','/'} , cmode = 0;
    char buf[100] = "[            0] [ ] ", b[20] = "0";
    
    move(b_lines - 1, 0);
    clrtoeol();
    outs(buf);
    move(b_lines, 0);
    clrtoeol();
    outs("\033[44m 小計算機  \033[31;47m      (0123456789+-*/=) "
     "\033[30m輸入     \033[31m  "
     "(Q)\033[30m 離開                   \033[m");
    while(1) {
    ch = igetch();
    switch(ch) {
    case '\r':
            ch = '=';
    case '=':
    case '+':
    case '-':
    case '*':
    case '/':
            ccount(&a, atof(b), cmode);
            flo = 0;
            b[0] = '0';
            b[1] = 0;
            move(b_lines - 1, 0);
            sprintf(buf, "[%13.2f] [%c] ", a, ch);
            outs(buf);
            break;
    case '.':
            if(!flo)
        flo = 1;
            else
        break;
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
    case '0':
        if(strlen(b) > 13)
        break;
        if(flo || b[0] != '0')
        sprintf(b,"%s%c",b,ch);
        else
        b[0]=ch;
        move(b_lines - 1, 0);
        sprintf(buf, "[%13s] [%c]", b, mode[(int)cmode]);
        outs(buf);
        break;
    case 'q':
        return 0;
    }
    
    switch(ch) {
    case '=':
        a = 0;
        cmode = 0;
        break;
    case '+':
        cmode = 2;
        break;
    case '-':
        cmode = 3;
        break;
    case '*':
        cmode = 4;
        break;
    case '/':
        cmode = 5;
        break;
    }
    }
}