3 * =============================================================================
5 * Copyright (C) 2004-2008 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 SMCResult CPluginInfoDatabase::MakeError(const char *fmt, ...)
91 vsnprintf(buffer, sizeof(buffer), fmt, ap);
94 m_errmsg = m_strtab->AddString(buffer);
96 return SMCResult_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 SMCResult CPluginInfoDatabase::ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value)
154 if (cur_plugin != -1)
156 PluginSettings *plugin = (PluginSettings *)m_strtab->GetMemTable()->GetAddress(cur_plugin);
159 if (strcmp(key, "pause") == 0)
161 if (strcasecmp(value, "yes") == 0)
163 plugin->pause_val = true;
167 plugin->pause_val = false;
170 else if (strcmp(key, "lifetime") == 0)
172 if (strcasecmp(value, "private") == 0)
174 plugin->type_val = PluginType_Private;
176 else if (strcasecmp(value, "mapsync") == 0)
178 plugin->type_val = PluginType_MapUpdated;
180 else if (strcasecmp(value, "maponly") == 0)
182 plugin->type_val = PluginType_MapOnly;
184 else if (strcasecmp(value, "global") == 0)
186 plugin->type_val = PluginType_Global;
190 return MakeError("Unknown value for key \"lifetime\": \"%s\"", value);
193 else if (strcmp(key, "blockload") == 0)
195 plugin->blockload_val = true;
199 return MakeError("Unknown property key: \"%s\"", key);
204 /* Cache every option, valid or not */
205 int keyidx = m_strtab->AddString(key);
206 int validx = m_strtab->AddString(value);
208 BaseMemTable *memtab = m_strtab->GetMemTable();
209 plugin = (PluginSettings *)memtab->GetAddress(cur_plugin);
210 if (plugin->opts_num + 1 > plugin->opts_size)
212 unsigned int oldsize = plugin->opts_size;
215 //right now we don't have many
216 plugin->opts_size = 2;
220 plugin->opts_size *= 2;
222 int newidx = memtab->CreateMem(plugin->opts_size * sizeof(PluginOpts), (void **)&table);
223 /* in case it resized */
224 plugin = (PluginSettings *)memtab->GetAddress(cur_plugin);
225 if (plugin->optarray != -1)
227 void *oldtable = memtab->GetAddress(plugin->optarray);
228 memcpy(table, oldtable, oldsize * sizeof(PluginOpts));
230 plugin->optarray = newidx;
234 table = (PluginOpts *)memtab->GetAddress(plugin->optarray);
236 PluginOpts *opt = &table[plugin->opts_num++];
243 return MakeError("Unknown property key: \"%s\"", key);
247 /* Ignore anything we don't know about! */
250 return SMCResult_Continue;
253 SMCResult CPluginInfoDatabase::ReadSMC_LeavingSection(const SMCStates *states)
257 if (cur_plugin != -1)
265 /* If the plugin is ending, add it to the table */
266 BaseMemTable *memtab = m_strtab->GetMemTable();
268 if (m_infodb_count + 1 > m_infodb_size)
270 unsigned int oldsize = m_infodb_size;
279 int newidx = memtab->CreateMem(m_infodb_size, (void **)&table);
282 void *oldtable = (int *)memtab->GetAddress(m_infodb);
283 memcpy(table, oldtable, oldsize * sizeof(int));
289 table = (int *)memtab->GetAddress(m_infodb);
291 /* Assign to table and scrap the current plugin */
292 table[m_infodb_count++] = cur_plugin;
302 return SMCResult_Continue;
305 SMCResult CPluginInfoDatabase::ReadSMC_NewSection(const SMCStates *states, const char *name)
309 /* If we're not in the main Plugins section, and we don't get it for the name, error out */
310 if (strcmp(name, "Plugins") != 0)
312 return MakeError("Unknown root section: \"%s\"", name);
316 /* Otherwise set our states */
324 if (cur_plugin == -1)
326 /* If we get a plugin node and we don't have a current plugin, create a new one */
327 PluginSettings *plugin;
328 int i_name = m_strtab->AddString(name);
329 cur_plugin = m_strtab->GetMemTable()->CreateMem(sizeof(PluginSettings), (void **)&plugin);
331 plugin->name = i_name;
336 if (!in_options && strcmp(name, "Options") == 0)
342 return MakeError("Unknown plugin sub-section: \"%s\"", name);
347 return SMCResult_Continue;