core/smn_keyvalues.cpp
author David Anderson <dvander@alliedmods.net>
Mon Sep 29 20:02:19 2008 -0700 (2008-09-29)
changeset 2335 cf312a67fb8f
parent 2289 44045ead61cd
child 2414 e28a9247061f
permissions -rw-r--r--
Fixed OnConfigsExecuted() not working on listen servers (bug 3287, r=me).
faluco@654
     1
/**
faluco@654
     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
 * =============================================================================
faluco@654
     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>.
faluco@654
    28
 *
faluco@654
    29
 * Version: $Id$
faluco@654
    30
 */
faluco@654
    31
faluco@654
    32
#include "sourcemod.h"
faluco@654
    33
#include "sourcemm_api.h"
faluco@654
    34
#include "sm_stringutil.h"
faluco@654
    35
#include "HandleSys.h"
ds@1944
    36
#include "HalfLife2.h"
faluco@654
    37
#include <KeyValues.h>
dvander@1766
    38
#include "utlbuffer.h"
faluco@654
    39
faluco@654
    40
HandleType_t g_KeyValueType;
faluco@654
    41
faluco@654
    42
struct KeyValueStack 
faluco@654
    43
{
faluco@654
    44
	KeyValues *pBase;
faluco@654
    45
	CStack<KeyValues *> pCurRoot;
faluco@654
    46
};
faluco@654
    47
faluco@703
    48
class KeyValueNatives : 
faluco@654
    49
	public SMGlobalClass,
faluco@654
    50
	public IHandleTypeDispatch
faluco@654
    51
{
faluco@654
    52
public:
faluco@654
    53
	void OnSourceModAllInitialized()
faluco@654
    54
	{
faluco@654
    55
		g_KeyValueType = g_HandleSys.CreateType("KeyValues", this, 0, NULL, NULL, g_pCoreIdent, NULL);
faluco@654
    56
	}
faluco@654
    57
	void OnSourceModShutdown()
faluco@654
    58
	{
faluco@654
    59
		g_HandleSys.RemoveType(g_KeyValueType, g_pCoreIdent);
faluco@654
    60
		g_KeyValueType = 0;
faluco@654
    61
	}
faluco@654
    62
	void OnHandleDestroy(HandleType_t type, void *object)
faluco@654
    63
	{
faluco@654
    64
		KeyValueStack *pStk = reinterpret_cast<KeyValueStack *>(object);
faluco@654
    65
		pStk->pBase->deleteThis();
faluco@654
    66
		delete pStk;
faluco@654
    67
	}
dvander@1766
    68
	int CalcKVSizeR(KeyValues *pv)
dvander@1766
    69
	{
dvander@1766
    70
		CUtlBuffer buf;
dvander@1766
    71
		int size;
dvander@1766
    72
dvander@1766
    73
		pv->RecursiveSaveToFile(buf, 0);
dvander@1766
    74
		size = buf.TellMaxPut();
dvander@1766
    75
dvander@1766
    76
		buf.Purge();
dvander@1766
    77
dvander@1766
    78
		return size;
dvander@1766
    79
	}
dvander@1766
    80
	bool GetHandleApproxSize(HandleType_t type, void *object, unsigned int *pSize)
dvander@1766
    81
	{
dvander@1766
    82
		KeyValueStack *pStk = (KeyValueStack *)object;
dvander@1766
    83
		unsigned int size = sizeof(KeyValueStack) + (pStk->pCurRoot.size() * sizeof(KeyValues *));
dvander@1766
    84
dvander@1766
    85
		/* Check how much memory the actual thing takes up */		
dvander@1766
    86
		size += CalcKVSizeR(pStk->pBase);
dvander@1766
    87
dvander@1766
    88
		*pSize = size;
dvander@1766
    89
dvander@1766
    90
		return true;
dvander@1766
    91
	}
faluco@654
    92
};
faluco@654
    93
faluco@682
    94
KeyValues *SourceModBase::ReadKeyValuesHandle(Handle_t hndl, HandleError *err, bool root)
faluco@682
    95
{
faluco@682
    96
	HandleError herr;
faluco@682
    97
	HandleSecurity sec;
faluco@682
    98
	KeyValueStack *pStk;
faluco@682
    99
faluco@682
   100
	sec.pOwner = NULL;
faluco@682
   101
	sec.pIdentity = g_pCoreIdent;
faluco@682
   102
faluco@682
   103
	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@682
   104
		!= HandleError_None)
faluco@682
   105
	{
faluco@682
   106
		if (err)
faluco@682
   107
		{
faluco@682
   108
			*err = herr;
faluco@682
   109
		}
faluco@682
   110
		return NULL;
faluco@682
   111
	}
faluco@682
   112
faluco@682
   113
	if (err)
faluco@682
   114
	{
faluco@682
   115
		*err = HandleError_None;
faluco@682
   116
	}
faluco@682
   117
faluco@682
   118
	return (root) ? pStk->pBase : pStk->pCurRoot.front();
faluco@682
   119
}
faluco@682
   120
faluco@654
   121
static cell_t smn_KvSetString(IPluginContext *pCtx, const cell_t *params)
faluco@654
   122
{
faluco@654
   123
	Handle_t hndl = static_cast<Handle_t>(params[1]);
faluco@654
   124
	HandleError herr;
faluco@654
   125
	HandleSecurity sec;
faluco@654
   126
	KeyValueStack *pStk;
faluco@654
   127
faluco@654
   128
	sec.pOwner = NULL;
faluco@654
   129
	sec.pIdentity = g_pCoreIdent;
faluco@654
   130
faluco@654
   131
	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654
   132
		!= HandleError_None)
faluco@654
   133
	{
faluco@654
   134
		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654
   135
	}
faluco@654
   136
faluco@654
   137
	char *key, *value;
dvander@1000
   138
	pCtx->LocalToStringNULL(params[2], &key);
faluco@654
   139
	pCtx->LocalToString(params[3], &value);
faluco@654
   140
faluco@654
   141
	pStk->pCurRoot.front()->SetString(key, value);
faluco@654
   142
faluco@654
   143
	return 1;
faluco@654
   144
}
faluco@654
   145
faluco@654
   146
static cell_t smn_KvSetNum(IPluginContext *pCtx, const cell_t *params)
faluco@654
   147
{
faluco@654
   148
	Handle_t hndl = static_cast<Handle_t>(params[1]);
faluco@654
   149
	HandleError herr;
faluco@654
   150
	HandleSecurity sec;
faluco@654
   151
	KeyValueStack *pStk;
faluco@654
   152
faluco@654
   153
	sec.pOwner = NULL;
faluco@654
   154
	sec.pIdentity = g_pCoreIdent;
faluco@654
   155
faluco@654
   156
	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654
   157
		!= HandleError_None)
