3 * =============================================================================
5 * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
6 * =============================================================================
8 * This program is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, version 3.0, as published by the
10 * Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
20 * As a special exception, AlliedModders LLC gives you permission to link the
21 * code of this program (as well as its derivative works) to "Half-Life 2," the
22 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
23 * by the Valve Corporation. You must obey the GNU General Public License in
24 * all respects for all other code used. Additionally, AlliedModders LLC grants
25 * this exception to all derivative works. AlliedModders LLC defines further
26 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
27 * or <http://www.sourcemod.net/license.php>.
34 #include "PluginInfoDatabase.h"
35 #include "PluginSys.h"
37 void PluginSettings::Init()
41 type_val = PluginType_MapUpdated;
45 blockload_val = false;
49 * :TODO: write the logger, make these errors log instead of being static
50 * NOTE: once we do that, we will have to change some code to ignore sections
53 CPluginInfoDatabase::CPluginInfoDatabase()
61 CPluginInfoDatabase::~CPluginInfoDatabase()
66 void CPluginInfoDatabase::ReadSMC_ParseStart()
68 /* Create or reset our string table */
73 m_strtab = new BaseStringTable(1024);
76 /* Set our internal states to the beginning */
85 SMCParseResult CPluginInfoDatabase::MakeError(const char *fmt, ...)
91 vsnprintf(buffer, sizeof(buffer), fmt, ap);
94 m_errmsg = m_strtab->AddString(buffer);
96 return SMCParse_HaltFail;
99 unsigned int CPluginInfoDatabase::GetSettingsNum()
101 return m_infodb_count;
104 PluginSettings *CPluginInfoDatabase::GetSettingsIfMatch(unsigned int index, const char *filename)
106 BaseMemTable *memtab = m_strtab->GetMemTable();
107 int *table = (int *)memtab->GetAddress(m_infodb);
109 if (!table || index >= m_infodb_count)
114 PluginSettings *plugin = (PluginSettings *)memtab->GetAddress(table[index]);
116 const char *name = m_strtab->GetString(plugin->name);
123 if (!g_PluginSys.TestAliasMatch(name, filename))
131 void CPluginInfoDatabase::GetOptionsForPlugin(PluginSettings *settings, unsigned int opt_num, const char **key, const char **val)
133 PluginOpts *table = (PluginOpts *)m_strtab->GetMemTable()->GetAddress(settings->optarray);
141 if (opt_num >= settings->opts_num)
148 *key = m_strtab->GetString(table[opt_num].key);
149 *val = m_strtab->GetString(table[opt_num].val);
152 SMCParseResult CPluginInfoDatabase::ReadSMC_KeyValue(const char *key,
157 if (cur_plugin != -1)
159 PluginSettings *plugin = (PluginSettings *)m_strtab->GetMemTable()->GetAddress(cur_plugin);
162 if (strcmp(key, "pause") == 0)
164 if (strcasecmp(value, "yes") == 0)
166 plugin->pause_val = true;
168 plugin->pause_val = false;
170 } else if (strcmp(key, "lifetime") == 0) {
171 if (strcasecmp(value, "private") == 0)
173 plugin->type_val = PluginType_Private;
174 } else if (strcasecmp(value, "mapsync") == 0) {
175 plugin->type_val = PluginType_MapUpdated;
176 } else if (strcasecmp(value, "maponly") == 0) {
177 plugin->type_val = PluginType_MapOnly;
178 } else if (strcasecmp(value, "global") == 0) {
179 plugin->type_val = PluginType_Global;
181 return MakeError("Unknown value for key \"lifetime\": \"%s\"", value);
183 } else if (strcmp(key, "blockload") == 0) {
184 plugin->blockload_val = true;
186 return MakeError("Unknown property key: \"%s\"", key);
189 /* Cache every option, valid or not */
190 int keyidx = m_strtab->AddString(key);
191 int validx = m_strtab->AddString(value);
193 BaseMemTable *memtab = m_strtab->GetMemTable();
194 plugin = (PluginSettings *)memtab->GetAddress(cur_plugin);
195 if (plugin->opts_num + 1 > plugin->opts_size)
197 unsigned int oldsize = plugin->opts_size;
200 //right now we don't have many
201 plugin->opts_size = 2;
203 plugin->opts_size *= 2;
205 int newidx = memtab->CreateMem(plugin->opts_size * sizeof(PluginOpts), (void **)&table);
206 /* in case it resized */
207 plugin = (PluginSettings *)memtab->GetAddress(cur_plugin);
208 if (plugin->optarray != -1)
210 void *oldtable = memtab->GetAddress(plugin->optarray);
211 memcpy(table, oldtable, oldsize * sizeof(PluginOpts));
213 plugin->optarray = newidx;
215 table = (PluginOpts *)memtab->GetAddress(plugin->optarray);
217 PluginOpts *opt = &table[plugin->opts_num++];
221 } else if (in_plugins) {
222 return MakeError("Unknown property key: \"%s\"", key);
224 /* Ignore anything we don't know about! */
227 return SMCParse_Continue;
230 SMCParseResult CPluginInfoDatabase::ReadSMC_LeavingSection()
234 if (cur_plugin != -1)
240 /* If the plugin is ending, add it to the table */
241 BaseMemTable *memtab = m_strtab->GetMemTable();
243 if (m_infodb_count + 1 > m_infodb_size)
245 unsigned int oldsize = m_infodb_size;
252 int newidx = memtab->CreateMem(m_infodb_size, (void **)&table);
255 void *oldtable = (int *)memtab->GetAddress(m_infodb);
256 memcpy(table, oldtable, oldsize * sizeof(int));
260 table = (int *)memtab->GetAddress(m_infodb);
262 /* Assign to table and scrap the current plugin */
263 table[m_infodb_count++] = cur_plugin;
271 return SMCParse_Continue;
274 SMCParseResult CPluginInfoDatabase::ReadSMC_NewSection(const char *name, bool opt_quotes)
278 /* If we're not in the main Plugins section, and we don't get it for the name, error out */
279 if (strcmp(name, "Plugins") != 0)
281 return MakeError("Unknown root section: \"%s\"", name);
283 /* Otherwise set our states */
289 if (cur_plugin == -1)
291 /* If we get a plugin node and we don't have a current plugin, create a new one */
292 PluginSettings *plugin;
293 int i_name = m_strtab->AddString(name);
294 cur_plugin = m_strtab->GetMemTable()->CreateMem(sizeof(PluginSettings), (void **)&plugin);
296 plugin->name = i_name;
299 if (!in_options && strcmp(name, "Options") == 0)
303 return MakeError("Unknown plugin sub-section: \"%s\"", name);
308 return SMCParse_Continue;