Move dlls/ to modules/

This commit is contained in:
xPaw
2015-03-13 15:18:47 +02:00
parent 54c978addb
commit e09f434ed8
365 changed files with 2233 additions and 2233 deletions

47
modules/sqlite/AMBuilder Normal file
View File

@ -0,0 +1,47 @@
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
import os.path
binary = AMXX.MetaModule(builder, 'sqlite')
binary.compiler.cxxincludes += [
os.path.join(builder.currentSourcePath, 'sqlitepp'),
os.path.join(builder.currentSourcePath, 'thread'),
os.path.join(builder.currentSourcePath, '..', '..', 'third_party', 'sqlite'),
]
binary.compiler.defines += [
'SM_DEFAULT_THREADER',
'HAVE_STDINT_H',
]
if builder.target_platform is 'linux' or builder.target_platform is 'mac':
binary.compiler.defines += ['stricmp=strcasecmp']
binary.compiler.postlink += ['-lpthread']
binary.sources += [
'basic_sql.cpp',
'handles.cpp',
'module.cpp',
'threading.cpp',
'../../public/sdk/amxxmodule.cpp',
'oldcompat_sql.cpp',
'thread/BaseWorker.cpp',
'thread/ThreadWorker.cpp',
'sqlitepp/SqliteQuery.cpp',
'sqlitepp/SqliteResultSet.cpp',
'sqlitepp/SqliteDatabase.cpp',
'sqlitepp/SqliteDriver.cpp',
'../../third_party/sqlite/sqlite3.c',
]
if builder.target_platform == 'windows':
binary.sources += [
'thread/WinThreads.cpp',
]
else:
binary.sources += [
'thread/PosixThreads.cpp',
]
if builder.target_platform == 'windows':
binary.sources += ['version.rc']
AMXX.modules += [builder.Add(binary)]

147
modules/sqlite/Makefile Normal file
View File

