X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fclient.cpp;h=e6af5c324589e3052004a42a836cb5191cfc1fa7;hb=0a83c42dfdf390cef75758096a481cdf8e2c828b;hp=a56e3c97458b0391c0365b5db3a4bc2b19b80efc;hpb=5e141ac920bb4866a377904a7dec608a7e119218;p=minetest.git diff --git a/src/client.cpp b/src/client.cpp index a56e3c974..e6af5c324 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -28,7 +28,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "network/networkpacket.h" #include "threading/mutex_auto_lock.h" #include "client/clientevent.h" +#include "client/gameui.h" #include "client/renderingengine.h" +#include "client/tile.h" #include "util/auth.h" #include "util/directiontables.h" #include "util/pointedthing.h" @@ -39,6 +41,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mapblock_mesh.h" #include "mapblock.h" #include "minimap.h" +#include "modchannels.h" #include "mods.h" #include "profiler.h" #include "shader.h" @@ -46,7 +49,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "clientmap.h" #include "clientmedia.h" #include "version.h" -#include "database-sqlite3.h" +#include "database/database-sqlite3.h" #include "serialization.h" #include "guiscalingfilter.h" #include "script/scripting_client.h" @@ -72,7 +75,7 @@ Client::Client( ISoundManager *sound, MtEventManager *event, bool ipv6, - GameUIFlags *game_ui_flags + GameUI *game_ui ): m_tsrc(tsrc), m_shsrc(shsrc), @@ -94,7 +97,8 @@ Client::Client( m_chosen_auth_mech(AUTH_MECHANISM_NONE), m_media_downloader(new ClientMediaDownloader()), m_state(LC_Created), - m_game_ui_flags(game_ui_flags) + m_game_ui(game_ui), + m_modchannel_mgr(new ModChannelMgr()) { // Add local player m_env.setLocalPlayer(new LocalPlayer(this, playername)); @@ -110,18 +114,38 @@ Client::Client( m_script->setEnv(&m_env); } -void Client::loadMods() +void Client::loadBuiltin() { // Load builtin scanModIntoMemory(BUILTIN_MOD_NAME, getBuiltinLuaPath()); - // If modding is not enabled, don't load mods, just builtin + m_script->loadModFromMemory(BUILTIN_MOD_NAME); +} + +void Client::loadMods() +{ + // Don't permit to load mods twice + if (m_mods_loaded) { + return; + } + + // If modding is not enabled or flavour disable it, don't load mods, just builtin if (!m_modding_enabled) { + warningstream << "Client side mods are disabled by configuration." << std::endl; return; } + + if (checkCSMFlavourLimit(CSMFlavourLimit::CSM_FL_LOAD_CLIENT_MODS)) { + warningstream << "Client side mods are disabled by server." << std::endl; + // If mods loading is disabled and builtin integrity is wrong, disconnect user. + if (!checkBuiltinIntegrity()) { + // @TODO disconnect user + } + return; + } + ClientModConfiguration modconf(getClientModsLuaPath()); m_mods = modconf.getMods(); - std::vector unsatisfied_mods = modconf.getUnsatisfiedMods(); // complain about mods with unsatisfied dependencies if (!modconf.isConsistent()) { modconf.printUnsatisfiedModsError(); @@ -142,6 +166,18 @@ void Client::loadMods() } scanModIntoMemory(mod.name, mod.path); } + + // Load and run "mod" scripts + for (const ModSpec &mod : m_mods) + m_script->loadModFromMemory(mod.name); + + m_mods_loaded = true; +} + +bool Client::checkBuiltinIntegrity() +{ + // @TODO + return true; } void Client::scanModSubfolder(const std::string &mod_name, const std::string &mod_path, @@ -161,20 +197,6 @@ void Client::scanModSubfolder(const std::string &mod_name, const std::string &mo } } -void Client::initMods() -{ - m_script->loadModFromMemory(BUILTIN_MOD_NAME); - - // If modding is not enabled, don't load mods, just builtin - if (!m_modding_enabled) { - return; - } - - // Load and run "mod" scripts - for (const ModSpec &mod : m_mods) - m_script->loadModFromMemory(mod.name); -} - const std::string &Client::getBuiltinLuaPath() { static const std::string builtin_dir = porting::path_share + DIR_DELIM + "builtin"; @@ -261,14 +283,9 @@ void Client::connect(Address address, bool is_local_server) void Client::step(float dtime) { // Limit a bit - if(dtime > 2.0) + if (dtime > 2.0) dtime = 2.0; - if(m_ignore_damage_timer > dtime) - m_ignore_damage_timer -= dtime; - else - m_ignore_damage_timer = 0.0; - m_animation_time += dtime; if(m_animation_time > 60.0) m_animation_time -= 60.0; @@ -391,18 +408,16 @@ void Client::step(float dtime) ClientEnvEvent envEvent = m_env.getClientEnvEvent(); if (envEvent.type == CEE_PLAYER_DAMAGE) { - if (m_ignore_damage_timer <= 0) { - u8 damage = envEvent.player_damage.amount; + u8 damage = envEvent.player_damage.amount; - if (envEvent.player_damage.send_to_server) - sendDamage(damage); + if (envEvent.player_damage.send_to_server) + sendDamage(damage); - // Add to ClientEvent queue - ClientEvent *event = new ClientEvent(); - event->type = CE_PLAYER_DAMAGE; - event->player_damage.amount = damage; - m_client_event_queue.push(event); - } + // Add to ClientEvent queue + ClientEvent *event = new ClientEvent(); + event->type = CE_PLAYER_DAMAGE; + event->player_damage.amount = damage; + m_client_event_queue.push(event); } } @@ -1188,7 +1203,7 @@ void Client::sendReady() void Client::sendPlayerPos() { LocalPlayer *myplayer = m_env.getLocalPlayer(); - if(myplayer == NULL) + if (!myplayer) return; ClientMap &map = m_env.getClientMap(); @@ -1214,20 +1229,6 @@ void Client::sendPlayerPos() myplayer->last_camera_fov = camera_fov; myplayer->last_wanted_range = wanted_range; - //infostream << "Sending Player Position information" << std::endl; - - u16 our_peer_id; - { - //MutexAutoLock lock(m_con_mutex); //bulk comment-out - our_peer_id = m_con->GetPeerID(); - } - - // Set peer id if not set already - if(myplayer->peer_id == PEER_ID_INEXISTENT) - myplayer->peer_id = our_peer_id; - - assert(myplayer->peer_id == our_peer_id); - NetworkPacket pkt(TOSERVER_PLAYERPOS, 12 + 12 + 4 + 4 + 4 + 1 + 1); writePlayerPos(myplayer, &map, &pkt); @@ -1238,16 +1239,9 @@ void Client::sendPlayerPos() void Client::sendPlayerItem(u16 item) { LocalPlayer *myplayer = m_env.getLocalPlayer(); - if(myplayer == NULL) + if (!myplayer) return; - u16 our_peer_id = m_con->GetPeerID(); - - // Set peer id if not set already - if(myplayer->peer_id == PEER_ID_INEXISTENT) - myplayer->peer_id = our_peer_id; - assert(myplayer->peer_id == our_peer_id); - NetworkPacket pkt(TOSERVER_PLAYERITEM, 2); pkt << item; @@ -1662,9 +1656,8 @@ void Client::afterContentReceived() text = wgettext("Initializing nodes..."); RenderingEngine::draw_load_screen(text, guienv, m_tsrc, 0, 72); m_nodedef->updateAliases(m_itemdef); - std::string texture_path = g_settings->get("texture_path"); - if (!texture_path.empty() && fs::IsDir(texture_path)) - m_nodedef->applyTextureOverrides(texture_path + DIR_DELIM + "override.txt"); + for (const auto &path : getTextureDirs()) + m_nodedef->applyTextureOverrides(path + DIR_DELIM + "override.txt"); m_nodedef->setNodeRegistrationStatus(true); m_nodedef->runNodeResolveCallbacks(); delete[] text; @@ -1779,34 +1772,9 @@ void Client::pushToEventQueue(ClientEvent *event) m_client_event_queue.push(event); } -void Client::showGameChat(const bool show) -{ - m_game_ui_flags->show_chat = show; -} - -void Client::showGameHud(const bool show) -{ - m_game_ui_flags->show_hud = show; -} - void Client::showMinimap(const bool show) { - m_game_ui_flags->show_minimap = show; -} - -void Client::showProfiler(const bool show) -{ - m_game_ui_flags->show_profiler_graph = show; -} - -void Client::showGameFog(const bool show) -{ - m_game_ui_flags->force_fog_off = !show; -} - -void Client::showGameDebug(const bool show) -{ - m_game_ui_flags->show_debug = show; + m_game_ui->showMinimap(show); } // IGameDef interface @@ -1855,7 +1823,7 @@ ParticleManager* Client::getParticleManager() return &m_particle_manager; } -scene::IAnimatedMesh* Client::getMesh(const std::string &filename) +scene::IAnimatedMesh* Client::getMesh(const std::string &filename, bool cache) { StringMap::const_iterator it = m_mesh_data.find(filename); if (it == m_mesh_data.end()) { @@ -1874,10 +1842,9 @@ scene::IAnimatedMesh* Client::getMesh(const std::string &filename) scene::IAnimatedMesh *mesh = RenderingEngine::get_scene_manager()->getMesh(rfile); rfile->drop(); - // NOTE: By playing with Irrlicht refcounts, maybe we could cache a bunch - // of uniquely named instances and re-use them mesh->grab(); - RenderingEngine::get_mesh_cache()->removeMesh(mesh); + if (!cache) + RenderingEngine::get_mesh_cache()->removeMesh(mesh); return mesh; } @@ -1919,3 +1886,57 @@ std::string Client::getModStoragePath() const { return porting::path_user + DIR_DELIM + "client" + DIR_DELIM + "mod_storage"; } + +/* + * Mod channels + */ + +bool Client::joinModChannel(const std::string &channel) +{ + if (m_modchannel_mgr->channelRegistered(channel)) + return false; + + NetworkPacket pkt(TOSERVER_MODCHANNEL_JOIN, 2 + channel.size()); + pkt << channel; + Send(&pkt); + + m_modchannel_mgr->joinChannel(channel, 0); + return true; +} + +bool Client::leaveModChannel(const std::string &channel) +{ + if (!m_modchannel_mgr->channelRegistered(channel)) + return false; + + NetworkPacket pkt(TOSERVER_MODCHANNEL_LEAVE, 2 + channel.size()); + pkt << channel; + Send(&pkt); + + m_modchannel_mgr->leaveChannel(channel, 0); + return true; +} + +bool Client::sendModChannelMessage(const std::string &channel, const std::string &message) +{ + if (!m_modchannel_mgr->canWriteOnChannel(channel)) + return false; + + if (message.size() > STRING_MAX_LEN) { + warningstream << "ModChannel message too long, dropping before sending " + << " (" << message.size() << " > " << STRING_MAX_LEN << ", channel: " + << channel << ")" << std::endl; + return false; + } + + // @TODO: do some client rate limiting + NetworkPacket pkt(TOSERVER_MODCHANNEL_MSG, 2 + channel.size() + 2 + message.size()); + pkt << channel << message; + Send(&pkt); + return true; +} + +ModChannel* Client::getModChannel(const std::string &channel) +{ + return m_modchannel_mgr->getModChannel(channel); +}