回精華區
作者hialan.bbs@bbs.math.cycu.edu.tw (過的太認真) 看板: plan
標題[功能] BBS 教學系統
時間數學之家 (2005/09/11 Sun 03:43:30) Updated: 2005/09/12
因為我們系上有許多人不會使用 BBS
所以我打算在使用者註冊完之後,請他們閱讀 BBS 簡單的操作說明

但是如果使用精華區的模式來寫文件,就必須假設使用者已經會使用精華區
所以我寫了一個東西,來簡介 BBS 如何使用。

因為寫的方式有點暴力,所以想先把我完成的架構公佈在這裡
希望有相同困擾或是有更好實做方式的人能夠給點意見

畢竟現在要修改內容實在是太麻煩了,而我最希望的是內容和程式分開
而又希望只要一個文件就可以達成,就是這樣 @@"

現在先把我已經寫好的東西貼上來,當然希望有看到的人能夠給些意見,感恩
====================================================================

/* bbsteach.c BBS 教學系統! */

#include "bbs.h"

#define FEETER_TEACH    \
COLOR1 "  BBS 教學  " COLOR2 " 本章節已經結束,請按任意鍵選擇章節       \033[m
"

#define TEACH_MSGTOP    2
#define TEACH_MSGBOT    (b_lines - 2)


#define MODE_CLEAR  0
#define MODE_WAIT   -1
#define MODE_NOWAIT -2

static int
bbsteach_msg(int line, char *msg)
{
    static int mycurrline = TEACH_MSGTOP;

    if(line < TEACH_MSGTOP && line > 0)
    {
        /*在目前行顯示訊息*/
        mycurrline = TEACH_MSGTOP;
    }
    else if(line == MODE_CLEAR)
    {
        /*清空畫面*/
        clear();
        outs("\033[0;1;46m【 BBS 教學系統 】\033[m");
        mycurrline = TEACH_MSGTOP;
        line = MODE_NOWAIT;
    }
    else if(line == MODE_WAIT || line == MODE_NOWAIT)
    {
        /*下一行*/
        if(++mycurrline > TEACH_MSGBOT)
            return bbsteach_msg(MODE_CLEAR, msg);
    }
    else if(line > TEACH_MSGBOT)
    {
        mycurrline = TEACH_MSGBOT;
    }

    if(msg!=0)
    {
        move(mycurrline, 0);
        clrtoeol();
        outs(msg);

        if(line != MODE_NOWAIT)
            return vmsg(NULL);
    }

    return 0;
}

static inline int
nextmsg(char *msg)
{
    return bbsteach_msg(MODE_WAIT, msg);
}

static inline int
nowaitmsg(char *msg)
{
    return bbsteach_msg(MODE_NOWAIT, msg);
}