@ -0,0 +1,147 @@
# (C)2004-2013 AMX Mod X Development Team
# Makefile written by David "BAILOPAN" Anderson
###########################################
### EDIT THESE PATHS FOR YOUR OWN SETUP ###
###########################################
HLSDK = ../../../hlsdk
MM_ROOT = ../../../metamod/metamod
PUBLIC_ROOT = ../../public
THIRD_PARTY = $(PUBLIC_ROOT)/third_party
SQL = $(THIRD_PARTY)/sqlite
#####################################
### EDIT BELOW FOR OTHER PROJECTS ###
#####################################
PROJECT = sqlite
OBJECTS = basic_sql.cpp handles.cpp module.cpp threading.cpp amxxmodule.cpp oldcompat_sql.cpp \
thread/BaseWorker.cpp thread/ThreadWorker.cpp thread/PosixThreads.cpp \
sqlitepp/SqliteQuery.cpp sqlitepp/SqliteResultSet.cpp sqlitepp/SqliteDatabase.cpp \
sqlitepp/SqliteDriver.cpp
OBJECTS += $(SQL)/sqlite3.c
##############################################
### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
##############################################
C_OPT_FLAGS = -DNDEBUG -O3 -funroll-loops -fomit-frame-pointer -pipe
C_DEBUG_FLAGS = -D_DEBUG -DDEBUG -g -ggdb3
C_GCC4_FLAGS = -fvisibility=hidden
CPP_GCC4_FLAGS = -fvisibility-inlines-hidden
CPP = gcc
CPP_OSX = clang
LINK =
INCLUDE = -I. -I$(PUBLIC_ROOT) -I$(PUBLIC_ROOT)/sdk -I$(PUBLIC_ROOT)/amtl \
-I$(HLSDK) -I$(HLSDK)/public -I$(HLSDK)/common -I$(HLSDK)/dlls -I$(HLSDK)/engine -I$(HLSDK)/game_shared -I$(HLSDK)/pm_shared\
-I$(SQL) -Isqlitepp -Ithread \
-I$(MM_ROOT)
################################################
### DO NOT EDIT BELOW HERE FOR MOST PROJECTS ###
################################################
OS := $(shell uname -s)
ifeq "$(OS)" "Darwin"
CPP = $(CPP_OSX)
LIB_EXT = dylib
LIB_SUFFIX = _amxx
CFLAGS += -DOSX
LINK += -dynamiclib -lstdc++ -mmacosx-version-min=10.5
else
LIB_EXT = so
LIB_SUFFIX = _amxx_i386
CFLAGS += -DLINUX
LINK += -shared
endif
LINK += -m32 -lm -ldl -lpthread
CFLAGS += -DSM_DEFAULT_THREADER -DPAWN_CELL_SIZE=32 -DJIT -DASM32 -DHAVE_STDINT_H \
-Dstricmp=strcasecmp -fno-strict-aliasing -m32 -Wall -Werror
CPPFLAGS += -fno-exceptions -fno-rtti
BINARY = $(PROJECT)$(LIB_SUFFIX).$(LIB_EXT)
ifeq "$(DEBUG)" "true"
BIN_DIR = Debug
CFLAGS += $(C_DEBUG_FLAGS)
else
BIN_DIR = Release
CFLAGS += $(C_OPT_FLAGS)
LINK += -s
endif
IS_CLANG := $(shell $(CPP) --version | head -1 | grep clang > /dev/null && echo "1" || echo "0")
ifeq "$(IS_CLANG)" "1"
CPP_MAJOR := $(shell $(CPP) --version | grep clang | sed "s/.*version \([0-9]\)*\.[0-9]*.*/\1/")
CPP_MINOR := $(shell $(CPP) --version | grep clang | sed "s/.*version [0-9]*\.\([0-9]\)*.*/\1/")
else
CPP_MAJOR := $(shell $(CPP) -dumpversion >&1 | cut -b1)
CPP_MINOR := $(shell $(CPP) -dumpversion >&1 | cut -b3)
endif
# Clang || GCC >= 4
ifeq "$(shell expr $(IS_CLANG) \| $(CPP_MAJOR) \>= 4)" "1"
CFLAGS += $(C_GCC4_FLAGS)
CPPFLAGS += $(CPP_GCC4_FLAGS)
endif
# GCC >= 4.6
ifeq "$(shell expr $(IS_CLANG) \= 0 \& \( \( $(CPP_MAJOR) \= 4 \& $(CPP_MINOR) \>= 6 \) \| $(CPP_MAJOR) \> 4 \))" "1"
CFLAGS += -Wno-unused-but-set-variable
endif
# Clang >= 3 || GCC >= 4.7
ifeq "$(shell expr $(IS_CLANG) \& $(CPP_MAJOR) \>= 3 \| $(CPP_MAJOR) \>= 4 \& $(CPP_MINOR) \>= 7)" "1"
CPPFLAGS += -Wno-delete-non-virtual-dtor
endif
# OS is Linux and not using clang
ifeq "$(shell expr $(OS) \= Linux \& $(IS_CLANG) \= 0)" "1"
LINK += -static-libgcc
endif
OBJ_BIN := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o)
OBJ_BIN := $(OBJ_BIN:%.c=$(BIN_DIR)/%.o)
# This will break if we include other Makefiles, but is fine for now. It allows
# us to make a copy of this file that uses altered paths (ie. Makefile.mine)
# or other changes without mucking up the original.
MAKEFILE_NAME := $(CURDIR)/$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
$(BIN_DIR)/%.o: %.cpp
$(CPP) $(INCLUDE) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<
$(BIN_DIR)/%.o: %.c
$(CPP) $(INCLUDE) $(CFLAGS) -o $@ -c $<
all:
mkdir -p $(BIN_DIR)
mkdir -p $(BIN_DIR)/thread
mkdir -p $(BIN_DIR)/sqlitepp
mkdir -p $(BIN_DIR)/$(SQL)
ln -sf $(PUBLIC_ROOT)/sdk/amxxmodule.cpp
$(MAKE) -f $(MAKEFILE_NAME) $(PROJECT)
$(PROJECT): $(OBJ_BIN)
$(CPP) $(INCLUDE) $(OBJ_BIN) $(LINK) -o $(BIN_DIR)/$(BINARY)
debug:
$(MAKE) -f $(MAKEFILE_NAME) all DEBUG=true
default: all
clean:
rm -rf $(BIN_DIR)/*.o
rm -rf $(BIN_DIR)/thread/*.o
rm -rf $(BIN_DIR)/sqlitepp/*.o
rm -rf $(BIN_DIR)/$(SQL)/*.o
rm -f $(BIN_DIR)/$(BINARY)

View File

@ -0,0 +1,626 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// SQLite Module
//
#include <stdio.h>
#include "sh_list.h"
#include "sqlite_header.h"
#include "sqlheaders.h"
SqliteDriver g_Sqlite;
void FreeConnection(void *p, unsigned int num)
{
SQL_Connection *cn = (SQL_Connection *)p;
free(cn->host);
free(cn->user);
free(cn->pass);
free(cn->db);
delete cn;
}
void FreeQuery(void *p, unsigned int num)
{
AmxQueryInfo *qry = (AmxQueryInfo *)p;
qry->pQuery->FreeHandle();
delete qry;
}
void FreeDatabase(void *p, unsigned int num)
{
IDatabase *db = (IDatabase *)p;
db->FreeHandle();
}
static cell AMX_NATIVE_CALL SQL_MakeDbTuple(AMX *amx, cell *params)
{
SQL_Connection *sql = new SQL_Connection;
int len;
sql->port = 0;
sql->host = strdup("");
sql->user = strdup("");
sql->pass = strdup("");
char *db = MF_GetAmxString(amx, params[4], 0, &len);
char path[255];
FILE *fp;
MF_BuildPathnameR(path, sizeof(path)-1, "%s", db);
if ((fp=fopen(path, "rb")))
{
fclose(fp);
sql->db = strdup(path);
} else {
MF_BuildPathnameR(path, sizeof(path)-1, "%s/sqlite3/%s.sq3",
MF_GetLocalInfo("amxx_datadir", "addons/amxmodx/data"),
db);
sql->db = strdup(path);
}
unsigned int num = MakeHandle(sql, Handle_Connection, FreeConnection);
return num;
}
static cell AMX_NATIVE_CALL SQL_FreeHandle(AMX *amx, cell *params)
{
if (!FreeHandle(params[1]))
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid handle: %d", params[1]);
return 0;
}
return 1;
}
static cell AMX_NATIVE_CALL SQL_Connect(AMX *amx, cell *params)
{
SQL_Connection *sql = (SQL_Connection *)GetHandle(params[1], Handle_Connection);
if (!sql)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid handle: %d", params[1]);
return 0;
}
DatabaseInfo nfo;
nfo.database = sql->db;
nfo.user = "";
nfo.pass = "";
nfo.port = 0;
nfo.host = "";
char buffer[512];
int errcode;
IDatabase *pDb = g_Sqlite.Connect(&nfo, &errcode, buffer, sizeof(buffer)-1);
if (!pDb)
{
cell *c_err = MF_GetAmxAddr(amx, params[2]);
*c_err = errcode;
MF_SetAmxString(amx, params[3], buffer, params[4]);
return 0;
}
return MakeHandle(pDb, Handle_Database, FreeDatabase);
}
static cell AMX_NATIVE_CALL SQL_PrepareQuery(AMX *amx, cell *params)
{
IDatabase *pDb = (IDatabase *)GetHandle(params[1], Handle_Database);
if (!pDb)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid database handle: %d", params[1]);
return 0;
}
int len;
char *fmt = MF_FormatAmxString(amx, params, 2, &len);
IQuery *pQuery = pDb->PrepareQuery(fmt);
if (!pQuery)
return 0;
AmxQueryInfo *qinfo = new AmxQueryInfo;
qinfo->pQuery = pQuery;
memset(&qinfo->info, 0, sizeof(QueryInfo));
return MakeHandle(qinfo, Handle_Query, FreeQuery);
}
static cell AMX_NATIVE_CALL SQL_Execute(AMX *amx, cell *params)
{
AmxQueryInfo *qInfo = (AmxQueryInfo *)GetHandle(params[1], Handle_Query);
if (!qInfo)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid query handle: %d", params[1]);
return 0;
}
qInfo->error[0] = '\0';
memset(&qInfo->info, 0, sizeof(QueryInfo));
if (!qInfo->pQuery->Execute2(&qInfo->info, qInfo->error, 254))
{
return 0;
}
return 1;
}
static cell AMX_NATIVE_CALL SQL_QueryError(AMX *amx, cell *params)
{
AmxQueryInfo *qInfo = (AmxQueryInfo *)GetHandle(params[1], Handle_Query);
if (!qInfo)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid query handle: %d", params[1]);
return 0;
}
MF_SetAmxString(amx, params[2], qInfo->error, params[3]);
return qInfo->info.errorcode;
}
static cell AMX_NATIVE_CALL SQL_MoreResults(AMX *amx, cell *params)
{
AmxQueryInfo *qInfo = (AmxQueryInfo *)GetHandle(params[1], Handle_Query);
if (!qInfo)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid query handle: %d", params[1]);
return 0;
}
if (!qInfo->info.rs)
return 0;
return (qInfo->info.rs->IsDone() ? 0 : 1);
}
static cell AMX_NATIVE_CALL SQL_IsNull(AMX *amx, cell *params)
{
AmxQueryInfo *qInfo = (AmxQueryInfo *)GetHandle(params[1], Handle_Query);
if (!qInfo)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid query handle: %d", params[1]);
return 0;
}
IResultSet *rs = qInfo->info.rs;
if (!rs || rs->IsDone())
{
MF_LogError(amx, AMX_ERR_NATIVE, "No result set in this query!");
return 0;
}
unsigned int col = static_cast<unsigned int>(params[2]);
if (col >= rs->FieldCount())
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid column: %d", col);
return 0;
}
IResultRow *rr = rs->GetRow();
return rr->IsNull(col) ? 1 : 0;
}
static cell AMX_NATIVE_CALL SQL_ReadResult(AMX *amx, cell *params)
{
AmxQueryInfo *qInfo = (AmxQueryInfo *)GetHandle(params[1], Handle_Query);
if (!qInfo)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid query handle: %d", params[1]);
return 0;
}
IResultSet *rs = qInfo->info.rs;
if (!rs || rs->IsDone())
{
MF_LogError(amx, AMX_ERR_NATIVE, "No result set in this query!");
return 0;
}
IResultRow *row = rs->GetRow();
unsigned int col = static_cast<unsigned int>(params[2]);
if (col >= rs->FieldCount())
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid column: %d", col);
return 0;
}
cell numparams = params[0] / sizeof(cell);
switch (numparams)
{
case 4:
{
const char *str = row->GetString(col);
if (!str)
str = "";
cell *len = MF_GetAmxAddr(amx, params[4]);
MF_SetAmxString(amx, params[3], str, (int)*len);
break;
}
case 3:
{
REAL num = row->GetFloat(col);
cell *addr = MF_GetAmxAddr(amx, params[3]);
*addr = amx_ftoc(num);
break;
}
case 2:
{
int num = row->GetInt(col);
return num;
break;
}
default:
{
MF_LogError(amx, AMX_ERR_NATIVE, "Bad number of arguments passed.");
break;
}
}
return 1;
}
static cell AMX_NATIVE_CALL SQL_NextRow(AMX *amx, cell *params)
{
AmxQueryInfo *qInfo = (AmxQueryInfo *)GetHandle(params[1], Handle_Query);
if (!qInfo)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid query handle: %d", params[1]);
return 0;
}
IResultSet *rs = qInfo->info.rs;
if (!rs || rs->IsDone())
{
MF_LogError(amx, AMX_ERR_NATIVE, "No result set in this query!");
return 0;
}
rs->NextRow();
return 1;
}
static cell AMX_NATIVE_CALL SQL_AffectedRows(AMX *amx, cell *params)
{
AmxQueryInfo *qInfo = (AmxQueryInfo *)GetHandle(params[1], Handle_Query);
if (!qInfo)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid query handle: %d", params[1]);
return 0;
}
return static_cast<cell>(qInfo->info.affected_rows);
}
static cell AMX_NATIVE_CALL SQL_NumResults(AMX *amx, cell *params)
{
AmxQueryInfo *qInfo = (AmxQueryInfo *)GetHandle(params[1], Handle_Query);
if (!qInfo)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid query handle: %d", params[1]);
return 0;
}
IResultSet *rs = qInfo->info.rs;
if (!rs)
{
return 0;
}
return rs->RowCount();
}
static cell AMX_NATIVE_CALL SQL_NumColumns(AMX *amx, cell *params)
{
AmxQueryInfo *qInfo = (AmxQueryInfo *)GetHandle(params[1], Handle_Query);
if (!qInfo)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid query handle: %d", params[1]);
return 0;
}
IResultSet *rs = qInfo->info.rs;
if (!rs)
{
MF_LogError(amx, AMX_ERR_NATIVE, "No result set in this query!");
return 0;
}
return rs->FieldCount();
}
static cell AMX_NATIVE_CALL SQL_FieldNumToName(AMX *amx, cell *params)
{
AmxQueryInfo *qInfo = (AmxQueryInfo *)GetHandle(params[1], Handle_Query);
if (!qInfo)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid query handle: %d", params[1]);
return 0;
}
IResultSet *rs = qInfo->info.rs;
if (!rs)
{
MF_LogError(amx, AMX_ERR_NATIVE, "No result set in this query!");
return 0;
}
unsigned int col = static_cast<unsigned int>(params[2]);
const char *namewa = rs->FieldNumToName(col);
if (!namewa)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid column: %d", col);
return 0;
}
MF_SetAmxString(amx, params[3], namewa, params[4]);
return 1;
}
static cell AMX_NATIVE_CALL SQL_GetQueryString(AMX *amx, cell *params)
{
AmxQueryInfo *qInfo = (AmxQueryInfo *)GetHandle(params[1], Handle_Query);
if (!qInfo || (!qInfo->pQuery && !qInfo->opt_ptr))
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid query handle: %d", params[1]);
return 0;
}
const char *ptr = qInfo->pQuery ? qInfo->pQuery->GetQueryString() : qInfo->opt_ptr;
return MF_SetAmxString(amx, params[2], ptr, params[3]);
}
static cell AMX_NATIVE_CALL SQL_FieldNameToNum(AMX *amx, cell *params)
{
AmxQueryInfo *qInfo = (AmxQueryInfo *)GetHandle(params[1], Handle_Query);
if (!qInfo)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid query handle: %d", params[1]);
return 0;
}
IResultSet *rs = qInfo->info.rs;
if (!rs)
{
MF_LogError(amx, AMX_ERR_NATIVE, "No result set in this query!");
return 0;
}
int len;
char *namewa = MF_GetAmxString(amx, params[2], 0, &len);
unsigned int columnId;
if (!rs->FieldNameToNum(namewa, &columnId))
{
return -1;
}
return columnId;
}
static cell AMX_NATIVE_CALL SQL_GetInsertId(AMX *amx, cell *params)
{
AmxQueryInfo *qInfo = (AmxQueryInfo *)GetHandle(params[1], Handle_Query);
if (!qInfo)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid query handle: %d", params[1]);
return 0;
}
return qInfo->info.insert_id;
}
static cell AMX_NATIVE_CALL SQL_GetAffinity(AMX *amx, cell *params)
{
return MF_SetAmxString(amx, params[1], g_Sqlite.NameString(), params[2]);
}
static cell AMX_NATIVE_CALL SQL_SetAffinity(AMX *amx, cell *params)
{
int len;
char *str = MF_GetAmxString(amx, params[1], 0, &len);
if (!str[0])
{
return 1;
}
if (stricmp(str, g_Sqlite.NameString()) == 0)
{
return 1;
}
SqlFunctions *pFuncs = (SqlFunctions *)MF_RequestFunction(SQL_DRIVER_FUNC);
while (pFuncs)
{
if (pFuncs->driver->IsCompatDriver(str))
{
return pFuncs->set_affinity(amx);
}
pFuncs = pFuncs->prev;
}
return 0;
}
static cell AMX_NATIVE_CALL SQL_Rewind(AMX *amx, cell *params)
{
AmxQueryInfo *qInfo = (AmxQueryInfo *)GetHandle(params[1], Handle_Query);
if (!qInfo)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid query handle: %d", params[1]);
return 0;
}
IResultSet *rs = qInfo->info.rs;
if (!rs)
{
MF_LogError(amx, AMX_ERR_NATIVE, "No result set in this query!");
return 0;
}
rs->Rewind();
return 1;
}
static cell AMX_NATIVE_CALL SQL_NextResultSet(AMX *amx, cell *params)
{
AmxQueryInfo *qInfo = (AmxQueryInfo *)GetHandle(params[1], Handle_Query);
if (!qInfo)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid query handle: %d", params[1]);
return 0;
}
IResultSet *rs = qInfo->info.rs;
if (!rs)
{
MF_LogError(amx, AMX_ERR_NATIVE, "No result set in this query!");
return 0;
}
if (rs->NextResultSet())
{
return 1;
}
else
{
qInfo->info.rs = NULL;
return 0;
}
}
static cell AMX_NATIVE_CALL SQL_QuoteString(AMX *amx, cell *params)
{
int len;
char *str = MF_GetAmxString(amx, params[4], 0, &len);
size_t newsize;
static char buffer[8192];
if (params[1] != 0)
{
IDatabase *pDb = (IDatabase *)GetHandle(params[1], Handle_Database);
if (!pDb)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid database handle: %d", params[1]);
return 0;
}
if (pDb->QuoteString(str, buffer, sizeof(buffer)-1, &newsize) == 0)
{
MF_SetAmxString(amx, params[2], buffer, params[3]);
return newsize;
} else {
return -1;
}
} else {
if (g_Sqlite.QuoteString(str, buffer, sizeof(buffer)-1, &newsize) == 0)
{
MF_SetAmxString(amx, params[2], buffer, params[3]);
return newsize;
} else {
return -1;
}
}
}
static cell AMX_NATIVE_CALL SQL_QuoteStringFmt(AMX *amx, cell *params)
{
int len;
char *str = MF_FormatAmxString(amx, params, 4, &len);
size_t newsize;
static char buffer[8192];
if (params[1] != 0)
{
IDatabase *pDb = (IDatabase *)GetHandle(params[1], Handle_Database);
if (!pDb)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid database handle: %d", params[1]);
return 0;
}
if (pDb->QuoteString(str, buffer, sizeof(buffer)-1, &newsize) == 0)
{
MF_SetAmxString(amx, params[2], buffer, params[3]);
return newsize;
} else {
return -1;
}
} else {
if (g_Sqlite.QuoteString(str, buffer, sizeof(buffer)-1, &newsize) == 0)
{
MF_SetAmxString(amx, params[2], buffer, params[3]);
return newsize;
} else {
return -1;
}
}
}
AMX_NATIVE_INFO g_BaseSqlNatives[] =
{
{"SQL_MakeDbTuple", SQL_MakeDbTuple},
{"SQL_FreeHandle", SQL_FreeHandle},
{"SQL_Connect", SQL_Connect},
{"SQL_PrepareQuery", SQL_PrepareQuery},
{"SQL_Execute", SQL_Execute},
{"SQL_QueryError", SQL_QueryError},
{"SQL_MoreResults", SQL_MoreResults},
{"SQL_IsNull", SQL_IsNull},
{"SQL_ReadResult", SQL_ReadResult},
{"SQL_NextRow", SQL_NextRow},
{"SQL_AffectedRows", SQL_AffectedRows},
{"SQL_NumResults", SQL_NumResults},
{"SQL_NumColumns", SQL_NumColumns},
{"SQL_FieldNumToName", SQL_FieldNumToName},
{"SQL_FieldNameToNum", SQL_FieldNameToNum},
{"SQL_GetAffinity", SQL_GetAffinity},
{"SQL_SetAffinity", SQL_SetAffinity},
{"SQL_GetInsertId", SQL_GetInsertId},
{"SQL_GetQueryString", SQL_GetQueryString},
{"SQL_Rewind", SQL_Rewind},
{"SQL_QuoteString", SQL_QuoteString},
{"SQL_QuoteStringFmt", SQL_QuoteStringFmt},
{"SQL_NextResultSet", SQL_NextResultSet},
{NULL, NULL},
};

120
modules/sqlite/handles.cpp Normal file
View File

@ -0,0 +1,120 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// SQLite Module
//
#include <string.h>
#include <sh_stack.h>
#include <am-vector.h>
#include "sqlite_header.h"
struct QHandle
{
void *_ptr;
FREEHANDLE _func;
HandleType type;
bool isfree;
};
ke::Vector<QHandle *> g_Handles;
CStack<unsigned int> g_FreeHandles;
unsigned int MakeHandle(void *ptr, HandleType type, FREEHANDLE f)
{
unsigned int num;
QHandle *h;
if (g_FreeHandles.size())
{
num = g_FreeHandles.front();
g_FreeHandles.pop();
h = g_Handles[num];
} else {
h = new QHandle;
g_Handles.append(h);
num = static_cast<unsigned int>(g_Handles.length()) - 1;
}
h->_ptr = ptr;
h->type = type;
h->_func = f;
h->isfree = false;
return num + 1;
}
void *GetHandle(unsigned int num, HandleType type)
{
if (num == 0)
return NULL;
num--;
if (num >= g_Handles.length())
return NULL;
QHandle *h = g_Handles[num];
if (h->isfree || (h->type != type))
return NULL;
return h->_ptr;
}
bool FreeHandle(unsigned int num)
{
if (num == 0)
return false;
unsigned int _num = num;
num--;
if (num >= g_Handles.length())
return false;
QHandle *h = g_Handles[num];
if (h->isfree)
return false;
h->_func(h->_ptr, _num);
h->_ptr = NULL;
h->_func = NULL;
h->isfree = true;
g_FreeHandles.push(num);
return true;
}
void FreeAllHandles(HandleType type)
{
QHandle *q;
for (size_t i = 0; i < g_Handles.length(); i++)
{
q = g_Handles[i];
if (q && !q->isfree && q->type == type)
{
FreeHandle((unsigned int)i);
}
}
}
void FreeHandleTable()
{
QHandle *q;
for (size_t i = 0; i < g_Handles.length(); i++)
{
q = g_Handles[i];
if (q && !q->isfree)
FreeHandle((unsigned int)i);
}
g_Handles.clear();
while (!g_FreeHandles.empty())
g_FreeHandles.pop();
}

99
modules/sqlite/module.cpp Normal file
View File

@ -0,0 +1,99 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// SQLite Module
//
#include "amxxmodule.h"
#include "sqlite_header.h"
#include "sqlheaders.h"
static int g_ident = 0;
SqlFunctions g_SqliteFuncs =
{
&g_Sqlite,
SetMysqlAffinity,
NULL
};
int SetMysqlAffinity(AMX *amx)
{
MF_AmxReRegister(amx, g_BaseSqlNatives, -1);
MF_AmxReRegister(amx, g_ThreadSqlNatives, -1);
return 1;
}
bool DirExists(const char *dir)
{
#if defined WIN32 || defined _WIN32
DWORD attr = GetFileAttributes(dir);
if (attr == INVALID_FILE_ATTRIBUTES)
return false;
if (attr & FILE_ATTRIBUTE_DIRECTORY)
return true;
#else
struct stat s;
if (stat(dir, &s) != 0)
return false;
if (S_ISDIR(s.st_mode))
return true;
#endif
return false;
}
void OnAmxxAttach()
{
MF_AddNatives(g_BaseSqlNatives);
MF_AddNatives(g_ThreadSqlNatives);
g_SqliteFuncs.prev = (SqlFunctions *)MF_RegisterFunctionEx(&g_SqliteFuncs, SQL_DRIVER_FUNC);
MF_AddLibraries("dbi", LibType_Class, &g_ident);
//override any mysqlx old compat stuff
MF_AddNatives(g_OldCompatNatives);
MF_OverrideNatives(g_OldCompatNatives, MODULE_NAME);
char path[255];
MF_BuildPathnameR(path, sizeof(path)-1, "%s/sqlite3", MF_GetLocalInfo("amxx_datadir", "addons/amxmodx/data"));
if (!DirExists(path))
{
mkdir(path
#if defined(__linux__) || defined(__APPLE__)
, 0775
#endif
);
}
}
void OnAmxxDetach()
{
ShutdownThreading();
MF_RemoveLibraries(&g_ident);
}
void OnPluginsUnloaded()
{
FreeAllHandles(Handle_OldResult);
FreeAllHandles(Handle_OldDb);
FreeAllHandles(Handle_Connection);
}
extern "C" void __cxa_pure_virtual(void)
{
}

View File

@ -0,0 +1,504 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// Module Config
//
#ifndef __MODULECONFIG_H__
#define __MODULECONFIG_H__
#include <amxmodx_version.h>
// Module info
#define MODULE_NAME "SQLite"
#define MODULE_VERSION AMXX_VERSION
#define MODULE_AUTHOR "AMX Mod X Dev Team"
#define MODULE_URL "http://www.amxmodx.org/"
#define MODULE_LOGTAG "SQLITE"
#define MODULE_LIBRARY "sqlite"
#define MODULE_LIBCLASS "sqlx"
// If you want the module not to be reloaded on mapchange, remove / comment out the next line
#define MODULE_RELOAD_ON_MAPCHANGE
#ifdef __DATE__
#define MODULE_DATE __DATE__
#else // __DATE__
#define MODULE_DATE "Unknown"
#endif // __DATE__
// metamod plugin?
#define USE_METAMOD
// use memory manager/tester?
// note that if you use this, you cannot construct/allocate
// anything before the module attached (OnAmxxAttach).
// be careful of default constructors using new/malloc!
// #define MEMORY_TEST
// Unless you use STL or exceptions, keep this commented.
// It allows you to compile without libstdc++.so as a dependency
// #define NO_ALLOC_OVERRIDES
// Uncomment this if you are using MSVC8 or greater and want to fix some of the compatibility issues yourself
// #define NO_MSVC8_AUTO_COMPAT
/**
* AMXX Init functions
* Also consider using FN_META_*
*/
/** AMXX query */
//#define FN_AMXX_QUERY OnAmxxQuery
/** AMXX attach
* Do native functions init here (MF_AddNatives)
*/
#define FN_AMXX_ATTACH OnAmxxAttach
/** AMXX Detach (unload) */
#define FN_AMXX_DETACH OnAmxxDetach
/** All plugins loaded
* Do forward functions init here (MF_RegisterForward)
*/
#define FN_AMXX_PLUGINSLOADED OnPluginsLoaded
/** All plugins are about to be unloaded */
#define FN_AMXX_PLUGINSUNLOADING OnPluginsUnloading
/** All plugins are now unloaded */
#define FN_AMXX_PLUGINSUNLOADED OnPluginsUnloaded
/**** METAMOD ****/
// If your module doesn't use metamod, you may close the file now :)
#ifdef USE_METAMOD
// ----
// Hook Functions
// Uncomment these to be called
// You can also change the function name
// - Metamod init functions
// Also consider using FN_AMXX_*
// Meta query
//#define FN_META_QUERY OnMetaQuery
// Meta attach
//#define FN_META_ATTACH OnMetaAttach
// Meta detach
//#define FN_META_DETACH OnMetaDetach
// (wd) are Will Day's notes
// - GetEntityAPI2 functions
// #define FN_GameDLLInit GameDLLInit /* pfnGameInit() */
// #define FN_DispatchSpawn DispatchSpawn /* pfnSpawn() */
// #define FN_DispatchThink DispatchThink /* pfnThink() */
// #define FN_DispatchUse DispatchUse /* pfnUse() */
// #define FN_DispatchTouch DispatchTouch /* pfnTouch() */
// #define FN_DispatchBlocked DispatchBlocked /* pfnBlocked() */
// #define FN_DispatchKeyValue DispatchKeyValue /* pfnKeyValue() */
// #define FN_DispatchSave DispatchSave /* pfnSave() */
// #define FN_DispatchRestore DispatchRestore /* pfnRestore() */
// #define FN_DispatchObjectCollsionBox DispatchObjectCollsionBox /* pfnSetAbsBox() */
// #define FN_SaveWriteFields SaveWriteFields /* pfnSaveWriteFields() */
// #define FN_SaveReadFields SaveReadFields /* pfnSaveReadFields() */
// #define FN_SaveGlobalState SaveGlobalState /* pfnSaveGlobalState() */
// #define FN_RestoreGlobalState RestoreGlobalState /* pfnRestoreGlobalState() */
// #define FN_ResetGlobalState ResetGlobalState /* pfnResetGlobalState() */
// #define FN_ClientConnect ClientConnect /* pfnClientConnect() (wd) Client has connected */
// #define FN_ClientDisconnect ClientDisconnect /* pfnClientDisconnect() (wd) Player has left the game */
// #define FN_ClientKill ClientKill /* pfnClientKill() (wd) Player has typed "kill" */
// #define FN_ClientPutInServer ClientPutInServer /* pfnClientPutInServer() (wd) Client is entering the game */
// #define FN_ClientCommand ClientCommand /* pfnClientCommand() (wd) Player has sent a command (typed or from a bind) */
// #define FN_ClientUserInfoChanged ClientUserInfoChanged /* pfnClientUserInfoChanged() (wd) Client has updated their setinfo structure */
// #define FN_ServerActivate ServerActivate /* pfnServerActivate() (wd) Server is starting a new map */
// #define FN_ServerDeactivate ServerDeactivate /* pfnServerDeactivate() (wd) Server is leaving the map (shutdown or changelevel); SDK2 */
// #define FN_PlayerPreThink PlayerPreThink /* pfnPlayerPreThink() */
// #define FN_PlayerPostThink PlayerPostThink /* pfnPlayerPostThink() */
#define FN_StartFrame StartFrame /* pfnStartFrame() */
// #define FN_ParmsNewLevel ParmsNewLevel /* pfnParmsNewLevel() */
// #define FN_ParmsChangeLevel ParmsChangeLevel /* pfnParmsChangeLevel() */
// #define FN_GetGameDescription GetGameDescription /* pfnGetGameDescription() Returns string describing current .dll. E.g. "TeamFotrress 2" "Half-Life" */
// #define FN_PlayerCustomization PlayerCustomization /* pfnPlayerCustomization() Notifies .dll of new customization for player. */
// #define FN_SpectatorConnect SpectatorConnect /* pfnSpectatorConnect() Called when spectator joins server */
// #define FN_SpectatorDisconnect SpectatorDisconnect /* pfnSpectatorDisconnect() Called when spectator leaves the server */
// #define FN_SpectatorThink SpectatorThink /* pfnSpectatorThink() Called when spectator sends a command packet (usercmd_t) */
// #define FN_Sys_Error Sys_Error /* pfnSys_Error() Notify game .dll that engine is going to shut down. Allows mod authors to set a breakpoint. SDK2 */
// #define FN_PM_Move PM_Move /* pfnPM_Move() (wd) SDK2 */
// #define FN_PM_Init PM_Init /* pfnPM_Init() Server version of player movement initialization; (wd) SDK2 */
// #define FN_PM_FindTextureType PM_FindTextureType /* pfnPM_FindTextureType() (wd) SDK2 */
// #define FN_SetupVisibility SetupVisibility /* pfnSetupVisibility() Set up PVS and PAS for networking for this client; (wd) SDK2 */
// #define FN_UpdateClientData UpdateClientData /* pfnUpdateClientData() Set up data sent only to specific client; (wd) SDK2 */
// #define FN_AddToFullPack AddToFullPack /* pfnAddToFullPack() (wd) SDK2 */
// #define FN_CreateBaseline CreateBaseline /* pfnCreateBaseline() Tweak entity baseline for network encoding allows setup of player baselines too.; (wd) SDK2 */
// #define FN_RegisterEncoders RegisterEncoders /* pfnRegisterEncoders() Callbacks for network encoding; (wd) SDK2 */
// #define FN_GetWeaponData GetWeaponData /* pfnGetWeaponData() (wd) SDK2 */
// #define FN_CmdStart CmdStart /* pfnCmdStart() (wd) SDK2 */
// #define FN_CmdEnd CmdEnd /* pfnCmdEnd() (wd) SDK2 */
// #define FN_ConnectionlessPacket ConnectionlessPacket /* pfnConnectionlessPacket() (wd) SDK2 */
// #define FN_GetHullBounds GetHullBounds /* pfnGetHullBounds() (wd) SDK2 */
// #define FN_CreateInstancedBaselines CreateInstancedBaselines /* pfnCreateInstancedBaselines() (wd) SDK2 */
// #define FN_InconsistentFile InconsistentFile /* pfnInconsistentFile() (wd) SDK2 */
// #define FN_AllowLagCompensation AllowLagCompensation /* pfnAllowLagCompensation() (wd) SDK2 */
// - GetEntityAPI2_Post functions
// #define FN_GameDLLInit_Post GameDLLInit_Post
// #define FN_DispatchSpawn_Post DispatchSpawn_Post
// #define FN_DispatchThink_Post DispatchThink_Post
// #define FN_DispatchUse_Post DispatchUse_Post
// #define FN_DispatchTouch_Post DispatchTouch_Post
// #define FN_DispatchBlocked_Post DispatchBlocked_Post
// #define FN_DispatchKeyValue_Post DispatchKeyValue_Post
// #define FN_DispatchSave_Post DispatchSave_Post
// #define FN_DispatchRestore_Post DispatchRestore_Post
// #define FN_DispatchObjectCollsionBox_Post DispatchObjectCollsionBox_Post
// #define FN_SaveWriteFields_Post SaveWriteFields_Post
// #define FN_SaveReadFields_Post SaveReadFields_Post
// #define FN_SaveGlobalState_Post SaveGlobalState_Post
// #define FN_RestoreGlobalState_Post RestoreGlobalState_Post
// #define FN_ResetGlobalState_Post ResetGlobalState_Post
// #define FN_ClientConnect_Post ClientConnect_Post
// #define FN_ClientDisconnect_Post ClientDisconnect_Post
// #define FN_ClientKill_Post ClientKill_Post
// #define FN_ClientPutInServer_Post ClientPutInServer_Post
// #define FN_ClientCommand_Post ClientCommand_Post
// #define FN_ClientUserInfoChanged_Post ClientUserInfoChanged_Post
// #define FN_ServerActivate_Post ServerActivate_Post
// #define FN_ServerDeactivate_Post ServerDeactivate_Post
// #define FN_PlayerPreThink_Post PlayerPreThink_Post
// #define FN_PlayerPostThink_Post PlayerPostThink_Post
// #define FN_StartFrame_Post StartFrame_Post
// #define FN_ParmsNewLevel_Post ParmsNewLevel_Post
// #define FN_ParmsChangeLevel_Post ParmsChangeLevel_Post
// #define FN_GetGameDescription_Post GetGameDescription_Post
// #define FN_PlayerCustomization_Post PlayerCustomization_Post
// #define FN_SpectatorConnect_Post SpectatorConnect_Post
// #define FN_SpectatorDisconnect_Post SpectatorDisconnect_Post
// #define FN_SpectatorThink_Post SpectatorThink_Post
// #define FN_Sys_Error_Post Sys_Error_Post
// #define FN_PM_Move_Post PM_Move_Post
// #define FN_PM_Init_Post PM_Init_Post
// #define FN_PM_FindTextureType_Post PM_FindTextureType_Post
// #define FN_SetupVisibility_Post SetupVisibility_Post
// #define FN_UpdateClientData_Post UpdateClientData_Post
// #define FN_AddToFullPack_Post AddToFullPack_Post
// #define FN_CreateBaseline_Post CreateBaseline_Post
// #define FN_RegisterEncoders_Post RegisterEncoders_Post
// #define FN_GetWeaponData_Post GetWeaponData_Post
// #define FN_CmdStart_Post CmdStart_Post
// #define FN_CmdEnd_Post CmdEnd_Post
// #define FN_ConnectionlessPacket_Post ConnectionlessPacket_Post
// #define FN_GetHullBounds_Post GetHullBounds_Post
// #define FN_CreateInstancedBaselines_Post CreateInstancedBaselines_Post
// #define FN_InconsistentFile_Post InconsistentFile_Post
// #define FN_AllowLagCompensation_Post AllowLagCompensation_Post
// - GetEngineAPI functions
// #define FN_PrecacheModel PrecacheModel
// #define FN_PrecacheSound PrecacheSound
// #define FN_SetModel SetModel
// #define FN_ModelIndex ModelIndex
// #define FN_ModelFrames ModelFrames
// #define FN_SetSize SetSize
// #define FN_ChangeLevel ChangeLevel
// #define FN_GetSpawnParms GetSpawnParms
// #define FN_SaveSpawnParms SaveSpawnParms
// #define FN_VecToYaw VecToYaw
// #define FN_VecToAngles VecToAngles
// #define FN_MoveToOrigin MoveToOrigin
// #define FN_ChangeYaw ChangeYaw
// #define FN_ChangePitch ChangePitch
// #define FN_FindEntityByString FindEntityByString
// #define FN_GetEntityIllum GetEntityIllum
// #define FN_FindEntityInSphere FindEntityInSphere
// #define FN_FindClientInPVS FindClientInPVS
// #define FN_EntitiesInPVS EntitiesInPVS
// #define FN_MakeVectors MakeVectors
// #define FN_AngleVectors AngleVectors
// #define FN_CreateEntity CreateEntity
// #define FN_RemoveEntity RemoveEntity
// #define FN_CreateNamedEntity CreateNamedEntity
// #define FN_MakeStatic MakeStatic
// #define FN_EntIsOnFloor EntIsOnFloor
// #define FN_DropToFloor DropToFloor
// #define FN_WalkMove WalkMove
// #define FN_SetOrigin SetOrigin
// #define FN_EmitSound EmitSound
// #define FN_EmitAmbientSound EmitAmbientSound
// #define FN_TraceLine TraceLine
// #define FN_TraceToss TraceToss
// #define FN_TraceMonsterHull TraceMonsterHull
// #define FN_TraceHull TraceHull
// #define FN_TraceModel TraceModel
// #define FN_TraceTexture TraceTexture
// #define FN_TraceSphere TraceSphere
// #define FN_GetAimVector GetAimVector
// #define FN_ServerCommand ServerCommand
// #define FN_ServerExecute ServerExecute
// #define FN_engClientCommand engClientCommand
// #define FN_ParticleEffect ParticleEffect
// #define FN_LightStyle LightStyle
// #define FN_DecalIndex DecalIndex
// #define FN_PointContents PointContents
// #define FN_MessageBegin MessageBegin
// #define FN_MessageEnd MessageEnd
// #define FN_WriteByte WriteByte
// #define FN_WriteChar WriteChar
// #define FN_WriteShort WriteShort
// #define FN_WriteLong WriteLong
// #define FN_WriteAngle WriteAngle
// #define FN_WriteCoord WriteCoord
// #define FN_WriteString WriteString
// #define FN_WriteEntity WriteEntity
// #define FN_CVarRegister CVarRegister
// #define FN_CVarGetFloat CVarGetFloat
// #define FN_CVarGetString CVarGetString
// #define FN_CVarSetFloat CVarSetFloat
// #define FN_CVarSetString CVarSetString
// #define FN_AlertMessage AlertMessage
// #define FN_EngineFprintf EngineFprintf
// #define FN_PvAllocEntPrivateData PvAllocEntPrivateData
// #define FN_PvEntPrivateData PvEntPrivateData
// #define FN_FreeEntPrivateData FreeEntPrivateData
// #define FN_SzFromIndex SzFromIndex
// #define FN_AllocString AllocString
// #define FN_GetVarsOfEnt GetVarsOfEnt
// #define FN_PEntityOfEntOffset PEntityOfEntOffset
// #define FN_EntOffsetOfPEntity EntOffsetOfPEntity
// #define FN_IndexOfEdict IndexOfEdict
// #define FN_PEntityOfEntIndex PEntityOfEntIndex
// #define FN_FindEntityByVars FindEntityByVars
// #define FN_GetModelPtr GetModelPtr
// #define FN_RegUserMsg RegUserMsg
// #define FN_AnimationAutomove AnimationAutomove
// #define FN_GetBonePosition GetBonePosition
// #define FN_FunctionFromName FunctionFromName
// #define FN_NameForFunction NameForFunction
// #define FN_ClientPrintf ClientPrintf
// #define FN_ServerPrint ServerPrint
// #define FN_Cmd_Args Cmd_Args
// #define FN_Cmd_Argv Cmd_Argv
// #define FN_Cmd_Argc Cmd_Argc
// #define FN_GetAttachment GetAttachment
// #define FN_CRC32_Init CRC32_Init
// #define FN_CRC32_ProcessBuffer CRC32_ProcessBuffer
// #define FN_CRC32_ProcessByte CRC32_ProcessByte
// #define FN_CRC32_Final CRC32_Final
// #define FN_RandomLong RandomLong
// #define FN_RandomFloat RandomFloat
// #define FN_SetView SetView
// #define FN_Time Time
// #define FN_CrosshairAngle CrosshairAngle
// #define FN_LoadFileForMe LoadFileForMe
// #define FN_FreeFile FreeFile
// #define FN_EndSection EndSection
// #define FN_CompareFileTime CompareFileTime
// #define FN_GetGameDir GetGameDir
// #define FN_Cvar_RegisterVariable Cvar_RegisterVariable
// #define FN_FadeClientVolume FadeClientVolume
// #define FN_SetClientMaxspeed SetClientMaxspeed
// #define FN_CreateFakeClient CreateFakeClient
// #define FN_RunPlayerMove RunPlayerMove
// #define FN_NumberOfEntities NumberOfEntities
// #define FN_GetInfoKeyBuffer GetInfoKeyBuffer
// #define FN_InfoKeyValue InfoKeyValue
// #define FN_SetKeyValue SetKeyValue
// #define FN_SetClientKeyValue SetClientKeyValue
// #define FN_IsMapValid IsMapValid
// #define FN_StaticDecal StaticDecal
// #define FN_PrecacheGeneric PrecacheGeneric
// #define FN_GetPlayerUserId GetPlayerUserId
// #define FN_BuildSoundMsg BuildSoundMsg
// #define FN_IsDedicatedServer IsDedicatedServer
// #define FN_CVarGetPointer CVarGetPointer
// #define FN_GetPlayerWONId GetPlayerWONId
// #define FN_Info_RemoveKey Info_RemoveKey
// #define FN_GetPhysicsKeyValue GetPhysicsKeyValue
// #define FN_SetPhysicsKeyValue SetPhysicsKeyValue
// #define FN_GetPhysicsInfoString GetPhysicsInfoString
// #define FN_PrecacheEvent PrecacheEvent
// #define FN_PlaybackEvent PlaybackEvent
// #define FN_SetFatPVS SetFatPVS
// #define FN_SetFatPAS SetFatPAS
// #define FN_CheckVisibility CheckVisibility
// #define FN_DeltaSetField DeltaSetField
// #define FN_DeltaUnsetField DeltaUnsetField
// #define FN_DeltaAddEncoder DeltaAddEncoder
// #define FN_GetCurrentPlayer GetCurrentPlayer
// #define FN_CanSkipPlayer CanSkipPlayer
// #define FN_DeltaFindField DeltaFindField
// #define FN_DeltaSetFieldByIndex DeltaSetFieldByIndex
// #define FN_DeltaUnsetFieldByIndex DeltaUnsetFieldByIndex
// #define FN_SetGroupMask SetGroupMask
// #define FN_engCreateInstancedBaseline engCreateInstancedBaseline
// #define FN_Cvar_DirectSet Cvar_DirectSet
// #define FN_ForceUnmodified ForceUnmodified
// #define FN_GetPlayerStats GetPlayerStats
// #define FN_AddServerCommand AddServerCommand
// #define FN_Voice_GetClientListening Voice_GetClientListening
// #define FN_Voice_SetClientListening Voice_SetClientListening
// #define FN_GetPlayerAuthId GetPlayerAuthId
// - GetEngineAPI_Post functions
// #define FN_PrecacheModel_Post PrecacheModel_Post
// #define FN_PrecacheSound_Post PrecacheSound_Post
// #define FN_SetModel_Post SetModel_Post
// #define FN_ModelIndex_Post ModelIndex_Post
// #define FN_ModelFrames_Post ModelFrames_Post
// #define FN_SetSize_Post SetSize_Post
// #define FN_ChangeLevel_Post ChangeLevel_Post
// #define FN_GetSpawnParms_Post GetSpawnParms_Post
// #define FN_SaveSpawnParms_Post SaveSpawnParms_Post
// #define FN_VecToYaw_Post VecToYaw_Post
// #define FN_VecToAngles_Post VecToAngles_Post
// #define FN_MoveToOrigin_Post MoveToOrigin_Post
// #define FN_ChangeYaw_Post ChangeYaw_Post
// #define FN_ChangePitch_Post ChangePitch_Post
// #define FN_FindEntityByString_Post FindEntityByString_Post
// #define FN_GetEntityIllum_Post GetEntityIllum_Post
// #define FN_FindEntityInSphere_Post FindEntityInSphere_Post
// #define FN_FindClientInPVS_Post FindClientInPVS_Post
// #define FN_EntitiesInPVS_Post EntitiesInPVS_Post
// #define FN_MakeVectors_Post MakeVectors_Post
// #define FN_AngleVectors_Post AngleVectors_Post
// #define FN_CreateEntity_Post CreateEntity_Post
// #define FN_RemoveEntity_Post RemoveEntity_Post
// #define FN_CreateNamedEntity_Post CreateNamedEntity_Post
// #define FN_MakeStatic_Post MakeStatic_Post
// #define FN_EntIsOnFloor_Post EntIsOnFloor_Post
// #define FN_DropToFloor_Post DropToFloor_Post
// #define FN_WalkMove_Post WalkMove_Post
// #define FN_SetOrigin_Post SetOrigin_Post
// #define FN_EmitSound_Post EmitSound_Post
// #define FN_EmitAmbientSound_Post EmitAmbientSound_Post
// #define FN_TraceLine_Post TraceLine_Post
// #define FN_TraceToss_Post TraceToss_Post
// #define FN_TraceMonsterHull_Post TraceMonsterHull_Post
// #define FN_TraceHull_Post TraceHull_Post
// #define FN_TraceModel_Post TraceModel_Post
// #define FN_TraceTexture_Post TraceTexture_Post
// #define FN_TraceSphere_Post TraceSphere_Post
// #define FN_GetAimVector_Post GetAimVector_Post
// #define FN_ServerCommand_Post ServerCommand_Post
// #define FN_ServerExecute_Post ServerExecute_Post
// #define FN_engClientCommand_Post engClientCommand_Post
// #define FN_ParticleEffect_Post ParticleEffect_Post
// #define FN_LightStyle_Post LightStyle_Post
// #define FN_DecalIndex_Post DecalIndex_Post
// #define FN_PointContents_Post PointContents_Post
// #define FN_MessageBegin_Post MessageBegin_Post
// #define FN_MessageEnd_Post MessageEnd_Post
// #define FN_WriteByte_Post WriteByte_Post
// #define FN_WriteChar_Post WriteChar_Post
// #define FN_WriteShort_Post WriteShort_Post
// #define FN_WriteLong_Post WriteLong_Post
// #define FN_WriteAngle_Post WriteAngle_Post
// #define FN_WriteCoord_Post WriteCoord_Post
// #define FN_WriteString_Post WriteString_Post
// #define FN_WriteEntity_Post WriteEntity_Post
// #define FN_CVarRegister_Post CVarRegister_Post
// #define FN_CVarGetFloat_Post CVarGetFloat_Post
// #define FN_CVarGetString_Post CVarGetString_Post
// #define FN_CVarSetFloat_Post CVarSetFloat_Post
// #define FN_CVarSetString_Post CVarSetString_Post
// #define FN_AlertMessage_Post AlertMessage_Post
// #define FN_EngineFprintf_Post EngineFprintf_Post
// #define FN_PvAllocEntPrivateData_Post PvAllocEntPrivateData_Post
// #define FN_PvEntPrivateData_Post PvEntPrivateData_Post
// #define FN_FreeEntPrivateData_Post FreeEntPrivateData_Post
// #define FN_SzFromIndex_Post SzFromIndex_Post
// #define FN_AllocString_Post AllocString_Post
// #define FN_GetVarsOfEnt_Post GetVarsOfEnt_Post
// #define FN_PEntityOfEntOffset_Post PEntityOfEntOffset_Post
// #define FN_EntOffsetOfPEntity_Post EntOffsetOfPEntity_Post
// #define FN_IndexOfEdict_Post IndexOfEdict_Post
// #define FN_PEntityOfEntIndex_Post PEntityOfEntIndex_Post
// #define FN_FindEntityByVars_Post FindEntityByVars_Post
// #define FN_GetModelPtr_Post GetModelPtr_Post
// #define FN_RegUserMsg_Post RegUserMsg_Post
// #define FN_AnimationAutomove_Post AnimationAutomove_Post
// #define FN_GetBonePosition_Post GetBonePosition_Post
// #define FN_FunctionFromName_Post FunctionFromName_Post
// #define FN_NameForFunction_Post NameForFunction_Post
// #define FN_ClientPrintf_Post ClientPrintf_Post
// #define FN_ServerPrint_Post ServerPrint_Post
// #define FN_Cmd_Args_Post Cmd_Args_Post
// #define FN_Cmd_Argv_Post Cmd_Argv_Post
// #define FN_Cmd_Argc_Post Cmd_Argc_Post
// #define FN_GetAttachment_Post GetAttachment_Post
// #define FN_CRC32_Init_Post CRC32_Init_Post
// #define FN_CRC32_ProcessBuffer_Post CRC32_ProcessBuffer_Post
// #define FN_CRC32_ProcessByte_Post CRC32_ProcessByte_Post
// #define FN_CRC32_Final_Post CRC32_Final_Post
// #define FN_RandomLong_Post RandomLong_Post
// #define FN_RandomFloat_Post RandomFloat_Post
// #define FN_SetView_Post SetView_Post
// #define FN_Time_Post Time_Post
// #define FN_CrosshairAngle_Post CrosshairAngle_Post
// #define FN_LoadFileForMe_Post LoadFileForMe_Post
// #define FN_FreeFile_Post FreeFile_Post
// #define FN_EndSection_Post EndSection_Post
// #define FN_CompareFileTime_Post CompareFileTime_Post
// #define FN_GetGameDir_Post GetGameDir_Post
// #define FN_Cvar_RegisterVariable_Post Cvar_RegisterVariable_Post
// #define FN_FadeClientVolume_Post FadeClientVolume_Post
// #define FN_SetClientMaxspeed_Post SetClientMaxspeed_Post
// #define FN_CreateFakeClient_Post CreateFakeClient_Post
// #define FN_RunPlayerMove_Post RunPlayerMove_Post
// #define FN_NumberOfEntities_Post NumberOfEntities_Post
// #define FN_GetInfoKeyBuffer_Post GetInfoKeyBuffer_Post
// #define FN_InfoKeyValue_Post InfoKeyValue_Post
// #define FN_SetKeyValue_Post SetKeyValue_Post
// #define FN_SetClientKeyValue_Post SetClientKeyValue_Post
// #define FN_IsMapValid_Post IsMapValid_Post
// #define FN_StaticDecal_Post StaticDecal_Post
// #define FN_PrecacheGeneric_Post PrecacheGeneric_Post
// #define FN_GetPlayerUserId_Post GetPlayerUserId_Post
// #define FN_BuildSoundMsg_Post BuildSoundMsg_Post
// #define FN_IsDedicatedServer_Post IsDedicatedServer_Post
// #define FN_CVarGetPointer_Post CVarGetPointer_Post
// #define FN_GetPlayerWONId_Post GetPlayerWONId_Post
// #define FN_Info_RemoveKey_Post Info_RemoveKey_Post
// #define FN_GetPhysicsKeyValue_Post GetPhysicsKeyValue_Post
// #define FN_SetPhysicsKeyValue_Post SetPhysicsKeyValue_Post
// #define FN_GetPhysicsInfoString_Post GetPhysicsInfoString_Post
// #define FN_PrecacheEvent_Post PrecacheEvent_Post
// #define FN_PlaybackEvent_Post PlaybackEvent_Post
// #define FN_SetFatPVS_Post SetFatPVS_Post
// #define FN_SetFatPAS_Post SetFatPAS_Post
// #define FN_CheckVisibility_Post CheckVisibility_Post
// #define FN_DeltaSetField_Post DeltaSetField_Post
// #define FN_DeltaUnsetField_Post DeltaUnsetField_Post
// #define FN_DeltaAddEncoder_Post DeltaAddEncoder_Post
// #define FN_GetCurrentPlayer_Post GetCurrentPlayer_Post
// #define FN_CanSkipPlayer_Post CanSkipPlayer_Post
// #define FN_DeltaFindField_Post DeltaFindField_Post
// #define FN_DeltaSetFieldByIndex_Post DeltaSetFieldByIndex_Post
// #define FN_DeltaUnsetFieldByIndex_Post DeltaUnsetFieldByIndex_Post
// #define FN_SetGroupMask_Post SetGroupMask_Post
// #define FN_engCreateInstancedBaseline_Post engCreateInstancedBaseline_Post
// #define FN_Cvar_DirectSet_Post Cvar_DirectSet_Post
// #define FN_ForceUnmodified_Post ForceUnmodified_Post
// #define FN_GetPlayerStats_Post GetPlayerStats_Post
// #define FN_AddServerCommand_Post AddServerCommand_Post
// #define FN_Voice_GetClientListening_Post Voice_GetClientListening_Post
// #define FN_Voice_SetClientListening_Post Voice_SetClientListening_Post
// #define FN_GetPlayerAuthId_Post GetPlayerAuthId_Post
// #define FN_OnFreeEntPrivateData OnFreeEntPrivateData
// #define FN_GameShutdown GameShutdown
// #define FN_ShouldCollide ShouldCollide
// #define FN_OnFreeEntPrivateData_Post OnFreeEntPrivateData_Post
// #define FN_GameShutdown_Post GameShutdown_Post
// #define FN_ShouldCollide_Post ShouldCollide_Post
#endif // USE_METAMOD
#endif // __MODULECONFIG_H__

