core/PluginInfoDatabase.cpp
author Nicholas Hastings <skamonkey@gmail.com>
Thu Mar 11 17:43:46 2010 -0500 (2010-03-11)
changeset 2937 f5016767bfdf
parent 2811 af581de19119
permissions -rw-r--r--
Added missing core voting cvars to sourcemod.cfg (bug 4224, r=pred)
dvander@370
     1
/**
ds@653
     2
 * vim: set ts=4 :
ds@1330
     3
 * =============================================================================
dvander@1231
     4
 * SourceMod
ds@1947
     5
 * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
ds@1330
     6
 * =============================================================================
dvander@370
     7
 *
ds@1330
     8
 * This program is free software; you can redistribute it and/or modify it under
ds@1330
     9
 * the terms of the GNU General Public License, version 3.0, as published by the
ds@1330
    10
 * Free Software Foundation.
dvander@1231
    11
 * 
ds@1330
    12
 * This program is distributed in the hope that it will be useful, but WITHOUT
ds@1330
    13
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
ds@1330
    14
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
ds@1330
    15
 * details.
dvander@1231
    16
 *
ds@1330
    17
 * You should have received a copy of the GNU General Public License along with
ds@1330
    18
 * this program.  If not, see <http://www.gnu.org/licenses/>.
dvander@1231
    19
 *
ds@1330
    20
 * As a special exception, AlliedModders LLC gives you permission to link the
ds@1330
    21
 * code of this program (as well as its derivative works) to "Half-Life 2," the
ds@1330
    22
 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
ds@1330
    23
 * by the Valve Corporation.  You must obey the GNU General Public License in
ds@1330
    24
 * all respects for all other code used.  Additionally, AlliedModders LLC grants
ds@1330
    25
 * this exception to all derivative works.  AlliedModders LLC defines further
ds@1330
    26
 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
ds@1330
    27
 * or <http://www.sourcemod.net/license.php>.
dvander@370
    28
 *
dvander@370
    29
 * Version: $Id$
dvander@370
    30
 */
dvander@370
    31
dvander@203
    32
#include <stdarg.h>
dvander@203
    33
#include <string.h>
dvander@203
    34
#include "PluginInfoDatabase.h"
dvander@203
    35
#include "PluginSys.h"
dvander@203
    36
dvander@203
    37
void PluginSettings::Init()
dvander@203
    38
{
dvander@203
    39
	name = -1;
dvander@203
    40
	pause_val = false;
dvander@203
    41
	type_val = PluginType_MapUpdated;
dvander@203
    42
	optarray = -1;
dvander@203
    43
	opts_num = 0;
dvander@203
    44
	opts_size = 0;
dvander@1436
    45
	blockload_val = false;
dvander@203
    46
}
dvander@203
    47
dvander@203
    48
/**
dvander@203
    49
 * :TODO: write the logger, make these errors log instead of being static
dvander@203
    50
 * NOTE: once we do that, we will have to change some code to ignore sections
dvander@203
    51
 */
dvander@203
    52
dvander@203
    53
CPluginInfoDatabase::CPluginInfoDatabase()
dvander@203
    54
{
dvander@203
    55
	m_strtab = NULL;
dvander@203
    56
	m_infodb_count = 0;
dvander@203
    57
	m_infodb_size = 0;
dvander@203
    58
	m_infodb = -1;
dvander@203
    59
}
dvander@203
    60
dvander@203
    61
CPluginInfoDatabase::~CPluginInfoDatabase()
dvander@203
    62
{
dvander@203
    63
	delete m_strtab;
dvander@203
    64
}
dvander@203
    65
dvander@203
    66
void CPluginInfoDatabase::ReadSMC_ParseStart()
dvander@203
    67
{
dvander@203
    68
	/* Create or reset our string table */
dvander@203
    69
	if (m_strtab)
dvander@203
    70
	{
dvander@203
    71
		m_strtab->Reset();
dvander@203
    72
	} else {
dvander@203
    73
		m_strtab = new BaseStringTable(1024);
dvander@203
    74
	}
dvander@203
    75
dvander@203
    76
	/* Set our internal states to the beginning */
dvander@203
    77
	in_plugins = false;
dvander@203
    78
	cur_plugin = -1;
dvander@203
    79
	in_options = false;
dvander@264
    80
	m_infodb_size = 0;
dvander@264
    81
	m_infodb_count = 0;
dvander@264
    82
	m_infodb = -1;
dvander@203
    83
}
dvander@203
    84
