extensions/clientprefs/extension.cpp
author Matt Woodrow <pred@alliedmods.net>
Sun Jul 06 03:30:06 2008 +0000 (2008-07-06)
changeset 2165 ca3757e676f6
parent 2135 2c56e1550aaa
child 2207 3a97a56ded62
permissions -rw-r--r--
Fixed requiring dependencies at the wrong time.
pred@2009
     1
/**
pred@2009
     2
 * vim: set ts=4 :
pred@2009
     3
 * =============================================================================
pred@2009
     4
 * SourceMod Client Preferences Extension
pred@2009
     5
 * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
pred@2009
     6
 * =============================================================================
pred@2009
     7
 *
pred@2009
     8
 * This program is free software; you can redistribute it and/or modify it under
pred@2009
     9
 * the terms of the GNU General Public License, version 3.0, as published by the
pred@2009
    10
 * Free Software Foundation.
pred@2009
    11
 * 
pred@2009
    12
 * This program is distributed in the hope that it will be useful, but WITHOUT
pred@2009
    13
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
pred@2009
    14
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
pred@2009
    15
 * details.
pred@2009
    16
 *
pred@2009
    17
 * You should have received a copy of the GNU General Public License along with
pred@2009
    18
 * this program.  If not, see <http://www.gnu.org/licenses/>.
pred@2009
    19
 *
pred@2009
    20
 * As a special exception, AlliedModders LLC gives you permission to link the
pred@2009
    21
 * code of this program (as well as its derivative works) to "Half-Life 2," the
pred@2009
    22
 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
pred@2009
    23
 * by the Valve Corporation.  You must obey the GNU General Public License in
pred@2009
    24
 * all respects for all other code used.  Additionally, AlliedModders LLC grants
pred@2009
    25
 * this exception to all derivative works.  AlliedModders LLC defines further
pred@2009
    26
 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
pred@2009
    27
 * or <http://www.sourcemod.net/license.php>.
pred@2009
    28
 *
pred@2009
    29
 * Version: $Id$
pred@2009
    30
 */
pred@2009
    31
pred@2009
    32
#include "extension.h"
pred@2009
    33
pred@2009
    34
/**
pred@2009
    35
 * @file extension.cpp
pred@2009
    36
 * @brief Implement extension code here.
pred@2009
    37
 */
pred@2009
    38
pred@2009
    39
ClientPrefs g_ClientPrefs;		/**< Global singleton for extension's main interface */
pred@2009
    40
pred@2009
    41
SMEXT_LINK(&g_ClientPrefs);
pred@2009
    42
pred@2009
    43
HandleType_t g_CookieType = 0;
pred@2009
    44
CookieTypeHandler g_CookieTypeHandler;
pred@2009
    45
pred@2048
    46
HandleType_t g_CookieIterator = 0;
pred@2048
    47
CookieIteratorHandler g_CookieIteratorHandler;
pred@2048
    48
pred@2009
    49
pred@2009
    50
int driver = 0;
pred@2009
    51
pred@2009
    52
