Ejemplo n.º 1
0
void GameLoop()
{
	ProcessAsyncSaveFinish();

	/* autosave game? */
	if (_do_autosave) {
		_do_autosave = false;
		DoAutosave();
		SetWindowDirty(WC_STATUS_BAR, 0);
	}

	/* switch game mode? */
	if (_switch_mode != SM_NONE) {
		SwitchToMode(_switch_mode);
		_switch_mode = SM_NONE;
	}

	IncreaseSpriteLRU();
	InteractiveRandom();

	extern int _caret_timer;
	_caret_timer += 3;
	CursorTick();

#ifdef ENABLE_NETWORK
	/* Check for UDP stuff */
	if (_network_available) NetworkUDPGameLoop();

	if (_networking && !IsGeneratingWorld()) {
		/* Multiplayer */
		NetworkGameLoop();
	} else {
		if (_network_reconnect > 0 && --_network_reconnect == 0) {
			/* This means that we want to reconnect to the last host
			 * We do this here, because it means that the network is really closed */
			NetworkClientConnectGame(NetworkAddress(_settings_client.network.last_host, _settings_client.network.last_port), COMPANY_SPECTATOR);
		}
		/* Singleplayer */
		StateGameLoop();
	}

	/* Check chat messages roughly once a second. */
	static uint check_message = 0;
	if (++check_message > 1000 / MILLISECONDS_PER_TICK) {
		check_message = 0;
		NetworkChatMessageLoop();
	}
#else
	StateGameLoop();
#endif /* ENABLE_NETWORK */

	if (!_pause_mode && HasBit(_display_opt, DO_FULL_ANIMATION)) DoPaletteAnimations();

	if (!_pause_mode || _game_mode == GM_EDITOR || _settings_game.construction.command_pause_level > CMDPL_NO_CONSTRUCTION) MoveAllTextEffects();

	InputLoop();

	_sound_driver->MainLoop();
	MusicLoop();
}
Ejemplo n.º 2
0
/**
 * Actual game loop for the client.
 * @return Whether everything went okay, or not.
 */
/* static */ bool ClientNetworkGameSocketHandler::GameLoop()
{
	_frame_counter++;

	NetworkExecuteLocalCommandQueue();

	extern void StateGameLoop();
	StateGameLoop();

	/* Check if we are in sync! */
	if (_sync_frame != 0) {
		if (_sync_frame == _frame_counter) {
#ifdef NETWORK_SEND_DOUBLE_SEED
			if (_sync_seed_1 != _random.state[0] || _sync_seed_2 != _random.state[1]) {
#else
			if (_sync_seed_1 != _random.state[0]) {
#endif
				NetworkError(STR_NETWORK_ERROR_DESYNC);
				DEBUG(desync, 1, "sync_err: %08x; %02x", _date, _date_fract);
				DEBUG(net, 0, "Sync error detected!");
				my_client->ClientError(NETWORK_RECV_STATUS_DESYNC);
				return false;
			}

			/* If this is the first time we have a sync-frame, we
			 *   need to let the server know that we are ready and at the same
			 *   frame as he is.. so we can start playing! */
			if (_network_first_time) {
				_network_first_time = false;
				SendAck();
			}

			_sync_frame = 0;
		} else if (_sync_frame < _frame_counter) {
			DEBUG(net, 1, "Missed frame for sync-test (%d / %d)", _sync_frame, _frame_counter);
			_sync_frame = 0;
		}
	}

	return true;
}


/** Our client's connection. */
ClientNetworkGameSocketHandler * ClientNetworkGameSocketHandler::my_client = NULL;

static uint32 last_ack_frame;

/** One bit of 'entropy' used to generate a salt for the company passwords. */
static uint32 _password_game_seed;
/** The other bit of 'entropy' used to generate a salt for the company passwords. */
static char _password_server_id[NETWORK_SERVER_ID_LENGTH];

/** Maximum number of companies of the currently joined server. */
static uint8 _network_server_max_companies;
/** Maximum number of spectators of the currently joined server. */
static uint8 _network_server_max_spectators;

/** Who would we like to join as. */
CompanyID _network_join_as;

/** Login password from -p argument */
const char *_network_join_server_password = NULL;
/** Company password from -P argument */
const char *_network_join_company_password = NULL;

/** Make sure the server ID length is the same as a md5 hash. */
assert_compile(NETWORK_SERVER_ID_LENGTH == 16 * 2 + 1);

/***********
 * Sending functions
 *   DEF_CLIENT_SEND_COMMAND has no parameters
 ************/

NetworkRecvStatus ClientNetworkGameSocketHandler::SendCompanyInformationQuery()
{
	my_client->status = STATUS_COMPANY_INFO;
	_network_join_status = NETWORK_JOIN_STATUS_GETTING_COMPANY_INFO;
	SetWindowDirty(WC_NETWORK_STATUS_WINDOW, 0);

	Packet *p = new Packet(PACKET_CLIENT_COMPANY_INFO);
	my_client->SendPacket(p);
	return NETWORK_RECV_STATUS_OKAY;
}

NetworkRecvStatus ClientNetworkGameSocketHandler::SendJoin()
{
	my_client->status = STATUS_JOIN;
	_network_join_status = NETWORK_JOIN_STATUS_AUTHORIZING;
	SetWindowDirty(WC_NETWORK_STATUS_WINDOW, 0);

	Packet *p = new Packet(PACKET_CLIENT_JOIN);
	p->Send_string(_openttd_revision);
	p->Send_string(_settings_client.network.client_name); // Client name
	p->Send_uint8 (_network_join_as);     // PlayAs
	p->Send_uint8 (NETLANG_ANY);          // Language
	my_client->SendPacket(p);
	return NETWORK_RECV_STATUS_OKAY;
}

NetworkRecvStatus ClientNetworkGameSocketHandler::SendNewGRFsOk()
{
	Packet *p = new Packet(PACKET_CLIENT_NEWGRFS_CHECKED);
	my_client->SendPacket(p);
	return NETWORK_RECV_STATUS_OKAY;
}

NetworkRecvStatus ClientNetworkGameSocketHandler::SendGamePassword(const char *password)
{
	Packet *p = new Packet(PACKET_CLIENT_GAME_PASSWORD);
	p->Send_string(password);
	my_client->SendPacket(p);
	return NETWORK_RECV_STATUS_OKAY;
}