/* ======================================= 读入配置文件 ======================================= */ CR_API void_t qst_load_cfg ( __CR_OT__ sQCOM_conf* cfgs ) { sINIu* ini; ansi_t* str; /* 加载配置文件 */ TRY_FREE(cfgs->font_face); str = file_load_as_strA(QST_PATH_CONFIG WIN_ICONF); if (str == NULL) goto _load_defs; ini = ini_parseU(str); mem_free(str); if (ini == NULL) goto _load_defs; /* 读入配置参数 */ cfgs->color = ini_key_intx32U("qcom::color", 0xFFC0C0C0UL, ini); cfgs->bkcolor = ini_key_intx32U("qcom::bkcolor", 0xFF000000UL, ini); cfgs->font_size = ini_key_intxU("qcom::font_size", 12, ini); cfgs->font_face = ini_key_stringU("qcom::font_face", ini); ini_closeU(ini); return; _load_defs: cfgs->color = 0xFFC0C0C0UL; cfgs->bkcolor = 0xFF000000UL; cfgs->font_size = 12; cfgs->font_face = NULL; }
/* ======================================= 主程序 ======================================= */ 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); }
/* --------------------------------------- 文件处理回调 --------------------------------------- */ static bool_t do_each_file (void_t *param, sSEARCHa *finfo) { wide_t *tmp; sCP_PARAM *ctx; leng_t idx, len; ansi_t *src, *dst; /* 统计文件总数 */ ctx = (sCP_PARAM*)param; ctx->tot += 1; /* 跳过空文件和只读文件 */ if ((finfo->size == 0) || (finfo->attr & CR_FILE_ATTR_RDO)) return (TRUE); /* 过滤掉大文件 */ if (finfo->size > CR_M2B(4)) return (TRUE); if (ctx->del_u8_bom && finfo->size <= 3) return (TRUE); /* 加载整个文件 */ src = file_load_as_strA(finfo->name); if (src == NULL) return (TRUE); /* 跳过二进制文件 */ len = str_lenA(src); if (len != finfo->size) goto _func_out; /* 删除 UTF-8 文件的 BOM 标志 */ if (ctx->del_u8_bom) { if (chr_cmpA(src, BOM_UTF8, 3) != 0) goto _func_out; if (!is_utf8_file(src)) goto _func_out; if (!file_saveA(finfo->name, src + 3, len - 3)) goto _func_out; ctx->cvt += 1; printf("%s\n", finfo->name); goto _func_out; } /* 检查是否是 UTF-8, 跳过不用转换的文件 */ if (ctx->skip_utf8 && is_utf8_file(src)) goto _func_out; /* 转换到 UTF-16 编码 */ len = MultiByteToWideChar(ctx->from, MB_ERR_INVALID_CHARS, src, -1, NULL, 0); if (len == 0) goto _func_out; if (ctx->to == CR_UTF16LE || ctx->to == CR_UTF16BE) { tmp = str_allocW(len + 1); if (tmp == NULL) goto _func_out; len = MultiByteToWideChar(ctx->from, 0, src, -1, tmp + 1, len); mem_cpy(tmp, BOM_UTF16LE, 2); if (ctx->to == CR_UTF16BE) { for (idx = 0; idx < len; idx++) tmp[idx] = xchg_int16u(tmp[idx]); } len = len * 2 + 1; dst = (ansi_t*)tmp; mem_free(src); } else { tmp = str_allocW(len); if (tmp == NULL) goto _func_out; MultiByteToWideChar(ctx->from, 0, src, -1, tmp, len); mem_free(src); /* 转换到目标编码 */ len = WideCharToMultiByte(ctx->to, 0, tmp, -1, NULL, 0, NULL, NULL); if (len == 0) { mem_free(tmp); return (TRUE); } dst = str_allocA(len); if (dst == NULL) { mem_free(tmp); return (TRUE); } len = WideCharToMultiByte(ctx->to, 0, tmp, -1, dst, len, NULL, NULL); mem_free(tmp); } /* 写入整个文件 (去掉后面的0) */ if (!file_saveA(finfo->name, dst, len - 1)) { mem_free(dst); return (TRUE); } ctx->cvt += 1; printf("%s\n", finfo->name); mem_free(dst); return (TRUE); _func_out: mem_free(src); return (TRUE); }
/* ======================================= 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(curt_app); CR_NOUSE(prev_app); CR_NOUSE(cmd_show); /* 只允许一个例程 */ ximp_stop_running(); if (misc_is_running(EXE_XNAME)) return (QST_ERROR); /* 建立 CrHack 系统 */ if (!set_app_type(CR_APP_GUI)) return (QST_ERROR); /* 获取命令行参数, 不包括进程文件名 */ argv = misc_get_param(cmd_line, &argc); sINIu* ini; ansi_t* str; bool_t old = TRUE; /* 加载配置文件 */ str = file_load_as_strA(QST_PATH_CONFIG WIN_ICONF); if (str != NULL) { ini = ini_parseU(str); mem_free(str); if (ini != NULL) { old = ini_key_intxU("sdir::old_style", TRUE, ini); ini_closeU(ini); } } /* 参数解析 [起始目录] */ g_root = NULL; if (argc > 0) { /* 验证目录是否存在 */ if (misc_dir_exist(argv[0])) g_root = argv[0]; } /* 未指定目录则使用上次结果 */ if (g_root == NULL) g_root = file_load_as_strA(QST_SELECT_DIR); if (!old) { BROWSEINFOA bi; LPITEMIDLIST pidl; ansi_t path[MAX_PATH]; /* 使用新风格的目录打开窗口 */ CoInitialize(NULL); bi.hwndOwner = NULL; bi.pidlRoot = NULL; bi.pszDisplayName = path; bi.lpszTitle = ""; bi.ulFlags = BIF_RETURNONLYFSDIRS; if (g_root == NULL) bi.lpfn = NULL; else bi.lpfn = BrowseCallbackProc; bi.lParam = 0; bi.iImage = 0; pidl = SHBrowseForFolderA(&bi); if (pidl != NULL && SHGetPathFromIDListA(pidl, path)) ximp_dir_write(path); CoUninitialize(); return (QST_OKAY); } /* 标准 VCL 过程开始 */ try { Application->Initialize(); Application->Title = WIN_TITLE; Application->CreateForm(__classid(TfrmMain), &frmMain); Application->Run(); } catch (Exception &exception) { Application->ShowException(&exception); } catch (...) { try { throw Exception(""); } catch (Exception &exception) { Application->ShowException(&exception); } } return (QST_OKAY); }
/* ======================================= 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(curt_app); CR_NOUSE(prev_app); CR_NOUSE(cmd_show); /* 建立 CrHack 系统 */ if (!set_app_type(CR_APP_GUI)) return (QST_ERROR); /* 获取命令行参数, 不包括进程文件名 */ argv = misc_get_param(cmd_line, &argc); /* 参数解析 <脚本文件> */ if (argc < 1) return (QST_ERROR); leng_t size; ansi_t* root; ansi_t* temp; ansi_t* exec; ansi_t path[MAX_PATHA]; /* 合成 LUA_PATH & LUA_CPATH 目录 */ exec = file_load_as_strA(QST_ROOT_START); if (exec == NULL) { size = GetCurrentDirectoryA(sizeof(path), path); if (size == 0 || size > sizeof(path)) return (QST_ERROR); if (path[size - 1] == '\\') path[size - 1] = 0x00; exec = str_dupA(path); if (exec == NULL) return (QST_ERROR); } temp = str_dupA(exec); if (temp == NULL) { mem_free(exec); return (QST_ERROR); } root = str_fmtA("%s\\lualib", exec); mem_free(exec); if (root == NULL) { mem_free(temp); return (QST_ERROR); } DWORD cf = 0; /* 根据扩展名选择用哪个启动 */ if (filext_checkA(argv[0], ".lua")) { exec = str_fmtA("%s\\lua.exe \"%s\"", temp, argv[0]); cf = CREATE_NEW_CONSOLE; } else if (filext_checkA(argv[0], ".wlua")) { exec = str_fmtA("%s\\wlua.exe \"%s\"", temp, argv[0]); cf = CREATE_NO_WINDOW; } else { exec = NULL; } mem_free(temp); if (exec == NULL) { mem_free(root); return (QST_ERROR); } STARTUPINFOA si; PROCESS_INFORMATION pi; /* 启动脚本 */ mem_zero(&si, sizeof(si)); si.cb = sizeof(STARTUPINFOA); SetEnvironmentVariableA("LUA_PATH", root); SetEnvironmentVariableA("LUA_CPATH", root); size = str_lenA(root); size -= str_lenA("\\lualib"); root[size] = 0x00; if (CreateProcessA(NULL, exec, NULL, NULL, FALSE, cf, NULL, root, &si, &pi)) { WaitForSingleObject(pi.hProcess, INFINITE); CloseHandle(pi.hThread); CloseHandle(pi.hProcess); } mem_free(exec); mem_free(root); return (QST_OKAY); }