faluco@654
   158
	{
faluco@654
   159
		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654
   160
	}
faluco@654
   161
faluco@654
   162
	char *key;
dvander@1000
   163
	pCtx->LocalToStringNULL(params[2], &key);
faluco@654
   164
faluco@654
   165
	pStk->pCurRoot.front()->SetInt(key, params[3]);
faluco@654
   166
faluco@654
   167
	return 1;
faluco@654
   168
}
faluco@654
   169
dvander@816
   170
static cell_t smn_KvSetUInt64(IPluginContext *pCtx, const cell_t *params)
faluco@654
   171
{
faluco@654
   172
	Handle_t hndl = static_cast<Handle_t>(params[1]);
faluco@654
   173
	HandleError herr;
faluco@654
   174
	HandleSecurity sec;
faluco@654
   175
	KeyValueStack *pStk;
faluco@654
   176
faluco@654
   177
	sec.pOwner = NULL;
faluco@654
   178
	sec.pIdentity = g_pCoreIdent;
faluco@654
   179
faluco@654
   180
	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654
   181
		!= HandleError_None)
faluco@654
   182
	{
faluco@654
   183
		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654
   184
	}
faluco@654
   185
faluco@654
   186
	char *key;
faluco@654
   187
	cell_t *addr;
faluco@654
   188
	uint64 value;
dvander@1000
   189
	pCtx->LocalToStringNULL(params[2], &key);
faluco@654
   190
	pCtx->LocalToPhysAddr(params[3], &addr);
faluco@654
   191
faluco@654
   192
	value = static_cast<uint64>(*addr);
faluco@654
   193
	pStk->pCurRoot.front()->SetUint64(key, value);
faluco@654
   194
faluco@654
   195
	return 1;
faluco@654
   196
}
faluco@654
   197
faluco@654
   198
static cell_t smn_KvSetFloat(IPluginContext *pCtx, const cell_t *params)
faluco@654
   199
{
faluco@654
   200
	Handle_t hndl = static_cast<Handle_t>(params[1]);
faluco@654
   201
	HandleError herr;
faluco@654
   202
	HandleSecurity sec;
faluco@654
   203
	KeyValueStack *pStk;
faluco@654
   204
faluco@654
   205
	sec.pOwner = NULL;
faluco@654
   206
	sec.pIdentity = g_pCoreIdent;
faluco@654
   207
faluco@654
   208
	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654
   209
		!= HandleError_None)
faluco@654
   210
	{
faluco@654
   211
		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654
   212
	}
faluco@654
   213
faluco@654
   214
	char *key;
dvander@1000
   215
	pCtx->LocalToStringNULL(params[2], &key);
faluco@654
   216
faluco@654
   217
	pStk->pCurRoot.front()->SetFloat(key, sp_ctof(params[3]));
faluco@654
   218
faluco@654
   219
	return 1;
faluco@654
   220
}
faluco@654
   221
faluco@654
   222
static cell_t smn_KvSetColor(IPluginContext *pCtx, const cell_t *params)
faluco@654
   223
{
faluco@654
   224
	Handle_t hndl = static_cast<Handle_t>(params[1]);
faluco@654
   225
	HandleError herr;
faluco@654
   226
	HandleSecurity sec;
faluco@654
   227
	KeyValueStack *pStk;
faluco@654
   228
faluco@654
   229
	sec.pOwner = NULL;
faluco@654
   230
	sec.pIdentity = g_pCoreIdent;
faluco@654
   231
faluco@654
   232
	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654
   233
		!= HandleError_None)
faluco@654
   234
	{
faluco@654
   235
		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654
   236
	}
faluco@654
   237
faluco@654
   238
	char *key;
dvander@1000
   239
	pCtx->LocalToStringNULL(params[2], &key);
faluco@654
   240
faluco@654
   241
	Color color(params[3], params[4], params[5], params[6]);
faluco@654
   242
	pStk->pCurRoot.front()->SetColor(key, color);
faluco@654
   243
faluco@654
   244
	return 1;
faluco@654
   245
}
faluco@654
   246
faluco@1734
   247
static cell_t smn_KvSetVector(IPluginContext *pCtx, const cell_t *params)
faluco@1734
   248
{
faluco@1734
   249
	Handle_t hndl = static_cast<Handle_t>(params[1]);
faluco@1734
   250
	HandleError herr;
faluco@1734
   251
	HandleSecurity sec;
faluco@1734
   252
	KeyValueStack *pStk;
faluco@1734
   253
faluco@1734
   254
	sec.pOwner = NULL;
faluco@1734
   255
	sec.pIdentity = g_pCoreIdent;
faluco@1734
   256
faluco@1734
   257
	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@1734
   258
		!= HandleError_None)
faluco@1734
   259
	{
faluco@1734
   260
		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@1734
   261
	}
faluco@1734
   262
faluco@1734
   263
	char *key;
faluco@1734
   264
	char buffer[64];
faluco@1734
   265
	cell_t *vector;
faluco@1734
   266
	pCtx->LocalToStringNULL(params[2], &key);
faluco@1734
   267
	pCtx->LocalToPhysAddr(params[3], &vector);
faluco@1734
   268
faluco@1734
   269
	UTIL_Format(buffer, sizeof(buffer), "%f %f %f", sp_ctof(vector[0]), sp_ctof(vector[1]), sp_ctof(vector[2]));
faluco@1734
   270
faluco@1734
   271
	pStk->pCurRoot.front()->SetString(key, buffer);
faluco@1734
   272
faluco@1734
   273
	return 1;
faluco@1734
   274
}
faluco@1734
   275
faluco@654
   276
static cell_t smn_KvGetString(IPluginContext *pCtx, const cell_t *params)
faluco@654
   277
{
faluco@654
   278
	Handle_t hndl = static_cast<Handle_t>(params[1]);
faluco@654
   279
	HandleError herr;
faluco@654
   280
	HandleSecurity sec;
faluco@654
   281
	KeyValueStack *pStk;
faluco@654
   282
faluco@654
   283
	sec.pOwner = NULL;
faluco@654
   284
	sec.pIdentity = g_pCoreIdent;
faluco@654
   285
faluco@654
   286
	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654
   287
		!= HandleError_None)
faluco@654
   288
	{
faluco@654
   289
		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654
   290
	}
faluco@654
   291
faluco@654
   292
	const char *value;
faluco@654
   293
	char *key, *defvalue;
dvander@1000
   294
	pCtx->LocalToStringNULL(params[2], &key);
faluco@654
   295
	pCtx->LocalToString(params[5], &defvalue);
faluco@654
   296
faluco@654
   297
	value = pStk->pCurRoot.front()->GetString(key, defvalue);
faluco@654
   298
	pCtx->StringToLocalUTF8(params[3], params[4], value, NULL);