bool ClientPrefs::SDK_OnLoad(char *error, size_t maxlength, bool late)
pred@2009
    53
{	
pred@2009
    54
	const DatabaseInfo *DBInfo = dbi->FindDatabaseConf("clientprefs");
pred@2009
    55
pred@2009
    56
	if (DBInfo == NULL)
pred@2009
    57
	{
pred@2009
    58
		DBInfo = dbi->FindDatabaseConf("default");
pred@2009
    59
pred@2009
    60
		if (DBInfo == NULL)
pred@2009
    61
		{
pred@2009
    62
			snprintf(error, maxlength, "Could not find \"clientprefs\" or \"default\" database configs");
pred@2009
    63
			return false;
pred@2009
    64
		}
pred@2009
    65
pred@2009
    66
	}
pred@2009
    67
pred@2009
    68
	if (DBInfo->driver[0] != '\0')
pred@2009
    69
	{
pred@2009
    70
		Driver = dbi->FindOrLoadDriver(DBInfo->driver);
pred@2009
    71
	}
pred@2009
    72
	else
pred@2009
    73
	{
pred@2009
    74
		Driver = dbi->GetDefaultDriver();
pred@2009
    75
	}
pred@2009
    76
pred@2009
    77
	if (Driver == NULL)
pred@2009
    78
	{
pred@2009
    79
		snprintf(error, maxlength, "Could not load DB Driver \"%s\"", DBInfo->driver);
pred@2009
    80
		return false;
pred@2009
    81
	}
pred@2009
    82
pred@2009
    83
	Database = Driver->Connect(DBInfo, true, error, maxlength);
pred@2009
    84
pred@2009
    85
	if (Database == NULL)
pred@2009
    86
	{
pred@2009
    87
		return false;
pred@2009
    88
	}
pred@2009
    89
dvander@2135
    90
	dbi->AddDependency(myself, Driver);
dvander@2135
    91
pred@2009
    92
	const char *identifier = Driver->GetIdentifier();
pred@2009
    93
pred@2009
    94
	if (strcmp(identifier, "sqlite") == 0)
pred@2009
    95
	{
pred@2009
    96
		driver = DRIVER_SQLITE;
pred@2087
    97
pred@2087
    98
		TQueryOp *op = new TQueryOp(
pred@2087
    99
						Database, 
pred@2104
   100
						"CREATE TABLE IF NOT EXISTS sm_cookies  \
pred@2087
   101
						( \
pred@2087
   102
							id INTEGER PRIMARY KEY AUTOINCREMENT, \
pred@2087
   103
							name varchar(30) NOT NULL UNIQUE, \
pred@2087
   104
							description varchar(255), \
pred@2087
   105
							access INTEGER \
pred@2087
   106
						)", 
pred@2087
   107
						Query_CreateTable, 
pred@2087
   108
						0);
pred@2087
   109
pred@2087
   110
		dbi->AddToThreadQueue(op, PrioQueue_Normal);
pred@2087
   111
pred@2087
   112
		op = new TQueryOp(
pred@2087
   113
						Database, 
pred@2104
   114
						"CREATE TABLE IF NOT EXISTS sm_cookie_cache \
pred@2087
   115
						( \
pred@2087
   116
							player varchar(65) NOT NULL, \
pred@2087
   117
							cookie_id int(10) NOT NULL, \
pred@2087
   118
							value varchar(100), \
pred@2087
   119
							timestamp int, \
pred@2087
   120
							PRIMARY KEY (player, cookie_id) \
pred@2087
   121
						)", 
pred@2087
   122
						Query_CreateTable, 
pred@2087
   123
						0);
pred@2087
   124
pred@2087
   125
		dbi->AddToThreadQueue(op, PrioQueue_Normal);
pred@2009
   126
	}
pred@2009
   127
	else if (strcmp(identifier, "mysql") == 0)
pred@2009
   128
	{
pred@2009
   129
		driver = DRIVER_MYSQL;
pred@2087
   130
pred@2087
   131
		TQueryOp *op = new TQueryOp(
pred@2087
   132
						Database, 
pred@2104
   133
						"CREATE TABLE IF NOT EXISTS sm_cookies \
pred@2087
   134
						( \
pred@2087
   135
							id INTEGER unsigned NOT NULL auto_increment, \
pred@2087
   136
							name varchar(30) NOT NULL UNIQUE, \
pred@2087
   137
							description varchar(255), \
pred@2087
   138
							access INTEGER, \
pred@2087
   139
							PRIMARY KEY (id) \
pred@2087
   140
						)", 
pred@2087
   141
						Query_CreateTable, 
pred@2087
   142
						0);
pred@2087
   143
pred@2087
   144
		dbi->AddToThreadQueue(op, PrioQueue_Normal);
pred@2087
   145
pred@2087
   146
		op = new TQueryOp(
pred@2087
   147
						Database, 
pred@2104
   148
						"CREATE TABLE IF NOT EXISTS sm_cookie_cache \
pred@2087
   149
						( \
pred@2087
   150
							player varchar(65) NOT NULL, \
pred@2087
   151
							cookie_id int(10) NOT NULL, \
pred@2087
   152
							value varchar(100), \
pred@2087
   153
							timestamp int NOT NULL, \
pred@2087
   154
							PRIMARY KEY (player, cookie_id) \
pred@2087
   155
						)", 
pred@2087
   156
						Query_CreateTable, 
pred@2087
   157
						0);
pred@2087
   158
pred@2087
   159
		dbi->AddToThreadQueue(op, PrioQueue_Normal);
pred@2009
   160
	}
pred@2009
   161
	else
pred@2009
   162
	{
pred@2009
   163
		snprintf(error, maxlength, "Unsupported driver \"%s\"", identifier);
pred@2009
   164
		return false;
pred@2009
   165
	}
pred@2009
   166
pred@2087
   167
pred@2087
   168
pred@2009
   169
	sharesys->AddNatives(myself, g_ClientPrefNatives);
pred@2009
   170
	sharesys->RegisterLibrary(myself, "clientprefs");
pred@2048
   171
	g_CookieManager.cookieDataLoadedForward = forwards->CreateForward("OnClientCookiesCached", ET_Ignore, 1, NULL, Param_Cell);
pred@2009
   172
pred@2009
   173
	g_CookieType = handlesys->CreateType("Cookie", 
pred@2009
   174
		&g_CookieTypeHandler, 
pred@2009
   175
		0, 
pred@2009
   176
		NULL, 
pred@2009
   177
		NULL, 
pred@2009
   178
		myself->GetIdentity(), 
pred@2009
   179
		NULL);
pred@2009
   180
pred@2048
   181
	g_CookieIterator = handlesys->CreateType("CookieIterator", 
pred@2048
   182
		&g_CookieIteratorHandler, 
pred@2048
   183
		0, 
pred@2048
   184
		NULL, 
pred@2048
   185
		NULL, 
pred@2048
   186
		myself->GetIdentity(), 
pred@2048
   187
		NULL);
pred@2048
   188
pred@2048
   189
	IMenuStyle *style = menus->GetDefaultStyle();
pred@2048
   190
	g_CookieManager.clientMenu = style->CreateMenu(&g_Handler, NULL);
pred@2048
   191
	g_CookieManager.clientMenu->SetDefaultTitle("Client Settings:");
pred@2048
   192
pred@2048
   193
	plsys->AddPluginsListener(&g_CookieManager);
pred@2048
   194
pred@2048
   195
	phrases = translator->CreatePhraseCollection();
pred@2048
   196
	phrases->AddPhraseFile("clientprefs.phrases");
pred@2048
   197
	phrases->AddPhraseFile("common.phrases");
pred@2048
   198
pred@2009
   199
	return true;
pred@2009
   200
}
pred@2009
   201
