int cli_scanrtf(cli_ctx *ctx) { char* tempname; const unsigned char* ptr; const unsigned char* ptr_end; int ret = CL_CLEAN; struct rtf_state state; struct stack stack; size_t bread; table_t* actiontable; uint8_t main_symbols[256]; size_t offset = 0; cli_dbgmsg("in cli_scanrtf()\n"); memset(main_symbols, 0, 256); main_symbols['{']=1; main_symbols['}']=1; main_symbols['\\']=1; stack.stack_cnt = 0; stack.stack_size = 16; stack.elements = 0; stack.warned = 0; stack.states = cli_malloc(stack.stack_size*sizeof(*stack.states)); if(!stack.states) { cli_errmsg("ScanRTF: Unable to allocate memory for stack states\n"); return CL_EMEM; } if(!(tempname = cli_gentemp(ctx->engine->tmpdir))) return CL_EMEM; if(mkdir(tempname, 0700)) { cli_dbgmsg("ScanRTF -> Can't create temporary directory %s\n", tempname); free(stack.states); free(tempname); return CL_ETMPDIR; } actiontable = tableCreate(); if((ret = load_actions(actiontable))) { cli_dbgmsg("RTF: Unable to load rtf action table\n"); free(stack.states); if(!ctx->engine->keeptmp) cli_rmdirs(tempname); free(tempname); tableDestroy(actiontable); return ret; } init_rtf_state(&state); for (offset = 0; (ptr = fmap_need_off_once_len(*ctx->fmap, offset, BUFF_SIZE, &bread)) && bread; offset += bread) { ptr_end = ptr + bread; while(ptr < ptr_end) { switch(state.parse_state) { case PARSE_MAIN: switch(*ptr++) { case '{': if(( ret = push_state(&stack,&state) )) { cli_dbgmsg("RTF:Push failure!\n"); SCAN_CLEANUP; return ret; } break; case '}': if(state.cb_data && state.cb_end) if(( ret = state.cb_end(&state, ctx) )) { SCAN_CLEANUP; return ret; } if(( ret = pop_state(&stack,&state) )) { cli_dbgmsg("RTF:pop failure!\n"); SCAN_CLEANUP; return ret; } break; case '\\': state.parse_state = PARSE_CONTROL_; break; default: ptr--; { size_t i; size_t left = ptr_end - ptr; size_t use = left; for(i = 1;i < left; i++) if(main_symbols[ptr[i]]) { use = i; break; } if(state.cb_begin) { if(!state.cb_data) if(( ret = state.cb_begin(&state, ctx,tempname) )) { SCAN_CLEANUP; return ret; } if(( ret = state.cb_process(&state, ptr, use) )) { if(state.cb_end) { state.cb_end(&state,ctx); } SCAN_CLEANUP; return ret; } } ptr += use; } } break; case PARSE_CONTROL_: if(isalpha(*ptr)) { state.parse_state = PARSE_CONTROL_WORD; state.controlword_cnt = 0; } else state.parse_state = PARSE_CONTROL_SYMBOL; break; case PARSE_CONTROL_SYMBOL: ptr++; /* Do nothing */ state.parse_state = PARSE_MAIN; break; case PARSE_CONTROL_WORD: if(state.controlword_cnt == 32) { cli_dbgmsg("Invalid control word: maximum size exceeded:%s\n",state.controlword); state.parse_state = PARSE_MAIN; } else if(isalpha(*ptr)) state.controlword[state.controlword_cnt++] = *ptr++; else { if(isspace(*ptr)) { state.controlword[state.controlword_cnt++] = *ptr++; state.parse_state = PARSE_INTERPRET_CONTROLWORD; } else if (isdigit(*ptr)) { state.parse_state = PARSE_CONTROL_WORD_PARAM; state.controlword_param = 0; state.controlword_param_sign = 1; } else if(*ptr == '-') { ptr++; state.parse_state = PARSE_CONTROL_WORD_PARAM; state.controlword_param = 0; state.controlword_param_sign = -1; } else { state.parse_state = PARSE_INTERPRET_CONTROLWORD; } } break; case PARSE_CONTROL_WORD_PARAM: if(isdigit(*ptr)) { state.controlword_param = state.controlword_param*10 + *ptr++ - '0'; } else if(isalpha(*ptr)) { ptr++; } else { if(state.controlword_param_sign < 0) state.controlword_param = -state.controlword_param; state.parse_state = PARSE_INTERPRET_CONTROLWORD; } break; case PARSE_INTERPRET_CONTROLWORD: { int action; state.controlword[state.controlword_cnt] = '\0'; action = tableFind(actiontable, state.controlword); if(action != -1) { if(state.cb_data && state.cb_end) {/* premature end of previous block */ state.cb_end(&state,ctx); state.cb_begin = NULL; state.cb_end = NULL; state.cb_data = NULL; } rtf_action(&state,action); } state.parse_state = PARSE_MAIN; break; } } } } SCAN_CLEANUP; return ret; }
void PlayerInst::enqueue_io_actions(GameState* gs) { LANARTS_ASSERT(is_local_player() && gs->local_player() == this); if (actions_set_for_turn) { return; } bool single_player = (gs->player_data().all_players().size() <= 1); actions_set_for_turn = true; GameSettings& settings = gs->game_settings(); GameView& view = gs->view(); PlayerDataEntry& pde = gs->player_data().local_player_data(); if (pde.action_queue.has_actions_for_frame(gs->frame())) { pde.action_queue.extract_actions_for_frame(queued_actions, gs->frame()); event_log("Player %d has %d actions", player_entry(gs).net_id, (int) queued_actions.size()); return; } if (!single_player) { gs->set_repeat_actions_counter(settings.frame_action_repeat); } int dx = 0, dy = 0; bool mouse_within = gs->mouse_x() < gs->view().width; int rmx = view.x + gs->mouse_x(), rmy = view.y + gs->mouse_y(); bool was_moving = moving, do_stopaction = false; IOController& io = gs->io_controller(); if (!settings.loadreplay_file.empty()) { load_actions(gs, queued_actions); } enqueue_io_movement_actions(gs, dx, dy); if (was_moving && !moving && cooldowns().can_do_stopaction()) { do_stopaction = true; } //Shifting target if (gs->key_press_state(SDLK_k)) { shift_autotarget(gs); } if (gs->key_press_state(SDLK_m)) spellselect = -1; bool attack_used = false; if (!gs->game_hud().handle_io(gs, queued_actions)) { attack_used = enqueue_io_spell_and_attack_actions(gs, dx, dy); enqueue_io_equipment_actions(gs, do_stopaction); } bool action_usage = io.query_event(IOEvent::ACTIVATE_SPELL_N) || io.query_event(IOEvent::USE_WEAPON) || io.query_event(IOEvent::AUTOTARGET_CURRENT_ACTION) || io.query_event(IOEvent::MOUSETARGET_CURRENT_ACTION); if ((do_stopaction && !action_usage) || gs->key_down_state(SDLK_PERIOD) || gs->mouse_downwheel()) { queue_portal_use(gs, this, queued_actions); } // If we haven't done anything, rest if (queued_actions.empty()) { queued_actions.push_back(game_action(gs, this, GameAction::USE_REST)); } ActionQueue only_passive_actions; for (int i = 0; i < queued_actions.size(); i++) { GameAction::action_t act = queued_actions[i].act; if (act == GameAction::MOVE || act == GameAction::USE_REST) { only_passive_actions.push_back(queued_actions[i]); } } GameNetConnection& net = gs->net_connection(); if (net.is_connected()) { net_send_player_actions(net, gs->frame(), player_get_playernumber(gs, this), queued_actions); } int repeat = single_player ? 0 : settings.frame_action_repeat; for (int i = 1; i <= repeat; i++) { for (int j = 0; j < only_passive_actions.size(); j++) { only_passive_actions[j].frame = gs->frame() + i; } pde.action_queue.queue_actions_for_frame(only_passive_actions, gs->frame() + i); if (net.is_connected()) { net_send_player_actions(net, gs->frame() + i, player_get_playernumber(gs, this), only_passive_actions); } } }