/* * The Mana Client * Copyright (C) 2004-2009 The Mana World Development Team * Copyright (C) 2009-2024 The Mana Developers * * This file is part of The Mana Client. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #pragma once #include "being.h" #include "defaults.h" #include "playerrelations.h" #include "video.h" #include "utils/xml.h" #include "net/serverinfo.h" #include #include #include #include #include /** * Configuration object, mapping values to names and possibly containing * lists of further configuration objects * * \ingroup CORE */ class ConfigurationObject { friend class Configuration; public: virtual ~ConfigurationObject(); /** * Sets an option using a string value. * * \param key Option identifier. * \param value Value. */ void setValue(const std::string &key, const std::string &value); /** * Gets a value as string. * * \param key Option identifier. * \param deflt Default option if not there or error. */ std::string getValue(const std::string &key, const std::string &deflt) const; int getValue(const std::string &key, int deflt) const; unsigned getValue(const std::string &key, unsigned deflt) const; double getValue(const std::string &key, double deflt) const; /** * Re-sets all data in the configuration */ void clear(); protected: void initFromXML(XML::Node node); std::map mOptions; }; /** * Configuration handler for reading (and writing). * * \ingroup CORE */ class Configuration : public ConfigurationObject { public: Configuration() = default; ~Configuration() override; /** * Reads config file and parse all options into memory. * * @param filename path to config file * @param useResManager Make use of the resource manager. */ void init(const std::string &filename, bool useResManager = false); /** * Set the default values for each keys. * * @param defaultsData data used as defaults. */ void setDefaultValues(DefaultsData *defaultsData); /** * returns a value corresponding to the given key. * The default value returned in based on fallbacks registry. * @see defaults.h */ int getIntValue(const std::string &key) const; float getFloatValue(const std::string &key) const; std::string getStringValue(const std::string &key) const; bool getBoolValue(const std::string &key) const; VariableData *getDefault(const std::string &key, VariableData::DataType type) const; private: /** * Clean up the default values member. */ void cleanDefaults(); std::string mConfigPath; /**< Location of config file */ DefaultsData *mDefaultsData = nullptr; /**< Defaults of value for a given key */ }; struct ItemShortcutEntry { int index; int itemId; }; struct EmoteShortcutEntry { int index; int emoteId; }; struct Outfit { int index; std::string items; bool unequip; }; struct UserColor { std::string color; int gradient; std::optional delay; }; struct WindowState { std::optional x; std::optional y; std::optional width; std::optional height; std::optional visible; std::optional sticky; }; struct Config { int overlayDetail = 2; std::string speechBubblecolor = "000000"; float speechBubbleAlpha = 1.0f; Being::Speech speech = Being::TEXT_OVERHEAD; bool visibleNames = true; bool showGender = false; bool showMonstersTakedDamage = false; bool showWarps = true; bool hideCompletedQuests = false; int particleMaxCount = 3000; int particleFastPhysics = 0; int particleEmitterSkip = 1; bool particleEffects = true; bool logToStandardOut = false; bool opengl = false; bool vsync = true; WindowMode windowMode = WindowMode::Windowed; int screenWidth = defaultScreenWidth; int screenHeight = defaultScreenHeight; int scale = 0; bool sound = true; int sfxVolume = 100; int notificationsVolume = 100; int musicVolume = 60; int fpsLimit = 0; bool remember = true; std::string username; std::string lastCharacter; std::string updatehost; std::string afkMessage; std::string screenshotDirectory; std::string screenshotDirectorySuffix; bool useScreenshotDirectorySuffix = true; bool enableSync = false; bool joystickEnabled = false; int upTolerance = 100; int downTolerance = 100; int leftTolerance = 100; int rightTolerance = 100; bool logNpcInGui = true; bool downloadMusic = false; float guiAlpha = 0.8f; int chatLogLength = 128; bool enableChatLog = false; bool whisperTab = true; bool customCursor = true; bool showOwnName = false; bool showPickupParticle = true; bool showPickupChat = false; bool showMinimap = true; int fontSize = 12; bool returnTogglesChat = false; int scrollLaziness = 16; int scrollRadius = 0; int scrollCenterOffsetX = 0; int scrollCenterOffsetY = 0; std::string onlineServerList; std::string theme = "jewelry"; bool disableTransparency = false; bool persistentPlayerList = true; std::string playerIgnoreStrategy = DEFAULT_IGNORE_STRATEGY; unsigned defaultPlayerPermissions = PlayerPermissions::DEFAULT; std::map keys; std::vector itemShortcuts; std::vector emoteShortcuts; std::vector outfits; std::map colors; std::map windows; std::map players; ServerInfos servers; // For compatibility with old configuration files or different clients std::map unknownOptions; }; void serialize(XML::Writer &writer, const Config &config); void deserialize(XML::Node node, Config &config); extern Config config; extern Configuration branding; extern Configuration paths; /** * Sets the given Config member and sends a change event. */ template void setConfigValue(T Config::*member, const T &value) { if (config.*member == value) return; config.*member = value; Event(Event::ConfigOptionChanged, member).trigger(Event::ConfigChannel); }