pred@2009
   202
void ClientPrefs::SDK_OnAllLoaded()
pred@2009
   203
{
pred@2009
   204
	playerhelpers->AddClientListener(&g_CookieManager);
pred@2009
   205
}
pred@2009
   206
dvander@2135
   207
bool ClientPrefs::QueryInterfaceDrop(SMInterface *pInterface)
dvander@2135
   208
{
dvander@2135
   209
	if ((void *)pInterface == (void *)(Database->GetDriver()))
dvander@2135
   210
	{
dvander@2135
   211
		return false;
dvander@2135
   212
	}
dvander@2135
   213
dvander@2135
   214
	return true;
dvander@2135
   215
}
dvander@2135
   216
dvander@2135
   217
void ClientPrefs::NotifyInterfaceDrop(SMInterface *pInterface)
dvander@2135
   218
{
dvander@2135
   219
	if (Database != NULL && (void *)pInterface == (void *)(Database->GetDriver()))
dvander@2135
   220
	{
dvander@2135
   221
		Database->Close();
dvander@2135
   222
		Database = NULL;
dvander@2135
   223
	}
dvander@2135
   224
}
dvander@2135
   225
pred@2009
   226
void ClientPrefs::SDK_OnUnload()
pred@2009
   227
{
pred@2009
   228
	handlesys->RemoveType(g_CookieType, myself->GetIdentity());
pred@2131
   229
	handlesys->RemoveType(g_CookieIterator, myself->GetIdentity());
pred@2009
   230
pred@2009
   231
	g_CookieManager.Unload();
pred@2009
   232
dvander@2135
   233
	if (Database != NULL)
dvander@2135
   234
	{
dvander@2135
   235
		Database->Close();
dvander@2135
   236
	}
pred@2009
   237
pred@2048
   238
	forwards->ReleaseForward(g_CookieManager.cookieDataLoadedForward);
pred@2048
   239
pred@2048
   240
	g_CookieManager.clientMenu->Destroy();
pred@2131
   241
pred@2131
   242
	phrases->Destroy();
pred@2131
   243
pred@2131
   244
	plsys->RemovePluginsListener(&g_CookieManager);
pred@2131
   245
	playerhelpers->RemoveClientListener(&g_CookieManager);
pred@2048
   246
}
pred@2048
   247