View File

@ -0,0 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sqlite", "sqlite.vcxproj", "{4FDFD106-7163-44F0-85C4-9FAFECD14973}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{4FDFD106-7163-44F0-85C4-9FAFECD14973}.Debug|Win32.ActiveCfg = Debug|Win32
{4FDFD106-7163-44F0-85C4-9FAFECD14973}.Debug|Win32.Build.0 = Debug|Win32
{4FDFD106-7163-44F0-85C4-9FAFECD14973}.Release|Win32.ActiveCfg = Release|Win32
{4FDFD106-7163-44F0-85C4-9FAFECD14973}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,151 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{4FDFD106-7163-44F0-85C4-9FAFECD14973}</ProjectGuid>
<RootNamespace>sqlite</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectName)_amxx</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectName)_amxx</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<AdditionalOptions>/D "NO_TCL" %(AdditionalOptions)</AdditionalOptions>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl\include;..\..\third_party;..\..\third_party\hashing;..\..\..\third_party\sqlite;..\sqlitepp;..\thread;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;sqlite_EXPORTS;SM_DEFAULT_THREADER;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<StructMemberAlignment>4Bytes</StructMemberAlignment>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<Link>
<IgnoreSpecificDefaultLibraries>LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
<ModuleDefinitionFile>
</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(OutDir)sqlite.pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<ImportLibrary>$(OutDir)sqlite.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalOptions>/D "NO_TCL" %(AdditionalOptions)</AdditionalOptions>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<OmitFramePointers>true</OmitFramePointers>
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl\include;..\..\third_party;..\..\third_party\hashing;..\..\..\third_party\sqlite;..\sqlitepp;..\thread;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\public;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;sqlite_EXPORTS;SM_DEFAULT_THREADER;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<StructMemberAlignment>4Bytes</StructMemberAlignment>
<FunctionLevelLinking>true</FunctionLevelLinking>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<ImportLibrary>$(OutDir)sqlite.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\basic_sql.cpp" />
<ClCompile Include="..\handles.cpp" />
<ClCompile Include="..\module.cpp" />
<ClCompile Include="..\oldcompat_sql.cpp" />
<ClCompile Include="..\..\..\third_party\sqlite\sqlite3.c" />
<ClCompile Include="..\threading.cpp" />
<ClCompile Include="..\sqlitepp\SqliteDatabase.cpp" />
<ClCompile Include="..\sqlitepp\SqliteDriver.cpp" />
<ClCompile Include="..\sqlitepp\SqliteQuery.cpp" />
<ClCompile Include="..\sqlitepp\SqliteResultSet.cpp" />
<ClCompile Include="..\thread\BaseWorker.cpp" />
<ClCompile Include="..\thread\ThreadWorker.cpp" />
<ClCompile Include="..\thread\WinThreads.cpp" />
<ClCompile Include="..\..\..\public\sdk\amxxmodule.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\sqlheaders.h" />
<ClInclude Include="..\..\..\third_party\sqlite\sqlite3.h" />
<ClInclude Include="..\sqlite_header.h" />
<ClInclude Include="..\threading.h" />
<ClInclude Include="..\sqlitepp\ISQLDriver.h" />
<ClInclude Include="..\sqlitepp\SqliteDatabase.h" />
<ClInclude Include="..\sqlitepp\SqliteDriver.h" />
<ClInclude Include="..\sqlitepp\SqliteHeaders.h" />
<ClInclude Include="..\sqlitepp\SqliteQuery.h" />
<ClInclude Include="..\sqlitepp\SqliteResultSet.h" />
<ClInclude Include="..\thread\BaseWorker.h" />
<ClInclude Include="..\thread\IThreader.h" />
<ClInclude Include="..\thread\PosixThreads.h" />
<ClInclude Include="..\thread\ThreadSupport.h" />
<ClInclude Include="..\thread\ThreadWorker.h" />
<ClInclude Include="..\thread\WinThreads.h" />
<ClInclude Include="..\moduleconfig.h" />
<ClInclude Include="..\..\..\public\sdk\amxxmodule.h" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\..\plugins\include\sqlx.inc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,148 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{fee21ba3-ba57-4165-a636-f131192c35ed}</UniqueIdentifier>
<Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{75726cf9-410b-4bb0-8258-e54d8a778fea}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc</Extensions>
</Filter>
<Filter Include="Database">
<UniqueIdentifier>{170198cf-e562-4903-bc68-4c3528e58f5f}</UniqueIdentifier>
</Filter>
<Filter Include="Database\Header Files">
<UniqueIdentifier>{d27ed8de-c2a0-460f-a0f4-a9adcf9e549f}</UniqueIdentifier>
</Filter>
<Filter Include="Database\Source Files">
<UniqueIdentifier>{55a33451-3931-4fac-ba8a-3be3b07d6a34}</UniqueIdentifier>
</Filter>
<Filter Include="Threader">
<UniqueIdentifier>{cf870f84-b709-46d7-a30c-ae8f4c45de23}</UniqueIdentifier>
</Filter>
<Filter Include="Threader\Header Files">
<UniqueIdentifier>{45cbffb2-fb23-4821-b89c-842ec027be01}</UniqueIdentifier>
</Filter>
<Filter Include="Threader\Source Files">
<UniqueIdentifier>{5ef60ee3-dc5b-420f-a8b8-1ef24213fcf7}</UniqueIdentifier>
</Filter>
<Filter Include="SQLite Source">
<UniqueIdentifier>{03fa14bf-6409-4ed7-bb07-da1b356b5076}</UniqueIdentifier>
</Filter>
<Filter Include="Module SDK">
<UniqueIdentifier>{b24e595e-f6a9-4358-bbe3-094ef6383e53}</UniqueIdentifier>
</Filter>
<Filter Include="Module SDK\SDK Base">
<UniqueIdentifier>{c60d3c45-e23b-4c5a-aae2-2c3c5441bac6}</UniqueIdentifier>
</Filter>
<Filter Include="Pawn Includes">
<UniqueIdentifier>{e0a36119-bb5b-4f07-9e0e-80f9aa7a7d21}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\basic_sql.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\handles.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\module.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\oldcompat_sql.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\threading.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\sqlitepp\SqliteDatabase.cpp">
<Filter>Database\Source Files</Filter>
</ClCompile>
<ClCompile Include="..\sqlitepp\SqliteDriver.cpp">
<Filter>Database\Source Files</Filter>
</ClCompile>
<ClCompile Include="..\sqlitepp\SqliteQuery.cpp">
<Filter>Database\Source Files</Filter>
</ClCompile>
<ClCompile Include="..\sqlitepp\SqliteResultSet.cpp">
<Filter>Database\Source Files</Filter>
</ClCompile>
<ClCompile Include="..\thread\BaseWorker.cpp">
<Filter>Threader\Source Files</Filter>
</ClCompile>
<ClCompile Include="..\thread\ThreadWorker.cpp">
<Filter>Threader\Source Files</Filter>
</ClCompile>
<ClCompile Include="..\thread\WinThreads.cpp">
<Filter>Threader\Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\public\sdk\amxxmodule.cpp">
<Filter>Module SDK\SDK Base</Filter>
</ClCompile>
<ClCompile Include="..\sqlite-source\sqlite3.c">
<Filter>SQLite Source</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\sqlheaders.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\sqlite_header.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\threading.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\sqlitepp\ISQLDriver.h">
<Filter>Database</Filter>
</ClInclude>
<ClInclude Include="..\sqlitepp\SqliteDatabase.h">
<Filter>Database\Header Files</Filter>
</ClInclude>
<ClInclude Include="..\sqlitepp\SqliteDriver.h">
<Filter>Database\Header Files</Filter>
</ClInclude>
<ClInclude Include="..\sqlitepp\SqliteHeaders.h">
<Filter>Database\Header Files</Filter>
</ClInclude>
<ClInclude Include="..\sqlitepp\SqliteQuery.h">
<Filter>Database\Header Files</Filter>
</ClInclude>
<ClInclude Include="..\sqlitepp\SqliteResultSet.h">
<Filter>Database\Header Files</Filter>
</ClInclude>
<ClInclude Include="..\thread\BaseWorker.h">
<Filter>Threader\Header Files</Filter>
</ClInclude>
<ClInclude Include="..\thread\IThreader.h">
<Filter>Threader\Header Files</Filter>
</ClInclude>
<ClInclude Include="..\thread\PosixThreads.h">
<Filter>Threader\Header Files</Filter>
</ClInclude>
<ClInclude Include="..\thread\ThreadSupport.h">
<Filter>Threader\Header Files</Filter>
</ClInclude>
<ClInclude Include="..\thread\ThreadWorker.h">
<Filter>Threader\Header Files</Filter>
</ClInclude>
<ClInclude Include="..\thread\WinThreads.h">
<Filter>Threader\Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\public\sdk\amxxmodule.h">
<Filter>Module SDK\SDK Base</Filter>
</ClInclude>
<ClInclude Include="..\moduleconfig.h">
<Filter>Module SDK</Filter>
</ClInclude>
<ClInclude Include="..\sqlite-source\sqlite3.h">
<Filter>SQLite Source</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\..\plugins\include\sqlx.inc">
<Filter>Pawn Includes</Filter>
</None>
</ItemGroup>
</Project>

