]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - src/network/clientpackethandler.cpp
Cleanup sound manager class (#7158)
[dragonfireclient.git] / src / network / clientpackethandler.cpp
index 3ff23453d9cd89a9c5c312751a390d3f8ca72bd1..37b6493647ba626f615291281a49a6658cad1098 100644 (file)
@@ -26,11 +26,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "map.h"
 #include "mapsector.h"
 #include "minimap.h"
+#include "modchannels.h"
 #include "nodedef.h"
 #include "serialization.h"
 #include "server.h"
 #include "util/strfnd.h"
 #include "client/clientevent.h"
+#include "client/sound.h"
 #include "network/clientopcodes.h"
 #include "network/connection.h"
 #include "script/scripting_client.h"
@@ -95,7 +97,12 @@ void Client::handleCommand_Hello(NetworkPacket* pkt)
 
        // Authenticate using that method, or abort if there wasn't any method found
        if (chosen_auth_mechanism != AUTH_MECHANISM_NONE) {
-               startAuth(chosen_auth_mechanism);
+               if (chosen_auth_mechanism == AUTH_MECHANISM_FIRST_SRP
+                               && !m_simple_singleplayer_mode) {
+                       promptConfirmRegistration(chosen_auth_mechanism);
+               } else {
+                       startAuth(chosen_auth_mechanism);
+               }
        } else {
                m_chosen_auth_mech = AUTH_MECHANISM_NONE;
                m_access_denied = true;
@@ -352,30 +359,6 @@ void Client::handleCommand_TimeOfDay(NetworkPacket* pkt)
                        << " dr=" << dr << std::endl;
 }
 
-void Client::handleCommand_ChatMessageOld(NetworkPacket *pkt)
-{
-       /*
-               u16 command
-               u16 length
-               wstring message
-       */
-       u16 len, read_wchar;
-
-       *pkt >> len;
-
-       std::wstring message;
-       for (u32 i = 0; i < len; i++) {
-               *pkt >> read_wchar;
-               message += (wchar_t)read_wchar;
-       }
-
-       // If chat message not consummed by client lua API
-       // @TODO send this to CSM using ChatMessage object
-       if (!moddingEnabled() || !m_script->on_receiving_message(wide_to_utf8(message))) {
-               pushToChatQueue(new ChatMessage(message));
-       }
-}
-
 void Client::handleCommand_ChatMessage(NetworkPacket *pkt)
 {
        /*
@@ -572,10 +555,6 @@ void Client::handleCommand_MovePlayer(NetworkPacket* pkt)
        event->player_force_move.pitch = pitch;
        event->player_force_move.yaw = yaw;
        m_client_event_queue.push(event);
-
-       // Ignore damage for a few seconds, so that the player doesn't
-       // get damage from falling on ground
-       m_ignore_damage_timer = 3.0;
 }
 
 void Client::handleCommand_DeathScreen(NetworkPacket* pkt)
@@ -954,7 +933,7 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt)
        float minsize;
        float maxsize;
        bool collisiondetection;
-       u32 id;
+       u32 server_id;
 
        *pkt >> amount >> spawntime >> minpos >> maxpos >> minvel >> maxvel
                >> minacc >> maxacc >> minexptime >> maxexptime >> minsize
@@ -962,7 +941,7 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt)
 
        std::string texture = pkt->readLongString();
 
-       *pkt >> id;
+       *pkt >> server_id;
 
        bool vertical = false;
        bool collision_removal = false;
@@ -982,6 +961,9 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt)
                glow = readU8(is);
        } catch (...) {}
 
+       u32 client_id = m_particle_manager.getSpawnerId();
+       m_particles_server_to_client[server_id] = client_id;
+
        ClientEvent *event = new ClientEvent();
        event->type                                   = CE_ADD_PARTICLESPAWNER;
        event->add_particlespawner.amount             = amount;
@@ -1001,7 +983,7 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt)
        event->add_particlespawner.attached_id        = attached_id;
        event->add_particlespawner.vertical           = vertical;
        event->add_particlespawner.texture            = new std::string(texture);
-       event->add_particlespawner.id                 = id;
+       event->add_particlespawner.id                 = client_id;
        event->add_particlespawner.animation          = animation;
        event->add_particlespawner.glow               = glow;
 
@@ -1011,12 +993,19 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt)
 
 void Client::handleCommand_DeleteParticleSpawner(NetworkPacket* pkt)
 {
-       u32 id;
-       *pkt >> id;
+       u32 server_id;
+       *pkt >> server_id;
+
+       u32 client_id;
+       auto i = m_particles_server_to_client.find(server_id);
+       if (i != m_particles_server_to_client.end())
+               client_id = i->second;
+       else
+               return;
 
        ClientEvent *event = new ClientEvent();
        event->type = CE_DELETE_PARTICLESPAWNER;
-       event->delete_particlespawner.id = id;
+       event->delete_particlespawner.id = client_id;
 
        m_client_event_queue.push(event);
 }
@@ -1026,7 +1015,7 @@ void Client::handleCommand_HudAdd(NetworkPacket* pkt)
        std::string datastring(pkt->getString(0), pkt->getSize());
        std::istringstream is(datastring, std::ios_base::binary);
 
-       u32 id;
+       u32 server_id;
        u8 type;
        v2f pos;
        std::string name;
@@ -1040,7 +1029,7 @@ void Client::handleCommand_HudAdd(NetworkPacket* pkt)
        v3f world_pos;
        v2s32 size;
 
-       *pkt >> id >> type >> pos >> name >> scale >> text >> number >> item
+       *pkt >> server_id >> type >> pos >> name >> scale >> text >> number >> item
                >> dir >> align >> offset;
        try {
                *pkt >> world_pos;
@@ -1053,7 +1042,7 @@ void Client::handleCommand_HudAdd(NetworkPacket* pkt)
 
        ClientEvent *event = new ClientEvent();
        event->type             = CE_HUDADD;
-       event->hudadd.id        = id;
+       event->hudadd.server_id = server_id;
        event->hudadd.type      = type;
        event->hudadd.pos       = new v2f(pos);
        event->hudadd.name      = new std::string(name);
@@ -1071,14 +1060,20 @@ void Client::handleCommand_HudAdd(NetworkPacket* pkt)
 
 void Client::handleCommand_HudRemove(NetworkPacket* pkt)
 {
-       u32 id;
+       u32 server_id;
 
-       *pkt >> id;
+       *pkt >> server_id;
 
-       ClientEvent *event = new ClientEvent();
-       event->type     = CE_HUDRM;
-       event->hudrm.id = id;
-       m_client_event_queue.push(event);
+       auto i = m_hud_server_to_client.find(server_id);
+       if (i != m_hud_server_to_client.end()) {
+               int client_id = i->second;
+               m_hud_server_to_client.erase(i);
+
+               ClientEvent *event = new ClientEvent();
+               event->type     = CE_HUDRM;
+               event->hudrm.id = client_id;
+               m_client_event_queue.push(event);
+       }
 }
 
 void Client::handleCommand_HudChange(NetworkPacket* pkt)
@@ -1088,10 +1083,10 @@ void Client::handleCommand_HudChange(NetworkPacket* pkt)
        v3f v3fdata;
        u32 intdata = 0;
        v2s32 v2s32data;
-       u32 id;
+       u32 server_id;
        u8 stat;
 
-       *pkt >> id >> stat;
+       *pkt >> server_id >> stat;
 
        if (stat == HUD_STAT_POS || stat == HUD_STAT_SCALE ||
                stat == HUD_STAT_ALIGN || stat == HUD_STAT_OFFSET)
@@ -1105,16 +1100,19 @@ void Client::handleCommand_HudChange(NetworkPacket* pkt)
        else
                *pkt >> intdata;
 
-       ClientEvent *event = new ClientEvent();
-       event->type              = CE_HUDCHANGE;
-       event->hudchange.id      = id;
-       event->hudchange.stat    = (HudElementStat)stat;
-       event->hudchange.v2fdata = new v2f(v2fdata);
-       event->hudchange.v3fdata = new v3f(v3fdata);
-       event->hudchange.sdata   = new std::string(sdata);
-       event->hudchange.data    = intdata;
-       event->hudchange.v2s32data = new v2s32(v2s32data);
-       m_client_event_queue.push(event);
+       std::unordered_map<u32, u32>::const_iterator i = m_hud_server_to_client.find(server_id);
+       if (i != m_hud_server_to_client.end()) {
+               ClientEvent *event = new ClientEvent();
+               event->type              = CE_HUDCHANGE;
+               event->hudchange.id      = i->second;
+               event->hudchange.stat    = (HudElementStat)stat;
+               event->hudchange.v2fdata = new v2f(v2fdata);
+               event->hudchange.v3fdata = new v3f(v3fdata);
+               event->hudchange.sdata   = new std::string(sdata);
+               event->hudchange.data    = intdata;
+               event->hudchange.v2s32data = new v2s32(v2s32data);
+               m_client_event_queue.push(event);
+       }
 }
 
 void Client::handleCommand_HudSetFlags(NetworkPacket* pkt)
@@ -1329,4 +1327,100 @@ void Client::handleCommand_SrpBytesSandB(NetworkPacket* pkt)
 void Client::handleCommand_CSMFlavourLimits(NetworkPacket *pkt)
 {
        *pkt >> m_csm_flavour_limits >> m_csm_noderange_limit;
+
+       // Now we have flavours, load mods if it's enabled
+       // Note: this should be moved after mods receptions from server instead
+       loadMods();
+}
+
+/*
+ * Mod channels
+ */
+
+void Client::handleCommand_ModChannelMsg(NetworkPacket *pkt)
+{
+       std::string channel_name, sender, channel_msg;
+       *pkt >> channel_name >> sender >> channel_msg;
+
+       verbosestream << "Mod channel message received from server " << pkt->getPeerId()
+               << " on channel " << channel_name << ". sender: `" << sender << "`, message: "
+               << channel_msg << std::endl;
+
+       if (!m_modchannel_mgr->channelRegistered(channel_name)) {
+               verbosestream << "Server sent us messages on unregistered channel "
+                       << channel_name << ", ignoring." << std::endl;
+               return;
+       }
+
+       m_script->on_modchannel_message(channel_name, sender, channel_msg);
+}
+
+void Client::handleCommand_ModChannelSignal(NetworkPacket *pkt)
+{
+       u8 signal_tmp;
+       ModChannelSignal signal;
+       std::string channel;
+
+       *pkt >> signal_tmp >> channel;
+
+       signal = (ModChannelSignal)signal_tmp;
+
+       bool valid_signal = true;
+       // @TODO: send Signal to Lua API
+       switch (signal) {
+               case MODCHANNEL_SIGNAL_JOIN_OK:
+                       m_modchannel_mgr->setChannelState(channel, MODCHANNEL_STATE_READ_WRITE);
+                       infostream << "Server ack our mod channel join on channel `" << channel
+                               << "`, joining." << std::endl;
+                       break;
+               case MODCHANNEL_SIGNAL_JOIN_FAILURE:
+                       // Unable to join, remove channel
+                       m_modchannel_mgr->leaveChannel(channel, 0);
+                       infostream << "Server refused our mod channel join on channel `" << channel
+                               << "`" << std::endl;
+                       break;
+               case MODCHANNEL_SIGNAL_LEAVE_OK:
+#ifndef NDEBUG
+                       infostream << "Server ack our mod channel leave on channel " << channel
+                               << "`, leaving." << std::endl;
+#endif
+                       break;
+               case MODCHANNEL_SIGNAL_LEAVE_FAILURE:
+                       infostream << "Server refused our mod channel leave on channel `" << channel
+                               << "`" << std::endl;
+                       break;
+               case MODCHANNEL_SIGNAL_CHANNEL_NOT_REGISTERED:
+#ifndef NDEBUG
+                       // Generally unused, but ensure we don't do an implementation error
+                       infostream << "Server tells us we sent a message on channel `" << channel
+                               << "` but we are not registered. Message was dropped." << std::endl;
+#endif
+                       break;
+               case MODCHANNEL_SIGNAL_SET_STATE: {
+                       u8 state;
+                       *pkt >> state;
+
+                       if (state == MODCHANNEL_STATE_INIT || state >= MODCHANNEL_STATE_MAX) {
+                               infostream << "Received wrong channel state " << state
+                                               << ", ignoring." << std::endl;
+                               return;
+                       }
+
+                       m_modchannel_mgr->setChannelState(channel, (ModChannelState) state);
+                       infostream << "Server sets mod channel `" << channel
+                                       << "` in read-only mode." << std::endl;
+                       break;
+               }
+               default:
+#ifndef NDEBUG
+                       warningstream << "Received unhandled mod channel signal ID "
+                               << signal << ", ignoring." << std::endl;
+#endif
+                       valid_signal = false;
+                       break;
+       }
+
+       // If signal is valid, forward it to client side mods
+       if (valid_signal)
+               m_script->on_modchannel_signal(channel, signal);
 }