Example #1
0
/*
=======================================
    主程序
=======================================
*/
int main (int argc, char *argv[])
{
    CR_NOUSE(argc);
    CR_NOUSE(argv);

    /* 建立 CrHack 系统 */
    if (!set_app_type(CR_APP_CUI))
        return (QST_ERROR);
    SetConsoleTitleA(WIN_TITLE);

    sint_t  x1, y1;
    uint_t  ww, hh;

    /* 初始化窗口 */
    s_hcui = GetStdHandle(STD_OUTPUT_HANDLE);
    if (s_hcui == INVALID_HANDLE_VALUE)
        return (QST_ERROR);
    s_hwnd = GetConsoleWindow();
    if (s_hwnd == NULL)
        return (QST_ERROR);
    misc_desk_init(WIN_ICONF, &x1, &y1, &ww, &hh,
                   QSRV_DEF_WIDTH, QSRV_DEF_HEIGHT);
    misc_cui_setwin(s_hwnd, s_hcui, x1, y1, ww, hh);

    sINIu*  ini;
    uint_t  temp;
    ansi_t* text;
    int16u  port = QST_DEF_PORT;
    ansi_t* addr = QST_DEF_ADDR;
    uint_t  count = QST_DEF_CLIENT;

    /* 读取参数 */
    text = file_load_as_strA(QST_CFG_STARTUP);
    if (text != NULL) {
        ini = ini_parseU(text);
        mem_free(text);
        text = NULL;
        if (ini != NULL) {
            text = ini_key_stringU("serv::bind", ini);
            if (text != NULL)
                addr = text;
            temp = ini_key_intxU("serv::port", QST_DEF_PORT, ini);
            if (temp > 1024 && temp < 32768)
                port = (int16u)temp;
            temp = ini_key_intxU("serv::count", QST_DEF_CLIENT, ini);
            if (temp > 0 && temp <= QST_MAX_CLIENT)
                count = temp;
            ini_closeU(ini);
        }
    }

    socket_t    serv;
    sQstWork*   work;

    /* 建立工作单元组 */
    work = qst_wrk_create(count);
    if (work == NULL)
        return (QST_ERROR);

    /* 初始化网络 */
    if (!socket_init())
        return (QST_ERROR);
    serv = server_tcp_open(addr, port);
    TRY_FREE(text);
    if (serv == NULL)
        return (QST_ERROR);

    /* 初始化锁 */
    mtlock_init(&s_qst_lck_shw);
    mtlock_init(&s_qst_lck_wrk);

    int16u  logo_color;

    /* 建立颜色值 */
    logo_color = cui_make_attr(0, CR_CUI_TEXT_LIGHT |
                        CR_CUI_TEXT_GREEN | CR_CUI_TEXT_RED |
                        CR_CUI_TEXT_BLUE);
    s_qst_clr_cin = cui_make_attr(0, CR_CUI_TEXT_LIGHT |
                        CR_CUI_TEXT_GREEN | CR_CUI_TEXT_RED);
    s_qst_clr_say = cui_make_attr(0, CR_CUI_TEXT_LIGHT |
                        CR_CUI_TEXT_GREEN);
    s_qst_clr_out = cui_make_attr(0, CR_CUI_TEXT_LIGHT |
                        CR_CUI_TEXT_RED);
    /* 工作循环 */
    cui_set_color(logo_color);
    printf("######################################\n");
    printf("##    QUESTLAB BROADCAST SERVER     ##\n");
    printf("######################################\n");
    while (!s_quit)
    {
        ansi_t*     ptr;
        bool_t      okay;
        ansi_t*     name;
        socket_t    netw;

        /* 接受一个客户端 */
        netw = server_tcp_accept(serv);
        if (netw == NULL)
            continue;

        /* 接收客户端名称 */
        socket_set_timeout(netw, -1, QST_TCP_TOUT);
        name = netw_cmd_recv(netw);
        if (name == NULL) {
            socket_close(netw);
            continue;
        }

        /* 客户端名称过滤 */
        if (str_lenA(name) > QST_MAX_NAME) {
            netw_ack_send(netw, FALSE);
            netw_cli_close(netw);
            mem_free(name);
            continue;
        }
        ptr = name;
        okay = TRUE;
        while (*ptr != NIL) {
            if (is_cntrlA(*ptr++)) {
                okay = FALSE;
                break;
            }
        }
        if (!okay) {
            netw_ack_send(netw, FALSE);
            netw_cli_close(netw);
            mem_free(name);
            continue;
        }

        /* 启动一个工作单元 */
        if (!qst_wrk_wakeup(work, name, netw, qst_srv_main)) {
            netw_cli_close(netw);
            mem_free(name);
            continue;
        }
    }
    return (QST_OKAY);
}
Example #2
0
/*
=======================================
    WinMain 程序入口
=======================================
*/
int WINAPI
WinMain (
  __CR_IN__ HINSTANCE   curt_app,
  __CR_IN__ HINSTANCE   prev_app,
  __CR_IN__ LPSTR       cmd_line,
  __CR_IN__ int         cmd_show
    )
{
    CR_NOUSE(prev_app);
    CR_NOUSE(cmd_line);
    CR_NOUSE(cmd_show);

    /* 只允许一个例程 */
    if (misc_is_running(EXE_XNAME))
        return (QST_ERROR);

    /* 建立 CrHack 系统 */
    if (!set_app_type(CR_APP_GUI))
        return (QST_ERROR);
    mem_zero(&s_wrk_ctx, sizeof(s_wrk_ctx));

    sint_t  x1, y1;
    uint_t  ww, hh;

    /* 生成一个可变大小的窗口 */
    mtlock_init(&s_wrk_ctx.lock);
    qst_load_cfg(&s_wrk_ctx.cfgs);
    misc_desk_init(WIN_ICONF, &x1, &y1, &ww, &hh,
                   QV2D_DEF_WIDTH, QV2D_DEF_HEIGHT);
    if (ww < QV2D_DEF_WIDTH)  ww = QV2D_DEF_WIDTH;
    if (hh < QV2D_DEF_HEIGHT) hh = QV2D_DEF_HEIGHT;
    s_wrk_ctx.hwnd = (HWND)window_open(curt_app, (void_t*)WindowProc,
                        x1, y1, ww, hh, WIN_TITLE, WIN_CLASS, (ansi_t*)101,
                                    CR_WSTYLE_NORMAL);
    if (s_wrk_ctx.hwnd == NULL)
        return (QST_ERROR);
    SetWindowLongPtr(s_wrk_ctx.hwnd, GWL_STYLE,
        GetWindowLongPtr(s_wrk_ctx.hwnd, GWL_STYLE) & (~WS_MAXIMIZEBOX));

    iGFX2*  draw;
    sIMAGE* imgs;

    /* 创建 GDI 绘制对象 (只支持32位色屏幕) */
    draw = (iGFX2*)create_gdi_canvas(s_wrk_ctx.hwnd, 0, 0, FALSE);
    if (draw == NULL) {
        window_kill(s_wrk_ctx.hwnd, curt_app, WIN_CLASS);
        return (QST_ERROR);
    }
    imgs = CR_VCALL(draw)->lock(draw);
    if (imgs == NULL || imgs->fmt != CR_ARGB8888) {
        window_kill(s_wrk_ctx.hwnd, curt_app, WIN_CLASS);
        return (QST_ERROR);
    }
    CR_VCALL(draw)->unlock(draw);
    CR_VCALL(draw)->clear(draw, s_wrk_ctx.cfgs.bkcolor, 0);
    s_wrk_ctx.draw = draw;

    /* 初始化网络 */
    if (!socket_init()) {
        window_kill(s_wrk_ctx.hwnd, curt_app, WIN_CLASS);
        return (QST_ERROR);
    }
    s_wrk_ctx.netw = netw_cli_open(EXE_XNAME);
    if (s_wrk_ctx.netw == NULL) {
        window_kill(s_wrk_ctx.hwnd, curt_app, WIN_CLASS);
        return (QST_ERROR);
    }
    /* 读取需要超时, 不然线程无法退出 */
    socket_set_timeout(s_wrk_ctx.netw, -1, QST_TCP_TOUT);

    thrd_t  thrd;

    /* 生成工作线程 */
    s_wrk_ctx.send = TRUE;
    s_wrk_ctx.quit = FALSE;
    s_wrk_ctx.cur_busy = LoadCursor(NULL, IDC_WAIT);
    s_wrk_ctx.cur_free = LoadCursor(NULL, IDC_ARROW);
    s_wrk_ctx.res_loader = res_loader_get();
    if (s_wrk_ctx.res_loader->init != NULL)
        s_wrk_ctx.res_loader->init(s_wrk_ctx.netw, NULL);
    qst_load_filter(&s_wrk_ctx);
    thrd = thread_new(0, qst_v2d_main, &s_wrk_ctx, FALSE);
    if (thrd == NULL) {
        window_kill(s_wrk_ctx.hwnd, curt_app, WIN_CLASS);
        return (QST_ERROR);
    }

    /* 消息循环 */
    while (!s_wrk_ctx.quit)
    {
        MSG     msg;

        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
            if (msg.message == WM_QUIT) {
                s_wrk_ctx.quit = TRUE;
                break;
            }
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else {
            qst_do_keyboard(&s_wrk_ctx);
        }
    }
    thread_wait(thrd);
    thread_del(thrd);
    window_kill(s_wrk_ctx.hwnd, curt_app, WIN_CLASS);
    netw_cli_close(s_wrk_ctx.netw);
    return (QST_OKAY);
}
Example #3
0
/*
---------------------------------------
    工作线程
---------------------------------------
*/
static uint_t STDCALL
qst_srv_main (
  __CR_IN__ void_t* param
    )
{
    uint_t      self, count;
    sQstWork*   ctx = (sQstWork*)param;
    sQstWork*   tot = (sQstWork*)ctx->self;

    /* 工作循环 */
    self = ctx->id;
    count = ctx->cnt;
    for (;;)
    {
        ansi_t* shell;
        ansi_t* string;

        /* 接收一条命令 */
        /* 一有错误表示非法客户端, 直接踢 */
        string = netw_cmd_recv_ex(ctx->netw);
        if (string == NULL)
            break;

        _ENTER_SHOW_SAY_
        printf("[%s] say: %s\n", ctx->name, string);
        _LEAVE_SHOW_SAY_

        /* 广播这条消息 */
        mtlock_acquire(&s_qst_lck_wrk);
        for (uint_t idx = 0; idx < count; idx++)
        {
            /* 跳过自己和空闲的单元 */
            if (idx == self || tot[idx].over)
                continue;
            netw_cmd_send(tot[idx].netw, string);
        }
        mtlock_release(&s_qst_lck_wrk);

        /* 处理一些公共指令 */
        shell = cmd_shl_get(string);
        mem_free(string);
        if (shell == NULL)
            continue;
        if (str_cmpA(shell, "app:exit") == 0 ||
            str_cmpA(shell, "qsrv:app:exit") == 0) {
            thread_sleep(1000);
            exit(0);
        }
        if (str_cmpA(shell, "win:load") == 0)
            qst_srv_win_load();
        else
        if (str_cmpA(shell, "win:save") == 0)
            qst_srv_win_save();
        else
        if (str_cmpA(shell, "win:show") == 0 ||
            str_cmpA(shell, "qsrv:win:show") == 0)
            qst_srv_win_show();
        mem_free(shell);
    }

    /* 显示已经断线 */
    _ENTER_SHOW_OUT_
    printf("[%s] is offline.\n", ctx->name);
    _LEAVE_SHOW_OUT_

    /* 释放资源 */
    mem_free(ctx->name);
    ctx->name = NULL;
    mtlock_acquire(&s_qst_lck_wrk);
    netw_cli_close(ctx->netw);
    ctx->netw = NULL;
    ctx->over = TRUE;
    mtlock_release(&s_qst_lck_wrk);
    return (QST_OKAY);
}
Example #4
0
/*
=======================================
    WinMain 程序入口
=======================================
*/
int WINAPI
WinMain (
  __CR_IN__ HINSTANCE   curt_app,
  __CR_IN__ HINSTANCE   prev_app,
  __CR_IN__ LPSTR       cmd_line,
  __CR_IN__ int         cmd_show
    )
{
    uint_t      argc;
    ansi_t**    argv;

    CR_NOUSE(prev_app);
    CR_NOUSE(cmd_show);

    /* 只允许一个例程 */
    if (misc_is_running(EXE_XNAME))
        return (QST_ERROR);

    /* 建立 CrHack 系统 */
    if (!set_app_type(CR_APP_GUI))
        return (QST_ERROR);
    mem_zero(&s_wrk_ctx, sizeof(s_wrk_ctx));

    int qt_argc;

    /* 获取命令行参数, 不包括进程文件名 */
    argv = misc_get_param(cmd_line, &argc);
    qt_argc = (int)argc;

    QApplication    qt_app(qt_argc, argv);

    qt_app.setApplicationName("QstComm");
    qt_app.setOrganizationName("QuestLAB");

    sint_t  x1, y1;
    uint_t  ww, hh;

    /* 生成一个可变大小的窗口 */
    mtlock_init(&s_wrk_ctx.lock);
    qst_load_cfg(&s_wrk_ctx.cfgs);
    misc_desk_init(WIN_ICONF, &x1, &y1, &ww, &hh,
                   QCOM_DEF_WIDTH, QCOM_DEF_HEIGHT);
    if (ww < QCOM_DEF_WIDTH)  ww = QCOM_DEF_WIDTH;
    if (hh < QCOM_DEF_HEIGHT) hh = QCOM_DEF_HEIGHT;

    RECT            w_rect;
    sint_t          fw, fh;
    QMainWindow     qt_win;

    /* Qt 里的宽高都不包括边框
       需要自己用 Win32 API 获取 */
    qt_win.setWindowFlags(qt_win.windowFlags()
        & (~Qt::WindowMaximizeButtonHint));
    qt_win.move(x1, y1);
    qt_win.resize(ww, hh);
    s_wrk_ctx.hwnd = (HWND)qt_win.winId();
    if (!GetWindowRect(s_wrk_ctx.hwnd, &w_rect))
        return (QST_ERROR);
    fw = w_rect.right - w_rect.left - ww;
    fh = w_rect.bottom - w_rect.top - hh;
    qt_win.setMinimumSize(QCOM_DEF_WIDTH  - fw,
                          QCOM_DEF_HEIGHT - fh);
    qt_win.resize(ww - fw, hh - fh);

    QWidget*        cent = new QWidget (&qt_win);
    CTextEdit*      edit = new CTextEdit (cent);
    QHBoxLayout*    hori = new QHBoxLayout (cent);

    /* 创建窗体里的控件 */
    hori->setSpacing(6);
    hori->setContentsMargins(8, 8, 8, 8);
    hori->addWidget(edit);
    qt_win.setCentralWidget(cent);

    CTextOper   oper(&qt_win, edit);

    s_wrk_ctx.oper = (void_t*)(&oper);
    SetClassLongPtr(s_wrk_ctx.hwnd, GCLP_HICON, (LONG_PTR)
                    LoadIconA(curt_app, (ansi_t*)101));

    /* 初始化 ANSI 上下文 */
    if (!qst_csi_init())
        return (QST_ERROR);
    qst_set_viewer(&s_wrk_ctx);

    /* 初始化网络 */
    if (!socket_init())
        return (QST_ERROR);
    s_wrk_ctx.netw = netw_cli_open(EXE_XNAME);
    if (s_wrk_ctx.netw == NULL)
        return (QST_ERROR);

    /* 读取需要超时, 不然线程无法退出 */
    socket_set_timeout(s_wrk_ctx.netw, -1, QST_TCP_TOUT);

    thrd_t  thrd;

    /* 生成工作线程 */
    s_wrk_ctx.quit = FALSE;
    s_wrk_ctx.comm.quit = FALSE;
    s_wrk_ctx.comm.text = TRUE;
    s_wrk_ctx.comm.rtype = "text";
    s_wrk_ctx.comm.stype = "text";
    s_wrk_ctx.comm.title = NULL;
    s_wrk_ctx.comm.render = qst_txt_show;
    s_wrk_ctx.page = get_sys_codepage();
    qst_update_title(&s_wrk_ctx);
    thrd = thread_new(0, qst_com_main, &s_wrk_ctx, FALSE);
    if (thrd == NULL)
        return (QST_ERROR);
    sio_init();

    /* 开始 Qt 流程 */
    qt_win.show();
    qt_app.exec();

    /* 关闭线程直接退出 */
    if (!s_wrk_ctx.quit)
        s_wrk_ctx.quit = TRUE;
    thread_wait(thrd);
    thread_del(thrd);
    netw_cli_close(s_wrk_ctx.netw);
    sio_free();
    qst_csi_free();
    return (QST_OKAY);
}