core/systems/PluginInfoDatabase.cpp
author Scott Ehlert <ds@alliedmods.net>
Fri Jun 01 06:33:54 2007 +0000 (2007-06-01)
changeset 873 a2136b3be10d
parent 653 ef60870067ff
child 1231 17badaf66ce4
permissions -rw-r--r--
- Added natives: PrintToChat() and PrintCenterText()
- Bit of reorganization with moving some natives from sourcemod.inc to halflife.inc
dvander@370
     1
/**
ds@653
     2
 * vim: set ts=4 :
dvander@370
     3
 * ===============================================================
dvander@370
     4
 * SourceMod (C)2004-2007 AlliedModders LLC.  All rights reserved.
dvander@370
     5
 * ===============================================================
dvander@370
     6
 *
dvander@370
     7
 * This file is not open source and may not be copied without explicit
dvander@370
     8
 * written permission of AlliedModders LLC.  This file may not be redistributed 
dvander@370
     9
 * in whole or significant part.
dvander@370
    10
 * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
dvander@370
    11
 *
dvander@370
    12
 * Version: $Id$
dvander@370
    13
 */
dvander@370
    14
dvander@203
    15
#include <stdarg.h>
dvander@203
    16
#include <string.h>
dvander@203
    17
#include "PluginInfoDatabase.h"
dvander@203
    18
#include "PluginSys.h"
dvander@203
    19
dvander@203
    20
void PluginSettings::Init()
dvander@203
    21
{
dvander@203
    22
	name = -1;
dvander@203
    23
	pause_val = false;
dvander@203
    24
	type_val = PluginType_MapUpdated;
dvander@203
    25
	optarray = -1;
dvander@203
    26
	opts_num = 0;
dvander@203
    27
	opts_size = 0;
dvander@203
    28
}
dvander@203
    29
dvander@203
    30
/**
dvander@203
    31
 * :TODO: write the logger, make these errors log instead of being static
dvander@203
    32
 * NOTE: once we do that, we will have to change some code to ignore sections
dvander@203
    33
 */
dvander@203
    34
dvander@203
    35
CPluginInfoDatabase::CPluginInfoDatabase()
dvander@203
    36
{
dvander@203
    37
	m_strtab = NULL;
dvander@203
    38
	m_infodb_count = 0;
dvander@203
    39
	m_infodb_size = 0;
dvander@203
    40
	m_infodb = -1;
dvander@203
    41
}
dvander@203
    42
dvander@203
    43
CPluginInfoDatabase::~CPluginInfoDatabase()
dvander@203
    44
{
dvander@203
    45
	delete m_strtab;
dvander@203
    46
}
dvander@203
    47
dvander@203
    48
void CPluginInfoDatabase::ReadSMC_ParseStart()
dvander@203
    49
{
dvander@203
    50
	/* Create or reset our string table */
dvander@203
    51
	if (m_strtab)
dvander@203
    52
	{
dvander@203
    53
		m_strtab->Reset();
dvander@203
    54
	} else {
dvander@203
    55
		m_strtab = new BaseStringTable(1024);
dvander@203
    56
	}
dvander@203
    57
dvander@203
    58
	/* Set our internal states to the beginning */
dvander@203
    59
	in_plugins = false;
dvander@203
    60
	cur_plugin = -1;
dvander@203
    61
	in_options = false;
dvander@264
    62
	m_infodb_size = 0;
dvander@264
    63
	m_infodb_count = 0;
dvander@264
    64
	m_infodb = -1;
dvander@203
    65
}
dvander@203
    66
dvander@203
    67
SMCParseResult CPluginInfoDatabase::MakeError(const char *fmt, ...)
dvander@203
    68
{
dvander@203
    69
	char buffer[512];
dvander@203
    70
	va_list ap;
dvander@203
    71
dvander@203
    72
	va_start(ap, fmt);
dvander@203
    73
	vsnprintf(buffer, sizeof(buffer), fmt, ap);
dvander@203
    74
	va_end(ap);
dvander@203
    75
dvander@203
    76
	m_errmsg = m_strtab->AddString(buffer);
dvander@203
    77
dvander@203
    78
	return SMCParse_HaltFail;
dvander@203
    79
}
dvander@203
    80
dvander@203
    81
unsigned int CPluginInfoDatabase::GetSettingsNum()
dvander@203
    82
{
dvander@203
    83
	return m_infodb_count;
dvander@203
    84
}
dvander@203
    85
dvander@203
    86
