Beispiel #1
0
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);
		}
	}

}