faluco@654
   299
faluco@654
   300
	return 1;
faluco@654
   301
}
faluco@654
   302
faluco@654
   303
static cell_t smn_KvGetNum(IPluginContext *pCtx, const cell_t *params)
faluco@654
   304
{
faluco@654
   305
	Handle_t hndl = static_cast<Handle_t>(params[1]);
faluco@654
   306
	HandleError herr;
faluco@654
   307
	HandleSecurity sec;
faluco@654
   308
	KeyValueStack *pStk;
faluco@654
   309
faluco@654
   310
	sec.pOwner = NULL;
faluco@654
   311
	sec.pIdentity = g_pCoreIdent;
faluco@654
   312
faluco@654
   313
	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654
   314
		!= HandleError_None)
faluco@654
   315
	{
faluco@654
   316
		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654
   317
	}
faluco@654
   318
faluco@654
   319
	int value;
faluco@654
   320
	char *key;
dvander@1000
   321
	pCtx->LocalToStringNULL(params[2], &key);
faluco@654
   322
faluco@654
   323
	value = pStk->pCurRoot.front()->GetInt(key, params[3]);
faluco@654
   324
faluco@654
   325
	return value;
faluco@654
   326
}
faluco@654
   327
faluco@654
   328
static cell_t smn_KvGetFloat(IPluginContext *pCtx, const cell_t *params)
faluco@654
   329
{
faluco@654
   330
	Handle_t hndl = static_cast<Handle_t>(params[1]);
faluco@654
   331
	HandleError herr;
faluco@654
   332
	HandleSecurity sec;
faluco@654
   333
	KeyValueStack *pStk;
faluco@654
   334
faluco@654
   335
	sec.pOwner = NULL;
faluco@654
   336
	sec.pIdentity = g_pCoreIdent;
faluco@654
   337
faluco@654
   338
	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654
   339
		!= HandleError_None)
faluco@654
   340
	{
faluco@654
   341
		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654
   342
	}
faluco@654
   343
faluco@654
   344
	float value;
faluco@654
   345
	char *key;
dvander@1000
   346
	pCtx->LocalToStringNULL(params[2], &key);
faluco@654
   347
faluco@654
   348
	value = pStk->pCurRoot.front()->GetFloat(key, sp_ctof(params[3]));
faluco@654
   349
faluco@654
   350
	return sp_ftoc(value);
faluco@654
   351
}
faluco@654
   352
faluco@654
   353
static cell_t smn_KvGetColor(IPluginContext *pCtx, const cell_t *params)
faluco@654
   354
{
faluco@654
   355
	Handle_t hndl = static_cast<Handle_t>(params[1]);
faluco@654
   356
	HandleError herr;
faluco@654
   357
	HandleSecurity sec;
faluco@654
   358
	KeyValueStack *pStk;
faluco@654
   359
faluco@654
   360
	sec.pOwner = NULL;
faluco@654
   361
	sec.pIdentity = g_pCoreIdent;
faluco@654
   362
faluco@654
   363
	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654
   364
		!= HandleError_None)
faluco@654
   365
	{
faluco@654
   366
		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654
   367
	}
faluco@654
   368
faluco@654
   369
	Color color;
faluco@654
   370
	char *key;
faluco@654
   371
	cell_t *r, *g, *b, *a;
dvander@1000
   372
	pCtx->LocalToStringNULL(params[2], &key);
faluco@654
   373
	pCtx->LocalToPhysAddr(params[3], &r);
faluco@654
   374
	pCtx->LocalToPhysAddr(params[4], &g);
faluco@654
   375
	pCtx->LocalToPhysAddr(params[5], &b);
faluco@654
   376
	pCtx->LocalToPhysAddr(params[6], &a);
faluco@654
   377
faluco@654
   378
	color = pStk->pCurRoot.front()->GetColor(key);
faluco@654
   379
	*r = color.r();
faluco@654
   380
	*g = color.g();
faluco@654
   381
	*b = color.b();
faluco@654
   382
	*a = color.a();
faluco@654
   383
faluco@654
   384
	return 1;
faluco@654
   385
}
faluco@654
   386
dvander@816
   387
static cell_t smn_KvGetUInt64(IPluginContext *pCtx, const cell_t *params)
faluco@654
   388
{
faluco@654
   389
	Handle_t hndl = static_cast<Handle_t>(params[1]);
faluco@654
   390
	HandleError herr;
faluco@654
   391
	HandleSecurity sec;
faluco@654
   392
	KeyValueStack *pStk;
faluco@654
   393
faluco@654
   394
	sec.pOwner = NULL;
faluco@654
   395
	sec.pIdentity = g_pCoreIdent;
faluco@654
   396
faluco@654
   397
	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654
   398
		!= HandleError_None)
faluco@654
   399
	{
faluco@654
   400
		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654
   401
	}
faluco@654
   402
faluco@654
   403
	char *key;
faluco@654
   404
	cell_t *addr, *defvalue;
faluco@654
   405
	uint64 value;
dvander@1000
   406
	pCtx->LocalToStringNULL(params[2], &key);
faluco@654
   407
	pCtx->LocalToPhysAddr(params[3], &addr);
faluco@654
   408
	pCtx->LocalToPhysAddr(params[4], &defvalue);
faluco@654
   409
faluco@654
   410
	value = pStk->pCurRoot.front()->GetUint64(key, static_cast<uint64>(*defvalue));
faluco@654
   411
	*reinterpret_cast<uint64 *>(addr) = value;
faluco@654
   412
faluco@654
   413
	return 1;
faluco@654
   414
}
faluco@654
   415
faluco@1734
   416
static cell_t smn_KvGetVector(IPluginContext *pCtx, const cell_t *params)
faluco@1734
   417
{
faluco@1734
   418
	Handle_t hndl = static_cast<Handle_t>(params[1]);
faluco@1734
   419
	HandleError herr;
faluco@1734
   420
	HandleSecurity sec;
faluco@1734
   421
	KeyValueStack *pStk;
faluco@1734
   422
faluco@1734
   423
	sec.pOwner = NULL;
faluco@1734
   424
	sec.pIdentity = g_pCoreIdent;
faluco@1734
   425
faluco@1734
   426
	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@1734
   427
		!= HandleError_None)
faluco@1734
   428
	{
faluco@1734
   429
		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@1734
   430
	}
faluco@1734
   431
faluco@1734
   432
	char *key;
faluco@1734
   433
	const char *value;
faluco@1734
   434
	cell_t *defvector, *outvector;
faluco@1734
   435
	char buffer[64];
faluco@1734
   436
	pCtx->LocalToStringNULL(params[2], &key);
faluco@1734
   437
	pCtx->LocalToPhysAddr(params[3], &outvector);