PluginSettings *CPluginInfoDatabase::GetSettingsIfMatch(unsigned int index, const char *filename)
dvander@203
    87
{
dvander@203
    88
	BaseMemTable *memtab = m_strtab->GetMemTable();
dvander@205
    89
	int *table = (int *)memtab->GetAddress(m_infodb);
dvander@203
    90
dvander@203
    91
	if (!table || index >= m_infodb_count)
dvander@203
    92
	{
dvander@203
    93
		return NULL;
dvander@203
    94
	}
dvander@203
    95
dvander@205
    96
	PluginSettings *plugin = (PluginSettings *)memtab->GetAddress(table[index]);
dvander@205
    97
dvander@205
    98
	const char *name = m_strtab->GetString(plugin->name);
dvander@203
    99
dvander@203
   100
	if (!name)
dvander@203
   101
	{
dvander@203
   102
		return NULL;
dvander@203
   103
	}
dvander@203
   104
dvander@211
   105
	if (!g_PluginSys.TestAliasMatch(name, filename))
dvander@203
   106
	{
dvander@203
   107
		return NULL;
dvander@203
   108
	}
dvander@203
   109
dvander@205
   110
	return plugin;
dvander@203
   111
}
dvander@203
   112
dvander@203
   113
void CPluginInfoDatabase::GetOptionsForPlugin(PluginSettings *settings, unsigned int opt_num, const char **key, const char **val)
dvander@203
   114
{
dvander@203
   115
	PluginOpts *table = (PluginOpts *)m_strtab->GetMemTable()->GetAddress(settings->optarray);
dvander@203
   116
	if (!table)
dvander@203
   117
	{
dvander@203
   118
		*key = NULL;
dvander@203
   119
		*val = NULL;
dvander@203
   120
		return;
dvander@203
   121
	}
dvander@203
   122
dvander@203
   123
	if (opt_num >= settings->opts_num)
dvander@203
   124
	{
dvander@203
   125
		*key = NULL;
dvander@203
   126
		*val = NULL;
dvander@203
   127
		return;
dvander@203
   128
	}
dvander@203
   129
dvander@203
   130
	*key = m_strtab->GetString(table[opt_num].key);
dvander@203
   131
	*val = m_strtab->GetString(table[opt_num].val);
dvander@203
   132
}
dvander@203
   133
dvander@203
   134
SMCParseResult CPluginInfoDatabase::ReadSMC_KeyValue(const char *key, 
dvander@203
   135
													 const char *value, 
dvander@203
   136
													 bool key_quotes, 
dvander@203
   137
													 bool value_quotes)
dvander@203
   138
{
dvander@203
   139
	if (cur_plugin != -1)
dvander@203
   140
	{
dvander@203
   141
		PluginSettings *plugin = (PluginSettings *)m_strtab->GetMemTable()->GetAddress(cur_plugin);
dvander@203
   142
		if (!in_options)
dvander@203
   143
		{
dvander@203
   144
			if (strcmp(key, "pause") == 0)
dvander@203
   145
			{
dvander@203
   146
				if (strcasecmp(value, "yes") == 0)
dvander@203
   147
				{
dvander@203
   148
					plugin->pause_val = true;
dvander@203
   149
				} else {
dvander@203
   150
					plugin->pause_val = false;
dvander@203
   151
				}
dvander@203
   152
			} else if (strcmp(key, "lifetime") == 0) {
dvander@203
   153
				if (strcasecmp(value, "private") == 0)
dvander@203
   154
				{
dvander@203
   155
					plugin->type_val = PluginType_Private;
dvander@203
   156
				} else if (strcasecmp(value, "mapsync") == 0) {
dvander@203
   157
					plugin->type_val = PluginType_MapUpdated;
dvander@203
   158
				} else if (strcasecmp(value, "maponly") == 0) {
dvander@203
   159
					plugin->type_val = PluginType_MapOnly;
dvander@203
   160
				} else if (strcasecmp(value, "global") == 0) {
dvander@203
   161
					plugin->type_val = PluginType_Global;
dvander@203
   162
				} else {
dvander@203
   163
					return MakeError("Unknown value for key \"lifetime\": \"%s\"", value);
dvander@203
   164
				}
dvander@203
   165
			} else {
dvander@203
   166
				return MakeError("Unknown property key: \"%s\"", key);
dvander@203
   167
			}
dvander@203
   168
		} else {
dvander@203
   169
			/* Cache every option, valid or not */
dvander@203
   170
			int keyidx = m_strtab->AddString(key);
dvander@203
   171
			int validx = m_strtab->AddString(value);
dvander@203
   172
			PluginOpts *table;
dvander@203
   173
			BaseMemTable *memtab = m_strtab->GetMemTable();
dvander@203
   174
			if (plugin->opts_num + 1 > plugin->opts_size)
dvander@203
   175
			{
dvander@203
   176
				unsigned int oldsize = plugin->opts_size;
dvander@203
   177
				if (oldsize == 0)
dvander@203
   178
				{
dvander@203
   179
					//right now we don't have many
dvander@203
   180
					plugin->opts_size = 2;
dvander@203
   181
				} else {
dvander@203
   182
					plugin->opts_size *= 2;
dvander@203
   183
				}
dvander@203
   184
				int newidx = memtab->CreateMem(plugin->opts_size * sizeof(PluginOpts), (void **)&table);
dvander@293
   185
				/* in case it resized */
dvander@293
   186
				plugin = (PluginSettings *)memtab->GetAddress(cur_plugin);
dvander@203
   187
				if (plugin->optarray != -1)
dvander@203
   188
				{
dvander@203
   189
					void *oldtable = memtab->GetAddress(plugin->optarray);
dvander@203
   190
					memcpy(table, oldtable, oldsize * sizeof(PluginOpts));
dvander@203
   191
				}
dvander@203
   192
				plugin->optarray = newidx;
dvander@203
   193
			} else {
dvander@203
   194
				table = (PluginOpts *)memtab->GetAddress(plugin->optarray);
dvander@203
   195
			}
dvander@203
   196
			PluginOpts *opt = &table[plugin->opts_num++];
dvander@203
   197
			opt->key = keyidx;
dvander@203
   198
			opt->val = validx;
dvander@203
   199
		}
dvander@203
   200
	} else if (in_plugins) {
dvander@203
   201
		return MakeError("Unknown property key: \"%s\"", key);
dvander@203
   202
	} else {
dvander@203
   203
		/* Ignore anything we don't know about! */
dvander@203
   204
	}
dvander@203
   205
dvander@203
   206
	return SMCParse_Continue;
dvander@203
   207
}
dvander@203
   208
