File: Mod.h

package info (click to toggle)
0ad 0.0.26-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 130,460 kB
  • sloc: cpp: 261,824; ansic: 198,392; javascript: 19,067; python: 14,557; sh: 7,629; perl: 4,072; xml: 849; makefile: 741; java: 533; ruby: 229; php: 190; pascal: 30; sql: 21; tcl: 4
file content (110 lines) | stat: -rw-r--r-- 3,765 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/* Copyright (C) 2021 Wildfire Games.
 * This file is part of 0 A.D.
 *
 * 0 A.D. 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
 * (at your option) any later version.
 *
 * 0 A.D. 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 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef INCLUDED_MOD
#define INCLUDED_MOD

#include "ps/CStr.h"
#include "scriptinterface/ScriptForward.h"

#include <vector>

#define g_Mods (Mod::Instance())

class Mod
{
	friend class TestMod;
public:
	// Singleton-like interface.
	static Mod& Instance();

	/**
	 * Parsed mod.json data for C++ usage.
	 * Note that converting to/from JS is lossy.
	 */
	struct ModData
	{
		// 'Folder name' of the mod, e.g. 'public' for the main 0 A.D. mod.
		CStr m_Pathname;
		// "name" property in the mod.json
		CStr m_Name;

		CStr m_Version;
		std::vector<CStr> m_Dependencies;
		// If true, the mod is assumed to be 'GUI-only', i.e. ignored for MP or replay compatibility checks.
		bool m_IgnoreInCompatibilityChecks;

		// For convenience when exporting to JS, keep a record of the full file.
		CStr m_Text;
	};

	const std::vector<CStr>& GetEnabledMods() const;
	const std::vector<CStr>& GetIncompatibleMods() const;
	const std::vector<ModData>& GetAvailableMods() const;

	/**
	 * Fetches available mods and stores some metadata about them.
	 * This may open the zipped mod archives, depending on the situation,
	 * and/or try to write files to the user mod folder,
	 * which can be quite slow, so should be run rarely.
	 * TODO: if this did not need the scriptInterface to parse JSON,
	 * we could run it in different contexts and possibly cleaner.
	 */
	void UpdateAvailableMods(const ScriptInterface& scriptInterface);

	/**
	 * Enables specified mods (& mods required by the engine).
	 * @param addPublic - if true, enable the public mod.
	 * @return whether the mods were enabled successfully. This can fail if e.g. mods are incompatible.
	 * If true, GetEnabledMods() should be non-empty, GetIncompatibleMods() empty. Otherwise, GetIncompatibleMods() is non-empty.
	 */
	bool EnableMods(const std::vector<CStr>& mods, const bool addPublic);

	/**
	 * Get data for the given mod.
	 * @param the mod path name (e.g. 'public')
	 * @return the mod data or nullptr if unavailable.
	 * TODO: switch to std::optional or something related.
	 */
	const ModData* GetModData(const CStr& mod) const;

	/**
	 * Get a list of the enabled mod's data (intended for compatibility checks).
	 * "user" mod and "mod" mod are ignored as they are irrelevant for compatibility checks.
	 */
	const std::vector<const Mod::ModData*> GetEnabledModsData() const;

	/**
	 * @return whether the two lists are compatible for replaying / MP play.
	 */
	static bool AreModsPlayCompatible(const std::vector<const Mod::ModData*>& modsA, const std::vector<const Mod::ModData*>& modsB);
private:

	/**
	 * Checks a list of @a mods and returns the incompatible mods, if any.
	 */
	std::vector<CStr> CheckForIncompatibleMods(const std::vector<CStr>& mods) const;
	bool CompareVersionStrings(const CStr& required, const CStr& op, const CStr& version) const;

	std::vector<CStr> m_EnabledMods;
	// Of the currently loaded mods, these are the incompatible with the engine and cannot be loaded.
	std::vector<CStr> m_IncompatibleMods;

	std::vector<ModData> m_AvailableMods;
};

#endif // INCLUDED_MOD