dvander@1656
    85
SMCResult CPluginInfoDatabase::MakeError(const char *fmt, ...)
dvander@203
    86
{
dvander@203
    87
	char buffer[512];
dvander@203
    88
	va_list ap;
dvander@203
    89
dvander@203
    90
	va_start(ap, fmt);
dvander@203
    91
	vsnprintf(buffer, sizeof(buffer), fmt, ap);
dvander@203
    92
	va_end(ap);
dvander@203
    93
dvander@203
    94
	m_errmsg = m_strtab->AddString(buffer);
dvander@203
    95
dvander@1656
    96
	return SMCResult_HaltFail;
dvander@203
    97
}
dvander@203
    98
dvander@203
    99
unsigned int CPluginInfoDatabase::GetSettingsNum()
dvander@203
   100
{
dvander@203
   101
	return m_infodb_count;
dvander@203
   102
}
dvander@203
   103
dvander@203
   104
PluginSettings *CPluginInfoDatabase::GetSettingsIfMatch(unsigned int index, const char *filename)
dvander@203
   105
{
dvander@203
   106
	BaseMemTable *memtab = m_strtab->GetMemTable();
dvander@205
   107
	int *table = (int *)memtab->GetAddress(m_infodb);
dvander@203
   108
dvander@203
   109
	if (!table || index >= m_infodb_count)
dvander@203
   110
	{
dvander@203
   111
		return NULL;
dvander@203
   112
	}
dvander@203
   113
dvander@205
   114
	PluginSettings *plugin = (PluginSettings *)memtab->GetAddress(table[index]);
dvander@205
   115
dvander@205
   116
	const char *name = m_strtab->GetString(plugin->name);
dvander@203
   117
dvander@203
   118
	if (!name)
dvander@203
   119
	{
dvander@203
   120
		return NULL;
dvander@203
   121
	}
dvander@203
   122
dvander@211
   123
	if (!g_PluginSys.TestAliasMatch(name, filename))
dvander@203
   124
	{
dvander@203
   125
		return NULL;
dvander@203
   126
	}
dvander@203
   127
dvander@205
   128
	return plugin;
dvander@203
   129
}
dvander@203
   130
dvander@203
   131
void CPluginInfoDatabase::GetOptionsForPlugin(PluginSettings *settings, unsigned int opt_num, const char **key, const char **val)
dvander@203
   132
{
dvander@203
   133
	PluginOpts *table = (PluginOpts *)m_strtab->GetMemTable()->GetAddress(settings->optarray);
dvander@203
   134
	if (!table)
dvander@203
   135
	{
dvander@203
   136
		*key = NULL;
dvander@203
   137
		*val = NULL;
dvander@203
   138
		return;
dvander@203
   139
	}
dvander@203
   140
dvander@203
   141
	if (opt_num >= settings->opts_num)
dvander@203
   142
	{
dvander@203
   143
		*key = NULL;
dvander@203
   144
		*val = NULL;
dvander@203
   145
		return;
dvander@203
   146
	}
dvander@203
   147
dvander@203
   148
	*key = m_strtab->GetString(table[opt_num].key);
dvander@203
   149
	*val = m_strtab->GetString(table[opt_num].val);
dvander@203
   150
}
dvander@203
   151
dvander@1656
   152