faluco@1734
   438
	pCtx->LocalToPhysAddr(params[4], &defvector);
faluco@1734
   439
faluco@1734
   440
	UTIL_Format(buffer, sizeof(buffer), "%f %f %f", sp_ctof(defvector[0]), sp_ctof(defvector[1]), sp_ctof(defvector[2]));
faluco@1734
   441
faluco@1734
   442
	value = pStk->pCurRoot.front()->GetString(key, buffer);
faluco@1734
   443
faluco@1734
   444
	float out;
faluco@1734
   445
	int components = 0;
faluco@1734
   446
	while (*value && components < 3)
faluco@1734
   447
	{
faluco@1734
   448
		while ((*value) && (*value == ' '))
faluco@1734
   449
		{
faluco@1734
   450
			value++;
faluco@1734
   451
		}
faluco@1734
   452
faluco@1734
   453
		out = 0.0f;
faluco@1734
   454
		bool isnegative;
faluco@1734
   455
		if (*value == '-')
faluco@1734
   456
		{
faluco@1734
   457
			isnegative = true;
faluco@1734
   458
			value++;
faluco@1734
   459
		}
faluco@1734
   460
		else
faluco@1734
   461
		{
faluco@1734
   462
			isnegative = false;
faluco@1734
   463
		}
faluco@1734
   464
faluco@1734
   465
		for (; *value && isdigit(*value); ++value)
faluco@1734
   466
		{
faluco@1734
   467
			out *= 10.0f;
faluco@1734
   468
			out += *value - '0';
faluco@1734
   469
		}
faluco@1734
   470
faluco@1734
   471
		if (*value == '.')
faluco@1734
   472
		{
faluco@1734
   473
			value++;
faluco@1734
   474
			float factor = 0.1f;
faluco@1734
   475
			for (; *value && isdigit(*value); ++value)
faluco@1734
   476
			{
faluco@1734
   477
				out += (*value - '0') * factor;
faluco@1734
   478
				factor *= 0.1f;
faluco@1734
   479
			}
faluco@1734
   480
		}
faluco@1734
   481
faluco@1734
   482
		out = (isnegative) ? -out : out;
faluco@1734
   483
		outvector[components++] = sp_ftoc(out);
faluco@1734
   484
	}
faluco@1734
   485
faluco@1734
   486
	return 1;
faluco@1734
   487
}
faluco@1734
   488
faluco@654
   489
static cell_t smn_CreateKeyValues(IPluginContext *pCtx, const cell_t *params)
faluco@654
   490
{
faluco@654
   491
	KeyValueStack *pStk;
faluco@654
   492
	char *name, *firstkey, *firstvalue;
faluco@654
   493
	bool is_empty;
faluco@654
   494
faluco@654
   495
	pCtx->LocalToString(params[1], &name);
faluco@654
   496
	pCtx->LocalToString(params[2], &firstkey);
faluco@654
   497
	pCtx->LocalToString(params[3], &firstvalue);
faluco@654
   498
faluco@654
   499
	is_empty = (firstkey[0] == '\0');
faluco@654
   500
	pStk = new KeyValueStack;
faluco@654
   501
	pStk->pBase = new KeyValues(name, is_empty ? NULL : firstkey, (is_empty||(firstvalue[0]=='\0')) ? NULL : firstvalue);
faluco@654
   502
	pStk->pCurRoot.push(pStk->pBase);
faluco@654
   503
faluco@654
   504
	return g_HandleSys.CreateHandle(g_KeyValueType, pStk, pCtx->GetIdentity(), g_pCoreIdent, NULL);
faluco@654
   505
}
faluco@654
   506
faluco@654
   507
static cell_t smn_KvJumpToKey(IPluginContext *pCtx, const cell_t *params)
faluco@654
   508
{
faluco@654
   509
	Handle_t hndl = static_cast<Handle_t>(params[1]);
faluco@654
   510
	HandleError herr;
faluco@654
   511
	HandleSecurity sec;
faluco@654
   512
	char *name;	
faluco@654
   513
	KeyValueStack *pStk;
faluco@654
   514
faluco@654
   515
	sec.pOwner = NULL;
faluco@654
   516
	sec.pIdentity = g_pCoreIdent;
faluco@654
   517
faluco@654
   518
	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654
   519
		!= HandleError_None)
faluco@654
   520
	{
faluco@654
   521
		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654
   522
	}
faluco@654
   523
faluco@654
   524
	pCtx->LocalToString(params[2], &name);
faluco@654
   525
dvander@726
   526
	KeyValues *pSubKey = pStk->pCurRoot.front();
dvander@726
   527
	pSubKey = pSubKey->FindKey(name, (params[3]) ? true : false);
faluco@654
   528
	if (!pSubKey)
faluco@654
   529
	{
faluco@654
   530
		return 0;
faluco@654
   531
	}
faluco@654
   532
	pStk->pCurRoot.push(pSubKey);
faluco@654
   533
faluco@654
   534
	return 1;
faluco@654
   535
}
faluco@654
   536
pred@1707
   537
static cell_t smn_KvJumpToKeySymbol(IPluginContext *pCtx, const cell_t *params)
pred@1707
   538
{
pred@1707
   539
	Handle_t hndl = static_cast<Handle_t>(params[1]);
pred@1707
   540
	HandleError herr;
pred@1707
   541
	HandleSecurity sec;
pred@1707
   542
	KeyValueStack *pStk;
pred@1707
   543
pred@1707
   544
	sec.pOwner = NULL;
pred@1707
   545
	sec.pIdentity = g_pCoreIdent;
pred@1707
   546
pred@1707
   547
	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
pred@1707
   548
		!= HandleError_None)
pred@1707
   549
	{
pred@1707
   550
		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
pred@1707
   551
	}
pred@1707
   552
pred@1707
   553
	KeyValues *pSubKey = pStk->pCurRoot.front();
pred@1707
   554
	pSubKey = pSubKey->FindKey(params[2]);
pred@1707
   555
	if (!pSubKey)
pred@1707
   556
	{
pred@1707
   557
		return 0;
pred@1707
   558
	}
pred@1707
   559
	pStk->pCurRoot.push(pSubKey);
pred@1707
   560
pred@1707
   561
	return 1;
pred@1707
   562
}
pred@1707
   563
dvander@753
   564
static cell_t smn_KvGotoFirstSubKey(IPluginContext *pCtx, const cell_t *params)
faluco@654
   565
{
faluco@654
   566
	Handle_t hndl = static_cast<Handle_t>(params[1]);
faluco@654
   567
	HandleError herr;
faluco@654
   568
	HandleSecurity sec;
faluco@654
   569
	KeyValueStack *pStk;
faluco@654
   570
faluco@654
   571
	sec.pOwner = NULL;
faluco@654
   572
	sec.pIdentity = g_pCoreIdent;
faluco@654
   573
faluco@654
   574
	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654
   575
		!= HandleError_None)