View File

@ -0,0 +1,459 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// SQLite Module
//
#include <stdio.h>
#include "sh_list.h"
#include "sqlite_header.h"
using namespace SourceMod;
struct olddb_s
{
IDatabase *pDatabase;
char error[255];
int errcode;
};
struct oldresult_s
{
IQuery *pQuery;
QueryInfo info;
bool firstCall;
};
void FreeOldDb(void *ptr, unsigned int hndl)
{
olddb_s *old = (olddb_s *)ptr;
if (old->pDatabase)
{
old->pDatabase->FreeHandle();
old->pDatabase = NULL;
}
delete old;
}
void FreeOldResult(void *ptr, unsigned int hndl)
{
oldresult_s *oldres = (oldresult_s *)ptr;
if (oldres->pQuery)
{
oldres->pQuery->FreeHandle();
oldres->pQuery = NULL;
}
delete oldres;
}
//native Sql:dbi_connect(_host[], _user[], _pass[], _dbname[], _error[]="", _maxlength=0);
static cell AMX_NATIVE_CALL dbi_connect(AMX *amx, cell *params)
{
int len;
DatabaseInfo info;
char *name = MF_GetAmxString(amx, params[4], 3, &len);
char path[255];
info.host = "";
info.user = "";
info.pass = "";
info.database = name;
int err;
char error[512];
/** if there is an older database, read there instead of the new path */
MF_BuildPathnameR(path, sizeof(path)-1, "%s", info.database);
FILE *fp = fopen(path, "rb");
if (fp)
{
fclose(fp);
info.database = path;
} else {
MF_BuildPathnameR(path, sizeof(path)-1, "%s/sqlite3/%s.sq3",
MF_GetLocalInfo("amxx_datadir", "addons/amxmodx/data"),
info.database);
info.database = path;
}
IDatabase *pDatabase = g_Sqlite.Connect(&info, &err, error, sizeof(error)-1);
if (!pDatabase)
{
MF_SetAmxString(amx, params[5], error, params[6]);
return 0;
}
olddb_s *old = new olddb_s;
int hndl;
old->pDatabase = pDatabase;
hndl = MakeHandle(old, Handle_OldDb, FreeOldDb);
return hndl;
}
//native Result:dbi_query(Sql:_sql, _query[], {Float,_}:...);
static cell AMX_NATIVE_CALL dbi_query(AMX *amx, cell *params)
{
olddb_s *old = (olddb_s *)GetHandle(params[1], Handle_OldDb);
if (!old)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid DBI handle %d", params[1]);
return -1;
}
int len;
char *queryString = MF_FormatAmxString(amx, params, 2, &len);
IQuery *pQuery = old->pDatabase->PrepareQuery(queryString);
QueryInfo info;
old->error[0] = '\0';
old->errcode = 0;
if (!pQuery->Execute2(&info, old->error, 254))
{
old->errcode = info.errorcode;
return -1;
} else {
if (info.rs && info.rs->RowCount())
{
oldresult_s *oldrs = new oldresult_s;
int hndl;
oldrs->info = info;
oldrs->pQuery = pQuery;
oldrs->firstCall = true;
hndl = MakeHandle(oldrs, Handle_OldResult, FreeOldResult);
return hndl;
} else {
pQuery->FreeHandle();
return 0;
}
}
/** never reach here */
return 0;
}
//native Result:dbi_query2(Sql:_sql, &rows, _query[], {Float,_}:...);
static cell AMX_NATIVE_CALL dbi_query2(AMX *amx, cell *params)
{
olddb_s *old = (olddb_s *)GetHandle(params[1], Handle_OldDb);
if (!old)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid DBI handle %d", params[1]);
return -1;
}
int len;
char *queryString = MF_FormatAmxString(amx, params, 3, &len);
IQuery *pQuery = old->pDatabase->PrepareQuery(queryString);
QueryInfo info;
old->error[0] = '\0';
old->errcode = 0;
if (!pQuery->Execute2(&info, old->error, 254))
{
old->errcode = info.errorcode;
return -1;
} else {
cell *addr = MF_GetAmxAddr(amx, params[2]);
*addr = static_cast<cell>(info.affected_rows);
if (info.rs && info.rs->RowCount())
{
oldresult_s *oldrs = new oldresult_s;
int hndl;
oldrs->info = info;
oldrs->pQuery = pQuery;
oldrs->firstCall = true;
hndl = MakeHandle(oldrs, Handle_OldResult, FreeOldResult);
return hndl;
} else {
pQuery->FreeHandle();
return 0;
}
}
/** never reach here */
return 0;
}
//native dbi_nextrow(Result:_result);
static cell AMX_NATIVE_CALL dbi_nextrow(AMX *amx, cell *params)
{
if (params[1] == 0)
{
return 0;
}
oldresult_s *oldrs = (oldresult_s *)GetHandle(params[1], Handle_OldResult);
if (!oldrs)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid DBI result handle %d", params[1]);
return 0;
}
if (oldrs->firstCall)
{
oldrs->firstCall = false;
return (oldrs->info.rs->IsDone() ? 0 : 1);
} else {
oldrs->info.rs->NextRow();
return (oldrs->info.rs->IsDone() ? 0 : 1);
}
}
//native dbi_field(Result:_result, _fieldnum, {Float,_}:... );
static cell AMX_NATIVE_CALL dbi_field(AMX *amx, cell *params)
{
oldresult_s *oldrs = (oldresult_s *)GetHandle(params[1], Handle_OldResult);
if (!oldrs)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid DBI result handle %d", params[1]);
return 0;
}
IResultSet *rs = oldrs->info.rs;
IResultRow *rr = rs->GetRow();
unsigned int num = (unsigned int)params[2] - 1;
if (num >= rs->FieldCount())
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid column %d", params[2]);
return 0;
}
cell stype = params[0] / sizeof(cell);
const char *data = rr->GetString(num);
if (!data)
data = "";
switch (stype)
{
case 2:
{
return atoi(data);
break;
}
case 3:
{
cell *destaddr = MF_GetAmxAddr(amx, params[3]);
REAL fdata = atof(data);
*destaddr = amx_ftoc(fdata);
return 1;
break;
}
case 4:
{
return MF_SetAmxString(amx, params[3], data, params[4]);
break;
}
}
/** never reach here */
return 0;
}
//native dbi_result(Result:_result, _field[], {Float,_}:... );
static cell AMX_NATIVE_CALL dbi_result(AMX *amx, cell *params)
{
oldresult_s *oldrs = (oldresult_s *)GetHandle(params[1], Handle_OldResult);
if (!oldrs)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid DBI result handle %d", params[1]);
return 0;
}
IResultSet *rs = oldrs->info.rs;
IResultRow *rr = rs->GetRow();
unsigned int num;
bool found = false;
unsigned int fields = rs->FieldCount();
int len;
char *field = MF_GetAmxString(amx, params[2], 0, &len);
for (unsigned int i=0; i<fields; i++)
{
if (strcmp(field, rs->FieldNumToName(i)) == 0)
{
num = i;
found = true;
break;
}
}
if (!found)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Unknown column \"%s\"", field);
return 0;
}
cell stype = params[0] / sizeof(cell);
const char *data = rr->GetString(num);
if (!data)
data = "";
switch (stype)
{
case 2:
{
return atoi(data);
break;
}
case 3:
{
cell *destaddr = MF_GetAmxAddr(amx, params[3]);
REAL fdata = atof(data);
*destaddr = amx_ftoc(fdata);
return 1;
break;
}
case 4:
{
return MF_SetAmxString(amx, params[3], data, params[4]);
break;
}
}
/** never reach here */
return 0;
}
//native dbi_num_rows(Result:_result);
static cell AMX_NATIVE_CALL dbi_num_rows(AMX *amx, cell *params)
{
oldresult_s *oldrs = (oldresult_s *)GetHandle(params[1], Handle_OldResult);
if (!oldrs)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid DBI result handle %d", params[1]);
return 0;
}
return oldrs->info.rs->RowCount();
}
//native dbi_free_result(&Result:result);
static cell AMX_NATIVE_CALL dbi_free_result(AMX *amx, cell *params)
{
cell *_r = MF_GetAmxAddr(amx, params[1]);
cell num = *_r;
if (!num)
{
return 1;
}
oldresult_s *oldrs = (oldresult_s *)GetHandle(num, Handle_OldResult);
if (!oldrs)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid DBI result handle %d", num);
return 0;
}
FreeHandle(num);
*_r = 0;
return 1;
}
//native dbi_close(&Sql:_sql);
static cell AMX_NATIVE_CALL dbi_close(AMX *amx, cell *params)
{
cell *_r = MF_GetAmxAddr(amx, params[1]);
cell num = *_r;
olddb_s *old = (olddb_s *)GetHandle(num, Handle_OldDb);
if (!old)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid DBI handle %d", num);
return 0;
}
FreeHandle(num);
*_r = 0;
return 1;
}
//native dbi_error(Sql:_sql, _error[], _len);
static cell AMX_NATIVE_CALL dbi_error(AMX *amx, cell *params)
{
olddb_s *old = (olddb_s *)GetHandle(params[1], Handle_OldDb);
if (!old)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid DBI handle %d", params[1]);
return -1;
}
MF_SetAmxString(amx, params[2], old->error, params[3]);
return old->errcode;
}
//native dbi_type(_type[], _len);
static cell AMX_NATIVE_CALL dbi_type(AMX *amx, cell *params)
{
return MF_SetAmxString(amx, params[1], g_Sqlite.NameString(), params[2]);
}
//native dbi_num_fields(Result:result);
static cell AMX_NATIVE_CALL dbi_num_fields(AMX *amx, cell *params)
{
oldresult_s *oldrs = (oldresult_s *)GetHandle(params[1], Handle_OldResult);
if (!oldrs)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid DBI result handle %d", params[1]);
return 0;
}
return oldrs->info.rs->FieldCount();
}
//native dbi_field_name(Result:result, field, name[], maxLength);
static cell AMX_NATIVE_CALL dbi_field_name(AMX *amx, cell *params)
{
oldresult_s *oldrs = (oldresult_s *)GetHandle(params[1], Handle_OldResult);
if (!oldrs)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid DBI result handle %d", params[1]);
return 0;
}
const char *name = oldrs->info.rs->FieldNumToName(static_cast<unsigned int>(params[2]-1));
if (!name)
return 0;
MF_SetAmxString(amx, params[3], name, params[4]);
return 1;
}
AMX_NATIVE_INFO g_OldCompatNatives[] =
{
{ "dbi_connect", dbi_connect },
{ "dbi_query", dbi_query },
{ "dbi_query2", dbi_query2 },
{ "dbi_field", dbi_field },
{ "dbi_nextrow", dbi_nextrow },
{ "dbi_close", dbi_close },
{ "dbi_error", dbi_error },
{ "dbi_type", dbi_type },
{ "dbi_free_result", dbi_free_result },
{ "dbi_num_rows", dbi_num_rows },
{ "dbi_result", dbi_result },
{ "dbi_num_fields", dbi_num_fields },
{ "dbi_field_name", dbi_field_name },
{ NULL, NULL }
};