SMCResult CPluginInfoDatabase::ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value)
dvander@203
   153
{
dvander@203
   154
	if (cur_plugin != -1)
dvander@203
   155
	{
dvander@203
   156
		PluginSettings *plugin = (PluginSettings *)m_strtab->GetMemTable()->GetAddress(cur_plugin);
dvander@203
   157
		if (!in_options)
dvander@203
   158
		{
dvander@203
   159
			if (strcmp(key, "pause") == 0)
dvander@203
   160
			{
dvander@203
   161
				if (strcasecmp(value, "yes") == 0)
dvander@203
   162
				{
dvander@203
   163
					plugin->pause_val = true;
dvander@1656
   164
				} 
dvander@1656
   165
				else 
dvander@1656
   166
				{
dvander@203
   167
					plugin->pause_val = false;
dvander@203
   168
				}
dvander@1656
   169
			} 
dvander@1656
   170
			else if (strcmp(key, "lifetime") == 0) 
dvander@1656
   171
			{
dvander@203
   172
				if (strcasecmp(value, "private") == 0)
dvander@203
   173
				{
dvander@203
   174
					plugin->type_val = PluginType_Private;
dvander@1656
   175
				} 
dvander@1656
   176
				else if (strcasecmp(value, "mapsync") == 0) 
dvander@1656
   177
				{
dvander@203
   178
					plugin->type_val = PluginType_MapUpdated;
dvander@1656
   179
				}
dvander@1656
   180
				else if (strcasecmp(value, "maponly") == 0) 
dvander@1656
   181
				{
dvander@203
   182
					plugin->type_val = PluginType_MapOnly;
dvander@1656
   183
				}
dvander@1656
   184
				else if (strcasecmp(value, "global") == 0) 
dvander@1656
   185
				{
dvander@203
   186
					plugin->type_val = PluginType_Global;
dvander@1656
   187
				}
dvander@1656
   188
				else 
dvander@1656
   189
				{
dvander@203
   190
					return MakeError("Unknown value for key \"lifetime\": \"%s\"", value);
dvander@203
   191
				}
dvander@1656
   192
			}
dvander@1656
   193
			else if (strcmp(key, "blockload") == 0) 
dvander@1656
   194
			{
dvander@1436
   195
				plugin->blockload_val = true;
dvander@1656
   196
			} 
dvander@1656
   197
			else 
dvander@1656
   198
			{
dvander@203
   199
				return MakeError("Unknown property key: \"%s\"", key);
dvander@203
   200
			}
dvander@1656
   201
		}
dvander@1656
   202
		else 
dvander@1656
   203
		{
dvander@203
   204
			/* Cache every option, valid or not */
dvander@203
   205
			int keyidx = m_strtab->AddString(key);
dvander@203
   206
			int validx = m_strtab->AddString(value);
dvander@203
   207
			PluginOpts *table;
dvander@203
   208
			BaseMemTable *memtab = m_strtab->GetMemTable();
dvander@1436
   209
			plugin = (PluginSettings *)memtab->GetAddress(cur_plugin);
dvander@203
   210
			if (plugin->opts_num + 1 > plugin->opts_size)
dvander@203
   211
			{
dvander@203
   212
				unsigned int oldsize = plugin->opts_size;
dvander@203
   213
				if (oldsize == 0)
dvander@203
   214
				{
dvander@203
   215
					//right now we don't have many
dvander@203
   216
					plugin->opts_size = 2;
dvander@1656
   217
				} 
dvander@1656
   218
				else
dvander@1656
   219
				{
dvander@203
   220
					plugin->opts_size *= 2;
dvander@203
   221
				}
dvander@203
   222
				int newidx = memtab->CreateMem(plugin->opts_size * sizeof(PluginOpts), (void **)&table);
dvander@293
   223
				/* in case it resized */
dvander@293
   224
				plugin = (PluginSettings *)memtab->GetAddress(cur_plugin);
dvander@203
   225
				if (plugin->optarray != -1)
dvander@203
   226
				{
dvander@203
   227
					void *oldtable = memtab->GetAddress(plugin->optarray);
dvander@203
   228
					memcpy(table, oldtable, oldsize * sizeof(PluginOpts));
dvander@203
   229
				}
dvander@203
   230
				plugin->optarray = newidx;
dvander@1656
   231
			}
dvander@1656
   232
			else
dvander@1656
   233
			{
dvander@203
   234
				table = (PluginOpts *)memtab->GetAddress(plugin->optarray);
dvander@203
   235
			}
dvander@203
   236
			PluginOpts *opt = &table[plugin->opts_num++];
dvander@203
   237
			opt->key = keyidx;
dvander@203
   238
			opt->val = validx;
dvander@203
   239
		}
dvander@1656
   240
	}
dvander@1656
   241
	else if (in_plugins)
dvander@1656
   242
	{
dvander@203
   243
		return MakeError("Unknown property key: \"%s\"", key);
dvander@1656
   244
	}
dvander@1656
   245
	else 
dvander@1656
   246
	{
dvander@203
   247
		/* Ignore anything we don't know about! */
dvander@203
   248
	}
dvander@203
   249
dvander@1656
   250
	return SMCResult_Continue;
dvander@203
   251
}
dvander@203
   252
dvander@1656
   253