dvander@203
   209
SMCParseResult CPluginInfoDatabase::ReadSMC_LeavingSection()
dvander@203
   210
{
dvander@203
   211
	if (in_plugins)
dvander@203
   212
	{
dvander@205
   213
		if (cur_plugin != -1)
dvander@203
   214
		{
dvander@203
   215
			if (in_options)
dvander@203
   216
			{
dvander@203
   217
				in_options = false;
dvander@203
   218
			} else {
dvander@203
   219
				/* If the plugin is ending, add it to the table */
dvander@203
   220
				BaseMemTable *memtab = m_strtab->GetMemTable();
dvander@203
   221
				int *table;
dvander@203
   222
				if (m_infodb_count + 1 > m_infodb_size)
dvander@203
   223
				{
dvander@203
   224
					unsigned int oldsize = m_infodb_size;
dvander@203
   225
					if (!m_infodb_size)
dvander@203
   226
					{
dvander@203
   227
						m_infodb_size = 8;
dvander@203
   228
					} else {
dvander@203
   229
						m_infodb_size *= 2;
dvander@203
   230
					}
dvander@203
   231
					int newidx = memtab->CreateMem(m_infodb_size, (void **)&table);
dvander@203
   232
					if (m_infodb != -1)
dvander@203
   233
					{
dvander@203
   234
						void *oldtable = (int *)memtab->GetAddress(m_infodb);
dvander@203
   235
						memcpy(table, oldtable, oldsize * sizeof(int));
dvander@203
   236
					}
dvander@203
   237
					m_infodb = newidx;
dvander@203
   238
				} else {
dvander@203
   239
					table = (int *)memtab->GetAddress(m_infodb);
dvander@203
   240
				}
dvander@203
   241
				/* Assign to table and scrap the current plugin */
dvander@203
   242
				table[m_infodb_count++] = cur_plugin;
dvander@203
   243
				cur_plugin = -1;
dvander@203
   244
			}
dvander@203
   245
		} else {
dvander@203
   246
			in_plugins = false;
dvander@203
   247
		}
dvander@203
   248
	}
dvander@203
   249
dvander@203
   250
	return SMCParse_Continue;
dvander@203
   251
}
dvander@203
   252
dvander@203
   253
SMCParseResult CPluginInfoDatabase::ReadSMC_NewSection(const char *name, bool opt_quotes)
dvander@203
   254
{
dvander@203
   255
	if (!in_plugins)
dvander@203
   256
	{
dvander@203
   257
		/* If we're not in the main Plugins section, and we don't get it for the name, error out */
dvander@203
   258
		if (strcmp(name, "Plugins") != 0)
dvander@203
   259
		{
dvander@203
   260
			return MakeError("Unknown root section: \"%s\"", name);
dvander@203
   261
		} else {
dvander@203
   262
			/* Otherwise set our states */
dvander@203
   263
			in_plugins = true;
dvander@203
   264
			cur_plugin = -1;
dvander@203
   265
			in_options = false;
dvander@203
   266
		}
dvander@203
   267
	} else {
dvander@203
   268
		if (cur_plugin == -1)
dvander@203
   269
		{
dvander@203
   270
			/* If we get a plugin node and we don't have a current plugin, create a new one */
dvander@203
   271
			PluginSettings *plugin;
dvander@203
   272
			cur_plugin = m_strtab->GetMemTable()->CreateMem(sizeof(PluginSettings), (void **)&plugin);
dvander@203
   273
			plugin->Init();
dvander@203
   274
			plugin->name = m_strtab->AddString(name);
dvander@203
   275
			in_options = false;
dvander@203
   276
		} else {
dvander@203
   277
			if (!in_options && strcmp(name, "Options") == 0)
dvander@203
   278
			{
dvander@203
   279
				in_options = true;
dvander@203
   280
			} else {
dvander@203
   281
				return MakeError("Unknown plugin sub-section: \"%s\"", name);
dvander@203
   282
			}
dvander@203
   283
		}
dvander@203
   284
	}
dvander@203
   285
dvander@203
   286
	return SMCParse_Continue;
dvander@203
   287
}