faluco@654
   576
	{
faluco@654
   577
		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654
   578
	}
faluco@654
   579
faluco@654
   580
	KeyValues *pSubKey = pStk->pCurRoot.front();
dvander@753
   581
	KeyValues *pFirstSubKey;
dvander@753
   582
	if (params[2])
dvander@753
   583
	{
dvander@753
   584
		pFirstSubKey = pSubKey->GetFirstTrueSubKey();
dvander@753
   585
	} else {
dvander@753
   586
		pFirstSubKey = pSubKey->GetFirstSubKey();
dvander@753
   587
	}
dvander@753
   588
faluco@654
   589
	if (!pFirstSubKey)
faluco@654
   590
	{
faluco@654
   591
		return 0;
faluco@654
   592
	}
faluco@654
   593
	pStk->pCurRoot.push(pFirstSubKey);
faluco@654
   594
faluco@654
   595
	return 1;
faluco@654
   596
}
faluco@654
   597
dvander@753
   598
static cell_t smn_KvGotoNextKey(IPluginContext *pCtx, const cell_t *params)
dvander@753
   599
{
dvander@753
   600
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@753
   601
	HandleError herr;
dvander@753
   602
	HandleSecurity sec;
dvander@753
   603
	KeyValueStack *pStk;
dvander@753
   604
dvander@753
   605
	sec.pOwner = NULL;
dvander@753
   606
	sec.pIdentity = g_pCoreIdent;
dvander@753
   607
dvander@753
   608
	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
dvander@753
   609
		!= HandleError_None)
dvander@753
   610
	{
dvander@753
   611
		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
dvander@753
   612
	}
dvander@753
   613
dvander@753
   614
	KeyValues *pSubKey = pStk->pCurRoot.front();
dvander@753
   615
	if (params[2])
dvander@753
   616
	{
dvander@1002
   617
		pSubKey = pSubKey->GetNextTrueSubKey();
dvander@753
   618
	} else {
dvander@1002
   619
		pSubKey = pSubKey->GetNextKey();
dvander@753
   620
	}
dvander@753
   621
	if (!pSubKey)
dvander@753
   622
	{
dvander@753
   623
		return 0;
dvander@753
   624
	}
dvander@753
   625
	pStk->pCurRoot.pop();
dvander@753
   626
	pStk->pCurRoot.push(pSubKey);
dvander@753
   627
dvander@753
   628
	return 1;	
dvander@753
   629
}
dvander@753
   630
faluco@654
   631
static cell_t smn_KvGoBack(IPluginContext *pCtx, const cell_t *params)
faluco@654
   632
{
faluco@654
   633
	Handle_t hndl = static_cast<Handle_t>(params[1]);
faluco@654
   634
	HandleError herr;
faluco@654
   635
	HandleSecurity sec;
faluco@654
   636
	KeyValueStack *pStk;
faluco@654
   637
faluco@654
   638
	sec.pOwner = NULL;
faluco@654
   639
	sec.pIdentity = g_pCoreIdent;
faluco@654
   640
faluco@654
   641
	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654
   642
		!= HandleError_None)
faluco@654
   643
	{
faluco@654
   644
		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654
   645
	}
faluco@654
   646
faluco@654
   647
	if (pStk->pCurRoot.size() == 1)
faluco@654
   648
	{
faluco@654
   649
		return 0;
faluco@654
   650
	}
faluco@654
   651
	pStk->pCurRoot.pop();
faluco@654
   652
faluco@654
   653
	return 1;
faluco@654
   654
}
faluco@654
   655
faluco@654
   656
static cell_t smn_KvRewind(IPluginContext *pCtx, const cell_t *params)
faluco@654
   657
{
faluco@654
   658
	Handle_t hndl = static_cast<Handle_t>(params[1]);
faluco@654
   659
	HandleError herr;
faluco@654
   660
	HandleSecurity sec;
faluco@654
   661
	KeyValueStack *pStk;
faluco@654
   662
faluco@654
   663
	sec.pOwner = NULL;
faluco@654
   664
	sec.pIdentity = g_pCoreIdent;
faluco@654
   665
faluco@654
   666
	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654
   667
		!= HandleError_None)
faluco@654
   668
	{
faluco@654
   669
		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654
   670
	}
faluco@654
   671
faluco@654
   672
	while (pStk->pCurRoot.size() > 1)
faluco@654
   673
	{
faluco@654
   674
		pStk->pCurRoot.pop();
faluco@654
   675
	}
faluco@654
   676
faluco@654
   677
	return 1;
faluco@654
   678
}
faluco@654
   679
faluco@654
   680
static cell_t smn_KvGetSectionName(IPluginContext *pCtx, const cell_t *params)
faluco@654
   681
{
faluco@654
   682
	Handle_t hndl = static_cast<Handle_t>(params[1]);
faluco@654
   683
	HandleError herr;
faluco@654
   684
	HandleSecurity sec;
faluco@654
   685
	KeyValueStack *pStk;
faluco@654
   686
faluco@654
   687
	sec.pOwner = NULL;
faluco@654
   688
	sec.pIdentity = g_pCoreIdent;
faluco@654
   689
faluco@654
   690
	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654
   691
		!= HandleError_None)
faluco@654
   692
	{
faluco@654
   693
		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654
   694
	}
faluco@654
   695
faluco@654
   696
	KeyValues *pSection = pStk->pCurRoot.front();
faluco@654
   697
	const char *name = pSection->GetName();
faluco@654
   698
	if (!name)
faluco@654
   699
	{
faluco@654
   700
		return 0;
faluco@654
   701
	}
faluco@654
   702
	pCtx->StringToLocalUTF8(params[2], params[3], name, NULL);
faluco@654
   703
faluco@654
   704
	return 1;
faluco@654
   705
}
faluco@654
   706
faluco@654
   707
static cell_t smn_KvSetSectionName(IPluginContext *pCtx, const cell_t *params)
faluco@654
   708
{
faluco@654
   709
	Handle_t hndl = static_cast<Handle_t>(params[1]);
faluco@654
   710
	HandleError herr;
faluco@654
   711
	HandleSecurity sec;
faluco@654
   712
	char *name;
faluco@654
   713
	KeyValueStack *pStk;
faluco@654
   714
faluco@654
   715
	sec.pOwner = NULL;
faluco@654
   716
	sec.pIdentity = g_pCoreIdent;
faluco@654
   717
faluco@654
   718
	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654
   719
		!= HandleError_None)
faluco@654
   720
	{
faluco@654
   721
		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654
   722
	}
faluco@654
   723
faluco@654
   724
	pCtx->LocalToString(params[2], &name);
faluco@654
   725
faluco@654
   726
	KeyValues *pSection = pStk->pCurRoot.front();
faluco@654
   727
	pSection->SetName(name);
faluco@654
   728
faluco@654
   729
	return 1;
faluco@654
   730
}
faluco@654
   731
faluco@654
   732
static cell_t smn_KvGetDataType(IPluginContext *pCtx, const cell_t *params)
faluco@654
   733
{
faluco@654
   734
	Handle_t hndl = static_cast<Handle_t>(params[1]);
faluco@654
   735
	HandleError herr;
faluco@654
   736
	HandleSecurity sec;
faluco@654
   737
	char *name;
faluco@654
   738
	KeyValueStack *pStk;
faluco@654
   739
faluco@654
   740
	sec.pOwner = NULL;
faluco@654
   741
	sec.pIdentity = g_pCoreIdent;
faluco@654
   742
faluco@654
   743
	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654
   744
		!= HandleError_None)
faluco@654
   745
	{
faluco@654
   746
		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654
   747
	}
faluco@654
   748
faluco@654
   749
	pCtx->LocalToString(params[2], &name);
faluco@654
   750
faluco@654
   751
	return pStk->pCurRoot.front()->GetDataType(name);
faluco@654
   752
}
faluco@654
   753
faluco@654
   754
static cell_t smn_KeyValuesToFile(IPluginContext *pCtx, const cell_t *params)
faluco@654
   755
{
faluco@654
   756
	Handle_t hndl = static_cast<Handle_t>(params[1]);
faluco@654
   757
	HandleError herr;
faluco@654
   758
	HandleSecurity sec;
faluco@654
   759
	char *path;
faluco@654
   760
	KeyValueStack *pStk;
faluco@654
   761
faluco@654
   762
	sec.pOwner = NULL;
faluco@654
   763
	sec.pIdentity = g_pCoreIdent;
faluco@654
   764
faluco@654
   765
	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654
   766
		!= HandleError_None)
faluco@654
   767
	{
faluco@654
   768
		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654
   769
	}
faluco@654
   770
faluco@654
   771
	pCtx->LocalToString(params[2], &path);
faluco@654
   772
faluco@654
   773
	char realpath[PLATFORM_MAX_PATH];
faluco@654
   774
	g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", path);
faluco@654
   775
faluco@654
   776
	return pStk->pCurRoot.front()->SaveToFile(basefilesystem, realpath);
faluco@654
   777
}
faluco@654
   778
faluco@654
   779
static cell_t smn_FileToKeyValues(IPluginContext *pCtx, const cell_t *params)
faluco@654
   780
{
faluco@654
   781
	Handle_t hndl = static_cast<Handle_t>(params[1]);
faluco@654
   782
	HandleError herr;
faluco@654
   783
	HandleSecurity sec;
faluco@654
   784
	char *path;
faluco@654
   785
	KeyValueStack *pStk;
ds@1944
   786
	KeyValues *kv;
faluco@654
   787
faluco@654
   788
	sec.pOwner = NULL;
faluco@654
   789
	sec.pIdentity = g_pCoreIdent;
faluco@654
   790
faluco@654
   791
	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654
   792
		!= HandleError_None)
faluco@654
   793
	{
faluco@654
   794
		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654
   795
	}
faluco@654
   796
faluco@654
   797
	pCtx->LocalToString(params[2], &path);
faluco@654
   798
faluco@654
   799
	char realpath[PLATFORM_MAX_PATH];
faluco@654
   800
	g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", path);
faluco@654
   801
ds@1944
   802
	kv = pStk->pCurRoot.front();
ds@1944
   803
	return g_HL2.KVLoadFromFile(kv, basefilesystem, realpath);
faluco@654
   804
}
faluco@654
   805
faluco@654
   806
static cell_t smn_KvSetEscapeSequences(IPluginContext *pCtx, const cell_t *params)
faluco@654
   807
{
faluco@654
   808
	Handle_t hndl = static_cast<Handle_t>(params[1]);
faluco@654
   809
	HandleError herr;
faluco@654
   810
	HandleSecurity sec;
faluco@654
   811
	KeyValueStack *pStk;
faluco@654
   812
faluco@654
   813
	sec.pOwner = NULL;
faluco@654
   814
	sec.pIdentity = g_pCoreIdent;
faluco@654
   815
faluco@654
   816
	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@654
   817
		!= HandleError_None)
faluco@654
   818
	{
faluco@654
   819
		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@654
   820
	}
faluco@654
   821
faluco@654
   822
	pStk->pCurRoot.front()->UsesEscapeSequences(params[2] ? true : false);
faluco@654
   823
faluco@654
   824
	return 1;
faluco@654
   825
}
faluco@654
   826
dvander@750
   827
static cell_t smn_KvNodesInStack(IPluginContext *pCtx, const cell_t *params)
dvander@750
   828
{
dvander@750
   829
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@750
   830
	HandleError herr;
dvander@750
   831
	HandleSecurity sec;
dvander@750
   832
	KeyValueStack *pStk;
dvander@750
   833
dvander@750
   834
	sec.pOwner = NULL;
dvander@750
   835
	sec.pIdentity = g_pCoreIdent;
dvander@750
   836
dvander@750
   837
	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
dvander@750
   838
		!= HandleError_None)
dvander@750
   839
	{
dvander@750
   840
		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
dvander@750
   841
	}
dvander@750
   842
dvander@751
   843
	return pStk->pCurRoot.size() - 1;
dvander@750
   844
}
dvander@750
   845
dvander@743
   846
static cell_t smn_KvDeleteThis(IPluginContext *pContext, const cell_t *params)
dvander@743
   847
{
dvander@743
   848
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@743
   849
	HandleError herr;
dvander@743
   850
	HandleSecurity sec;
dvander@743
   851
	KeyValueStack *pStk;
dvander@743
   852
dvander@743
   853
	sec.pOwner = NULL;
dvander@743
   854
	sec.pIdentity = g_pCoreIdent;
dvander@743
   855
dvander@743
   856
	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
dvander@743
   857
		!= HandleError_None)
dvander@743
   858
	{
dvander@743
   859
		return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
dvander@743
   860
	}
dvander@743
   861
dvander@743
   862
	if (pStk->pCurRoot.size() < 2)
dvander@743
   863
	{
dvander@743
   864
		return 0;
dvander@743
   865
	}
dvander@743
   866
dvander@743
   867
	KeyValues *pValues = pStk->pCurRoot.front();
dvander@743
   868
	pStk->pCurRoot.pop();
dvander@753
   869
	KeyValues *pRoot = pStk->pCurRoot.front();
dvander@743
   870
dvander@753
   871
	/* We have to manually verify this since Valve sucks
dvander@753
   872
	 * :TODO: make our own KeyValues.h file and make
dvander@753
   873
	 * the sub stuff private so we can do this ourselves!
dvander@753
   874
 	 */
dvander@753
   875
	KeyValues *sub = pRoot->GetFirstSubKey();
dvander@753
   876
	while (sub)
dvander@753
   877
	{
dvander@753
   878
		if (sub == pValues)
dvander@753
   879
		{
dvander@753
   880
			KeyValues *pNext = pValues->GetNextKey();
dvander@753
   881
			pRoot->RemoveSubKey(pValues);
dvander@753
   882
			pValues->deleteThis();
dvander@753
   883
			if (pNext)
dvander@753
   884
			{
dvander@753
   885
				pStk->pCurRoot.push(pNext);
dvander@753
   886
				return 1;
dvander@753
   887
			} else {
dvander@753
   888
				return -1;
dvander@753
   889
			}
dvander@753
   890
		}
dvander@753
   891
		sub = sub->GetNextKey();
dvander@753
   892
	}
dvander@753
   893
dvander@753
   894
	/* Push this back on :( */
dvander@753
   895
	pStk->pCurRoot.push(pValues);
dvander@753
   896
dvander@753
   897
	return 0;
dvander@743
   898
}
dvander@743
   899
dvander@743
   900
static cell_t smn_KvDeleteKey(IPluginContext *pContext, const cell_t *params)
dvander@743
   901
{
dvander@743
   902
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@743
   903
	HandleError herr;
dvander@743
   904
	HandleSecurity sec;
dvander@743
   905
	KeyValueStack *pStk;
dvander@743
   906
dvander@743
   907
	sec.pOwner = NULL;
dvander@743
   908
	sec.pIdentity = g_pCoreIdent;
dvander@743
   909
dvander@743
   910
	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
dvander@743
   911
		!= HandleError_None)
dvander@743
   912
	{
dvander@743
   913
		return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
dvander@743
   914
	}
dvander@743
   915
dvander@743
   916
	if (pStk->pCurRoot.size() < 2)
dvander@743
   917
	{
dvander@743
   918
		return 0;
dvander@743
   919
	}
dvander@743
   920
dvander@743
   921
	char *keyName;
dvander@743
   922
	pContext->LocalToString(params[2], &keyName);
dvander@743
   923
dvander@743
   924
	KeyValues *pRoot = pStk->pCurRoot.front();
dvander@743
   925
	KeyValues *pValues = pRoot->FindKey(keyName);
dvander@743
   926
	if (!pValues)
dvander@743
   927
	{
dvander@743
   928
		return 0;
dvander@743
   929
	}
dvander@743
   930
dvander@743
   931
	pRoot->RemoveSubKey(pValues);
dvander@743
   932
	pValues->deleteThis();
dvander@743
   933
dvander@743
   934
	return 1;
dvander@743
   935
}
dvander@743
   936
dvander@753
   937
static cell_t smn_KvSavePosition(IPluginContext *pContext, const cell_t *params)
dvander@753
   938
{
dvander@753
   939
	Handle_t hndl = static_cast<Handle_t>(params[1]);
dvander@753
   940
	HandleError herr;
dvander@753
   941
	HandleSecurity sec;
dvander@753
   942
	KeyValueStack *pStk;
dvander@753
   943
dvander@753
   944
	sec.pOwner = NULL;
dvander@753
   945
	sec.pIdentity = g_pCoreIdent;
dvander@753
   946
dvander@753
   947
	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
dvander@753
   948
		!= HandleError_None)
dvander@753
   949
	{
dvander@753
   950
		return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
dvander@753
   951
	}
dvander@753
   952
dvander@753
   953
	if (pStk->pCurRoot.size() < 2)
dvander@753
   954
	{
dvander@753
   955
		return 0;
dvander@753
   956
	}
dvander@753
   957
dvander@753
   958
	KeyValues *pValues = pStk->pCurRoot.front();
dvander@753
   959
	pStk->pCurRoot.push(pValues);
dvander@753
   960
dvander@753
   961
	return 1;
dvander@753
   962
}
dvander@753
   963
faluco@1401
   964
static cell_t smn_CopySubkeys(IPluginContext *pContext, const cell_t *params)
faluco@1401
   965
{
faluco@1401
   966
	Handle_t hndl_copied = static_cast<Handle_t>(params[1]);
faluco@1401
   967
	Handle_t hndl_parent = static_cast<Handle_t>(params[2]);
faluco@1401
   968
	HandleError herr;
faluco@1401
   969
	HandleSecurity sec;
faluco@1401
   970
	KeyValueStack *pStk_copied, *pStk_parent;
faluco@1401
   971
faluco@1401
   972
	sec.pOwner = NULL;
faluco@1401
   973
	sec.pIdentity = g_pCoreIdent;
faluco@1401
   974
faluco@1401
   975
	if ((herr=g_HandleSys.ReadHandle(hndl_copied, g_KeyValueType, &sec, (void **)&pStk_copied))
faluco@1401
   976
		!= HandleError_None)
faluco@1401
   977
	{
faluco@1401
   978
		return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl_copied, herr);
faluco@1401
   979
	}
faluco@1401
   980
	if ((herr=g_HandleSys.ReadHandle(hndl_parent, g_KeyValueType, &sec, (void **)&pStk_parent))
faluco@1401
   981
		!= HandleError_None)
faluco@1401
   982
	{
faluco@1401
   983
		return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl_parent, herr);
faluco@1401
   984
	}
faluco@1401
   985
faluco@1401
   986
	pStk_copied->pCurRoot.front()->CopySubkeys(pStk_parent->pCurRoot.front());
faluco@1401
   987
faluco@1401
   988
	return 1;
faluco@1401
   989
}
faluco@1401
   990
faluco@1401
   991
static cell_t smn_GetNameSymbol(IPluginContext *pContext, const cell_t *params)
faluco@1401
   992
{
faluco@1401
   993
	Handle_t hndl = static_cast<Handle_t>(params[1]);
faluco@1401
   994
	HandleError herr;
faluco@1401
   995
	HandleSecurity sec;
faluco@1401
   996
	KeyValueStack *pStk;
faluco@1401
   997
	cell_t *val;
faluco@1401
   998
	char *key;
faluco@1401
   999
faluco@1401
  1000
	sec.pOwner = NULL;
faluco@1401
  1001
	sec.pIdentity = g_pCoreIdent;
faluco@1401
  1002
faluco@1401
  1003
	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@1401
  1004
		!= HandleError_None)
faluco@1401
  1005
	{
faluco@1401
  1006
		return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@1401
  1007
	}
faluco@1401
  1008
faluco@1401
  1009
	if (pStk->pCurRoot.size() < 2)
faluco@1401
  1010
	{
faluco@1401
  1011
		return 0;
faluco@1401
  1012
	}