View File

@ -0,0 +1,31 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// SQLite Module
//
#ifndef _INCLUDE_SQLHEADERS_H
#define _INCLUDE_SQLHEADERS_H
#include "ISQLDriver.h"
#define SQL_DRIVER_FUNC "GetSqlFuncs"
typedef int (*SQLAFFINITY)(AMX *amx);
struct SqlFunctions
{
SourceMod::ISQLDriver *driver;
SQLAFFINITY set_affinity;
SqlFunctions *prev;
};
#endif //_INCLUDE_SQLHEADERS_H

View File

@ -0,0 +1,69 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// SQLite Module
//
#ifndef _INCLUDE_AMXMODX_MYSQL2_HEADER_H
#define _INCLUDE_AMXMODX_MYSQL2_HEADER_H
#include "SqliteDriver.h"
#include "amxxmodule.h"
#include "ThreadSupport.h"
#include "ThreadWorker.h"
#define SQLITE_THREADED
struct AmxQueryInfo
{
AmxQueryInfo() : opt_ptr(NULL) { };
IQuery *pQuery;
QueryInfo info;
char error[255];
char *opt_ptr;
};
enum HandleType
{
Handle_Invalid = -1,
Handle_Connection = 0,
Handle_Database,
Handle_Query,
Handle_OldDb,
Handle_OldResult,
};
struct SQL_Connection
{
char *host;
char *user;
char *pass;
char *db;
int port;
};
typedef void (*FREEHANDLE)(void *, unsigned int);
unsigned int MakeHandle(void *ptr, HandleType type, FREEHANDLE f);
void *GetHandle(unsigned int num, HandleType type);
bool FreeHandle(unsigned int num);
void FreeAllHandles(HandleType type);
void FreeHandleTable();
void ShutdownThreading();
int SetMysqlAffinity(AMX *amx);
extern AMX_NATIVE_INFO g_BaseSqlNatives[];
extern AMX_NATIVE_INFO g_ThreadSqlNatives[];
extern AMX_NATIVE_INFO g_OldCompatNatives[];
extern MainThreader g_Threader;
extern ThreadWorker *g_pWorker;
extern SourceMod::SqliteDriver g_Sqlite;
#endif //_INCLUDE_AMXMODX_MYSQL2_HEADER_H

View File

@ -0,0 +1,187 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// SQLite Module
//
#ifndef _INCLUDE_SOURCEMOD_DATABASE2_H
#define _INCLUDE_SOURCEMOD_DATABASE2_H
#include <stdarg.h>
namespace SourceMod
{
class IResultRow
{
public:
virtual ~IResultRow() { };
public:
/**
* This will return NULL if the entry is NULL.
* Remember that in SQL, a field can have NULL
* entries, which are not the same as 0 or "".
*/
virtual const char *GetString(unsigned int columnId) =0;
virtual double GetDouble(unsigned int columnId) =0;
virtual float GetFloat(unsigned int columnId) =0;
virtual int GetInt(unsigned int columnId) =0;
virtual bool IsNull(unsigned int columnId) =0;
/**
* NULL can be returned. The length will be zero if so.
*/
virtual const char *GetRaw(unsigned int columnId, size_t *length) =0;
};
class IResultSet
{
public:
virtual ~IResultSet() { };
public:
//free the handle if necessary (see IQuery).
virtual void FreeHandle() =0;
public: //Basic stuff
virtual unsigned int RowCount() =0;
virtual unsigned int FieldCount() =0;
virtual const char *FieldNumToName(unsigned int num) =0;
virtual bool FieldNameToNum(const char *name, unsigned int *columnId) =0;
public: //iteration
/**
* Returns true if there are no more handles left.
*/
virtual bool IsDone() =0;
/**
* Returns the current row. If "IsDone()" is false
* this is guaranteed to return non-NULL.
* Handles to IResultRow are guaranteed to not leak
* (you don't need to free them), however,
* they should be considered volatile - don't cache
* them.
*/
virtual IResultRow *GetRow() =0;
/**
* Advances to the next row. Note that you need to
* call IsDone() after each call to NextRow().
*/
virtual void NextRow() =0;
/**
* Resets back to the first row.
*/
virtual void Rewind() =0;
/* Always returns false in Sqlite */
virtual bool NextResultSet() =0;
};
struct QueryInfo
{
IResultSet *rs;
unsigned long long affected_rows;
int errorcode;
bool success;
unsigned long long insert_id;
};
class IQuery
{
public:
virtual ~IQuery() { };
public:
//you must free the handle when done
virtual void FreeHandle() =0;
public:
/**
* Executes the query. Specify optional error string buffer.
* If "info" is NULL, no results will be stored.
* Returns false on failure.
* Calling Execute() multiple times will cause each result handle
* to be freed in succession. That means that you do not need to
* explicitly free IResultSets when using Execute(), but their
* handles are deep-invalidated on succesive calls, and
* thus Execute() is also not thread safe.
*/
virtual bool Execute(QueryInfo *info, char *error, size_t maxlength) =0;
/**
* Same as above, except result handles are not freed for you.
*/
virtual bool ExecuteR(QueryInfo *info, char *error, size_t maxlength) =0;
/**
* Returns the query string.
*/
virtual const char *GetQueryString() =0;
/**
* Same as execute, but supports insert_id
*/
virtual bool Execute2(QueryInfo *info, char *error, size_t maxlength) =0;
};
class ISQLDriver;
class IDatabase
{
public:
virtual ~IDatabase() { };
public:
/**
* Closes the database and frees the handle.
*/
virtual void FreeHandle() =0;
/**
* Returns the parent driver.
*/
virtual ISQLDriver *Driver() =0;
public:
/**
* Query preparation.
*/
virtual IQuery *PrepareQueryFmt(const char *fmt, ...) =0;
virtual IQuery *PrepareQueryFmt(const char *fmt, va_list ap) =0;
virtual IQuery *PrepareQuery(const char *query) =0;
/**
* Quotes a string properly.
* Returns 0 on success. On failure, returns
* the size of the buffer needed, or a negative number
* on internal failure.
*/
virtual int QuoteString(const char *str, char buffer[], size_t maxlen, size_t *newsize) =0;
/**
* @brief Sets the character set of the current connection
*
* @param characterset The characterset to switch to. e.g. "utf8".
*/
virtual bool SetCharacterSet(const char *characterset) =0;
};
struct DatabaseInfo
{
DatabaseInfo() : max_timeout(0) { };
const char *host;
const char *database;
const char *user;
const char *pass;
unsigned int port;
unsigned int max_timeout;
const char *charset;
};
class ISQLDriver
{
public:
virtual ~ISQLDriver() { };
public:
virtual IDatabase *Connect(DatabaseInfo *info, int *errcode, char *error, size_t maxlength) =0;
//Supports the timeout clause
virtual IDatabase *Connect2(DatabaseInfo *info, int *errcode, char *error, size_t maxlength) =0;
virtual const char *NameString() =0;
virtual bool IsCompatDriver(const char *namestring) =0;
};
};
#endif //_INCLUDE_SOURCEMOD_DATABASE2_H

View File

@ -0,0 +1,99 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// SQLite Module
//
#include <stdio.h>
#include <string.h>
#include "SqliteDriver.h"
#include "SqliteDatabase.h"
#include "SqliteQuery.h"
#if defined WIN32 && !defined vsnprintf
#define vsnprintf _vsnprintf
#endif
using namespace SourceMod;
SqliteDatabase::SqliteDatabase(sqlite3 *sql, SqliteDriver *drvr) :
m_pSql(sql), m_pParent(drvr)
{
}
SqliteDatabase::~SqliteDatabase()
{
Disconnect();
}
void SqliteDatabase::Disconnect()
{
if (m_pSql)
{
sqlite3_close(m_pSql);
m_pSql = NULL;
}
}
void SqliteDatabase::FreeHandle()
{
delete this;
}
ISQLDriver *SqliteDatabase::Driver()
{
return static_cast<ISQLDriver *>(m_pParent);
}
IQuery *SqliteDatabase::PrepareQuery(const char *query)
{
SqliteQuery *pQuery = new SqliteQuery(this, query);
return static_cast<IQuery *>(pQuery);
}
IQuery *SqliteDatabase::PrepareQueryFmt(const char *fmt, va_list ap)
{
char buffer[4096];
vsnprintf(buffer, sizeof(buffer)-1, fmt, ap);
return PrepareQuery(buffer);
}
IQuery *SqliteDatabase::PrepareQueryFmt(const char *fmt, ...)
{
va_list ap;
IQuery *qry;
va_start(ap, fmt);
qry = PrepareQueryFmt(fmt, ap);
va_end(ap);
return qry;
}
int SqliteDatabase::QuoteString(const char *str, char buffer[], size_t maxlen, size_t *newsize)
{
char *res = sqlite3_snprintf(static_cast<int>(maxlen), buffer, "%q", str);
if (res != NULL && newsize != NULL)
{
*newsize = strlen(buffer);
}
return 0;
}
bool SqliteDatabase::SetCharacterSet(const char *characterset)
{
// sqlite only supports utf8 and utf16 - by the time the database is created. It's too late here.
return false;
}

View File

@ -0,0 +1,48 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// SQLite Module
//
#ifndef _INCLUDE_SOURCEMOD_SQLITE_DATABASE_H
#define _INCLUDE_SOURCEMOD_SQLITE_DATABASE_H
#include "SqliteHeaders.h"
#include "SqliteDriver.h"
namespace SourceMod
{
class SqliteDriver;
class SqliteDatabase : public IDatabase
{
friend class SqliteQuery;
public:
SqliteDatabase(sqlite3 *sql, SqliteDriver *drvr);
~SqliteDatabase();
public:
void FreeHandle();
ISQLDriver *Driver();
public:
IQuery *PrepareQueryFmt(const char *fmt, ...);
IQuery *PrepareQueryFmt(const char *fmt, va_list ap);
IQuery *PrepareQuery(const char *query);
int QuoteString(const char *str, char buffer[], size_t maxlen, size_t *newsize);
bool SetCharacterSet(const char *characterset);
private:
void Disconnect();
private:
sqlite3 *m_pSql;
SqliteDriver *m_pParent;
};
};
#endif //_INCLUDE_SOURCEMOD_SQLITE_DATABASE_H

View File

@ -0,0 +1,87 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// SQLite Module
//
#include "amxxmodule.h"
#include "SqliteHeaders.h"
#include "SqliteDriver.h"
#include "SqliteDatabase.h"
#if defined WIN32
#define WINDOWS_LEAN_AND_MEAN
#include <windows.h>
#else
#include <unistd.h>
#endif
using namespace SourceMod;
bool SqliteDriver::IsCompatDriver(const char *namestr)
{
return (strncasecmp(namestr, "sqlite", 5) == 0);
}
const char *SqliteDriver::NameString()
{
return "sqlite";
}
int busy_handler(void *unused1, int unused2)
{
#if defined __linux__ || defined __APPLE__
usleep(100000);
#else
Sleep(100);
#endif
return 1;
}
IDatabase *SqliteDriver::Connect2(DatabaseInfo *info, int *errcode, char *error, size_t maxlength)
{
return Connect(info, errcode, error, maxlength);
}
IDatabase *SqliteDriver::Connect(DatabaseInfo *info, int *errcode, char *error, size_t maxlength)
{
sqlite3 *pSql;
int err = sqlite3_open(info->database, &pSql);
if (err != SQLITE_OK)
{
if (errcode)
{
*errcode = sqlite3_errcode(pSql);
}
if (error)
{
UTIL_Format(error, maxlength, "%s", sqlite3_errmsg(pSql));
}
sqlite3_close(pSql);
return NULL;
} else {
sqlite3_busy_handler(pSql, busy_handler, NULL);
SqliteDatabase *pDb = new SqliteDatabase(pSql, this);
return static_cast<IDatabase *>(pDb);
}
}
int SqliteDriver::QuoteString(const char *str, char buffer[], size_t maxlen, size_t *newsize)
{
char *res = sqlite3_snprintf(static_cast<int>(maxlen), buffer, "%q", str);
if (res != NULL && newsize != NULL)
{
*newsize = strlen(buffer);
}
return 0;
}

View File

@ -0,0 +1,32 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// SQLite Module
//
#ifndef _INCLUDE_SOURCEMOD_SQLITE_DRIVER_H
#define _INCLUDE_SOURCEMOD_SQLITE_DRIVER_H
#include "SqliteHeaders.h"
namespace SourceMod
{
class SqliteDriver : public ISQLDriver
{
public:
IDatabase *Connect(DatabaseInfo *info, int *errcode, char *error, size_t maxlength);
IDatabase *Connect2(DatabaseInfo *info, int *errcode, char *error, size_t maxlength);
const char *NameString();
bool IsCompatDriver(const char *namestr);
int QuoteString(const char *str, char buffer[], size_t maxlen, size_t *newsize);
};
};
#endif //_INCLUDE_SOURCEMOD_SQLITE_DRIVER_H

View File

@ -0,0 +1,30 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// SQLite Module
//
#ifndef _INCLUDE_SOURCEMOD_SQLITE_HEADERS_H
#define _INCLUDE_SOURCEMOD_SQLITE_HEADERS_H
#if _MSC_VER >= 1400
/* disable deprecation warnings */
#if !defined _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE
#endif
#pragma warning (disable:4996)
#endif //_MSC_VER >= 1400
#include <ISQLDriver.h>
#include "sqlite3.h"
#endif //_INCLUDE_SOURCEMOD_SQLITE_HEADERS_H

View File

@ -0,0 +1,124 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// SQLite Module
//
#include "amxxmodule.h"
#include "SqliteQuery.h"
#include "SqliteDatabase.h"
#include "SqliteResultSet.h"
using namespace SourceMod;
SqliteQuery::SqliteQuery(SqliteDatabase *db, const char *query) :
m_pDatabase(db), m_LastRes(NULL)
{
m_QueryString = new char[strlen(query)+1];
strcpy(m_QueryString, query);
}
SqliteQuery::~SqliteQuery()
{
if (m_LastRes)
{
m_LastRes->FreeHandle();
m_LastRes = NULL;
}
delete [] m_QueryString;
}
void SqliteQuery::FreeHandle()
{
delete this;
}
bool SqliteQuery::Execute(QueryInfo *info, char *error, size_t maxlength)
{
bool res = ExecuteR(info, error, maxlength);
if (m_LastRes)
{
m_LastRes->FreeHandle();
}
m_LastRes = (SqliteResultSet *)info->rs;
return res;
}
bool SqliteQuery::Execute2(QueryInfo *info, char *error, size_t maxlength)
{
bool res = ExecuteR(info, error, maxlength);
if (m_LastRes)
m_LastRes->FreeHandle();
m_LastRes = (SqliteResultSet *)info->rs;
if (info->success)
{
info->insert_id = sqlite3_last_insert_rowid(m_pDatabase->m_pSql);
} else {
info->insert_id = 0;
}
return res;
}
const char *SqliteQuery::GetQueryString()
{
return m_QueryString;
}
bool SqliteQuery::ExecuteR(QueryInfo *info, char *error, size_t maxlength)
{
int err;
char *errmsg;
char **results;
int rows, cols;
err = sqlite3_get_table(m_pDatabase->m_pSql, m_QueryString, &results, &rows, &cols, &errmsg);
if (err != SQLITE_OK)
{
if (error && maxlength && errmsg)
{
UTIL_Format(error, maxlength, "%s", errmsg);
}
info->affected_rows = 0;
info->errorcode = err;
info->rs = NULL;
info->success = false;
} else {
info->affected_rows = sqlite3_changes(m_pDatabase->m_pSql);
info->errorcode = 0;
info->success = true;
if (cols)
{
SqliteResults data;
data.cols = cols;
data.rows = rows;
data.results = results;
SqliteResultSet *pRes = new SqliteResultSet(data);
info->rs = static_cast<IResultSet *>(pRes);
} else {
info->rs = NULL;
if (results)
{
sqlite3_free_table(results);
}
}
}
return info->success;
}

View File

@ -0,0 +1,49 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// SQLite Module
//
#ifndef _INCLUDE_SOURCEMOD_SQLITE_QUERY_H
#define _INCLUDE_SOURCEMOD_SQLITE_QUERY_H
#include "SqliteHeaders.h"
namespace SourceMod
{
class SqliteDatabase;;
class SqliteResultSet;
class SqliteQuery : public IQuery
{
public:
struct SqliteResults
{
char **results;
int rows;
int cols;
};
public:
SqliteQuery(SqliteDatabase *db, const char *query);
~SqliteQuery();
public:
void FreeHandle();
bool Execute(QueryInfo *info, char *error, size_t maxlength);
bool ExecuteR(QueryInfo *info, char *error, size_t maxlength);
bool Execute2(QueryInfo *info, char *error, size_t maxlength);
const char *GetQueryString();
private:
SqliteDatabase *m_pDatabase;
SqliteResultSet *m_LastRes;
char *m_QueryString;
};
};
#endif //_INCLUDE_SOURCEMOD_SQLITE_QUERY_H

View File

