*pkt >> pos >> pitch >> yaw;
- player->got_teleported = true;
player->setPosition(pos);
infostream << "Client got TOCLIENT_MOVE_PLAYER"
if (num_files == 0)
return;
- if (m_media_downloader == NULL ||
- !m_media_downloader->isStarted()) {
+ if (!m_media_downloader || !m_media_downloader->isStarted()) {
const char *problem = m_media_downloader ?
"media has not been requested" :
"all media has been received already";
void Client::handleCommand_PlaySound(NetworkPacket* pkt)
{
+ /*
+ [0] u32 server_id
+ [4] u16 name length
+ [6] char name[len]
+ [ 6 + len] f32 gain
+ [10 + len] u8 type
+ [11 + len] (f32 * 3) pos
+ [23 + len] u16 object_id
+ [25 + len] bool loop
+ [26 + len] f32 fade
+ [30 + len] f32 pitch
+ */
+
s32 server_id;
std::string name;
+
float gain;
u8 type; // 0=local, 1=positional, 2=object
v3f pos;
u16 object_id;
bool loop;
+ float fade = 0.0f;
+ float pitch = 1.0f;
*pkt >> server_id >> name >> gain >> type >> pos >> object_id >> loop;
+ try {
+ *pkt >> fade;
+ *pkt >> pitch;
+ } catch (PacketError &e) {};
+
// Start playing
int client_id = -1;
switch(type) {
case 0: // local
- client_id = m_sound->playSound(name, loop, gain);
+ client_id = m_sound->playSound(name, loop, gain, fade, pitch);
break;
case 1: // positional
- client_id = m_sound->playSoundAt(name, loop, gain, pos);
+ client_id = m_sound->playSoundAt(name, loop, gain, pos, pitch);
break;
case 2:
{ // object
ClientActiveObject *cao = m_env.getActiveObject(object_id);
if (cao)
pos = cao->getPosition();
- client_id = m_sound->playSoundAt(name, loop, gain, pos);
+ client_id = m_sound->playSoundAt(name, loop, gain, pos, pitch);
// TODO: Set up sound to move with object
break;
}
*pkt >> server_id;
- UNORDERED_MAP<s32, int>::iterator i = m_sounds_server_to_client.find(server_id);
+ std::unordered_map<s32, int>::iterator i = m_sounds_server_to_client.find(server_id);
if (i != m_sounds_server_to_client.end()) {
int client_id = i->second;
m_sound->stopSound(client_id);
}
}
+void Client::handleCommand_FadeSound(NetworkPacket *pkt)
+{
+ s32 sound_id;
+ float step;
+ float gain;
+
+ *pkt >> sound_id >> step >> gain;
+
+ std::unordered_map<s32, int>::const_iterator i =
+ m_sounds_server_to_client.find(sound_id);
+
+ if (i != m_sounds_server_to_client.end())
+ m_sound->fadeSound(i->second, step, gain);
+}
+
void Client::handleCommand_Privileges(NetworkPacket* pkt)
{
m_privileges.clear();
m_minimap_disabled_by_server = !(player->hud_flags & HUD_FLAG_MINIMAP_VISIBLE);
// Hide minimap if it has been disabled by the server
- if (m_minimap_disabled_by_server && was_minimap_visible) {
+ if (m_minimap && m_minimap_disabled_by_server && was_minimap_visible) {
// defers a minimap update, therefore only call it if really
// needed, by checking that minimap was visible before
m_minimap->setMinimapMode(MINIMAP_MODE_OFF);
player->hud_hotbar_itemcount = hotbar_itemcount;
}
else if (param == HUD_PARAM_HOTBAR_IMAGE) {
+ // If value not empty verify image exists in texture source
+ if (value != "" && !getTextureSource()->isKnownSourceImage(value)) {
+ errorstream << "Server sent wrong Hud hotbar image (sent value: '"
+ << value << "')" << std::endl;
+ return;
+ }
player->hotbar_image = value;
}
else if (param == HUD_PARAM_HOTBAR_SELECTED_IMAGE) {
+ // If value not empty verify image exists in texture source
+ if (value != "" && !getTextureSource()->isKnownSourceImage(value)) {
+ errorstream << "Server sent wrong Hud hotbar selected image (sent value: '"
+ << value << "')" << std::endl;
+ return;
+ }
player->hotbar_selected_image = value;
}
}
for (size_t i = 0; i < count; i++)
params->push_back(deSerializeString(is));
+ bool clouds = true;
+ try {
+ clouds = readU8(is);
+ } catch (...) {}
+
ClientEvent event;
event.type = CE_SET_SKY;
event.set_sky.bgcolor = bgcolor;
event.set_sky.type = type;
event.set_sky.params = params;
+ event.set_sky.clouds = clouds;
+ m_client_event_queue.push(event);
+}
+
+void Client::handleCommand_CloudParams(NetworkPacket* pkt)
+{
+ f32 density;
+ video::SColor color_bright;
+ video::SColor color_ambient;
+ f32 height;
+ f32 thickness;
+ v2f speed;
+
+ *pkt >> density >> color_bright >> color_ambient
+ >> height >> thickness >> speed;
+
+ ClientEvent event;
+ event.type = CE_CLOUD_PARAMS;
+ event.cloud_params.density = density;
+ // use the underlying u32 representation, because we can't
+ // use struct members with constructors here, and this way
+ // we avoid using new() and delete() for no good reason
+ event.cloud_params.color_bright = color_bright.color;
+ event.cloud_params.color_ambient = color_ambient.color;
+ event.cloud_params.height = height;
+ event.cloud_params.thickness = thickness;
+ // same here: deconstruct to skip constructor
+ event.cloud_params.speed_x = speed.X;
+ event.cloud_params.speed_y = speed.Y;
m_client_event_queue.push(event);
}
*pkt >> player->eye_offset_first >> player->eye_offset_third;
}
+void Client::handleCommand_UpdatePlayerList(NetworkPacket* pkt)
+{
+ u8 type;
+ u16 num_players;
+ *pkt >> type >> num_players;
+ PlayerListModifer notice_type = (PlayerListModifer) type;
+
+ for (u16 i = 0; i < num_players; i++) {
+ std::string name;
+ *pkt >> name;
+ switch (notice_type) {
+ case PLAYER_LIST_INIT:
+ case PLAYER_LIST_ADD:
+ m_env.addPlayerName(name);
+ continue;
+ case PLAYER_LIST_REMOVE:
+ m_env.removePlayerName(name);
+ continue;
+ }
+ }
+}
+
void Client::handleCommand_SrpBytesSandB(NetworkPacket* pkt)
{
if ((m_chosen_auth_mech != AUTH_MECHANISM_LEGACY_PASSWORD)