static void
bbsteach_key(int key, char *msg)
{
    int cmd;
    uschar str;
    char buf[256]={'\0'};

    move(b_lines, 0);
    clrtoeol();
    prints(COLOR1 " ★ 請輸入 %-60.60s\033[m", msg);

    while((cmd = vkey()) != key)
    {
        str = (unsigned char) cmd;

        if(tolower(cmd) == 'q')
          break;

        if(islower(key))
        {
            if(tolower(cmd) == key && isupper(cmd))
                sprintf(buf, "歐喔! 你輸入到大寫的 %c 了,而我需要的是小寫的 %c,請注意你
有沒有開啟大寫燈!", cmd, key);
        }
        else if(isupper(key))
        {
            if(toupper(cmd) == key && islower(cmd))
                sprintf(buf, "歐喔! 你輸入到小寫的 %c 了,而我需要的是大寫的 %c,請注意你
有沒有開啟大寫燈!", cmd, key);
        }

        if(str >= 0x81 && str < 0xFE)
        {
            sprintf(buf, "歐喔! 你輸入的是全型符號,請輸入半型的 %c 喔!", key);
        }

        if(buf[0] != '\0')
        {
            move(b_lines-1, 0);
            clrtoeol();
            outs(buf);

            buf[0] = '\0';
        }
    }

    nextmsg(0);
    nextmsg(msg);
    nextmsg(0);
}

int bbsteach()
{
    int playing = 0;
    int cmd;
    char buf[80], buf2[256];

    while(1)
    {
        switch(playing)
        {
        case 0:
            bbsteach_msg(MODE_CLEAR, "歡迎使用 BBS 教學系統");
            nextmsg(0);
            nextmsg("本系統會介紹 BBS 基本使用的方式");
            nextmsg("主要提供給還沒使用過 BBS 的使用者。");
            nextmsg("\033[1;33;41m  強烈建議還沒始用過 BBS 閱\讀本文件。  \033[m");
            nextmsg("如果本系統在您登入時自動出現,表示您尚未通過認證。");
            nextmsg(0);
            nextmsg("你可以在以下地方找到這個教學精靈:");
            nowaitmsg("(\033[1;36mX\033[m)yz       【 特殊招待所 】");
            nowaitmsg("    (\033[1;36mO\033[m)ther      【 雜七雜八 】");
            nowaitmsg("        (\033[1;36mB\033[m)BSTeach   【 教學精靈 】");
            nextmsg(0);
            nextmsg("如果您想要離開本系統,請在稍後輸入 '0' 結束!");

            break;
        case 1:
            bbsteach_msg(MODE_CLEAR, "BBS 瀏覽方式簡介");
            nextmsg(0);
            nextmsg("要瀏覽 BBS ,只要使用鍵盤的方向鍵即可");
            nextmsg("往左 (←) 通常代表離開,往右 (→) 通常代表進入或閱\讀");
            nextmsg("當然,你也可以使用英文字母來做特定功\能的事情。");
            nextmsg("但要注意大小寫英文字母是不一樣的,像是 'A' 和 'a' 就會產生不同的結果。");
            nextmsg("所以請特別注意你的大寫燈(鍵盤右邊三個燈中間那個)是否已經開啟。");
            nextmsg(0);
            nextmsg("有的時候你可能會不知道有什麼按鍵可以用,這時候你可以看看畫面最下方或是畫面上方。");
            nextmsg(FEETER_TEACH);
            nextmsg("他會顯示在目前情況下最常用的按鍵指令。但是畫面有限,總不能列出所有指令。");
            nextmsg("這時候我們就可以按 小寫 'h' 來看看屬於此畫面的說明");
            nextmsg(0);
            nextmsg("接下來我們將介紹最先看到的目錄選單。");

            break;

        case 2:
            bbsteach_msg(MODE_CLEAR, "目錄選單");
            nextmsg(0);
            nextmsg("在您進入 BBS 之後,會看到如下的選單:");
            nowaitmsg("(\033[1;36mA\033[m)nnounce  【 精華公佈欄 】");
            nowaitmsg("(\033[1;36mB\033[m)oards    【 佈告討論區 】");
            nowaitmsg("(\033[1;36mC\033[m)lass     【 分組討論集 】");
            nowaitmsg("(\033[1;36mF\033[m)avorite  【 我的最愛群 】");
            nowaitmsg("(\033[1;36mM\033[m)ail      【 信件典藏盒 】");
            nowaitmsg("(\033[1;36mT\033[m)alk      【 休閒聊天地 】");
            nowaitmsg("(\033[1;36mU\033[m)ser      【 個人工具坊 】");
            nowaitmsg("(\033[1;36mX\033[m)yz       【 特殊招待所 】");
            nowaitmsg("(\033[1;36mG\033[m)oodbye   【 下次再會吧 】");
            nextmsg(0);
            nextmsg("你可以移動選單光棒(就是藍色的那個)到你想要進入的地方");
            nextmsg("例如: [\033[1;44m(C)lass     【 分組討論集 】\033[m]");
            nextmsg("然後使用 (→) 進入, (←) 離開");
            nextmsg(0);
            nextmsg("這裡面有很多東西,幾乎所有提供的功\能都會放在上面");
            nextmsg("在結束這個精靈之後,您可以到處看看,這個 BBS 裡面到底有什麼功\能。");

            break;

        case 3:
            bbsteach_msg(MODE_CLEAR, "選擇看板");
            nextmsg(0);
            nextmsg("在 BBS 有許\多討論群組,而一個討論群組我們叫做看板。");
            nextmsg("為了讓我們更快找到我們想要的看板,通常都會將看板分類。");
            nextmsg(0);
            nextmsg("接著我們示範如何找到 sysop 看板。");
            nextmsg("首先,在主目錄選擇【 分組討論集 】");
            nextmsg(0);
            nextmsg("[\033[1;44m(C)lass     【 分組討論集 】\033[m]");
            nextmsg(0);
            nextmsg("然後選擇(將 '>' 符號移到前面,或是用光棒選擇他)");
            nextmsg(0);
            nextmsg("     1 \033[1;36m□BBS/\033[m                 [ 站務管理 ] BBS 相關事務討論區");
            nextmsg(0);
            nextmsg("然後使用 (→) 或是 ENTER 進入這個分類。接著選擇:");
            nextmsg(0);
            nextmsg("  1176   sysop        \033[1;30m站務\033[m ◇ 報告站長!數學之家欺負我~~       1 SYSOP");
            nextmsg(0);
            nextmsg("如此一來,你就進入 sysop 看板了。");
            nextmsg(0);
            nextmsg("接著我們將教你如何閱\讀與發表文章。");

            break;

        case 4:
            bbsteach_msg(MODE_CLEAR, "閱\讀與發表文章");
            nextmsg(0);
            nextmsg("閱\讀文章就如同選擇看板一樣,將 '>' 移到想要閱\讀的文章前面。");
            nextmsg("(→)進入,按(↑)(↓)或是 空白鍵 閱\讀文章,按 (←) 離開。");
            nextmsg(0);
            nextmsg("現在我們來發表文章。");
            nextmsg("在看板列表中按著 'Ctrl' 再按 'p'。");
            nextmsg("(這種組合按鍵我們通常表示成 Ctrl+P) 就可以發表文章");
            nowaitmsg("現在就請你按 Ctrl+P 吧!");

            bbsteach_key(Ctrl('P'), "Ctrl+P");
            nextmsg("很好,目前你已經進入發表文章的模式了,接著請你輸入標題:");

            vget(b_lines, 0, "標題: ", buf, 60, DOECHO);

            move(b_lines, 0);   /*好像會有問題 -_-*/
            clrtoeol();

            nextmsg(0);
            nextmsg(buf);
            nextmsg(0);
            nextmsg("現在我們要編輯文章,你可以在裡面使用方向鍵控制游標,看看要在哪裡輸入。");
            nextmsg("在最前面如果是 '~' 符號,表示那一行目前沒有東西。你將無法移動到那個位置。");
            nextmsg("再寫完文章以後如果想要存檔離開,請使用按鍵 Ctrl+X。");
            nextmsg("然後選擇存檔 (輸入小寫 's') 然後按 ENTER 即可。");
            nowaitmsg("現在測試按鍵,請輸入 Ctrl+X");

            bbsteach_key(Ctrl('X'), "Ctrl+X");

            nextmsg("現在我們將編輯文章,請記得使用 Ctrl+X 發摽文章或離開。");

            sprintf(buf, "tmp/bbsteach_post");
            vedit(buf, 0);

            unlink(buf);

            bbsteach_msg(MODE_CLEAR, "很好,你現在已經會發表文章了!");
            nextmsg("接著,我們將教你如何回應文章。");

            break;

        case 5:
        {
            struct tm *ptime;
            time_t now;

            bbsteach_msg(MODE_CLEAR, "回覆文章與推薦文章");
            nextmsg(0);
            nextmsg("通常看到一篇文章,如果你有意見想要發表,該怎麼辦呢?");
            nextmsg("這時候我們可以使用小寫 'y' 來回應文章。");
            nowaitmsg("現在就讓我們來練習一下如何回復文章吧! 請按小寫 'y'");

            bbsteach_key('y', "小寫 'y'");

            nextmsg("很好,現在已經進入回覆文章的狀態了。");
            nextmsg("然後系統會問你要回覆到看板,還是作者信箱。通常都選擇看板。");

            vget(b_lines, 0, "▲ 回應至 (F)看板 (M)作者信箱 (B)二者皆是 (Q)取消?[F] ", buf, 3, LCECHO);
            move(b_lines, 0);
            clrtoeol();

            nextmsg(0);
            nextmsg("然後系統會請你修改標題。");

            strcpy(buf, "這是原文的標題。");
            vget(b_lines, 0, "標題:", buf, 60, GCARRY);
            move(b_lines, 0);
            clrtoeol();

            nextmsg(0);
            nextmsg(buf);
            nextmsg(0);

            nextmsg("接著會詢問是否要引用原文。");
            nextmsg("其中比較特殊的是引用全文,他會連標題時間等等都變成引文。");
            nextmsg("還有一個叫做重貼全文,他不會修改文章的任何地方。");
            nowaitmsg("現在就讓我們來試試看。");

            vget(b_lines, 0, "是否引用原文 Y)引用 N)不引用 A)引用全文 R)重貼全文 1-9)引用層數?[Y] ", buf, 3, LCECHO);
            move(b_lines, 0);
            clrtoeol();

            nextmsg("接著就是編輯文章,細節請閱\讀上一個章節。");

            bbsteach_msg(MODE_CLEAR, "推薦文章");
            nextmsg(0);
            nextmsg("還有另外一種回覆的機制就是推薦文章。");
            nextmsg("如果你對這篇文章只有一點點小意見,像是只有一句話而已,還沒有大到需要回文的地步。");
            nextmsg("這個時候就可以使用推薦文章。");
            nextmsg(0);
            nextmsg("推薦文章只需要在文章前面輸入 '%' 符號,然後將理由打上即可。");
            nowaitmsg("現在就讓我們來實習一下:");

            bbsteach_key('%', "半型 %");

            vget(b_lines, 0, "◎ 評分 1)推文?[1]", buf, 3, LCECHO);
            move(b_lines, 0);
            clrtoeol();

            strcpy(buf, "這裡是推薦內容!!");
            vget(b_lines, 0, "請輸入理由:", buf, 60, GCARRY);
            move(b_lines, 0);
            clrtoeol();

            nextmsg(buf);
            nextmsg(0);
            nextmsg("然後會在文章下面加入以下結果:");
            nextmsg(0);

            time(&now);
            ptime = localtime(&now);
            sprintf(buf2, "→ \033[36m%s \033[1;31m推\033[m:%-*s%02d/%02d/%02d\n",
                cuser.userid, 62 - strlen(cuser.userid), buf,
                ptime->tm_year % 100, ptime->tm_mon + 1, ptime->tm_mday);

            nextmsg(buf2);
            nextmsg(0);

            nextmsg("如此就完成推文了!");

            break;
        }

        default:
            bbsteach_msg(MODE_CLEAR, "本教學已經完畢。");
            nextmsg(0);
            nextmsg("謝謝你耐心看完這份教學文件。");
            nextmsg("如果還有任何問題請直接在 sysop 看板中發問");
            nextmsg("熱心的站務將會告訴你解決的方式。");
            nextmsg("祝您有個愉快使用 BBS 的經驗。");

            playing = -1;
            return 0;
        }   /* End of switch */


        move(b_lines, 0);
        clrtoeol();
        outs(FEETER_TEACH);
        vkey();

        while(1)
        {
                bbsteach_msg(MODE_CLEAR, "選擇章節");
                nextmsg(0);
                nowaitmsg("請直接按 ENTER 看下一個章節,或選擇想要閱\讀的章節:");
                nowaitmsg(0);
                nowaitmsg("1) 瀏覽方式簡介");
                nowaitmsg("2) 目錄選單");
                nowaitmsg("3) 選擇看板");
                nowaitmsg("4) 閱\讀與發表文章");
                nowaitmsg("5) 回覆文章與推薦文章");
                nowaitmsg(0);
                nowaitmsg("0) 離開");

                move(b_lines, 0);
                clrtoeol();
                printf("請輸入想要閱\讀的主題, 不輸入=%d: ", ++playing);
                if((cmd = tolower(vkey())) && ((cmd >= '0' && cmd <= '9') || cmd == 'q' || cmd == '\n' ))
                {
                    if(cmd == 'q' || cmd == '0')
                        return 0;

                    if(cmd > '0' && cmd < '6')
                        playing = cmd - '0';

                    break;
                }
        }
    }

    return 0;
}



--
 ee�ee▄  ee                      http://www.moztw.org/firefox/
   e▄ �ee    e▄�ee▄▄▄▄▄�ee▄▄▄▄▄▄
      e   ee     ee�eee�eee�e▄▄  ▄
███e███e█ee           e�ee
        ▄�e ee   e    e�e �e      e�ee
 e     ▄▄  e    ▄�e▄▄▄▄▄�e�e▄  ◎FongChen◎

--
  Origin:  中原大學˙數學之家  bbs.math.cycu.edu.tw 
  Author: hialan 203-67-154-247.adsl.dynamic.seed.net.tw 發表
--
精華選讀←離開[主題上]主題下(k)上篇(j)下篇S/a搜尋 G串列 TAB精華 ↑↓捲 Pg/Space翻