@ -0,0 +1,184 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// SQLite Module
//
#include <string.h>
#include <stdlib.h>
#include "SqliteResultSet.h"
using namespace SourceMod;
SqliteResultSet::SqliteResultSet(SqliteQuery::SqliteResults &res)
{
m_pResults = res.results;
m_Columns = res.cols;
m_Rows = res.rows;
m_CurRow = 1;
m_CurIndex = (m_CurRow * m_Columns);
}
SqliteResultSet::~SqliteResultSet()
{
if (m_pResults)
{
sqlite3_free_table(m_pResults);
m_pResults = NULL;
}
}
const char *SqliteResultSet::GetStringSafe(unsigned int columnId)
{
if (columnId > m_Columns)
{
return "";
}
const char *data = m_pResults[m_CurIndex + columnId];
return data ? data : "";
}
const char *SqliteResultSet::GetString(unsigned int columnId)
{
if (columnId > m_Columns)
{
return NULL;
}
return m_pResults[m_CurIndex + columnId];
}
bool SqliteResultSet::IsNull(unsigned int columnId)
{
return (GetString(columnId) == NULL);
}
double SqliteResultSet::GetDouble(unsigned int columnId)
{
return atof(GetStringSafe(columnId));
}
float SqliteResultSet::GetFloat(unsigned int columnId)
{
return (float)atof(GetStringSafe(columnId));
}
int SqliteResultSet::GetInt(unsigned int columnId)
{
return atoi(GetStringSafe(columnId));
}
/**
* :TODO: - convert this whole beast to sqlite3_prepare/step
* that way we get finer control and actual raw/null data.
*/
const char *SqliteResultSet::GetRaw(unsigned int columnId, size_t *length)
{
if (columnId >= m_Columns)
{
if (length)
{
*length = 0;
}
return NULL;
}
const char *str = GetString(columnId);
if (!str)
{
if (length)
{
*length = 0;
}
return NULL;
} else {
if (length)
{
*length = strlen(str);
}
return str;
}
}
void SqliteResultSet::FreeHandle()
{
delete this;
}
IResultRow *SqliteResultSet::GetRow()
{
return static_cast<IResultRow *>(this);
}
unsigned int SqliteResultSet::RowCount()
{
return m_Rows;
}
const char *SqliteResultSet::FieldNumToName(unsigned int num)
{
if (num >= m_Columns)
{
return NULL;
}
return m_pResults[num];
}
bool SqliteResultSet::FieldNameToNum(const char *name, unsigned int *columnId)
{
for (unsigned int i=0; i<m_Columns; i++)
{
if (strcmp(m_pResults[i], name) == 0)
{
if (columnId)
{
*columnId = i;
}
return true;
}
}
if (columnId)
{
*reinterpret_cast<int *>(columnId) = -1;
}
return false;
}
unsigned int SqliteResultSet::FieldCount()
{
return m_Columns;
}
bool SqliteResultSet::IsDone()
{
return (m_CurRow > m_Rows);
}
void SqliteResultSet::NextRow()
{
m_CurIndex = (++m_CurRow * m_Columns);
}
void SqliteResultSet::Rewind()
{
m_CurRow = 1;
m_CurIndex = (m_CurRow * m_Columns);
}
bool SqliteResultSet::NextResultSet()
{
return false;
}

View File

@ -0,0 +1,68 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// SQLite Module
//
#ifndef _INCLUDE_SOURCEMOD_SQLITE_RESULTSET_H
#define _INCLUDE_SOURCEMOD_SQLITE_RESULTSET_H
#include "SqliteHeaders.h"
#include "SqliteDriver.h"
#include "SqliteDatabase.h"
#include "SqliteQuery.h"
namespace SourceMod
{
class SqliteResultSet : public IResultSet, public IResultRow
{
/**
* IResultSet
*/
public:
SqliteResultSet(SqliteQuery::SqliteResults &res);
~SqliteResultSet();
public:
void FreeHandle();
public:
unsigned int RowCount();
unsigned int FieldCount();
const char *FieldNumToName(unsigned int num);
bool FieldNameToNum(const char *name, unsigned int *columnId);
public:
bool IsDone();
IResultRow *GetRow();
void NextRow();
void Rewind();
public:
/**
* IResultRow
*/
public:
const char *GetString(unsigned int columnId);
double GetDouble(unsigned int columnId);
float GetFloat(unsigned int columnId);
int GetInt(unsigned int columnId);
bool IsNull(unsigned int columnId);
const char *GetRaw(unsigned int columnId, size_t *length);
bool NextResultSet();
private:
const char *GetStringSafe(unsigned int columnId);
private:
char **m_pResults;
unsigned int m_Columns;
unsigned int m_Rows;
unsigned int m_CurRow;
unsigned int m_CurIndex;
};
};
#endif //_INCLUDE_SOURCEMOD_SQLITE_RESULTSET_H

View File

@ -0,0 +1,258 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
#include "BaseWorker.h"
BaseWorker::BaseWorker() :
m_perFrame(SM_DEFAULT_THREADS_PER_FRAME),
m_state(Worker_Stopped)
{
}
BaseWorker::~BaseWorker()
{
if (m_state != Worker_Stopped || m_state != Worker_Invalid)
Stop(true);
if (m_ThreadQueue.size())
Flush(true);
}
void BaseWorker::MakeThread(IThread *pThread)
{
ThreadParams pt;
pt.flags = Thread_AutoRelease;
pt.prio = ThreadPrio_Normal;
MakeThread(pThread, &pt);
}
IThreadHandle *BaseWorker::MakeThread(IThread *pThread, ThreadFlags flags)
{
ThreadParams pt;
pt.flags = flags;
pt.prio = ThreadPrio_Normal;
return MakeThread(pThread, &pt);
}
IThreadHandle *BaseWorker::MakeThread(IThread *pThread, const ThreadParams *params)
{
if (m_state != Worker_Running)
return NULL;
SWThreadHandle *swt = new SWThreadHandle(this, params, pThread);
AddThreadToQueue(swt);
return swt;
}
void BaseWorker::GetPriorityBounds(ThreadPriority &max, ThreadPriority &min)
{
max = ThreadPrio_Normal;
min = ThreadPrio_Normal;
}
unsigned int BaseWorker::Flush(bool flush_cancel)
{
SWThreadHandle *swt;
unsigned int num = 0;
while ((swt=PopThreadFromQueue()) != NULL)
{
swt->m_state = Thread_Done;
if (!flush_cancel)
swt->pThread->RunThread(swt);
swt->pThread->OnTerminate(swt, flush_cancel);
if (swt->m_params.flags & Thread_AutoRelease)
delete swt;
num++;
}
return num;
}
SWThreadHandle *BaseWorker::PopThreadFromQueue()
{
if (!m_ThreadQueue.size())
return NULL;
List<SWThreadHandle *>::iterator begin;
SWThreadHandle *swt;
begin = m_ThreadQueue.begin();
swt = (*begin);
m_ThreadQueue.erase(begin);
return swt;
}
void BaseWorker::AddThreadToQueue(SWThreadHandle *pHandle)
{
m_ThreadQueue.push_back(pHandle);
}
unsigned int BaseWorker::GetMaxThreadsPerFrame()
{
return m_perFrame;
}
WorkerState BaseWorker::GetStatus(unsigned int *threads)
{
if (threads)
*threads = m_perFrame;
return m_state;
}
unsigned int BaseWorker::RunFrame()
{
unsigned int done = 0;
unsigned int max = GetMaxThreadsPerFrame();
SWThreadHandle *swt = NULL;
IThread *pThread = NULL;
while (done < max)
{
if ((swt=PopThreadFromQueue()) == NULL)
break;
pThread = swt->pThread;
swt->m_state = Thread_Running;
pThread->RunThread(swt);
swt->m_state = Thread_Done;
pThread->OnTerminate(swt, false);
if (swt->m_params.flags & Thread_AutoRelease)
delete swt;
done++;
}
return done;
}
void BaseWorker::SetMaxThreadsPerFrame(unsigned int threads)
{
m_perFrame = threads;
}
bool BaseWorker::Start()
{
if (m_state != Worker_Invalid && m_state != Worker_Stopped)
{
return false;
}
m_state = Worker_Running;
return true;
}
bool BaseWorker::Stop(bool flush_cancel)
{
if (m_state == Worker_Invalid || m_state == Worker_Stopped)
return false;
if (m_state == Worker_Paused)
{
if (!Unpause())
return false;
}
m_state = Worker_Stopped;
Flush(flush_cancel);
return true;
}
bool BaseWorker::Pause()
{
if (m_state != Worker_Running)
return false;
m_state = Worker_Paused;
return true;
}
bool BaseWorker::Unpause()
{
if (m_state != Worker_Paused)
return false;
m_state = Worker_Running;
return true;
}
/***********************
* THREAD HANDLE STUFF *
***********************/
void SWThreadHandle::DestroyThis()
{
delete this;
}
void SWThreadHandle::GetParams(ThreadParams *p)
{
*p = m_params;
}
ThreadPriority SWThreadHandle::GetPriority()
{
return m_params.prio;
}
ThreadState SWThreadHandle::GetState()
{
return m_state;
}
IThreadCreator *SWThreadHandle::Parent()
{
return m_parent;
}
bool SWThreadHandle::SetPriority(ThreadPriority prio)
{
if (m_params.prio != ThreadPrio_Normal)
return false;
m_params.prio = prio;
return true;
}
bool SWThreadHandle::Unpause()
{
if (m_state != Thread_Paused)
return false;
m_state = Thread_Running;
return true;
}
bool SWThreadHandle::WaitForThread()
{
return false;
}
SWThreadHandle::SWThreadHandle(IThreadCreator *parent, const ThreadParams *p, IThread *thread) :
m_state(Thread_Paused), m_params(*p), m_parent(parent), pThread(thread)
{
}
IThread *SWThreadHandle::GetThread()
{
return pThread;
}

View File

@ -0,0 +1,81 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
#ifndef _INCLUDE_SOURCEMOD_BASEWORKER_H
#define _INCLUDE_SOURCEMOD_BASEWORKER_H
#include <sh_list.h>
#include "ThreadSupport.h"
#define SM_DEFAULT_THREADS_PER_FRAME 1
class BaseWorker;
//SW = Simple Wrapper
class SWThreadHandle : public IThreadHandle
{
friend class BaseWorker;
public:
SWThreadHandle(IThreadCreator *parent, const ThreadParams *p, IThread *thread);
IThread *GetThread();
public:
//NOTE: We don't support this by default.
//It's specific usage that'd require many mutexes
virtual bool WaitForThread();
public:
virtual void DestroyThis();
virtual IThreadCreator *Parent();
virtual void GetParams(ThreadParams *ptparams);
public:
//Priorities not supported by default.
virtual ThreadPriority GetPriority();
virtual bool SetPriority(ThreadPriority prio);
public:
virtual ThreadState GetState();
virtual bool Unpause();
private:
ThreadState m_state;
ThreadParams m_params;
IThreadCreator *m_parent;
IThread *pThread;
};
class BaseWorker : public IWorker
{
public:
BaseWorker();
virtual ~BaseWorker();
public: //IWorker
virtual unsigned int RunFrame();
//Controls the worker
virtual bool Pause();
virtual bool Unpause();
virtual bool Start();
virtual bool Stop(bool flush_cancel);
//Flushes out any remaining threads
virtual unsigned int Flush(bool flush_cancel);
//returns status and number of threads in queue
virtual WorkerState GetStatus(unsigned int *numThreads);
public: //IThreadCreator
virtual void MakeThread(IThread *pThread);
virtual IThreadHandle *MakeThread(IThread *pThread, ThreadFlags flags);
virtual IThreadHandle *MakeThread(IThread *pThread, const ThreadParams *params);
virtual void GetPriorityBounds(ThreadPriority &max, ThreadPriority &min);
public: //BaseWorker
virtual void AddThreadToQueue(SWThreadHandle *pHandle);
virtual SWThreadHandle *PopThreadFromQueue();
virtual void SetMaxThreadsPerFrame(unsigned int threads);
virtual unsigned int GetMaxThreadsPerFrame();
protected:
List<SWThreadHandle *> m_ThreadQueue;
unsigned int m_perFrame;
volatile WorkerState m_state;
};
#endif //_INCLUDE_SOURCEMOD_BASEWORKER_H

View File

@ -0,0 +1,237 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
#ifndef _INCLUDE_SOURCEMOD_THREADER_H
#define _INCLUDE_SOURCEMOD_THREADER_H
namespace SourceMod
{
enum ThreadFlags
{
Thread_Default = 0,
//auto release handle on finish
//you are not guaranteed the handle for this is valid after
// calling MakeThread(), so never use it until OnTerminate is called.
Thread_AutoRelease = 1,
//Thread is created "suspended", meaning
// it is inactive until unpaused.
Thread_CreateSuspended = 2,
};
enum ThreadPriority
{
ThreadPrio_Minimum = -8,
ThreadPrio_Low = -3,
ThreadPrio_Normal = 0,
ThreadPrio_High = 3,
ThreadPrio_Maximum = 8,
};
enum ThreadState
{
Thread_Running = 0,
Thread_Paused = 1,
Thread_Done = 2,
};
struct ThreadParams
{
ThreadParams() :
flags(Thread_Default),
prio(ThreadPrio_Normal)
{
};
ThreadFlags flags;
ThreadPriority prio;
};
class IThreadCreator;
/**
* Describes a handle to a thread
*/
class IThreadHandle
{
public:
virtual ~IThreadHandle() { };
public:
/**
* Pauses parent thread until this thread completes.
*/
virtual bool WaitForThread() =0;
/**
* Destroys the thread handle.
* This will not necessarily cancel the thread.
*/
virtual void DestroyThis() =0;
/**
* Returns the parent threader.
*/
virtual IThreadCreator *Parent() =0;
/**
* Returns the thread states.
*/
virtual void GetParams(ThreadParams *ptparams) =0;
/**
* Returns priority
*/
virtual ThreadPriority GetPriority() =0;
/**
* Sets thread priority
*/
virtual bool SetPriority(ThreadPriority prio) =0;
/**
* Gets thread state
*/
virtual ThreadState GetState() =0;
/**
* Attempts to unpause a paused thread.
*/
virtual bool Unpause() =0;
};
/**
* Describes a single unit of execution/context flow
*/
class IThread
{
public:
virtual ~IThread() { };
public:
//Called when the thread runs
virtual void RunThread(IThreadHandle *pHandle) =0;
//Called when the thread terminates.
//"Cancel" is true if the thread did not finish
//(this could mean suspended or terminated abruptly)
virtual void OnTerminate(IThreadHandle *pHandle, bool cancel) =0;
};
/**
* Describes a thread creator
*/
class IThreadCreator
{
public:
virtual ~IThreadCreator() { };
public:
//Makes a thread and cleans up the handle for you
virtual void MakeThread(IThread *pThread) =0;
//Makes a thread with flag specified
virtual IThreadHandle *MakeThread(IThread *pThread, ThreadFlags flags) =0;
//Makes a thread, full options can be specified
virtual IThreadHandle *MakeThread(IThread *pThread, const ThreadParams *params) =0;
//Return priority bounds
virtual void GetPriorityBounds(ThreadPriority &max, ThreadPriority &min) =0;
};
/**
* Basic Mutex
*/
class IMutex
{
public:
virtual ~IMutex() { };
public:
/**
* Attempts to lock, but returns instantly.
*/
virtual bool TryLock() =0;
/**
* Attempts to lock by waiting for release.
*/
virtual void Lock() =0;
/**
* Unlocks mutex.
*/
virtual void Unlock() =0;
/**
* Frees the mutex handle.
*/
virtual void DestroyThis() =0;
};
class IEventSignal
{
public:
virtual ~IEventSignal() { };
public:
/**
* Waits for the signal.
*/
virtual void Wait() =0;
/**
* Triggers the signal.
* Resets the signals after triggering.
*/
virtual void Signal() =0;
/**
* Frees the signal handle.
*/
virtual void DestroyThis() =0;
};
/**
* Describes a threading system
*/
class IThreader : public IThreadCreator
{
public:
virtual IMutex *MakeMutex() =0;
virtual void MakeThread(IThread *pThread) =0;
virtual IThreadHandle *MakeThread(IThread *pThread, ThreadFlags flags) =0;
virtual IThreadHandle *MakeThread(IThread *pThread, const ThreadParams *params) =0;
virtual void GetPriorityBounds(ThreadPriority &max, ThreadPriority &min) =0;
virtual void ThreadSleep(unsigned int ms) =0;
/**
* Creates a non-signalled event.
*/
virtual IEventSignal *MakeEventSignal() =0;
};
enum WorkerState
{
Worker_Invalid = -3,
Worker_Stopped = -2,
Worker_Paused = -1,
Worker_Running,
};
/**
* This is an extension of the threader that is implemented.
* It "simulates" threading in a queue, and processes the queue whenever
* RunFrame is called (leaving it up to the implementation).
* Worker may or may not be started upon instantiation.
*/
class IWorker : public IThreadCreator
{
public:
virtual unsigned int RunFrame() =0;
virtual void MakeThread(IThread *pThread) =0;
virtual IThreadHandle *MakeThread(IThread *pThread, ThreadFlags flags) =0;
virtual IThreadHandle *MakeThread(IThread *pThread, const ThreadParams *params) =0;
virtual void GetPriorityBounds(ThreadPriority &max, ThreadPriority &min) =0;
public:
//Controls the worker
virtual bool Pause() =0;
virtual bool Unpause() =0;
virtual bool Start() =0;
//If flush is true, all remaining tasks will be cancelled.
//Otherwise, it will wait until the tasks have been depleted, then
// end.
virtual bool Stop(bool flush_cancel) =0;
//Flushes out any remaining threads
virtual unsigned int Flush(bool flush_cancel) =0;
//returns status and number of threads in queue
virtual WorkerState GetStatus(unsigned int *numThreads) =0;
};
};
#endif //_INCLUDE_SOURCEMOD_THREADER_H

View File

