bool Register(CvarProxy* proxy, const std::string& name, std::string description, int flags, const std::string& defaultValue) {
        CvarMap& cvars = GetCvarMap();
        cvarRecord_t* cvar;

        auto it = cvars.find(name);
        if (it == cvars.end()) {
            if (!Cmd::IsValidCvarName(name)) {
                Log::Notice("Invalid cvar name '%s'", name.c_str());
                return false;
            }

            //Create the cvar and parse its default value
            cvar = new cvarRecord_t{defaultValue, defaultValue, flags, description, proxy, {}};
            cvars[name] = cvar;

            Cmd::AddCommand(name, cvarCommand, "cvar - \"" + defaultValue + "\" - " + description);

        } else {
            cvar = it->second;

            if (proxy && cvar->proxy) {
                Log::Warn("Cvar %s cannot be registered twice", name.c_str());
            }

            // Register the cvar with the previous user_created value
            cvar->flags &= ~CVAR_USER_CREATED;
            cvar->flags |= flags;
            cvar->proxy = proxy;
            if ((flags & ROM) || (!cheatsAllowed && (flags & CHEAT))) {
                cvar->value = defaultValue;
            }

            cvar->resetValue = defaultValue;
            cvar->description = "";

            if (proxy) { //TODO replace me with an assert once we do not need to support the C API
                OnValueChangedResult result = proxy->OnValueChanged(cvar->value);
                if (result.success) {
                    ChangeCvarDescription(name, cvar, result.description);
                } else {
                    OnValueChangedResult defaultValueResult = proxy->OnValueChanged(defaultValue);
                    if (defaultValueResult.success) {
                        ChangeCvarDescription(name, cvar, result.description);
                    } else {
                        Log::Notice("Default value '%s' is not correct for cvar '%s': %s\n",
                                defaultValue.c_str(), name.c_str(), defaultValueResult.description.c_str());
                    }
                }
            }
        }
        GetCCvar(name, *cvar);
        return true;
    }
Exemple #2
0
void SetCheatsAllowed(bool allowed) {
    cheatsAllowed = allowed;

    if (cheatsAllowed) {
        return;
    }

    CvarMap& cvars = GetCvarMap();

    // Reset all the CHEAT cvars to their default value
    for (auto& entry : cvars) {
        cvarRecord_t* cvar = entry.second;

        if (cvar->flags & CHEAT && cvar->value != cvar->resetValue) {
            cvar->value = cvar->resetValue;
            SetCCvar(*cvar);

            if (cvar->proxy) {
                OnValueChangedResult result =
                        cvar->proxy->OnValueChanged(cvar->resetValue);
                if (result.success) {
                    ChangeCvarDescription(entry.first, cvar, result.description);
                } else {
                    Com_Printf("Default value '%s' is not correct for cvar '%s': %s\n",
                               cvar->resetValue.c_str(),
                               entry.first.c_str(),
                               result.description.c_str());
                }
            }
        }
    }
}
    void InternalSetValue(const std::string& cvarName, std::string value, int flags, bool rom, bool warnRom) {
        CvarMap& cvars = GetCvarMap();

        auto it = cvars.find(cvarName);
        //TODO: rom means the cvar should have been created before?
        if (it == cvars.end()) {
            if (!Cmd::IsValidCvarName(cvarName)) {
                Log::Notice("Invalid cvar name '%s'", cvarName.c_str());
                return;
            }

            //The user creates a new cvar through a command.
            cvars[cvarName] = new cvarRecord_t{value, value, flags | CVAR_USER_CREATED, "user created", nullptr, {}};
            Cmd::AddCommand(cvarName, cvarCommand, "cvar - user created");
            GetCCvar(cvarName, *cvars[cvarName]);

        } else {
            cvarRecord_t* cvar = it->second;

            if (not (cvar->flags & CVAR_USER_CREATED)) {
                if (cvar->flags & (CVAR_ROM | CVAR_INIT) and not rom) {
                    Log::Notice("%s is read only.\n", cvarName.c_str());
                    return;
                }

                if (rom and warnRom and not (cvar->flags & (CVAR_ROM | CVAR_INIT))) {
                    Log::Notice("SetValueROM called on non-ROM cvar '%s'\n", cvarName.c_str());
                }

                if (not cheatsAllowed && cvar->flags & CHEAT) {
                    Log::Notice("%s is cheat-protected.\n", cvarName.c_str());
                    return;
                }
            }

            std::swap(cvar->value, value);
            cvar->flags |= flags;

            // mark for archival if flagged as archive-on-change
            if (cvar->flags & ARCHIVE) {
                cvar->flags |= USER_ARCHIVE;
            }

            if (cvar->proxy) {
                //Tell the cvar proxy about the new value
                OnValueChangedResult result = cvar->proxy->OnValueChanged(cvar->value);

                if (result.success) {
                    ChangeCvarDescription(cvarName, cvar, result.description);
                } else {
                    //The proxy could not parse the value, rollback
                    Log::Notice("Value '%s' is not valid for cvar %s: %s\n",
                            cvar->value.c_str(), cvarName.c_str(), result.description.c_str());
                    cvar->value = value;
                }
            }
            SetCCvar(*cvar);
        }

    }