extensions/clientprefs/extension.cpp
author Matt Woodrow <pred@alliedmods.net>
Mon May 26 07:51:36 2008 +0000 (2008-05-26)
changeset 2087 c1ac266bd660
parent 2048 2454ff4d6afb
child 2104 9e9fe838efeb
permissions -rw-r--r--
Fixed amb1690 - Client prefs tables now create themselves.
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
pred@2009
    90
	const char *identifier = Driver->GetIdentifier();
pred@2009
    91
pred@2009
    92
	if (strcmp(identifier, "sqlite") == 0)
pred@2009
    93
	{
pred@2009
    94
		driver = DRIVER_SQLITE;
pred@2087
    95
pred@2087
    96
		TQueryOp *op = new TQueryOp(
pred@2087
    97
						Database, 
pred@2087
    98
						"CREATE TABLE sm_cookies IF NOT EXISTS \
pred@2087
    99
						( \
pred@2087
   100
							id INTEGER PRIMARY KEY AUTOINCREMENT, \
pred@2087
   101
							name varchar(30) NOT NULL UNIQUE, \
pred@2087
   102
							description varchar(255), \
pred@2087
   103
							access INTEGER \
pred@2087
   104
						)", 
pred@2087
   105
						Query_CreateTable, 
pred@2087
   106
						0);
pred@2087
   107
pred@2087
   108
		dbi->AddToThreadQueue(op, PrioQueue_Normal);
pred@2087
   109
pred@2087
   110
		op = new TQueryOp(
pred@2087
   111
						Database, 
pred@2087
   112
						"CREATE TABLE sm_cookie_cache IF NOT EXISTS \
pred@2087
   113
						( \
pred@2087
   114
							player varchar(65) NOT NULL, \
pred@2087
   115
							cookie_id int(10) NOT NULL, \
pred@2087
   116
							value varchar(100), \
pred@2087
   117
							timestamp int, \
pred@2087
   118
							PRIMARY KEY (player, cookie_id) \
pred@2087
   119
						)", 
pred@2087
   120
						Query_CreateTable, 
pred@2087
   121
						0);
pred@2087
   122
pred@2087
   123
		dbi->AddToThreadQueue(op, PrioQueue_Normal);
pred@2009
   124
	}
pred@2009
   125
	else if (strcmp(identifier, "mysql") == 0)
pred@2009
   126
	{
pred@2009
   127
		driver = DRIVER_MYSQL;
pred@2087
   128
pred@2087
   129
		TQueryOp *op = new TQueryOp(
pred@2087
   130
						Database, 
pred@2087
   131
						"CREATE TABLE sm_cookies IF NOT EXISTS \
pred@2087
   132
						( \
pred@2087
   133
							id INTEGER unsigned NOT NULL auto_increment, \
pred@2087
   134
							name varchar(30) NOT NULL UNIQUE, \
pred@2087
   135
							description varchar(255), \
pred@2087
   136
							access INTEGER, \
pred@2087
   137
							PRIMARY KEY (id) \
pred@2087
   138
						)", 
pred@2087
   139
						Query_CreateTable, 
pred@2087
   140
						0);
pred@2087
   141
pred@2087
   142
		dbi->AddToThreadQueue(op, PrioQueue_Normal);
pred@2087
   143
pred@2087
   144
		op = new TQueryOp(
pred@2087
   145
						Database, 
pred@2087
   146
						"CREATE TABLE sm_cookie_cache IF NOT EXISTS \
pred@2087
   147
						( \
pred@2087
   148
							player varchar(65) NOT NULL, \
pred@2087
   149
							cookie_id int(10) NOT NULL, \
pred@2087
   150
							value varchar(100), \
pred@2087
   151
							timestamp int NOT NULL, \
pred@2087
   152
							PRIMARY KEY (player, cookie_id) \
pred@2087
   153
						)", 
pred@2087
   154
						Query_CreateTable, 
pred@2087
   155
						0);
pred@2087
   156
pred@2087
   157
		dbi->AddToThreadQueue(op, PrioQueue_Normal);
pred@2009
   158
	}
pred@2009
   159
	else
pred@2009
   160
	{
pred@2009
   161
		snprintf(error, maxlength, "Unsupported driver \"%s\"", identifier);
pred@2009
   162
		return false;
pred@2009
   163
	}
pred@2009
   164
pred@2087
   165
pred@2087
   166
pred@2009
   167
	sharesys->AddNatives(myself, g_ClientPrefNatives);
pred@2009
   168
	sharesys->RegisterLibrary(myself, "clientprefs");
pred@2048
   169
	g_CookieManager.cookieDataLoadedForward = forwards->CreateForward("OnClientCookiesCached", ET_Ignore, 1, NULL, Param_Cell);
pred@2009
   170
pred@2009
   171
	g_CookieType = handlesys->CreateType("Cookie", 
pred@2009
   172
		&g_CookieTypeHandler, 
pred@2009
   173
		0, 
pred@2009
   174
		NULL, 
pred@2009
   175
		NULL, 
pred@2009
   176
		myself->GetIdentity(), 
pred@2009
   177
		NULL);