@ -0,0 +1,272 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
#include <unistd.h>
#include "PosixThreads.h"
void PosixThreader::ThreadSleep(unsigned int ms)
{
usleep( ms * 1000 );
}
void PosixThreader::GetPriorityBounds(ThreadPriority &max, ThreadPriority &min)
{
max = ThreadPrio_Normal;
min = ThreadPrio_Normal;
}
IMutex *PosixThreader::MakeMutex()
{
pthread_mutex_t mutex;
if (pthread_mutex_init(&mutex, NULL) != 0)
return NULL;
PosixMutex *pMutex = new PosixMutex(mutex);
return pMutex;
}
void PosixThreader::MakeThread(IThread *pThread)
{
ThreadParams defparams;
defparams.flags = Thread_AutoRelease;
defparams.prio = ThreadPrio_Normal;
MakeThread(pThread, &defparams);
}
IThreadHandle *PosixThreader::MakeThread(IThread *pThread, ThreadFlags flags)
{
ThreadParams defparams;
defparams.flags = flags;
defparams.prio = ThreadPrio_Normal;
return MakeThread(pThread, &defparams);
}
void *Posix_ThreadGate(void *param)
{
PosixThreader::ThreadHandle *pHandle =
reinterpret_cast<PosixThreader::ThreadHandle *>(param);
//Block this thread from being started initially.
pthread_mutex_lock(&pHandle->m_runlock);
//if we get here, we've obtained the lock and are allowed to run.
//unlock and continue.
pthread_mutex_unlock(&pHandle->m_runlock);
pHandle->m_run->RunThread(pHandle);
ThreadParams params;
pthread_mutex_lock(&pHandle->m_statelock);
pHandle->m_state = Thread_Done;
pHandle->GetParams(&params);
pthread_mutex_unlock(&pHandle->m_statelock);
pHandle->m_run->OnTerminate(pHandle, false);
if (params.flags & Thread_AutoRelease)
delete pHandle;
return 0;
}
ThreadParams g_defparams;
IThreadHandle *PosixThreader::MakeThread(IThread *pThread, const ThreadParams *params)
{
if (params == NULL)
params = &g_defparams;
PosixThreader::ThreadHandle *pHandle =
new PosixThreader::ThreadHandle(this, pThread, params);
pthread_mutex_lock(&pHandle->m_runlock);
int err;
err = pthread_create(&pHandle->m_thread, NULL, Posix_ThreadGate, (void *)pHandle);
if (err != 0)
{
pthread_mutex_unlock(&pHandle->m_runlock);
delete pHandle;
return NULL;
}
//Don't bother setting priority...
if (!(pHandle->m_params.flags & Thread_CreateSuspended))
{
pHandle->m_state = Thread_Running;
err = pthread_mutex_unlock(&pHandle->m_runlock);
if (err != 0)
pHandle->m_state = Thread_Paused;
}
return pHandle;
}
IEventSignal *PosixThreader::MakeEventSignal()
{
return new PosixEventSignal();
}
/*****************
**** Mutexes ****
*****************/
PosixThreader::PosixMutex::~PosixMutex()
{
pthread_mutex_destroy(&m_mutex);
}
bool PosixThreader::PosixMutex::TryLock()
{
int err = pthread_mutex_trylock(&m_mutex);
return (err == 0);
}
void PosixThreader::PosixMutex::Lock()
{
pthread_mutex_lock(&m_mutex);
}
void PosixThreader::PosixMutex::Unlock()
{
pthread_mutex_unlock(&m_mutex);
}
void PosixThreader::PosixMutex::DestroyThis()
{
delete this;
}
/******************
* Thread Handles *
******************/
PosixThreader::ThreadHandle::ThreadHandle(IThreader *parent, IThread *run, const ThreadParams *params) :
m_parent(parent), m_params(*params), m_run(run), m_state(Thread_Paused)
{
pthread_mutex_init(&m_runlock, NULL);
pthread_mutex_init(&m_statelock, NULL);
}
PosixThreader::ThreadHandle::~ThreadHandle()
{
pthread_mutex_destroy(&m_runlock);
pthread_mutex_destroy(&m_statelock);
}
bool PosixThreader::ThreadHandle::WaitForThread()
{
void *arg;
if (pthread_join(m_thread, &arg) != 0)
return false;
return true;
}
ThreadState PosixThreader::ThreadHandle::GetState()
{
ThreadState state;
pthread_mutex_lock(&m_statelock);
state = m_state;
pthread_mutex_unlock(&m_statelock);
return state;
}
IThreadCreator *PosixThreader::ThreadHandle::Parent()
{
return m_parent;
}
void PosixThreader::ThreadHandle::DestroyThis()
{
if (m_params.flags & Thread_AutoRelease)
return;
delete this;
}
void PosixThreader::ThreadHandle::GetParams(ThreadParams *ptparams)
{
if (!ptparams)
return;
*ptparams = m_params;
}
ThreadPriority PosixThreader::ThreadHandle::GetPriority()
{
return ThreadPrio_Normal;
}
bool PosixThreader::ThreadHandle::SetPriority(ThreadPriority prio)
{
return (prio == ThreadPrio_Normal);
}
bool PosixThreader::ThreadHandle::Unpause()
{
if (m_state != Thread_Paused)
return false;
m_state = Thread_Running;
if (pthread_mutex_unlock(&m_runlock) != 0)
{
m_state = Thread_Paused;
return false;
}
return true;
}
/*****************
* EVENT SIGNALS *
*****************/
PosixThreader::PosixEventSignal::PosixEventSignal()
{
pthread_cond_init(&m_cond, NULL);
pthread_mutex_init(&m_mutex, NULL);
}
PosixThreader::PosixEventSignal::~PosixEventSignal()
{
pthread_cond_destroy(&m_cond);
pthread_mutex_destroy(&m_mutex);
}
void PosixThreader::PosixEventSignal::Wait()
{
pthread_mutex_lock(&m_mutex);
pthread_cond_wait(&m_cond, &m_mutex);
pthread_mutex_unlock(&m_mutex);
}
void PosixThreader::PosixEventSignal::Signal()
{
pthread_mutex_lock(&m_mutex);
pthread_cond_broadcast(&m_cond);
pthread_mutex_unlock(&m_mutex);
}
void PosixThreader::PosixEventSignal::DestroyThis()
{
delete this;
}

View File

@ -0,0 +1,91 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
#ifndef _INCLUDE_POSIXTHREADS_H_
#define _INCLUDE_POSIXTHREADS_H_
#include <pthread.h>
#include "IThreader.h"
using namespace SourceMod;
void *Posix_ThreadGate(void *param);
class PosixThreader : public IThreader
{
public:
class ThreadHandle : public IThreadHandle
{
friend class PosixThreader;
friend void *Posix_ThreadGate(void *param);
public:
ThreadHandle(IThreader *parent, IThread *run, const ThreadParams *params);
virtual ~ThreadHandle();
public:
virtual bool WaitForThread();
virtual void DestroyThis();
virtual IThreadCreator *Parent();
virtual void GetParams(ThreadParams *ptparams);
virtual ThreadPriority GetPriority();
virtual bool SetPriority(ThreadPriority prio);
virtual ThreadState GetState();
virtual bool Unpause();
protected:
IThreader *m_parent; //Parent handle
pthread_t m_thread; //Windows HANDLE
ThreadParams m_params; //Current Parameters
IThread *m_run; //Runnable context
pthread_mutex_t m_statelock;
pthread_mutex_t m_runlock;
ThreadState m_state; //internal state
};
class PosixMutex : public IMutex
{
public:
PosixMutex(pthread_mutex_t m) : m_mutex(m)
{
};
virtual ~PosixMutex();
public:
virtual bool TryLock();
virtual void Lock();
virtual void Unlock();
virtual void DestroyThis();
protected:
pthread_mutex_t m_mutex;
};
class PosixEventSignal : public IEventSignal
{
public:
PosixEventSignal();
virtual ~PosixEventSignal();
public:
virtual void Wait();
virtual void Signal();
virtual void DestroyThis();
protected:
pthread_cond_t m_cond;
pthread_mutex_t m_mutex;
};
public:
virtual IMutex *MakeMutex();
virtual void MakeThread(IThread *pThread);
virtual IThreadHandle *MakeThread(IThread *pThread, ThreadFlags flags);
virtual IThreadHandle *MakeThread(IThread *pThread, const ThreadParams *params);
virtual void GetPriorityBounds(ThreadPriority &max, ThreadPriority &min);
virtual void ThreadSleep(unsigned int ms);
virtual IEventSignal *MakeEventSignal();
};
#if defined SM_DEFAULT_THREADER && !defined SM_MAIN_THREADER
#define SM_MAIN_THREADER PosixThreader;
typedef class PosixThreader MainThreader;
#endif
#endif //_INCLUDE_POSIXTHREADS_H_

View File

@ -0,0 +1,19 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
#ifndef _INCLUDE_SOURCEMOD_THREAD_SUPPORT_H
#define _INCLUDE_SOURCEMOD_THREAD_SUPPORT_H
#if defined __linux__ || defined __APPLE__
#include "PosixThreads.h"
#elif defined WIN32
#include "WinThreads.h"
#endif
#endif //_INCLUDE_SOURCEMOD_THREAD_SUPPORT_H

View File

@ -0,0 +1,267 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
#include "ThreadWorker.h"
ThreadWorker::ThreadWorker() :
m_Threader(NULL),
m_QueueLock(NULL),
m_StateLock(NULL),
m_PauseSignal(NULL),
m_AddSignal(NULL),
me(NULL),
m_think_time(DEFAULT_THINK_TIME_MS)
{
m_state = Worker_Invalid;
}
ThreadWorker::ThreadWorker(IThreader *pThreader, unsigned int thinktime) :
m_Threader(pThreader),
m_QueueLock(NULL),
m_StateLock(NULL),
m_PauseSignal(NULL),
m_AddSignal(NULL),
me(NULL),
m_think_time(thinktime)
{
if (m_Threader)
{
m_state = Worker_Stopped;
} else {
m_state = Worker_Invalid;
}
}
ThreadWorker::~ThreadWorker()
{
if (m_state != Worker_Stopped || m_state != Worker_Invalid)
Stop(true);
if (m_ThreadQueue.size())
Flush(true);
}
void ThreadWorker::OnTerminate(IThreadHandle *pHandle, bool cancel)
{
//we don't particularly care
return;
}
void ThreadWorker::RunThread(IThreadHandle *pHandle)
{
WorkerState this_state = Worker_Running;
size_t num;
while (true)
{
/**
* Check number of items in the queue
*/
m_StateLock->Lock();
this_state = m_state;
m_StateLock->Unlock();
if (this_state != Worker_Stopped)
{
m_QueueLock->Lock();
num = m_ThreadQueue.size();
if (!num)
{
/**
* if none, wait for an item
*/
m_Waiting = true;
m_QueueLock->Unlock();
/* first check if we should end again */
if (this_state == Worker_Stopped)
{
break;
}
m_AddSignal->Wait();
m_Waiting = false;
} else {
m_QueueLock->Unlock();
}
}
m_StateLock->Lock();
this_state = m_state;
m_StateLock->Unlock();
if (this_state != Worker_Running)
{
if (this_state == Worker_Paused || this_state == Worker_Stopped)
{
//wait until the lock is cleared.
if (this_state == Worker_Paused)
{
m_PauseSignal->Wait();
}
if (this_state == Worker_Stopped)
{
//if we're supposed to flush cleanrly,
// run all of the remaining frames first.
if (!m_FlushType)
{
while (m_ThreadQueue.size())
RunFrame();
}
break;
}
}
}
/**
* Run the frame.
*/
RunFrame();
/**
* wait in between threads if specified
*/
if (m_think_time)
m_Threader->ThreadSleep(m_think_time);
}
}
SWThreadHandle *ThreadWorker::PopThreadFromQueue()
{
if (m_state <= Worker_Stopped && !m_QueueLock)
return NULL;
SWThreadHandle *swt;
m_QueueLock->Lock();
swt = BaseWorker::PopThreadFromQueue();
m_QueueLock->Unlock();
return swt;
}
void ThreadWorker::AddThreadToQueue(SWThreadHandle *pHandle)
{
if (m_state <= Worker_Stopped)
return;
m_QueueLock->Lock();
BaseWorker::AddThreadToQueue(pHandle);
if (m_Waiting)
{
m_AddSignal->Signal();
}
m_QueueLock->Unlock();
}
WorkerState ThreadWorker::GetStatus(unsigned int *threads)
{
WorkerState state;
m_StateLock->Lock();
state = BaseWorker::GetStatus(threads);
m_StateLock->Unlock();
return state;
}
bool ThreadWorker::Start()
{
if (m_state == Worker_Invalid)
{
if (m_Threader == NULL)
return false;
} else if (m_state != Worker_Stopped) {
return false;
}
m_Waiting = false;
m_QueueLock = m_Threader->MakeMutex();
m_StateLock = m_Threader->MakeMutex();
m_PauseSignal = m_Threader->MakeEventSignal();
m_AddSignal = m_Threader->MakeEventSignal();
m_state = Worker_Running;
ThreadParams pt;
pt.flags = Thread_Default;
pt.prio = ThreadPrio_Normal;
me = m_Threader->MakeThread(this, &pt);
return true;
}
bool ThreadWorker::Stop(bool flush_cancel)
{
if (m_state == Worker_Invalid || m_state == Worker_Stopped)
return false;
WorkerState oldstate;
//set new state
m_StateLock->Lock();
oldstate = m_state;
m_state = Worker_Stopped;
m_FlushType = flush_cancel;
m_StateLock->Unlock();
if (oldstate == Worker_Paused)
{
Unpause();
} else {
m_QueueLock->Lock();
if (m_Waiting)
{
m_AddSignal->Signal();
}
m_QueueLock->Unlock();
}
me->WaitForThread();
//destroy it
me->DestroyThis();
//flush all remaining events
Flush(true);
//free mutex locks
m_QueueLock->DestroyThis();
m_StateLock->DestroyThis();
m_PauseSignal->DestroyThis();
m_AddSignal->DestroyThis();
//invalidizzle
m_QueueLock = NULL;
m_StateLock = NULL;
m_PauseSignal = NULL;
m_AddSignal = NULL;
me = NULL;
return true;
}
bool ThreadWorker::Pause()
{
if (m_state != Worker_Running)
return false;
m_StateLock->Lock();
m_state = Worker_Paused;
m_StateLock->Unlock();
return true;
}
bool ThreadWorker::Unpause()
{
if (m_state != Worker_Paused)
return false;
m_StateLock->Lock();
m_state = Worker_Running;
m_StateLock->Unlock();
m_PauseSignal->Signal();
if (m_Waiting)
{
m_AddSignal->Signal();
}
return true;
}

View File

@ -0,0 +1,49 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
#ifndef _INCLUDE_SOURCEMOD_THREADWORKER_H
#define _INCLUDE_SOURCEMOD_THREADWORKER_H
#include "BaseWorker.h"
#define DEFAULT_THINK_TIME_MS 25
class ThreadWorker : public BaseWorker, public IThread
{
public:
ThreadWorker();
ThreadWorker(IThreader *pThreader, unsigned int thinktime=DEFAULT_THINK_TIME_MS);
virtual ~ThreadWorker();
public: //IThread
virtual void OnTerminate(IThreadHandle *pHandle, bool cancel);
virtual void RunThread(IThreadHandle *pHandle);
public: //IWorker
//Controls the worker
virtual bool Pause();
virtual bool Unpause();
virtual bool Start();
virtual bool Stop(bool flush_cancel);
//returns status and number of threads in queue
virtual WorkerState GetStatus(unsigned int *numThreads);
public: //BaseWorker
virtual void AddThreadToQueue(SWThreadHandle *pHandle);
virtual SWThreadHandle *PopThreadFromQueue();
protected:
IThreader *m_Threader;
IMutex *m_QueueLock;
IMutex *m_StateLock;
IEventSignal *m_PauseSignal;
IEventSignal *m_AddSignal;
IThreadHandle *me;
unsigned int m_think_time;
volatile bool m_Waiting;
volatile bool m_FlushType;
};
#endif //_INCLUDE_SOURCEMOD_THREADWORKER_H

View File

@ -0,0 +1,298 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
#include "WinThreads.h"
void WinThreader::ThreadSleep(unsigned int ms)
{
Sleep((DWORD)ms);
}
IMutex *WinThreader::MakeMutex()
{
HANDLE mutex = CreateMutexA(NULL, FALSE, NULL);
if (mutex == NULL)
return NULL;
WinMutex *pMutex = new WinMutex(mutex);
return pMutex;
}
IThreadHandle *WinThreader::MakeThread(IThread *pThread, ThreadFlags flags)
{
ThreadParams defparams;
defparams.flags = flags;
defparams.prio = ThreadPrio_Normal;
return MakeThread(pThread, &defparams);
}
void WinThreader::MakeThread(IThread *pThread)
{
ThreadParams defparams;
defparams.flags = Thread_AutoRelease;
defparams.prio = ThreadPrio_Normal;
MakeThread(pThread, &defparams);
}
DWORD WINAPI Win32_ThreadGate(LPVOID param)
{
WinThreader::ThreadHandle *pHandle =
reinterpret_cast<WinThreader::ThreadHandle *>(param);
pHandle->m_run->RunThread(pHandle);
ThreadParams params;
EnterCriticalSection(&pHandle->m_crit);
pHandle->m_state = Thread_Done;
pHandle->GetParams(&params);
LeaveCriticalSection(&pHandle->m_crit);
pHandle->m_run->OnTerminate(pHandle, false);
if (params.flags & Thread_AutoRelease)
delete pHandle;
return 0;
}
void WinThreader::GetPriorityBounds(ThreadPriority &max, ThreadPriority &min)
{
max = ThreadPrio_Maximum;
min = ThreadPrio_Minimum;
}
ThreadParams g_defparams;
IThreadHandle *WinThreader::MakeThread(IThread *pThread, const ThreadParams *params)
{
if (params == NULL)
params = &g_defparams;
WinThreader::ThreadHandle *pHandle =
new WinThreader::ThreadHandle(this, NULL, pThread, params);
DWORD tid;
pHandle->m_thread =
CreateThread(NULL, 0, &Win32_ThreadGate, (LPVOID)pHandle, CREATE_SUSPENDED, &tid);
if (!pHandle->m_thread)
{
delete pHandle;
return NULL;
}
if (pHandle->m_params.prio != ThreadPrio_Normal)
{
pHandle->SetPriority(pHandle->m_params.prio);
}
if (!(pHandle->m_params.flags & Thread_CreateSuspended))
{
pHandle->Unpause();
}
return pHandle;
}
IEventSignal *WinThreader::MakeEventSignal()
{
HANDLE event = CreateEventA(NULL, FALSE, FALSE, NULL);
if (!event)
return NULL;
WinEvent *pEvent = new WinEvent(event);
return pEvent;
}
/*****************
**** Mutexes ****
*****************/
WinThreader::WinMutex::~WinMutex()
{
if (m_mutex)
{
CloseHandle(m_mutex);
m_mutex = NULL;
}
}
bool WinThreader::WinMutex::TryLock()
{
if (!m_mutex)
return false;
if (WaitForSingleObject(m_mutex, 0) != WAIT_FAILED)
return true;
return false;
}
void WinThreader::WinMutex::Lock()
{
if (!m_mutex)
return;
WaitForSingleObject(m_mutex, INFINITE);
}
void WinThreader::WinMutex::Unlock()
{
if (!m_mutex)
return;
ReleaseMutex(m_mutex);
}
void WinThreader::WinMutex::DestroyThis()
{
delete this;
}
/******************
* Thread Handles *
******************/
WinThreader::ThreadHandle::ThreadHandle(IThreader *parent, HANDLE hthread, IThread *run, const ThreadParams *params) :
m_parent(parent), m_thread(hthread), m_run(run), m_params(*params),
m_state(Thread_Paused)
{
InitializeCriticalSection(&m_crit);
}
WinThreader::ThreadHandle::~ThreadHandle()
{
if (m_thread)
{
CloseHandle(m_thread);
m_thread = NULL;
}
DeleteCriticalSection(&m_crit);
}
bool WinThreader::ThreadHandle::WaitForThread()
{
if (m_thread == NULL)
return false;
if (WaitForSingleObject(m_thread, INFINITE) != 0)
return false;
return true;
}
ThreadState WinThreader::ThreadHandle::GetState()
{
ThreadState state;
EnterCriticalSection(&m_crit);
state = m_state;
LeaveCriticalSection(&m_crit);
return state;
}
IThreadCreator *WinThreader::ThreadHandle::Parent()
{
return m_parent;
}
void WinThreader::ThreadHandle::DestroyThis()
{
if (m_params.flags & Thread_AutoRelease)
return;
delete this;
}
void WinThreader::ThreadHandle::GetParams(ThreadParams *ptparams)
{
if (!ptparams)
return;
*ptparams = m_params;
}
ThreadPriority WinThreader::ThreadHandle::GetPriority()
{
return m_params.prio;
}
bool WinThreader::ThreadHandle::SetPriority(ThreadPriority prio)
{
if (!m_thread)
return false;
BOOL res = FALSE;
if (prio >= ThreadPrio_Maximum)
res = SetThreadPriority(m_thread, THREAD_PRIORITY_HIGHEST);
else if (prio <= ThreadPrio_Minimum)
res = SetThreadPriority(m_thread, THREAD_PRIORITY_LOWEST);
else if (prio == ThreadPrio_Normal)
res = SetThreadPriority(m_thread, THREAD_PRIORITY_NORMAL);
else if (prio == ThreadPrio_High)
res = SetThreadPriority(m_thread, THREAD_PRIORITY_ABOVE_NORMAL);
else if (prio == ThreadPrio_Low)
res = SetThreadPriority(m_thread, THREAD_PRIORITY_BELOW_NORMAL);
m_params.prio = prio;
return (res != FALSE);
}
bool WinThreader::ThreadHandle::Unpause()
{
if (!m_thread)
return false;
if (m_state != Thread_Paused)
return false;
m_state = Thread_Running;
if (ResumeThread(m_thread) == -1)
{
m_state = Thread_Paused;
return false;
}
return true;
}
/*****************
* EVENT SIGNALS *
*****************/
WinThreader::WinEvent::~WinEvent()
{
CloseHandle(m_event);
}
void WinThreader::WinEvent::Wait()
{
WaitForSingleObject(m_event, INFINITE);
}
void WinThreader::WinEvent::Signal()
{
SetEvent(m_event);
}
void WinThreader::WinEvent::DestroyThis()
{
delete this;
}