pred@2048
   248
size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...)
pred@2048
   249
{
pred@2048
   250
	va_list ap;
pred@2048
   251
	va_start(ap, fmt);
pred@2048
   252
	size_t len = vsnprintf(buffer, maxlength, fmt, ap);
pred@2048
   253
	va_end(ap);
pred@2048
   254
pred@2048
   255
	if (len >= maxlength)
pred@2048
   256
	{
pred@2048
   257
		buffer[maxlength - 1] = '\0';
pred@2048
   258
		return (maxlength - 1);
pred@2048
   259
	}
pred@2048
   260
	else
pred@2048
   261
	{
pred@2048
   262
		return len;
pred@2048
   263
	}
pred@2048
   264
}
pred@2048
   265
pred@2048
   266
bool Translate(char *buffer, 
pred@2048
   267
				   size_t maxlength,
pred@2048
   268
				   const char *format,
pred@2048
   269
				   unsigned int numparams,
pred@2048
   270
				   size_t *pOutLength,
pred@2048
   271
				   ...)
pred@2048
   272
{
pred@2048
   273
	va_list ap;
pred@2048
   274
	unsigned int i;
pred@2048
   275
	const char *fail_phrase;
pred@2048
   276
	void *params[MAX_TRANSLATE_PARAMS];
pred@2048
   277
pred@2048
   278
	if (numparams > MAX_TRANSLATE_PARAMS)
pred@2048
   279
	{
pred@2048
   280
		assert(false);
pred@2048
   281
		return false;
pred@2048
   282
	}
pred@2048
   283
pred@2048
   284
	va_start(ap, pOutLength);
pred@2048
   285
	for (i = 0; i < numparams; i++)
pred@2048
   286
	{
pred@2048
   287
		params[i] = va_arg(ap, void *);
pred@2048
   288
	}
pred@2048
   289
	va_end(ap);
pred@2048
   290
pred@2048
   291
	if (!g_ClientPrefs.phrases->FormatString(buffer,
pred@2048
   292
		maxlength, 
pred@2048
   293
		format, 
pred@2048
   294
		params,
pred@2048
   295
		numparams,
pred@2048
   296
		pOutLength,
pred@2048
   297
		&fail_phrase))
pred@2048
   298
	{
pred@2048
   299
		if (fail_phrase != NULL)
pred@2048
   300
		{
pred@2048
   301
			g_pSM->LogError(myself, "[SM] Could not find core phrase: %s", fail_phrase);
pred@2048
   302
		}
pred@2048
   303
		else
pred@2048
   304
		{
pred@2048
   305
			g_pSM->LogError(myself, "[SM] Unknown fatal error while translating a core phrase.");
pred@2048
   306
		}
pred@2048
   307
pred@2048
   308
		return false;
pred@2048
   309
	}
pred@2048
   310
pred@2048
   311
	return true;
pred@2009
   312
}
pred@2009
   313
pred@2009
   314
pred@2048
   315