faluco@1401
  1013
faluco@1401
  1014
	pContext->LocalToString(params[2], &key);
faluco@1401
  1015
faluco@1401
  1016
	KeyValues *pKv = pStk->pCurRoot.front()->FindKey(key);
faluco@1401
  1017
	if (!pKv)
faluco@1401
  1018
	{
faluco@1401
  1019
		return 0;
faluco@1401
  1020
	}
faluco@1401
  1021
	pContext->LocalToPhysAddr(params[3], &val);
faluco@1401
  1022
	*val = pKv->GetNameSymbol();
faluco@1401
  1023
faluco@1401
  1024
	return 1;
faluco@1401
  1025
}
faluco@1401
  1026
faluco@1401
  1027
static cell_t smn_FindKeyById(IPluginContext *pContext, const cell_t *params)
faluco@1401
  1028
{
faluco@1401
  1029
	Handle_t hndl = static_cast<Handle_t>(params[1]);
faluco@1401
  1030
	HandleError herr;
faluco@1401
  1031
	HandleSecurity sec;
faluco@1401
  1032
	KeyValueStack *pStk;
faluco@1401
  1033
faluco@1401
  1034
	sec.pOwner = NULL;
faluco@1401
  1035
	sec.pIdentity = g_pCoreIdent;
faluco@1401
  1036
faluco@1401
  1037
	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
faluco@1401
  1038
		!= HandleError_None)
faluco@1401
  1039
	{
faluco@1401
  1040
		return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
faluco@1401
  1041
	}
faluco@1401
  1042
faluco@1401
  1043
	KeyValues *pKv = pStk->pCurRoot.front()->FindKey(params[2]);
faluco@1401
  1044
	if (!pKv)
faluco@1401
  1045
	{
faluco@1401
  1046
		return 0;
faluco@1401
  1047
	}
faluco@1401
  1048
faluco@1401
  1049
	pContext->StringToLocalUTF8(params[3], params[4], pKv->GetName(), NULL);
faluco@1401
  1050
faluco@1401
  1051
	return 1;
faluco@1401
  1052
}
faluco@1401
  1053
pred@1709
  1054
static cell_t smn_KvGetSectionSymbol(IPluginContext *pCtx, const cell_t *params)
pred@1709
  1055
{
pred@1709
  1056
	Handle_t hndl = static_cast<Handle_t>(params[1]);
pred@1709
  1057
	HandleError herr;
pred@1709
  1058
	HandleSecurity sec;
pred@1709
  1059
	KeyValueStack *pStk;
pred@1709
  1060
	cell_t *val;
pred@1709
  1061
pred@1709
  1062
	sec.pOwner = NULL;
pred@1709
  1063
	sec.pIdentity = g_pCoreIdent;
pred@1709
  1064
pred@1709
  1065
	if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
pred@1709
  1066
		!= HandleError_None)
pred@1709
  1067
	{
pred@1709
  1068
		return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
pred@1709
  1069
	}
pred@1709
  1070
pred@1709
  1071
	KeyValues *pSection = pStk->pCurRoot.front();
pred@1709
  1072
pred@1710
  1073
	pCtx->LocalToPhysAddr(params[2], &val);
pred@1709
  1074
	*val = pSection->GetNameSymbol();
pred@1709
  1075
pred@1709
  1076
	if (!*val)
pred@1709
  1077
	{
pred@1709
  1078
		return 0;
pred@1709
  1079
	}
pred@1709
  1080
pred@1709
  1081
	return 1;
pred@1709
  1082
}
pred@1709
  1083
faluco@703
  1084
static KeyValueNatives s_KeyValueNatives;
faluco@654
  1085
faluco@654
  1086
REGISTER_NATIVES(keyvaluenatives)
faluco@654
  1087
{
faluco@654
  1088
	{"KvSetString",				smn_KvSetString},
faluco@654
  1089
	{"KvSetNum",				smn_KvSetNum},
dvander@816
  1090
	{"KvSetUInt64",				smn_KvSetUInt64},
faluco@654
  1091
	{"KvSetFloat",				smn_KvSetFloat},
faluco@654
  1092
	{"KvSetColor",				smn_KvSetColor},
faluco@654
  1093
	{"KvGetString",				smn_KvGetString},
faluco@654
  1094
	{"KvGetNum",				smn_KvGetNum},
faluco@654
  1095
	{"KvGetFloat",				smn_KvGetFloat},
faluco@654
  1096
	{"KvGetColor",				smn_KvGetColor},
dvander@816
  1097
	{"KvGetUInt64",				smn_KvGetUInt64},
faluco@654
  1098
	{"CreateKeyValues",			smn_CreateKeyValues},
faluco@654
  1099
	{"KvJumpToKey",				smn_KvJumpToKey},
pred@1707
  1100
	{"KvJumpToKeySymbol",		smn_KvJumpToKeySymbol},
dvander@753
  1101
	{"KvGotoNextKey",			smn_KvGotoNextKey},
dvander@753
  1102
	{"KvGotoFirstSubKey",		smn_KvGotoFirstSubKey},
faluco@654
  1103
	{"KvGoBack",				smn_KvGoBack},
faluco@654
  1104
	{"KvRewind",				smn_KvRewind},
faluco@654
  1105
	{"KvGetSectionName",		smn_KvGetSectionName},
faluco@654
  1106
	{"KvSetSectionName",		smn_KvSetSectionName},
faluco@654
  1107
	{"KvGetDataType",			smn_KvGetDataType},
faluco@654
  1108
	{"KeyValuesToFile",			smn_KeyValuesToFile},
faluco@654
  1109
	{"FileToKeyValues",			smn_FileToKeyValues},
faluco@654
  1110
	{"KvSetEscapeSequences",	smn_KvSetEscapeSequences},
dvander@743
  1111
	{"KvDeleteThis",			smn_KvDeleteThis},
dvander@743
  1112
	{"KvDeleteKey",				smn_KvDeleteKey},
dvander@750
  1113
	{"KvNodesInStack",			smn_KvNodesInStack},
dvander@753
  1114
	{"KvSavePosition",			smn_KvSavePosition},
faluco@1401
  1115
	{"KvCopySubkeys",			smn_CopySubkeys},
faluco@1401
  1116
	{"KvFindKeyById",			smn_FindKeyById},
faluco@1401
  1117
	{"KvGetNameSymbol",			smn_GetNameSymbol},
pred@1709
  1118
	{"KvGetSectionSymbol",		smn_KvGetSectionSymbol},
faluco@1734
  1119
	{"KvGetVector",				smn_KvGetVector},
faluco@1734
  1120
	{"KvSetVector",				smn_KvSetVector},
faluco@654
  1121
	{NULL,						NULL}
faluco@654
  1122
};