View File

@ -0,0 +1,91 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
#ifndef _INCLUDE_WINTHREADS_H_
#define _INCLUDE_WINTHREADS_H_
#include <windows.h>
#include "IThreader.h"
using namespace SourceMod;
DWORD WINAPI Win32_ThreadGate(LPVOID param);
class WinThreader : public IThreader
{
public:
class ThreadHandle : public IThreadHandle
{
friend class WinThreader;
friend DWORD WINAPI Win32_ThreadGate(LPVOID param);
public:
ThreadHandle(IThreader *parent, HANDLE hthread, IThread *run, const ThreadParams *params);
virtual ~ThreadHandle();
public:
virtual bool WaitForThread();
virtual void DestroyThis();
virtual IThreadCreator *Parent();
virtual void GetParams(ThreadParams *ptparams);
virtual ThreadPriority GetPriority();
virtual bool SetPriority(ThreadPriority prio);
virtual ThreadState GetState();
virtual bool Unpause();
protected:
IThreader *m_parent; //Parent handle
HANDLE m_thread; //Windows HANDLE
ThreadParams m_params; //Current Parameters
IThread *m_run; //Runnable context
ThreadState m_state; //internal state
CRITICAL_SECTION m_crit;
};
class WinMutex : public IMutex
{
public:
WinMutex(HANDLE mutex) : m_mutex(mutex)
{
};
virtual ~WinMutex();
public:
virtual bool TryLock();
virtual void Lock();
virtual void Unlock();
virtual void DestroyThis();
protected:
HANDLE m_mutex;
};
class WinEvent : public IEventSignal
{
public:
WinEvent(HANDLE event) : m_event(event)
{
};
virtual ~WinEvent();
public:
virtual void Wait();
virtual void Signal();
virtual void DestroyThis();
public:
HANDLE m_event;
};
public:
virtual IMutex *MakeMutex();
virtual void MakeThread(IThread *pThread);
virtual IThreadHandle *MakeThread(IThread *pThread, ThreadFlags flags);
virtual IThreadHandle *MakeThread(IThread *pThread, const ThreadParams *params);
virtual void GetPriorityBounds(ThreadPriority &max, ThreadPriority &min);
virtual void ThreadSleep(unsigned int ms);
virtual IEventSignal *MakeEventSignal();
};
#if defined SM_DEFAULT_THREADER && !defined SM_MAIN_THREADER
#define SM_MAIN_THREADER WinThreader;
typedef class WinThreader MainThreader;
#endif
#endif //_INCLUDE_WINTHREADS_H_

View File

@ -0,0 +1,587 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// SQLite Module
//
#include "amxxmodule.h"
#include "sqlite_header.h"
#include "threading.h"
#include <am-string.h>
MainThreader g_Threader;
ThreadWorker *g_pWorker = NULL;
extern DLL_FUNCTIONS *g_pFunctionTable;
IMutex *g_QueueLock = NULL;
CStack<MysqlThread *> g_ThreadQueue;
CStack<MysqlThread *> g_FreeThreads;
float g_lasttime = 0.0f;
void ShutdownThreading()
{
if (g_pWorker)
{
// Flush all the remaining job fast!
g_pWorker->SetMaxThreadsPerFrame(8192);
g_pWorker->Stop(true);
delete g_pWorker;
g_pWorker = NULL;
}
g_QueueLock->Lock();
while (!g_ThreadQueue.empty())
{
delete g_ThreadQueue.front();
g_ThreadQueue.pop();
}
while (!g_FreeThreads.empty())
{
delete g_FreeThreads.front();
g_FreeThreads.pop();
}
g_QueueLock->Unlock();
g_QueueLock->DestroyThis();
FreeHandleTable();
}
//public QueryHandler(state, Handle:query, error[], errnum, data[], size)
//native SQL_ThreadQuery(Handle:cn_tuple, const handler[], const query[], const data[]="", dataSize=0);
static cell AMX_NATIVE_CALL SQL_ThreadQuery(AMX *amx, cell *params)
{
if (!g_pWorker)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Thread worker was unable to start.");
return 0;
}
SQL_Connection *cn = (SQL_Connection *)GetHandle(params[1], Handle_Connection);
if (!cn)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid info tuple handle: %d", params[1]);
return 0;
}
int len;
const char *handler = MF_GetAmxString(amx, params[2], 0, &len);
int fwd = MF_RegisterSPForwardByName(amx, handler, FP_CELL, FP_CELL, FP_STRING, FP_CELL, FP_ARRAY, FP_CELL, FP_CELL, FP_DONE);
if (fwd < 1)
{
MF_LogError(amx, AMX_ERR_NATIVE, "Function not found: %s", handler);
return 0;
}
MysqlThread *kmThread;
g_QueueLock->Lock();
if (g_FreeThreads.empty())
{
kmThread = new MysqlThread();
} else {
kmThread = g_FreeThreads.front();
g_FreeThreads.pop();
}
g_QueueLock->Unlock();
kmThread->SetInfo(cn->db);
kmThread->SetForward(fwd);
kmThread->SetQuery(MF_GetAmxString(amx, params[3], 1, &len));
kmThread->SetCellData(MF_GetAmxAddr(amx, params[4]), (ucell)params[5]);
g_pWorker->MakeThread(kmThread);
return 1;
}
MysqlThread::MysqlThread()
{
m_fwd = 0;
m_data = NULL;
m_datalen = 0;
m_maxdatalen = 0;
}
MysqlThread::~MysqlThread()
{
if (m_fwd)
{
MF_UnregisterSPForward(m_fwd);
m_fwd = 0;
}
delete [] m_data;
m_data = NULL;
}
void MysqlThread::SetCellData(cell data[], ucell len)
{
if (len > m_maxdatalen)
{
delete [] m_data;
m_data = new cell[len];
m_maxdatalen = len;
}
if (len)
{
m_datalen = len;
memcpy(m_data, data, len*sizeof(cell));
}
}
void MysqlThread::SetForward(int forward)
{
m_fwd = forward;
}
void MysqlThread::SetInfo(const char *db)
{
m_db = db;
m_qrInfo.queue_time = gpGlobals->time;
}
void MysqlThread::SetQuery(const char *query)
{
m_query = query;
}
void MysqlThread::RunThread(IThreadHandle *pHandle)
{
DatabaseInfo info;
info.database = m_db.chars();
info.pass = "";
info.user = "";
info.host = "";
info.port = 0;
float save_time = m_qrInfo.queue_time;
memset(&m_qrInfo, 0, sizeof(m_qrInfo));
m_qrInfo.queue_time = save_time;
IDatabase *pDatabase = g_Sqlite.Connect(&info, &m_qrInfo.amxinfo.info.errorcode, m_qrInfo.amxinfo.error, 254);
IQuery *pQuery = NULL;
if (!pDatabase)
{
m_qrInfo.connect_success = false;
m_qrInfo.query_success = false;
} else {
m_qrInfo.connect_success = true;
pQuery = pDatabase->PrepareQuery(m_query.chars());
if (!pQuery->Execute2(&m_qrInfo.amxinfo.info, m_qrInfo.amxinfo.error, 254))
{
m_qrInfo.query_success = false;
} else {
m_qrInfo.query_success = true;
}
}
if (m_qrInfo.query_success && m_qrInfo.amxinfo.info.rs)
{
m_atomicResult.CopyFrom(m_qrInfo.amxinfo.info.rs);
m_qrInfo.amxinfo.info.rs = &m_atomicResult;
}
if (pQuery)
{
m_qrInfo.amxinfo.pQuery = pQuery;
} else {
m_qrInfo.amxinfo.opt_ptr = new char[m_query.length() + 1];
strcpy(m_qrInfo.amxinfo.opt_ptr, m_query.chars());
}
if (pDatabase)
{
pDatabase->FreeHandle();
pDatabase = NULL;
}
}
void MysqlThread::Invalidate()
{
m_atomicResult.FreeHandle();
}
void MysqlThread::OnTerminate(IThreadHandle *pHandle, bool cancel)
{
if (cancel)
{
Invalidate();
g_QueueLock->Lock();
g_FreeThreads.push(this);
g_QueueLock->Unlock();
} else {
g_QueueLock->Lock();
g_ThreadQueue.push(this);
g_QueueLock->Unlock();
}
}
void NullFunc(void *ptr, unsigned int num)
{
}
//public QueryHandler(state, Handle:query, error[], errnum, data[], size)
void MysqlThread::Execute()
{
cell data_addr;
if (m_datalen)
{
data_addr = MF_PrepareCellArray(m_data, m_datalen);
} else {
static cell tmpdata[1] = {0};
data_addr = MF_PrepareCellArray(tmpdata, 1);
}
int state = 0;
if (!m_qrInfo.connect_success)
{
state = -2;
} else if (!m_qrInfo.query_success) {
state = -1;
}
float diff = gpGlobals->time - m_qrInfo.queue_time;
cell c_diff = amx_ftoc(diff);
unsigned int hndl = MakeHandle(&m_qrInfo.amxinfo, Handle_Query, NullFunc);
if (state != 0)
{
MF_ExecuteForward(m_fwd,
(cell)state,
(cell)hndl,
m_qrInfo.amxinfo.error,
m_qrInfo.amxinfo.info.errorcode,
data_addr,
m_datalen,
c_diff);
} else {
MF_ExecuteForward(m_fwd,
(cell)0,
(cell)hndl,
"",
(cell)0,
data_addr,
m_datalen,
c_diff);
}
FreeHandle(hndl);
if (m_qrInfo.amxinfo.pQuery)
{
m_qrInfo.amxinfo.pQuery->FreeHandle();
m_qrInfo.amxinfo.pQuery = NULL;
}
delete [] m_qrInfo.amxinfo.opt_ptr;
m_qrInfo.amxinfo.opt_ptr = NULL;
}
/*****************
* METAMOD STUFF *
*****************/
void OnPluginsLoaded()
{
if (g_pWorker)
{
return;
}
if (!g_QueueLock)
{
g_QueueLock = g_Threader.MakeMutex();
}
g_pWorker = new ThreadWorker(&g_Threader, DEFAULT_THINK_TIME_MS);
if (!g_pWorker->Start())
{
delete g_pWorker;
g_pWorker = NULL;
}
g_pFunctionTable->pfnSpawn = NULL;
g_lasttime = 0.0f;
return;
}
void StartFrame()
{
if (g_pWorker && (g_lasttime < gpGlobals->time))
{
g_lasttime = gpGlobals->time + 0.025f;
g_QueueLock->Lock();
size_t remaining = g_ThreadQueue.size();
if (remaining)
{
MysqlThread *kmThread;
do
{
kmThread = g_ThreadQueue.front();
g_ThreadQueue.pop();
g_QueueLock->Unlock();
kmThread->Execute();
kmThread->Invalidate();
g_FreeThreads.push(kmThread);
g_QueueLock->Lock();
} while (!g_ThreadQueue.empty());
}
g_QueueLock->Unlock();
}
RETURN_META(MRES_IGNORED);
}
void OnPluginsUnloading()
{
if (!g_pWorker)
{
return;
}
// Flush all the remaining job fast!
g_pWorker->SetMaxThreadsPerFrame(8192);
g_pWorker->Stop(false);
delete g_pWorker;
g_pWorker = NULL;
g_QueueLock->Lock();
size_t remaining = g_ThreadQueue.size();
if (remaining)
{
MysqlThread *kmThread;
do
{
kmThread = g_ThreadQueue.front();
g_ThreadQueue.pop();
g_QueueLock->Unlock();
kmThread->Execute();
kmThread->Invalidate();
g_FreeThreads.push(kmThread);
g_QueueLock->Lock();
} while (!g_ThreadQueue.empty());
}
g_QueueLock->Unlock();
}
/***********************
* ATOMIC RESULT STUFF *
***********************/
AtomicResult::AtomicResult()
{
m_IsFree = true;
m_CurRow = 1;
m_RowCount = 0;
m_Table = NULL;
m_AllocSize = 0;
}
AtomicResult::~AtomicResult()
{
if (!m_IsFree)
{
FreeHandle();
}
for (size_t i=0; i<=m_AllocSize; i++)
{
delete m_Table[i];
}
delete [] m_Table;
m_Table = NULL;
m_IsFree = true;
}
unsigned int AtomicResult::RowCount()
{
return m_RowCount;
}
bool AtomicResult::IsNull(unsigned int columnId)
{
return (GetString(columnId) == NULL);
}
unsigned int AtomicResult::FieldCount()
{
return m_FieldCount;
}
bool AtomicResult::FieldNameToNum(const char *name, unsigned int *columnId)
{
for (unsigned int i=0; i<m_FieldCount; i++)
{
assert(m_Table[i] != NULL);
if (strcmp(m_Table[i]->chars(), name) == 0)
{
if (columnId)
{
*columnId = i;
}
return true;
}
}
return false;
}
const char *AtomicResult::FieldNumToName(unsigned int num)
{
if (num >= m_FieldCount)
return NULL;
assert(m_Table[num] != NULL);
return m_Table[num]->chars();
}
double AtomicResult::GetDouble(unsigned int columnId)
{
return atof(GetStringSafe(columnId));
}
float AtomicResult::GetFloat(unsigned int columnId)
{
return atof(GetStringSafe(columnId));
}
int AtomicResult::GetInt(unsigned int columnId)
{
return atoi(GetStringSafe(columnId));
}
const char *AtomicResult::GetRaw(unsigned int columnId, size_t *length)
{
//we don't support this yet...
*length = 0;
return "";
}
const char *AtomicResult::GetStringSafe(unsigned int columnId)
{
const char *str = GetString(columnId);
return str ? str : "";
}
const char *AtomicResult::GetString(unsigned int columnId)
{
if (columnId >= m_FieldCount)
return NULL;
size_t idx = (m_CurRow * m_FieldCount) + columnId;
assert(m_Table[idx] != NULL);
return m_Table[idx]->chars();
}
IResultRow *AtomicResult::GetRow()
{
return static_cast<IResultRow *>(this);
}
bool AtomicResult::IsDone()
{
if (m_CurRow > m_RowCount)
return true;
return false;
}
void AtomicResult::NextRow()
{
m_CurRow++;
}
void AtomicResult::_InternalClear()
{
if (m_IsFree)
return;
m_IsFree = true;
}
void AtomicResult::FreeHandle()
{
_InternalClear();
}
void AtomicResult::CopyFrom(IResultSet *rs)
{
if (!m_IsFree)
{
_InternalClear();
}
m_IsFree = false;
m_FieldCount = rs->FieldCount();
m_RowCount = rs->RowCount();
m_CurRow = 1;
size_t newTotal = (m_RowCount * m_FieldCount) + m_FieldCount;
if (newTotal > m_AllocSize)
{
ke::AString **table = new ke::AString *[newTotal];
memset(table, 0, newTotal * sizeof(ke::AString *));
if (m_Table)
{
memcpy(table, m_Table, m_AllocSize * sizeof(ke::AString *));
delete [] m_Table;
}
m_Table = table;
m_AllocSize = newTotal;
}
for (unsigned int i=0; i<m_FieldCount; i++)
{
if (m_Table[i])
{
*m_Table[i] = rs->FieldNumToName(i);
} else {
m_Table[i] = new ke::AString(rs->FieldNumToName(i));
}
}
IResultRow *row;
unsigned int idx = m_FieldCount;
while (!rs->IsDone())
{
row = rs->GetRow();
for (unsigned int i=0; i<m_FieldCount; i++,idx++)
{
if (m_Table[idx])
{
*m_Table[idx] = row->GetString(i);
} else {
m_Table[idx] = new ke::AString(row->GetString(i));
}
}
rs->NextRow();
}
}
void AtomicResult::Rewind()
{
m_CurRow = 1;
}
bool AtomicResult::NextResultSet()
{
return false;
}
AMX_NATIVE_INFO g_ThreadSqlNatives[] =
{
{"SQL_ThreadQuery", SQL_ThreadQuery},
{NULL, NULL},
};

View File

@ -0,0 +1,98 @@
// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
//
// SQLite Module
//
#ifndef _INCLUDE_MYSQL_THREADING_H
#define _INCLUDE_MYSQL_THREADING_H
#include "IThreader.h"
#include "ISQLDriver.h"
#include <am-string.h>
#include <am-vector.h>
#include <sh_stack.h>
struct QueuedResultInfo
{
AmxQueryInfo amxinfo;
bool connect_success;
bool query_success;
float queue_time;
};
class AtomicResult :
public IResultSet,
public IResultRow
{
friend class MysqlThread;
public:
AtomicResult();
~AtomicResult();
public:
//free the handle if necessary (see IQuery).
virtual void FreeHandle();
virtual unsigned int RowCount();
virtual unsigned int FieldCount();
virtual const char *FieldNumToName(unsigned int num);
virtual bool FieldNameToNum(const char *name, unsigned int *columnId);
virtual bool IsDone();
virtual IResultRow *GetRow();
virtual void NextRow();
virtual void Rewind();
public:
virtual const char *GetString(unsigned int columnId);
virtual const char *GetStringSafe(unsigned int columnId);
virtual double GetDouble(unsigned int columnId);
virtual float GetFloat(unsigned int columnId);
virtual int GetInt(unsigned int columnId);
virtual bool IsNull(unsigned int columnId);
virtual const char *GetRaw(unsigned int columnId, size_t *length);
virtual bool NextResultSet();
public:
void CopyFrom(IResultSet *rs);
private:
void _InternalClear();
private:
unsigned int m_RowCount;
unsigned int m_FieldCount;
size_t m_AllocSize;
ke::AString **m_Table;
unsigned int m_CurRow;
bool m_IsFree;
};
class MysqlThread : public IThread
{
public:
MysqlThread();
~MysqlThread();
public:
void SetInfo(const char *db);
void SetQuery(const char *query);
void SetCellData(cell data[], ucell len);
void SetForward(int forward);
void Invalidate();
void Execute();
public:
void RunThread(IThreadHandle *pHandle);
void OnTerminate(IThreadHandle *pHandle, bool cancel);
private:
ke::AString m_query;
ke::AString m_db;
cell *m_data;
ucell m_datalen;
size_t m_maxdatalen;
int m_fwd;
QueuedResultInfo m_qrInfo;
AtomicResult m_atomicResult;
};
#endif //_INCLUDE_MYSQL_THREADING_H

101
modules/sqlite/version.rc Normal file
View File

@ -0,0 +1,101 @@
// Microsoft Visual C++ generated resource script.
//
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include <winresrc.h>
#include <moduleconfig.h>
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION AMXX_VERSION_FILE
PRODUCTVERSION AMXX_VERSION_FILE
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "000004b0"
BEGIN
VALUE "Comments", "AMX Mod X"
VALUE "FileDescription", "AMX Mod X"
VALUE "FileVersion", AMXX_VERSION
VALUE "InternalName", MODULE_LIBRARY
VALUE "LegalCopyright", "Copyright (c) AMX Mod X Dev Team"
VALUE "OriginalFilename", MODULE_LIBRARY "_amxx.dll"
VALUE "ProductName", MODULE_NAME
VALUE "ProductVersion", AMXX_VERSION
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0, 1200
END
END
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""winres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED