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