SMCResult CPluginInfoDatabase::ReadSMC_LeavingSection(const SMCStates *states)
dvander@203
   254
{
dvander@203
   255
	if (in_plugins)
dvander@203
   256
	{
dvander@205
   257
		if (cur_plugin != -1)
dvander@203
   258
		{
dvander@203
   259
			if (in_options)
dvander@203
   260
			{
dvander@203
   261
				in_options = false;
dvander@1656
   262
			}
dvander@1656
   263
			else 
dvander@1656
   264
			{
dvander@203
   265
				/* If the plugin is ending, add it to the table */
dvander@203
   266
				BaseMemTable *memtab = m_strtab->GetMemTable();
dvander@203
   267
				int *table;
dvander@203
   268
				if (m_infodb_count + 1 > m_infodb_size)
dvander@203
   269
				{
dvander@203
   270
					unsigned int oldsize = m_infodb_size;
dvander@203
   271
					if (!m_infodb_size)
dvander@203
   272
					{
dvander@203
   273
						m_infodb_size = 8;
dvander@1656
   274
					}
dvander@1656
   275
					else 
dvander@1656
   276
					{
dvander@203
   277
						m_infodb_size *= 2;
dvander@203
   278
					}
fyrenmoo@2811
   279
					int newidx = memtab->CreateMem(m_infodb_size * sizeof(int), (void **)&table);
dvander@203
   280
					if (m_infodb != -1)
dvander@203
   281
					{
dvander@203
   282
						void *oldtable = (int *)memtab->GetAddress(m_infodb);
dvander@203
   283
						memcpy(table, oldtable, oldsize * sizeof(int));
dvander@203
   284
					}
dvander@203
   285
					m_infodb = newidx;
dvander@1656
   286
				}
dvander@1656
   287
				else 
dvander@1656
   288
				{
dvander@203
   289
					table = (int *)memtab->GetAddress(m_infodb);
dvander@203
   290
				}
dvander@203
   291
				/* Assign to table and scrap the current plugin */
dvander@203
   292
				table[m_infodb_count++] = cur_plugin;
dvander@203
   293
				cur_plugin = -1;
dvander@203
   294
			}
dvander@1656
   295
		}
dvander@1656
   296
		else 
dvander@1656
   297
		{
dvander@203
   298
			in_plugins = false;
dvander@203
   299
		}
dvander@203
   300
	}
dvander@203
   301
dvander@1656
   302
	return SMCResult_Continue;
dvander@203
   303
}
dvander@203
   304
dvander@1656
   305
SMCResult CPluginInfoDatabase::ReadSMC_NewSection(const SMCStates *states, const char *name)
dvander@203
   306
{
dvander@203
   307
	if (!in_plugins)
dvander@203
   308
	{
dvander@203
   309
		/* If we're not in the main Plugins section, and we don't get it for the name, error out */
dvander@203
   310
		if (strcmp(name, "Plugins") != 0)
dvander@203
   311
		{
dvander@203
   312
			return MakeError("Unknown root section: \"%s\"", name);
dvander@1656
   313
		}
dvander@1656
   314
		else 
dvander@1656
   315
		{
dvander@203
   316
			/* Otherwise set our states */
dvander@203
   317
			in_plugins = true;
dvander@203
   318
			cur_plugin = -1;
dvander@203
   319
			in_options = false;
dvander@203
   320
		}
dvander@1656
   321
	}
dvander@1656
   322
	else
dvander@1656
   323
	{
dvander@203
   324
		if (cur_plugin == -1)
dvander@203
   325
		{
dvander@203
   326
			/* If we get a plugin node and we don't have a current plugin, create a new one */
dvander@203
   327
			PluginSettings *plugin;
dvander@1436
   328
			int i_name = m_strtab->AddString(name);
dvander@203
   329
			cur_plugin = m_strtab->GetMemTable()->CreateMem(sizeof(PluginSettings), (void **)&plugin);
dvander@203
   330
			plugin->Init();
dvander@1436
   331
			plugin->name = i_name;
dvander@203
   332
			in_options = false;
dvander@1656
   333
		} 
dvander@1656
   334
		else 
dvander@1656
   335
		{
dvander@203
   336
			if (!in_options && strcmp(name, "Options") == 0)
dvander@203
   337
			{
dvander@203
   338
				in_options = true;
dvander@1656
   339
			}
dvander@1656
   340
			else
dvander@1656
   341
			{
dvander@203
   342
				return MakeError("Unknown plugin sub-section: \"%s\"", name);
dvander@203
   343
			}
dvander@203
   344
		}
dvander@203
   345
	}
dvander@203
   346
dvander@1656
   347
	return SMCResult_Continue;
dvander@203
   348
}
dvander@1656
   349