/* Create a new easy handle, and add it to the global curl_multi */ static void new_conn(char *url, GlobalInfo *g) { ConnInfo *conn; CURLMcode rc; conn = g_malloc0(sizeof(ConnInfo)); conn->error[0]='\0'; conn->easy = curl_easy_init(); if(!conn->easy) { MSG_OUT("curl_easy_init() failed, exiting!\n"); exit(2); } conn->global = g; conn->url = g_strdup(url); curl_easy_setopt(conn->easy, CURLOPT_URL, conn->url); curl_easy_setopt(conn->easy, CURLOPT_WRITEFUNCTION, write_cb); curl_easy_setopt(conn->easy, CURLOPT_WRITEDATA, &conn); curl_easy_setopt(conn->easy, CURLOPT_VERBOSE, (long)SHOW_VERBOSE); curl_easy_setopt(conn->easy, CURLOPT_ERRORBUFFER, conn->error); curl_easy_setopt(conn->easy, CURLOPT_PRIVATE, conn); curl_easy_setopt(conn->easy, CURLOPT_NOPROGRESS, SHOW_PROGRESS?0L:1L); curl_easy_setopt(conn->easy, CURLOPT_PROGRESSFUNCTION, prog_cb); curl_easy_setopt(conn->easy, CURLOPT_PROGRESSDATA, conn); curl_easy_setopt(conn->easy, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(conn->easy, CURLOPT_CONNECTTIMEOUT, 30L); curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_LIMIT, 1L); curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_TIME, 30L); MSG_OUT("Adding easy %p to multi %p (%s)\n", conn->easy, g->multi, url); rc = curl_multi_add_handle(g->multi, conn->easy); mcode_or_die("new_conn: curl_multi_add_handle", rc); /* note that the add_handle() will set a time-out to trigger very soon so that the necessary socket_action() call will be called by this app */ }
/* Check for completed transfers, and remove their easy handles */ static void check_multi_info(GlobalInfo *g) { char *eff_url; CURLMsg *msg; int msgs_left; ConnInfo *conn; CURL *easy; CURLcode res; MSG_OUT("REMAINING: %d\n", g->still_running); while ((msg = curl_multi_info_read(g->multi, &msgs_left))) { if (msg->msg == CURLMSG_DONE) { easy = msg->easy_handle; res = msg->data.result; curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn); curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &eff_url); MSG_OUT("DONE: %s => (%d) %s\n", eff_url, res, conn->error); curl_multi_remove_handle(g->multi, easy); free(conn->url); curl_easy_cleanup(easy); free(conn); } } }
/* CURLMOPT_SOCKETFUNCTION */ static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp) { GlobalInfo *g = (GlobalInfo*) cbp; SockInfo *fdp = (SockInfo*) sockp; static const char *whatstr[]={ "none", "IN", "OUT", "INOUT", "REMOVE" }; MSG_OUT("socket callback: s=%d e=%p what=%s ", s, e, whatstr[what]); if (what == CURL_POLL_REMOVE) { MSG_OUT("\n"); remsock(fdp); } else { if (!fdp) { MSG_OUT("Adding data: %s%s\n", what&CURL_POLL_IN?"READ":"", what&CURL_POLL_OUT?"WRITE":"" ); addsock(s, e, what, g); } else { MSG_OUT( "Changing action from %d to %d\n", fdp->action, what); setsock(fdp, s, e, what, g); } } return 0; }
int init_fifo(void) { struct stat st; const char *fifo = "hiper.fifo"; int socket; if (lstat (fifo, &st) == 0) { if ((st.st_mode & S_IFMT) == S_IFREG) { errno = EEXIST; perror("lstat"); exit (1); } } unlink (fifo); if (mkfifo (fifo, 0600) == -1) { perror("mkfifo"); exit (1); } socket = open (fifo, O_RDWR | O_NONBLOCK, 0); if (socket == -1) { perror("open"); exit (1); } MSG_OUT("Now, pipe some URL's into > %s\n", fifo); return socket; }
/* Die if we get a bad CURLMcode somewhere */ static void mcode_or_die(const char *where, CURLMcode code) { if ( CURLM_OK != code ) { const char *s; switch (code) { case CURLM_BAD_HANDLE: s="CURLM_BAD_HANDLE"; break; case CURLM_BAD_EASY_HANDLE: s="CURLM_BAD_EASY_HANDLE"; break; case CURLM_OUT_OF_MEMORY: s="CURLM_OUT_OF_MEMORY"; break; case CURLM_INTERNAL_ERROR: s="CURLM_INTERNAL_ERROR"; break; case CURLM_BAD_SOCKET: s="CURLM_BAD_SOCKET"; break; case CURLM_UNKNOWN_OPTION: s="CURLM_UNKNOWN_OPTION"; break; case CURLM_LAST: s="CURLM_LAST"; break; default: s="CURLM_unknown"; } MSG_OUT("ERROR: %s returns %s\n", where, s); exit(code); } }
static RESULT cmd_useskill(const char** argv, int argc, GameContext* pContext, GameEventContext* pEvent) { int idx; RESULT ret; if(get_game_status(pContext) == Status_None) { MSG_OUT("当前不在游戏中!\n"); return R_E_STATUS; } ret = R_DEF; if(argc >= 2 && 0 == to_int(argv[1], &idx)) { ret = game_cmd_use_skill(pContext, pEvent, idx); } else if(argc >= 2 && (0 == strcasecmp(argv[1], "weapon") || 0 == strcasecmp(argv[1], "w")) ) { ret = game_cmd_use_weapon(pContext, pEvent); } else if(argc >= 2 && (0 == strcasecmp(argv[1], "armor") || 0 == strcasecmp(argv[1], "a")) ) { ret = game_cmd_use_armor(pContext, pEvent); } else { param_error(argv[0]); return R_E_PARAM; } return ret; }
/* Called by glib when we get action on a multi socket */ static gboolean event_cb(GIOChannel *ch, GIOCondition condition, gpointer data) { GlobalInfo *g = (GlobalInfo*) data; CURLMcode rc; int fd = g_io_channel_unix_get_fd(ch); int action = (condition & G_IO_IN ? CURL_CSELECT_IN : 0) | (condition & G_IO_OUT ? CURL_CSELECT_OUT : 0); rc = curl_multi_socket_action(g->multi, fd, action, &g->still_running); mcode_or_die("event_cb: curl_multi_socket_action", rc); check_multi_info(g); if(g->still_running) { return TRUE; } else { MSG_OUT("last transfer done, kill timeout\n"); if(g->timer_event) { g_source_remove(g->timer_event); } return FALSE; } }
static RESULT cmd_load(const char** argv, int argc, GameContext* pContext, GameEventContext* pEvent) { GameEventContext event; //RESULT ret; if(pContext->status != Status_None) { MSG_OUT("已经在游戏中,不能加载一个游戏进度!\n"); return R_E_STATUS; } if(argc != 2) { param_error(argv[0]); return R_E_PARAM; } // load game INIT_EVENT(&event, GameEvent_LoadGame, INVALID_PLAYER , INVALID_PLAYER, pEvent); event.file_name = argv[1]; //ret = game_load(pContext, argv[1]); //if(R_SUCC != ret) //{ // return ret; //} // game main return game_main(pContext, &event); }
/* CURLOPT_PROGRESSFUNCTION */ static int prog_cb(void *p, double dltotal, double dlnow, double ult, double uln) { ConnInfo *conn = (ConnInfo *)p; MSG_OUT("Progress: %s (%g/%g)\n", conn->url, dlnow, dltotal); return 0; }
static RESULT cmd_discard(const char** argv, int argc, GameContext* pContext, GameEventContext* pEvent) { int idx[MAX_PARAM_NUM]; int cnt = 0; int n; if(get_game_status(pContext) == Status_None) { MSG_OUT("当前不在游戏中!\n"); return R_E_STATUS; } if(argc < 2) { param_error(argv[0]); return R_E_PARAM; } for(n = 1; n < argc && cnt < MAX_PARAM_NUM; n++) { if(0 != to_int(argv[n], &idx[cnt])) { param_error(argv[0]); return R_E_PARAM; } cnt++; } return game_cmd_discard_card(pContext, pEvent, idx, cnt); }
RESULT game_cmd_use_skill(GameContext* pGame, GameEventContext* pEvent, int idx) { RESULT ret; //char name[128]; int skill_num; Player* p = CUR_PLAYER(pGame); //const HeroConfig* pHero = get_hero_config(p->hero); //if(pHero == NULL) //{ // MSG_OUT("skill (%d) not exist!\n", idx ); // return R_E_PARAM; //} skill_num = p->hero == HeroID_None ? 0 : hero_skill_num(p->hero); if(idx < 1 || idx > skill_num) { MSG_OUT("无效的技能序号 [%d] !\n", idx ); return R_E_PARAM; } if(YES != can_use_skill(pGame, pEvent)) { MSG_OUT("你当前不能发动技能!\n"); return R_E_STATUS; } if(USE_MANUAL != call_hero_skill_can_use(p->hero, idx, pGame, pEvent, pGame->cur_player)) { MSG_OUT("当前你不能发动技能【%s】!\n", get_hero_skill_name(p->hero, idx) ); return R_E_STATUS; } // todo: trigger event per use skill MSG_OUT("【%s】发动武将技能【%s】。\n", p->name, get_hero_skill_name(p->hero, idx)); ret = call_hero_skill_event(p->hero, idx, pGame, pEvent, pGame->cur_player); // post trigger use skill (void)ret; return R_SUCC; }
static void cmd_comm(GameContext* pContext, GameEventContext* pEvent, char* cmd) { // 这里直接检测 info 和 quit 指令 const char* argv[MAX_PARAM_NUM]; int argc; char* next; char* w; int n; next = cmd; argc = 0; memset(argv, 0, sizeof(argv)); while( NULL != (w = get_word(next, &next) ) ) { if(argc < (int)COUNT(argv)) { argv[argc++] = w; } } if(*next != 0) { MSG_OUT("error cmd at col %d!\n", (int)(next - cmd)); } else if(argc > 0) { for(n= 0; n < CMD_NUM; n++) { if(s_cmdDispatch[n].flag == cmd_f_comm && (!strcmp(argv[0], s_cmdDispatch[n].name) || (s_cmdDispatch[n].sort_name && !strcmp(argv[0], s_cmdDispatch[n].sort_name)))) { break; } } if(n < CMD_NUM) { (*s_cmdDispatch[n].func)(argv, argc, pContext, pEvent); } else { MSG_OUT("invalid cmd : %s!\n", argv[0]); } } }
static RESULT cmd_reload(const char** argv, int argc, GameContext* pContext, GameEventContext* pEvent) { if(pContext->status != Status_None) { MSG_OUT("在游戏中不能重新加载脚本,请先结束本局游戏!\n"); return R_E_STATUS; } return reload_game_script(); }
RESULT game_cmd_use_armor(GameContext* pGame, GameEventContext* pEvent) { RESULT ret; Player* p = CUR_PLAYER(pGame); VCard vcard; PosCard pcard; //char temp[128]; if(R_SUCC != get_player_card(p, CardWhere_PlayerEquip, EquipIdx_Armor, &vcard)) { MSG_OUT("你没有装备%s!\n", equip_idx_str(EquipIdx_Armor)); return R_E_FAIL; } pcard.card = vcard.vcard; if(YES != can_use_skill(pGame, pEvent)) { MSG_OUT("你当前不能发动技能!\n"); return R_E_STATUS; } pcard.where = CardWhere_PlayerEquip; pcard.pos = EquipIdx_Armor; if(USE_MANUAL != game_card_can_use(pGame, pEvent, get_game_cur_player(pGame), &pcard)) { MSG_OUT("你装备的%s【%s】当前不能使用!\n", equip_idx_str(EquipIdx_Armor), get_card_name(pcard.card.id)); return R_E_FAIL; } MSG_OUT("【%s】发动【%s】的%s效果。\n", p->name, get_card_name(pcard.card.id), equip_idx_str(EquipIdx_Armor)); set_player_card_flag(p, pcard.where, pcard.pos, CardFlag_InUse); ret = call_card_event(pcard.card.id, pGame, pEvent, get_game_cur_player(pGame)); set_player_card_flag(p, pcard.where, pcard.pos, CardFlag_None); (void)ret; return R_SUCC; }
static void cmd_help_i(const char* cmd) { int n; if(cmd == NULL) { for(n = 0; n < CMD_NUM; n++) { if(s_cmdDispatch[n].brief != NULL) { MSG_OUT("%s\n", s_cmdDispatch[n].brief); } } } else { for(n = 0; n < CMD_NUM; n++) { if(!strcmp(cmd, s_cmdDispatch[n].name) || (s_cmdDispatch[n].sort_name && !strcmp(cmd, s_cmdDispatch[n].sort_name))) { if(s_cmdDispatch[n].brief != NULL) { MSG_OUT("%s\n", s_cmdDispatch[n].brief); if(s_cmdDispatch[n].detail != NULL) { MSG_OUT("%s\n", s_cmdDispatch[n].detail); } } else { MSG_OUT("no help info for cmd \'%s\'\n", cmd); } break; } } if(n >= CMD_NUM) { MSG_OUT("cmd \'%s\' not found!\n", cmd); } } }
/* Check for completed transfers, and remove their easy handles */ static void check_run_count(GlobalInfo *g) { if (g->prev_running > g->still_running) { char *eff_url=NULL; CURLMsg *msg; int msgs_left; ConnInfo *conn=NULL; CURL*easy; CURLcode res; MSG_OUT("REMAINING: %d\n", g->still_running); /* I am still uncertain whether it is safe to remove an easy handle from inside the curl_multi_info_read loop, so here I will search for completed transfers in the inner "while" loop, and then remove them in the outer "do-while" loop... */ do { easy=NULL; while ((msg = curl_multi_info_read(g->multi, &msgs_left))) { if (msg->msg == CURLMSG_DONE) { easy=msg->easy_handle; res=msg->data.result; break; } } if (easy) { curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn); curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &eff_url); MSG_OUT("DONE: %s => (%d) %s\n", eff_url, res, conn->error); curl_multi_remove_handle(g->multi, easy); g_free(conn->url); curl_easy_cleanup(easy); g_free(conn); g->completed++; } } while ( easy ); MSG_OUT("Requested: %d Completed:%d\n", g->requested, g->completed); } g->prev_running = g->still_running; }
static char* get_line(const char* prompt, char* buf, int size) { #ifdef WIN32 int n,c; //fflush(stdin); MSG_OUT("%s", prompt); for(n = 0; n < size-1; n++) { c = getchar(); if(c == EOF) { if(n == 0) return NULL; break; } else if(c=='\n') { break; } else { buf[n] = (char)c; } } buf[n] = 0; #elif defined(LINUX) char utf8[1024]; char* sl; A2UTF8( prompt, utf8, sizeof(utf8)); log_text(utf8); sl = readline(utf8); if(strlen(sl) > 0) add_history(sl); strncpy(buf, sl, size); free(sl); #endif log_text("%s\n", buf); return buf; }
/* Create a new easy handle, and add it to the global curl_multi */ static void new_conn(char *url, GlobalInfo *g ) { ConnInfo *conn; CURLMcode rc; conn = g_malloc0(sizeof(ConnInfo)); conn->error[0]='\0'; conn->easy = curl_easy_init(); if (!conn->easy) { MSG_OUT("curl_easy_init() failed, exiting!\n"); exit(2); } conn->global = g; conn->url = g_strdup(url); curl_easy_setopt(conn->easy, CURLOPT_URL, conn->url); curl_easy_setopt(conn->easy, CURLOPT_WRITEFUNCTION, write_cb); curl_easy_setopt(conn->easy, CURLOPT_WRITEDATA, &conn); curl_easy_setopt(conn->easy, CURLOPT_VERBOSE, (long)SHOW_VERBOSE); curl_easy_setopt(conn->easy, CURLOPT_ERRORBUFFER, conn->error); curl_easy_setopt(conn->easy, CURLOPT_PRIVATE, conn); curl_easy_setopt(conn->easy, CURLOPT_NOPROGRESS, SHOW_PROGRESS?0L:1L); curl_easy_setopt(conn->easy, CURLOPT_PROGRESSFUNCTION, prog_cb); curl_easy_setopt(conn->easy, CURLOPT_PROGRESSDATA, conn); curl_easy_setopt(conn->easy, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(conn->easy, CURLOPT_CONNECTTIMEOUT, 30L); curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_LIMIT, 1L); curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_TIME, 30L); MSG_OUT("Adding easy %p to multi %p (%s)\n", conn->easy, g->multi, url); rc =curl_multi_add_handle(g->multi, conn->easy); mcode_or_die("new_conn: curl_multi_add_handle", rc); g->requested++; do { rc = curl_multi_socket_all(g->multi, &g->still_running); } while (CURLM_CALL_MULTI_PERFORM == rc); mcode_or_die("new_conn: curl_multi_socket_all", rc); check_run_count(g); }
/* Update the event timer after curl_multi library calls */ static int update_timeout_cb(CURLM *multi, long timeout_ms, void *userp) { struct timeval timeout; GlobalInfo *g=(GlobalInfo *)userp; timeout.tv_sec = timeout_ms/1000; timeout.tv_usec = (timeout_ms%1000)*1000; MSG_OUT("*** update_timeout_cb %ld => %ld:%ld ***\n", timeout_ms, timeout.tv_sec, timeout.tv_usec); g->timer_event = g_timeout_add(timeout_ms, timer_cb, g); return 0; }
static RESULT cmd_pass(const char** argv, int argc, GameContext* pContext, GameEventContext* pEvent) { if(get_game_status(pContext) == Status_None) { MSG_OUT("当前不在游戏中!\n"); return R_E_STATUS; } return game_cmd_pass(pContext, pEvent); //return CMD_RET_SUCC; }
static RESULT cmd_start(const char** argv, int argc, GameContext* pContext, GameEventContext* pEvent) { //RESULT ret; int cfg; const NewGameConfig* pConfig; GameEventContext event; if(pContext->status != Status_None) { MSG_OUT("你正在游戏中,不能开始一个新的游戏!"); return R_E_STATUS; } if(argc < 2 || 0 != to_int(argv[1], &cfg)) { param_error(argv[0]); return R_E_PARAM; } // get config struct pConfig = select_config(cfg); if(pConfig == NULL ) { param_error(argv[0]); return R_E_PARAM; } // new game INIT_EVENT(&event, GameEvent_NewGame, INVALID_PLAYER, INVALID_PLAYER, pEvent); event.new_game_config = pConfig; //ret = init_game_context(pContext, pConfig->ministers, pConfig->spies, pConfig->mutineers); //if(ret != R_SUCC) //{ // MSG_OUT("start init new game failed!"); // return ret; //} // game main return game_main(pContext, &event); }
/* Called by glib when we get action on a multi socket */ static gboolean event_cb(GIOChannel *ch, GIOCondition condition, gpointer data) { GlobalInfo *g = (GlobalInfo*) data; CURLMcode rc; int fd=g_io_channel_unix_get_fd(ch); do { rc = curl_multi_socket(g->multi, fd, &g->still_running); } while (rc == CURLM_CALL_MULTI_PERFORM); mcode_or_die("event_cb: curl_multi_socket", rc); check_run_count(g); if(g->still_running) { return TRUE; } else { MSG_OUT("last transfer done, kill timeout\n"); if (g->timer_event) { g_source_remove(g->timer_event); } return FALSE; } }
static RESULT cmd_get(const char** argv, int argc, GameContext* pContext, GameEventContext* pEvent) { if(get_game_status(pContext) == Status_None) { MSG_OUT("当前不在游戏中!\n"); return R_E_STATUS; } int num = 1; if(argc>= 2) { if(0 != to_int(argv[1], &num)) { num = 1; } } return game_cmd_getcard(pContext, pEvent, num); }
static RESULT cmd_save(const char** argv, int argc, GameContext* pContext, GameEventContext* pEvent) { if(get_game_status(pContext) == Status_None) { MSG_OUT("当前不在游戏中,不能保存进度!\n"); return R_E_STATUS; } if(argc != 2) { param_error(argv[0]); return R_E_PARAM; } game_save(pContext, argv[1]); return R_DEF; }
/* Update the event timer after curl_multi library calls */ static int update_timeout_cb(CURLM *multi, long timeout_ms, void *userp) { struct timeval timeout; GlobalInfo *g = (GlobalInfo *)userp; timeout.tv_sec = timeout_ms/1000; timeout.tv_usec = (timeout_ms%1000)*1000; MSG_OUT("*** update_timeout_cb %ld => %ld:%ld ***\n", timeout_ms, timeout.tv_sec, timeout.tv_usec); /* TODO * * if timeout_ms is 0, call curl_multi_socket_action() at once! * * if timeout_ms is -1, just delete the timer * * for all other values of timeout_ms, this should set or *update* * the timer to the new value */ g->timer_event = g_timeout_add(timeout_ms, timer_cb, g); return 0; }
static RESULT cmd_do_script(GameContext* pGame, GameEventContext* pEvent) { RESULT ret; int state; lua_State* L = get_game_script(); lua_pushlightuserdata(L, pGame); lua_pushlightuserdata(L, pEvent); state = script_pcall(L, 2, 1); if(state != 0) { MSG_OUT("%s\n", lua_tostring(L, -1)); lua_pop(L, 1); return R_E_FAIL; } ret = (RESULT)lua_tointeger(L, -1); lua_pop(L, 1); return ret; }
static void param_error(const char* cmd) { MSG_OUT("execute cmd \'%s\', get wrong params!\n", cmd); cmd_help_i(cmd); }
RESULT cmd_loop(GameContext* pContext, GameEventContext* pEvent, YESNO force, const char* strAlter) { char prompt[MAX_NAME_LEN + 10]; char cmdline[MAX_CMD_LEN]; const char* argv[MAX_PARAM_NUM]; int argc; char *next, *w; int n; RESULT ret; if(get_game_status(pContext) == Status_None) { snprintf(prompt, sizeof(prompt), "[SGS2010] $ "); } else { snprintf(prompt, sizeof(prompt), "[%s] $ ", CUR_PLAYER(pContext)->name); } while(1) { if (strAlter != NULL) { MSG_OUT("%s\n", strAlter) ; } if(NULL == get_cmd_line(pContext, pEvent, prompt, cmdline, sizeof(cmdline))) { break; } next = cmdline; argc = 0; memset(argv, 0, sizeof(argv)); while( NULL != (w = get_word(next, &next) ) ) { if(argc < (int)COUNT(argv)) { argv[argc++] = w; } } if(*next != 0) { MSG_OUT("error cmd at col %d!\n", (int)(next - cmdline)); } else if(argc > 0) { ret = R_DEF; //if(funper != NULL) //{ // ret = (*funper)(argv, argc, pContext, ud); // if(ret < 0) // return ret; //} if(ret == R_DEF) { for(n= 0; n < CMD_NUM; n++) { if(!strcmp(argv[0], s_cmdDispatch[n].name) || (s_cmdDispatch[n].sort_name && !strcmp(argv[0], s_cmdDispatch[n].sort_name))) { break; } } if(n < CMD_NUM) { ret = (*s_cmdDispatch[n].func)(argv, argc, pContext, pEvent); if(ret == R_CANCEL && force == YES) { MSG_OUT("当前不能取消(放弃)操作!\n"); } else { switch(ret) { case R_SUCC: // success and back to caller case R_BACK: // back to caller no result case R_CANCEL: // cancel current operator and back to caller case R_EXIT: // exit game return ret; default: break; } } } else { MSG_OUT("无效的命令:\'%s\'!\n", argv[0]); } } } } // end of input ??? return R_EXIT; }
static char* get_cmd_line(GameContext* pGame, GameEventContext* pEvent, const char* prompt, char* buf, int len) { int mode; RESULT ret; if(is_test_mode()) { // contiue test proc mode = CMD_LINE_MODE_NORMAL; MSG_OUT("%s", prompt); ret = script_test_continue(s_out_messages,s_out_len, buf, len, &mode); if(R_SUCC == ret) { s_out_len = 0; s_out_messages[0] = 0; if(mode == CMD_LINE_MODE_SCRIPT) { if(R_SUCC != cmd_do_script(pGame, pEvent)) { s_test_mode = 0; buf[0] = 0; CMD_OUT(buf); script_test_error(); if(pGame->status != Status_None) { //longjmp(pContext->__jb__, R_EXIT); //pGame->status = Status_GameAbort; luaL_error(get_game_script(), "Run test error!"); } return buf; } } CMD_OUT(buf); return buf; } s_out_len = 0; s_out_messages[0] = 0; // 失败退出测试模式 s_test_mode = 0; buf[0] = 0; CMD_OUT(buf); if(R_CANCEL == ret) { // test finished } else if(pGame->status != Status_None) { //longjmp(pContext->__jb__, R_EXIT); //pGame->status = Status_GameAbort; luaL_error(get_game_script(), "Run test error!"); } return buf; } else { mode = CMD_LINE_MODE_NORMAL; return logic_wait_cmd(prompt, buf, len); } }
static RESULT cmd_info(const char** argv, int argc, GameContext* pContext, GameEventContext* pEvent) { if(argc <= 1) // self info { if(pContext->status == Status_None) { MSG_OUT("游戏中才能查看当前玩家信息!\n"); return R_E_STATUS; } else { game_cur_info(pContext, pEvent); } } else if(!strcmp(argv[1], "event") || !strcmp(argv[1], "e")) // game event info { game_event_info(pContext, pEvent, 0); } else if(!strcmp(argv[1], "eventfull") || !strcmp(argv[1], "ef")) // game event info { game_event_info(pContext, pEvent, 1); } else if(!strcmp(argv[1], "game") || !strcmp(argv[1], "g")) // game global info { if(pContext->status == Status_None) { MSG_OUT("游戏中才能查看游戏全局信息!\n"); return R_E_STATUS; } else { game_global_info(pContext, pEvent); } } else if(!strcmp(argv[1], "gamefull") || !strcmp(argv[1], "gf")) // game full info { MSG_OUT("暂时不支持该指令!\n"); } else if(!strcmp(argv[1], "stack") || !strcmp(argv[1], "s")) // list out cards { if(pContext->status == Status_None) { MSG_OUT("游戏中才能查看牌堆信息!\n"); return R_E_STATUS; } else { game_stack_info(pContext, pEvent); } } else if(!strcmp(argv[1], "player") || !strcmp(argv[1], "p")) // player info: -n - prev [n] player; +n - next n player; n - player index n info; { const char* pp; char cp = 0; int n = 0; if(pContext->status == Status_None) { MSG_OUT("游戏中才能查看玩家信息!\n"); return R_E_STATUS; } if(argc < 3) { param_error(argv[0]); return R_E_PARAM; } pp = argv[2]; if(*pp == '+' || *pp == '-') { cp = *pp; pp++; } if(*pp ==0 ) { param_error(argv[0]); return R_E_PARAM; } while(*pp >= '0' && *pp <= '9') { n = n * 10 + (*pp -'0'); pp++; } if(*pp != 0 ) { param_error(argv[0]); return R_E_PARAM; } if(cp == '+') { n = (n + pContext->cur_player) % pContext->player_count; } else if(cp == '-') { n = (pContext->cur_player - n % pContext->player_count + pContext->player_count) % pContext->player_count; } else { n = n % pContext->player_count; } game_other_player_info(pContext, pEvent, n); } else if(!strcmp(argv[1], "card") || !strcmp(argv[1], "c")) { game_card_info(pContext, pEvent, argc < 3 ? NULL : argv[2]); } else if(!strcmp(argv[1], "hero") || !strcmp(argv[1], "h")) { game_hero_info(pContext, pEvent, argc < 3 ? NULL : argv[2]); } else { param_error(argv[0]); return R_E_PARAM; } return R_DEF; }