pred@2009
   178
pred@2048
   179
	g_CookieIterator = handlesys->CreateType("CookieIterator", 
pred@2048
   180
		&g_CookieIteratorHandler, 
pred@2048
   181
		0, 
pred@2048
   182
		NULL, 
pred@2048
   183
		NULL, 
pred@2048
   184
		myself->GetIdentity(), 
pred@2048
   185
		NULL);
pred@2048
   186
pred@2048
   187
	IMenuStyle *style = menus->GetDefaultStyle();
pred@2048
   188
	g_CookieManager.clientMenu = style->CreateMenu(&g_Handler, NULL);
pred@2048
   189
	g_CookieManager.clientMenu->SetDefaultTitle("Client Settings:");
pred@2048
   190
pred@2048
   191
	plsys->AddPluginsListener(&g_CookieManager);
pred@2048
   192
pred@2048
   193
	phrases = translator->CreatePhraseCollection();
pred@2048
   194
	phrases->AddPhraseFile("clientprefs.phrases");
pred@2048
   195
	phrases->AddPhraseFile("common.phrases");
pred@2048
   196
pred@2048
   197
pred@2009
   198
	return true;
pred@2009
   199
}
pred@2009
   200
pred@2009
   201
void ClientPrefs::SDK_OnAllLoaded()
pred@2009
   202
{
pred@2009
   203
	playerhelpers->AddClientListener(&g_CookieManager);
pred@2009
   204
}
pred@2009
   205
pred@2009
   206
void ClientPrefs::SDK_OnUnload()
pred@2009
   207
{
pred@2009
   208
	handlesys->RemoveType(g_CookieType, myself->GetIdentity());
pred@2009
   209
pred@2009
   210
	g_CookieManager.Unload();
pred@2009
   211
pred@2009
   212
	Database->Close();
pred@2009
   213
pred@2048
   214
	forwards->ReleaseForward(g_CookieManager.cookieDataLoadedForward);
pred@2048
   215
pred@2048
   216
	g_CookieManager.clientMenu->Destroy();
pred@2048
   217
}
pred@2048
   218
pred@2048
   219
size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...)
pred@2048
   220
{
pred@2048
   221
	va_list ap;
pred@2048
   222
	va_start(ap, fmt);
pred@2048
   223
	size_t len = vsnprintf(buffer, maxlength, fmt, ap);
pred@2048
   224
	va_end(ap);
pred@2048
   225
pred@2048
   226
	if (len >= maxlength)
pred@2048
   227
	{
pred@2048
   228
		buffer[maxlength - 1] = '\0';
pred@2048
   229
		return (maxlength - 1);
pred@2048
   230
	}
pred@2048
   231
	else
pred@2048
   232
	{
pred@2048
   233
		return len;
pred@2048
   234
	}
pred@2048
   235
}
pred@2048
   236
pred@2048
   237
bool Translate(char *buffer, 
pred@2048
   238
				   size_t maxlength,
pred@2048
   239
				   const char *format,
pred@2048
   240
				   unsigned int numparams,
pred@2048
   241
				   size_t *pOutLength,
pred@2048
   242
				   ...)
pred@2048
   243
{
pred@2048
   244
	va_list ap;
pred@2048
   245
	unsigned int i;
pred@2048
   246
	const char *fail_phrase;
pred@2048
   247
	void *params[MAX_TRANSLATE_PARAMS];
pred@2048
   248
pred@2048
   249
	if (numparams > MAX_TRANSLATE_PARAMS)
pred@2048
   250
	{
pred@2048
   251
		assert(false);
pred@2048
   252
		return false;
pred@2048
   253
	}
pred@2048
   254
pred@2048
   255
	va_start(ap, pOutLength);
pred@2048
   256
	for (i = 0; i < numparams; i++)
pred@2048
   257
	{
pred@2048
   258
		params[i] = va_arg(ap, void *);
pred@2048
   259
	}
pred@2048
   260
	va_end(ap);
pred@2048
   261
pred@2048
   262
	if (!g_ClientPrefs.phrases->FormatString(buffer,
pred@2048
   263
		maxlength, 
pred@2048
   264
		format, 
pred@2048
   265
		params,
pred@2048
   266
		numparams,
pred@2048
   267
		pOutLength,
pred@2048
   268
		&fail_phrase))
pred@2048
   269
	{
pred@2048
   270
		if (fail_phrase != NULL)
pred@2048
   271
		{
pred@2048
   272
			g_pSM->LogError(myself, "[SM] Could not find core phrase: %s", fail_phrase);
pred@2048
   273
		}
pred@2048
   274
		else
pred@2048
   275
		{
pred@2048
   276
			g_pSM->LogError(myself, "[SM] Unknown fatal error while translating a core phrase.");
pred@2048
   277
		}
pred@2048
   278
pred@2048
   279
		return false;
pred@2048
   280
	}
pred@2048
   281
pred@2048
   282
	return true;
pred@2009
   283
}
pred@2009
   284
pred@2009
   285
pred@2048
   286