Modernize client code (#6250)
[oweals/minetest.git] / src / clientiface.h
index f6c4294e2b335c5823082d2c096b9dddb7109dfb..ce74cfeced0ee42b4fa64278f5d0312dde9f5ccd 100644 (file)
@@ -23,13 +23,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "constants.h"
 #include "serialization.h"             // for SER_FMT_VER_INVALID
-#include "jthread/jmutex.h"
 #include "network/networkpacket.h"
+#include "porting.h"
 
 #include <list>
 #include <vector>
-#include <map>
 #include <set>
+#include <mutex>
 
 class MapBlock;
 class ServerEnvironment;
@@ -165,7 +165,9 @@ namespace con {
        class Connection;
 }
 
-#define CI_ARRAYSIZE(a) (sizeof(a) / sizeof((a)[0]))
+
+// Also make sure to update the ClientInterface::statenames
+// array when modifying these enums
 
 enum ClientState
 {
@@ -224,51 +226,27 @@ public:
        // NOTE: If client is made allowed to exist while peer doesn't,
        //       this has to be set to 0 when there is no peer.
        //       Also, the client must be moved to some other container.
-       u16 peer_id;
+       u16 peer_id = PEER_ID_INEXISTENT;
        // The serialization version to use with the client
-       u8 serialization_version;
+       u8 serialization_version = SER_FMT_VER_INVALID;
        //
-       u16 net_proto_version;
+       u16 net_proto_version = 0;
 
        /* Authentication information */
-       std::string enc_pwd;
-       bool create_player_on_auth_success;
-       AuthMechanism chosen_mech;
-       void * auth_data;
-       u32 allowed_auth_mechs;
-       u32 allowed_sudo_mechs;
+       std::string enc_pwd = "";
+       bool create_player_on_auth_success = false;
+       AuthMechanism chosen_mech  = AUTH_MECHANISM_NONE;
+       void *auth_data = nullptr;
+       u32 allowed_auth_mechs = 0;
+       u32 allowed_sudo_mechs = 0;
 
        bool isSudoMechAllowed(AuthMechanism mech)
        { return allowed_sudo_mechs & mech; }
        bool isMechAllowed(AuthMechanism mech)
        { return allowed_auth_mechs & mech; }
 
-       RemoteClient():
-               peer_id(PEER_ID_INEXISTENT),
-               serialization_version(SER_FMT_VER_INVALID),
-               net_proto_version(0),
-               create_player_on_auth_success(false),
-               chosen_mech(AUTH_MECHANISM_NONE),
-               auth_data(NULL),
-               m_time_from_building(9999),
-               m_pending_serialization_version(SER_FMT_VER_INVALID),
-               m_state(CS_Created),
-               m_nearest_unsent_d(0),
-               m_nearest_unsent_reset_timer(0.0),
-               m_excess_gotblocks(0),
-               m_nothing_to_send_pause_timer(0.0),
-               m_name(""),
-               m_version_major(0),
-               m_version_minor(0),
-               m_version_patch(0),
-               m_full_version("unknown"),
-               m_deployed_compression(0),
-               m_connection_time(getTime(PRECISION_SECONDS))
-       {
-       }
-       ~RemoteClient()
-       {
-       }
+       RemoteClient() {}
+       ~RemoteClient() {}
 
        /*
                Finds block that should be sent next to the client.
@@ -315,22 +293,18 @@ public:
        }
 
        // Time from last placing or removing blocks
-       float m_time_from_building;
+       float m_time_from_building = 9999;
 
        /*
                List of active objects that the client knows of.
-               Value is dummy.
        */
        std::set<u16> m_known_objects;
 
-       ClientState getState()
-               { return m_state; }
+       ClientState getState() const { return m_state; }
 
-       std::string getName()
-               { return m_name; }
+       std::string getName() const { return m_name; }
 
-       void setName(std::string name)
-               { m_name = name; }
+       void setName(const std::string &name) { m_name = name; }
 
        /* update internal client state */
        void notifyEvent(ClientStateEvent event);
@@ -346,10 +320,11 @@ public:
                { serialization_version = m_pending_serialization_version; }
 
        /* get uptime */
-       u32 uptime();
+       u64 uptime() const;
 
        /* set version information */
-       void setVersionInfo(u8 major, u8 minor, u8 patch, std::string full) {
+       void setVersionInfo(u8 major, u8 minor, u8 patch, const std::string &full)
+       {
                m_version_major = major;
                m_version_minor = minor;
                m_version_patch = patch;
@@ -357,16 +332,15 @@ public:
        }
 
        /* read version information */
-       u8 getMajor() { return m_version_major; }
-       u8 getMinor() { return m_version_minor; }
-       u8 getPatch() { return m_version_patch; }
-       std::string getVersion() { return m_full_version; }
+       u8 getMajor() const { return m_version_major; }
+       u8 getMinor() const { return m_version_minor; }
+       u8 getPatch() const { return m_version_patch; }
 private:
        // Version is stored in here after INIT before INIT2
-       u8 m_pending_serialization_version;
+       u8 m_pending_serialization_version = SER_FMT_VER_INVALID;
 
        /* current state of client */
-       ClientState m_state;
+       ClientState m_state = CS_Created;
 
        /*
                Blocks that have been sent to client.
@@ -374,13 +348,13 @@ private:
                - A block is cleared from here when client says it has
                  deleted it from it's memory
 
-               Key is position, value is dummy.
+               List of block positions.
                No MapBlock* is stored here because the blocks can get deleted.
        */
        std::set<v3s16> m_blocks_sent;
-       s16 m_nearest_unsent_d;
+       s16 m_nearest_unsent_d = 0;
        v3s16 m_last_center;
-       float m_nearest_unsent_reset_timer;
+       float m_nearest_unsent_reset_timer = 0.0f;
 
        /*
                Blocks that are currently on the line.
@@ -392,6 +366,16 @@ private:
        */
        std::map<v3s16, float> m_blocks_sending;
 
+       /*
+               Blocks that have been modified since last sending them.
+               These blocks will not be marked as sent, even if the
+               client reports it has received them to account for blocks
+               that are being modified while on the line.
+
+               List of block positions.
+       */
+       std::set<v3s16> m_blocks_modified;
+
        /*
                Count of excess GotBlocks().
                There is an excess amount because the client sometimes
@@ -399,33 +383,35 @@ private:
                and the client then sends two GOTBLOCKs.
                This is resetted by PrintInfo()
        */
-       u32 m_excess_gotblocks;
+       u32 m_excess_gotblocks = 0;
 
        // CPU usage optimization
-       float m_nothing_to_send_pause_timer;
+       float m_nothing_to_send_pause_timer = 0.0f;
 
        /*
                name of player using this client
        */
-       std::string m_name;
+       std::string m_name = "";
 
        /*
                client information
         */
-       u8 m_version_major;
-       u8 m_version_minor;
-       u8 m_version_patch;
+       u8 m_version_major = 0;
+       u8 m_version_minor = 0;
+       u8 m_version_patch = 0;
 
-       std::string m_full_version;
+       std::string m_full_version = "unknown";
 
-       u16 m_deployed_compression;
+       u16 m_deployed_compression = 0;
 
        /*
                time this client was created
         */
-       const u32 m_connection_time;
+       const u64 m_connection_time = porting::getTimeS();
 };
 
+typedef std::unordered_map<u16, RemoteClient*> RemoteClientMap;
+
 class ClientInterface {
 public:
 
@@ -441,13 +427,14 @@ public:
        std::vector<u16> getClientIDs(ClientState min_state=CS_Active);
 
        /* get list of client player names */
-       std::vector<std::string> getPlayerNames();
+       const std::vector<std::string> &getPlayerNames() const { return m_clients_names; }
 
        /* send message to client */
        void send(u16 peer_id, u8 channelnum, NetworkPacket* pkt, bool reliable);
 
        /* send to all clients */
-       void sendToAll(u16 channelnum, NetworkPacket* pkt, bool reliable);
+       void sendToAll(NetworkPacket *pkt);
+       void sendToAllCompat(NetworkPacket *pkt, NetworkPacket *legacypkt, u16 min_proto_ver);
 
        /* delete a client */
        void DeleteClient(u16 peer_id);
@@ -487,13 +474,10 @@ public:
 
 protected:
        //TODO find way to avoid this functions
-       void Lock()
-               { m_clients_mutex.Lock(); }
-       void Unlock()
-               { m_clients_mutex.Unlock(); }
+       void lock() { m_clients_mutex.lock(); }
+       void unlock() { m_clients_mutex.unlock(); }
 
-       std::map<u16, RemoteClient*>& getClientList()
-               { return m_clients; }
+       RemoteClientMap& getClientList() { return m_clients; }
 
 private:
        /* update internal player list */
@@ -501,14 +485,14 @@ private:
 
        // Connection
        con::Connection* m_con;
-       JMutex m_clients_mutex;
+       std::mutex m_clients_mutex;
        // Connected clients (behind the con mutex)
-       std::map<u16, RemoteClient*> m_clients;
+       RemoteClientMap m_clients;
        std::vector<std::string> m_clients_names; //for announcing masterserver
 
        // Environment
        ServerEnvironment *m_env;
-       JMutex m_env_mutex;
+       std::mutex m_env_mutex;
 
        float m_print_info_timer;