Move dlls/ to modules/
This commit is contained in:
60
modules/mysqlx/AMBuilder
Normal file
60
modules/mysqlx/AMBuilder
Normal file
@ -0,0 +1,60 @@
|
||||
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
|
||||
import os.path
|
||||
|
||||
if AMXX.mysql_path:
|
||||
binary = AMXX.MetaModule(builder, 'mysql')
|
||||
|
||||
binary.compiler.cxxincludes += [
|
||||
os.path.join(AMXX.mysql_path, 'include'),
|
||||
os.path.join(builder.currentSourcePath, 'mysql'),
|
||||
os.path.join(builder.currentSourcePath, 'thread'),
|
||||
]
|
||||
|
||||
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.linkflags += [
|
||||
os.path.join(AMXX.mysql_path, 'lib', 'libmysqlclient_r.a'),
|
||||
'-lpthread',
|
||||
'-lm'
|
||||
]
|
||||
elif builder.target_platform is 'windows':
|
||||
binary.compiler.linkflags += [
|
||||
os.path.join(AMXX.mysql_path, 'lib', 'opt', 'mysqlclient.lib'),
|
||||
'ws2_32.lib'
|
||||
]
|
||||
|
||||
binary.compiler.linkflags += [AMXX.zlib.binary]
|
||||
|
||||
binary.sources = [
|
||||
'basic_sql.cpp',
|
||||
'handles.cpp',
|
||||
'module.cpp',
|
||||
'threading.cpp',
|
||||
'../../public/sdk/amxxmodule.cpp',
|
||||
'oldcompat_sql.cpp',
|
||||
'thread/BaseWorker.cpp',
|
||||
'thread/ThreadWorker.cpp',
|
||||
'mysql/MysqlQuery.cpp',
|
||||
'mysql/MysqlResultSet.cpp',
|
||||
'mysql/MysqlDatabase.cpp',
|
||||
'mysql/MysqlDriver.cpp',
|
||||
]
|
||||
|
||||
if builder.target_platform == 'windows':
|
||||
binary.sources += ['version.rc']
|
||||
|
||||
if builder.target_platform == 'windows':
|
||||
binary.sources += [
|
||||
'thread/WinThreads.cpp',
|
||||
]
|
||||
else:
|
||||
binary.sources += [
|
||||
'thread/PosixThreads.cpp',
|
||||
]
|
||||
|
||||
AMXX.modules += [builder.Add(binary)]
|
133
modules/mysqlx/Makefile
Normal file
133
modules/mysqlx/Makefile
Normal file
@ -0,0 +1,133 @@
|
||||
# (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
|
||||
MYSQL_DIR = ../../../mysql-5.0
|
||||
PUBLIC_ROOT = ../../public
|
||||
|
||||
#####################################
|
||||
### EDIT BELOW FOR OTHER PROJECTS ###
|
||||
#####################################
|
||||
|
||||
PROJECT = mysql
|
||||
|
||||
OBJECTS = basic_sql.cpp handles.cpp module.cpp threading.cpp amxxmodule.cpp oldcompat_sql.cpp \
|
||||
thread/BaseWorker.cpp thread/ThreadWorker.cpp thread/PosixThreads.cpp \
|
||||
mysql/MysqlQuery.cpp mysql/MysqlResultSet.cpp mysql/MysqlDatabase.cpp mysql/MysqlDriver.cpp
|
||||
|
||||
##############################################
|
||||
### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
|
||||
##############################################
|
||||
|
||||
C_OPT_FLAGS = -DNDEBUG -O2 -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 = $(MYSQL_DIR)/lib/libmysqlclient_r.a -lz -lpthread -L$(MYSQL_DIR)/lib
|
||||
|
||||
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$(MYSQL_DIR)/include -Ithread -Imysql \
|
||||
-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
|
||||
|
||||
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
|
||||
|
||||
# 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)
|
||||
|
||||
# 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 $<
|
||||
|
||||
all:
|
||||
mkdir -p $(BIN_DIR)
|
||||
mkdir -p $(BIN_DIR)/mysql
|
||||
mkdir -p $(BIN_DIR)/thread
|
||||
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)/mysql/*.o
|
||||
rm -rf $(BIN_DIR)/thread/*.o
|
||||
rm -f $(BIN_DIR)/$(BINARY)
|
||||
|
662
modules/mysqlx/basic_sql.cpp
Normal file
662
modules/mysqlx/basic_sql.cpp
Normal file
@ -0,0 +1,662 @@
|
||||
// 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
|
||||
|
||||
//
|
||||
// MySQL Module
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include "mysql2_header.h"
|
||||
#include "sqlheaders.h"
|
||||
|
||||
using namespace SourceMod;
|
||||
|
||||
MysqlDriver g_Mysql;
|
||||
|
||||
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);
|
||||
free(cn->charset);
|
||||
|
||||
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;
|
||||
|
||||
char *host = strdup(MF_GetAmxString(amx, params[1], 0, &len));
|
||||
|
||||
char *p = strchr(host, ':');
|
||||
if (p)
|
||||
{
|
||||
sql->port = atoi(p+1);
|
||||
*p = '\0';
|
||||
} else {
|
||||
sql->port = 0;
|
||||
}
|
||||
|
||||
sql->host = host;
|
||||
sql->user = strdup(MF_GetAmxString(amx, params[2], 0, &len));
|
||||
sql->pass = strdup(MF_GetAmxString(amx, params[3], 0, &len));
|
||||
sql->db = strdup(MF_GetAmxString(amx, params[4], 0, &len));
|
||||
if (params[0] / sizeof(cell) >= 5)
|
||||
{
|
||||
sql->max_timeout = static_cast<unsigned int>(params[5]);
|
||||
}
|
||||
sql->charset = NULL;
|
||||
|
||||
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 info tuple handle: %d", params[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DatabaseInfo nfo;
|
||||
nfo.database = sql->db;
|
||||
nfo.user = sql->user;
|
||||
nfo.pass = sql->pass;
|
||||
nfo.port = sql->port;
|
||||
nfo.host = sql->host;
|
||||
nfo.max_timeout = sql->max_timeout;
|
||||
nfo.charset = sql->charset;
|
||||
|
||||
char buffer[512];
|
||||
int errcode;
|
||||
|
||||
IDatabase *pDb = g_Mysql.Connect2(&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_Mysql.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_Mysql.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_Mysql.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_Mysql.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_SetCharset(AMX *amx, cell *params)
|
||||
{
|
||||
SQL_Connection *sql = (SQL_Connection *)GetHandle(params[1], Handle_Connection);
|
||||
if (!sql)
|
||||
{
|
||||
IDatabase *pDb = (IDatabase *)GetHandle(params[1], Handle_Database);
|
||||
if (!pDb)
|
||||
{
|
||||
MF_LogError(amx, AMX_ERR_NATIVE, "Invalid info tuple or database handle: %d", params[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int len;
|
||||
return pDb->SetCharacterSet(MF_GetAmxString(amx, params[2], 0, &len));
|
||||
}
|
||||
else
|
||||
{
|
||||
int len;
|
||||
const char *charset = MF_GetAmxString(amx, params[2], 0, &len);
|
||||
|
||||
if (!sql->charset || stricmp(charset, sql->charset))
|
||||
{
|
||||
sql->charset = strdup(charset);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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},
|
||||
{"SQL_SetCharset", SQL_SetCharset},
|
||||
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
120
modules/mysqlx/handles.cpp
Normal file
120
modules/mysqlx/handles.cpp
Normal 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
|
||||
|
||||
//
|
||||
// MySQL Module
|
||||
//
|
||||
|
||||
#include <string.h>
|
||||
#include <sh_stack.h>
|
||||
#include <am-vector.h>
|
||||
#include "mysql2_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();
|
||||
}
|
64
modules/mysqlx/module.cpp
Normal file
64
modules/mysqlx/module.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
// 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
|
||||
|
||||
//
|
||||
// MySQL Module
|
||||
//
|
||||
|
||||
#include "amxxmodule.h"
|
||||
#include "mysql2_header.h"
|
||||
#include "sqlheaders.h"
|
||||
|
||||
static int g_ident = 0;
|
||||
|
||||
SqlFunctions g_MysqlFuncs =
|
||||
{
|
||||
&g_Mysql,
|
||||
SetMysqlAffinity,
|
||||
NULL
|
||||
};
|
||||
|
||||
int SetMysqlAffinity(AMX *amx)
|
||||
{
|
||||
MF_AmxReRegister(amx, g_BaseSqlNatives, -1);
|
||||
MF_AmxReRegister(amx, g_ThreadSqlNatives, -1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void OnAmxxAttach()
|
||||
{
|
||||
MF_AddNatives(g_BaseSqlNatives);
|
||||
MF_AddNatives(g_ThreadSqlNatives);
|
||||
g_MysqlFuncs.prev = (SqlFunctions *)MF_RegisterFunctionEx(&g_MysqlFuncs, SQL_DRIVER_FUNC);
|
||||
if (!MF_RequestFunction("GetDbDriver")
|
||||
&& !MF_FindLibrary("SQLITE", LibType_Library))
|
||||
{
|
||||
MF_AddNatives(g_OldCompatNatives);
|
||||
MF_AddLibraries("dbi", LibType_Class, &g_ident);
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
514
modules/mysqlx/moduleconfig.h
Normal file
514
modules/mysqlx/moduleconfig.h
Normal file
@ -0,0 +1,514 @@
|
||||
// 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
|
||||
* -The logtag is the tag that the module's log messages will be
|
||||
* prepended with.
|
||||
* -The library is the name that the #pragma library
|
||||
* message will have prepended.
|
||||
* -The library class is the class of libraries that
|
||||
* a module belongs to (like DBI). Keep it "" to
|
||||
* ignore.
|
||||
* -For both library and library class, you can use a comma
|
||||
* to add multiple entries.
|
||||
*/
|
||||
#define MODULE_NAME "MySQL"
|
||||
#define MODULE_VERSION AMXX_VERSION
|
||||
#define MODULE_AUTHOR "AMX Mod X Dev Team"
|
||||
#define MODULE_URL "http://www.amxmodx.org/"
|
||||
#define MODULE_LOGTAG "MySQL"
|
||||
#define MODULE_LIBRARY "mysql"
|
||||
#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__
|
20
modules/mysqlx/msvc12/mysqlx.sln
Normal file
20
modules/mysqlx/msvc12/mysqlx.sln
Normal file
@ -0,0 +1,20 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2010
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mysqlx", "mysqlx.vcxproj", "{7877D370-E48E-4A85-8EE4-131863A5B09F}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{7877D370-E48E-4A85-8EE4-131863A5B09F}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{7877D370-E48E-4A85-8EE4-131863A5B09F}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{7877D370-E48E-4A85-8EE4-131863A5B09F}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{7877D370-E48E-4A85-8EE4-131863A5B09F}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
211
modules/mysqlx/msvc12/mysqlx.vcxproj
Normal file
211
modules/mysqlx/msvc12/mysqlx.vcxproj
Normal file
@ -0,0 +1,211 @@
|
||||
<?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>{7877D370-E48E-4A85-8EE4-131863A5B09F}</ProjectGuid>
|
||||
<RootNamespace>mysqlx</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'">mysql_amxx</TargetName>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">mysql_amxx</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl\include;..\..\third_party;..\..\third_party\hashing;..\..\..\..\mysql-5.0\include;..\mysql;..\sdk;..\thread;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\public;$(MYSQL5)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_ITERATOR_DEBUG_LEVEL=0;_DEBUG;_WINDOWS;_USRDLL;MYSQL2_EXPORTS;SM_DEFAULT_THREADER;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>ws2_32.lib;..\..\..\..\mysql-5.0\lib\opt\mysqlclient.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<IgnoreSpecificDefaultLibraries>LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(OutDir)mysql2.pdb</ProgramDatabaseFile>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<ImportLibrary>$(OutDir)mysql2.lib</ImportLibrary>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..\;..\..\..\public;..\..\..\public\sdk; ..\..\..\public\amtl\include;..\..\third_party;..\..\third_party\hashing;..\..\..\..\mysql-5.0\include;..\mysql;..\sdk;..\thread;$(METAMOD)\metamod;$(HLSDK)\common;$(HLSDK)\engine;$(HLSDK)\dlls;$(HLSDK)\public;$(MYSQL5)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;_ITERATOR_DEBUG_LEVEL=0;NDEBUG;_WINDOWS;_USRDLL;MYSQL2_EXPORTS;SM_DEFAULT_THREADER;HAVE_STDINT_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>ws2_32.lib;..\..\..\..\mysql-5.0\lib\opt\mysqlclient.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<ImportLibrary>$(OutDir)mysql2.lib</ImportLibrary>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\third_party\zlib\adler32.c">
|
||||
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)zlib\</ObjectFileName>
|
||||
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)zlib\</ObjectFileName>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\third_party\zlib\compress.c">
|
||||
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)zlib\</ObjectFileName>
|
||||
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)zlib\</ObjectFileName>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\third_party\zlib\crc32.c">
|
||||
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)zlib\</ObjectFileName>
|
||||
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)zlib\</ObjectFileName>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\third_party\zlib\deflate.c">
|
||||
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)zlib\</ObjectFileName>
|
||||
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)zlib\</ObjectFileName>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\third_party\zlib\gzclose.c">
|
||||
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)zlib\</ObjectFileName>
|
||||
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)zlib\</ObjectFileName>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\third_party\zlib\gzlib.c">
|
||||
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)zlib\</ObjectFileName>
|
||||
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)zlib\</ObjectFileName>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\third_party\zlib\gzread.c">
|
||||
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)zlib\</ObjectFileName>
|
||||
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)zlib\</ObjectFileName>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\third_party\zlib\gzwrite.c">
|
||||
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)zlib\</ObjectFileName>
|
||||
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)zlib\</ObjectFileName>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\third_party\zlib\infback.c">
|
||||
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)zlib\</ObjectFileName>
|
||||
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)zlib\</ObjectFileName>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\third_party\zlib\inffast.c">
|
||||
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)zlib\</ObjectFileName>
|
||||
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)zlib\</ObjectFileName>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\third_party\zlib\inflate.c">
|
||||
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)zlib\</ObjectFileName>
|
||||
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)zlib\</ObjectFileName>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\third_party\zlib\inftrees.c">
|
||||
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)zlib\</ObjectFileName>
|
||||
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)zlib\</ObjectFileName>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\third_party\zlib\trees.c">
|
||||
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)zlib\</ObjectFileName>
|
||||
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)zlib\</ObjectFileName>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\third_party\zlib\uncompr.c">
|
||||
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)zlib\</ObjectFileName>
|
||||
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)zlib\</ObjectFileName>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\third_party\zlib\zutil.c">
|
||||
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)zlib\</ObjectFileName>
|
||||
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)zlib\</ObjectFileName>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\basic_sql.cpp" />
|
||||
<ClCompile Include="..\handles.cpp" />
|
||||
<ClCompile Include="..\module.cpp" />
|
||||
<ClCompile Include="..\oldcompat_sql.cpp" />
|
||||
<ClCompile Include="..\threading.cpp" />
|
||||
<ClCompile Include="..\thread\BaseWorker.cpp" />
|
||||
<ClCompile Include="..\thread\ThreadWorker.cpp" />
|
||||
<ClCompile Include="..\thread\WinThreads.cpp" />
|
||||
<ClCompile Include="..\mysql\MysqlDatabase.cpp" />
|
||||
<ClCompile Include="..\mysql\MysqlDriver.cpp" />
|
||||
<ClCompile Include="..\mysql\MysqlQuery.cpp" />
|
||||
<ClCompile Include="..\mysql\MysqlResultSet.cpp" />
|
||||
<ClCompile Include="..\..\..\public\sdk\amxxmodule.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\third_party\zlib\crc32.h" />
|
||||
<ClInclude Include="..\..\..\third_party\zlib\deflate.h" />
|
||||
<ClInclude Include="..\..\..\third_party\zlib\gzguts.h" />
|
||||
<ClInclude Include="..\..\..\third_party\zlib\inffast.h" />
|
||||
<ClInclude Include="..\..\..\third_party\zlib\inffixed.h" />
|
||||
<ClInclude Include="..\..\..\third_party\zlib\inflate.h" />
|
||||
<ClInclude Include="..\..\..\third_party\zlib\inftrees.h" />
|
||||
<ClInclude Include="..\..\..\third_party\zlib\trees.h" />
|
||||
<ClInclude Include="..\..\..\third_party\zlib\zconf.h" />
|
||||
<ClInclude Include="..\..\..\third_party\zlib\zlib.h" />
|
||||
<ClInclude Include="..\..\..\third_party\zlib\zutil.h" />
|
||||
<ClInclude Include="..\mysql2_header.h" />
|
||||
<ClInclude Include="..\sqlheaders.h" />
|
||||
<ClInclude Include="..\threading.h" />
|
||||
<ClInclude Include="..\thread\IThreader.h" />
|
||||
<ClInclude Include="..\thread\BaseWorker.h" />
|
||||
<ClInclude Include="..\thread\ThreadSupport.h" />
|
||||
<ClInclude Include="..\thread\ThreadWorker.h" />
|
||||
<ClInclude Include="..\thread\WinThreads.h" />
|
||||
<ClInclude Include="..\mysql\ISQLDriver.h" />
|
||||
<ClInclude Include="..\mysql\MysqlDatabase.h" />
|
||||
<ClInclude Include="..\mysql\MysqlDriver.h" />
|
||||
<ClInclude Include="..\mysql\MysqlHeaders.h" />
|
||||
<ClInclude Include="..\mysql\MysqlQuery.h" />
|
||||
<ClInclude Include="..\mysql\MysqlResultSet.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>
|
220
modules/mysqlx/msvc12/mysqlx.vcxproj.filters
Normal file
220
modules/mysqlx/msvc12/mysqlx.vcxproj.filters
Normal file
@ -0,0 +1,220 @@
|
||||
<?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>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Threader">
|
||||
<UniqueIdentifier>{4dd9f741-116d-4a02-a132-3cfab02530db}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Threader\Source Files">
|
||||
<UniqueIdentifier>{27929344-5a05-4bb9-9cda-a27eb373d954}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Threader\Header Files">
|
||||
<UniqueIdentifier>{7633aa37-83c6-4e55-821f-0f02c47ab4f6}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Database">
|
||||
<UniqueIdentifier>{705fb714-2fe0-478c-9ae0-bd3566b4d2d0}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Database\Header Files">
|
||||
<UniqueIdentifier>{33a3d700-3b61-42fb-a808-7dd8cd92120e}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Database\Source Files">
|
||||
<UniqueIdentifier>{65b4ccbd-e7f7-4ddd-8d49-d059ff804f93}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Module SDK">
|
||||
<UniqueIdentifier>{15c62ca4-f448-4a1e-8277-9bee3e572408}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Module SDK\SDK Base">
|
||||
<UniqueIdentifier>{41c3be98-7cfc-4071-b7fd-be17c2ee7279}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Pawn Includes">
|
||||
<UniqueIdentifier>{05423057-6d62-454a-b5f8-b451d91be196}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Third Party">
|
||||
<UniqueIdentifier>{2753269b-35b5-4947-b0f3-806b3c39959a}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Third Party\Zlib">
|
||||
<UniqueIdentifier>{557b0e54-eb0e-488f-b8bc-3cee3f8ddfba}</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="..\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="..\mysql\MysqlDatabase.cpp">
|
||||
<Filter>Database\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\mysql\MysqlDriver.cpp">
|
||||
<Filter>Database\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\mysql\MysqlQuery.cpp">
|
||||
<Filter>Database\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\mysql\MysqlResultSet.cpp">
|
||||
<Filter>Database\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\public\sdk\amxxmodule.cpp">
|
||||
<Filter>Module SDK\SDK Base</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\third_party\zlib\adler32.c">
|
||||
<Filter>Third Party\Zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\third_party\zlib\compress.c">
|
||||
<Filter>Third Party\Zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\third_party\zlib\crc32.c">
|
||||
<Filter>Third Party\Zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\third_party\zlib\deflate.c">
|
||||
<Filter>Third Party\Zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\third_party\zlib\gzclose.c">
|
||||
<Filter>Third Party\Zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\third_party\zlib\gzlib.c">
|
||||
<Filter>Third Party\Zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\third_party\zlib\gzread.c">
|
||||
<Filter>Third Party\Zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\third_party\zlib\gzwrite.c">
|
||||
<Filter>Third Party\Zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\third_party\zlib\infback.c">
|
||||
<Filter>Third Party\Zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\third_party\zlib\inffast.c">
|
||||
<Filter>Third Party\Zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\third_party\zlib\inflate.c">
|
||||
<Filter>Third Party\Zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\third_party\zlib\inftrees.c">
|
||||
<Filter>Third Party\Zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\third_party\zlib\trees.c">
|
||||
<Filter>Third Party\Zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\third_party\zlib\uncompr.c">
|
||||
<Filter>Third Party\Zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\third_party\zlib\zutil.c">
|
||||
<Filter>Third Party\Zlib</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\mysql2_header.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\sqlheaders.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\threading.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\thread\IThreader.h">
|
||||
<Filter>Threader</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\thread\BaseWorker.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="..\mysql\ISQLDriver.h">
|
||||
<Filter>Database</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\mysql\MysqlDatabase.h">
|
||||
<Filter>Database\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\mysql\MysqlDriver.h">
|
||||
<Filter>Database\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\mysql\MysqlHeaders.h">
|
||||
<Filter>Database\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\mysql\MysqlQuery.h">
|
||||
<Filter>Database\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\mysql\MysqlResultSet.h">
|
||||
<Filter>Database\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\moduleconfig.h">
|
||||
<Filter>Module SDK</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\public\sdk\amxxmodule.h">
|
||||
<Filter>Module SDK\SDK Base</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\third_party\zlib\crc32.h">
|
||||
<Filter>Third Party\Zlib</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\third_party\zlib\deflate.h">
|
||||
<Filter>Third Party\Zlib</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\third_party\zlib\gzguts.h">
|
||||
<Filter>Third Party\Zlib</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\third_party\zlib\inffast.h">
|
||||
<Filter>Third Party\Zlib</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\third_party\zlib\inffixed.h">
|
||||
<Filter>Third Party\Zlib</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\third_party\zlib\inflate.h">
|
||||
<Filter>Third Party\Zlib</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\third_party\zlib\inftrees.h">
|
||||
<Filter>Third Party\Zlib</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\third_party\zlib\trees.h">
|
||||
<Filter>Third Party\Zlib</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\third_party\zlib\zconf.h">
|
||||
<Filter>Third Party\Zlib</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\third_party\zlib\zlib.h">
|
||||
<Filter>Third Party\Zlib</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\third_party\zlib\zutil.h">
|
||||
<Filter>Third Party\Zlib</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\..\plugins\include\sqlx.inc">
|
||||
<Filter>Pawn Includes</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
188
modules/mysqlx/mysql/ISQLDriver.h
Normal file
188
modules/mysqlx/mysql/ISQLDriver.h
Normal file
@ -0,0 +1,188 @@
|
||||
// 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
|
||||
|
||||
//
|
||||
// MySQL 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;
|
||||
/**
|
||||
* Rewinds to the first row.
|
||||
*/
|
||||
virtual void Rewind() =0;
|
||||
/**
|
||||
* Transitions to the next result set, if any is available.
|
||||
*/
|
||||
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
|
102
modules/mysqlx/mysql/MysqlDatabase.cpp
Normal file
102
modules/mysqlx/mysql/MysqlDatabase.cpp
Normal file
@ -0,0 +1,102 @@
|
||||
// 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
|
||||
|
||||
//
|
||||
// MySQL Module
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "MysqlDriver.h"
|
||||
#include "MysqlDatabase.h"
|
||||
#include "MysqlQuery.h"
|
||||
|
||||
#if defined WIN32 && !defined vsnprintf
|
||||
#define vsnprintf _vsnprintf
|
||||
#endif
|
||||
|
||||
using namespace SourceMod;
|
||||
|
||||
MysqlDatabase::MysqlDatabase(MYSQL *mysql, MysqlDriver *drvr) :
|
||||
m_pMysql(mysql), m_pParent(drvr)
|
||||
{
|
||||
}
|
||||
|
||||
MysqlDatabase::~MysqlDatabase()
|
||||
{
|
||||
Disconnect();
|
||||
}
|
||||
|
||||
void MysqlDatabase::Disconnect()
|
||||
{
|
||||
mysql_close(m_pMysql);
|
||||
m_pMysql = NULL;
|
||||
}
|
||||
|
||||
void MysqlDatabase::FreeHandle()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
ISQLDriver *MysqlDatabase::Driver()
|
||||
{
|
||||
return static_cast<ISQLDriver *>(m_pParent);
|
||||
}
|
||||
|
||||
IQuery *MysqlDatabase::PrepareQuery(const char *query)
|
||||
{
|
||||
MysqlQuery *mquery = new MysqlQuery(query, this);
|
||||
|
||||
return static_cast<IQuery *>(mquery);
|
||||
}
|
||||
|
||||
IQuery *MysqlDatabase::PrepareQueryFmt(const char *fmt, va_list ap)
|
||||
{
|
||||
char buffer[4096];
|
||||
|
||||
vsnprintf(buffer, sizeof(buffer)-1, fmt, ap);
|
||||
|
||||
return PrepareQuery(buffer);
|
||||
}
|
||||
|
||||
IQuery *MysqlDatabase::PrepareQueryFmt(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
IQuery *qry;
|
||||
|
||||
va_start(ap, fmt);
|
||||
qry = PrepareQueryFmt(fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return qry;
|
||||
}
|
||||
|
||||
int MysqlDatabase::QuoteString(const char *str, char buffer[], size_t maxlen, size_t *newsize)
|
||||
{
|
||||
unsigned long size = static_cast<unsigned long>(strlen(str));
|
||||
unsigned long needed = size*2 + 1;
|
||||
|
||||
if (maxlen < needed)
|
||||
{
|
||||
return (int)needed;
|
||||
}
|
||||
|
||||
needed = mysql_real_escape_string(m_pMysql, buffer, str, size);
|
||||
if (newsize)
|
||||
{
|
||||
*newsize = static_cast<size_t>(needed);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool MysqlDatabase::SetCharacterSet(const char *characterset)
|
||||
{
|
||||
return mysql_set_character_set(m_pMysql, characterset) == 0 ? true : false;
|
||||
}
|
48
modules/mysqlx/mysql/MysqlDatabase.h
Normal file
48
modules/mysqlx/mysql/MysqlDatabase.h
Normal 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
|
||||
|
||||
//
|
||||
// MySQL Module
|
||||
//
|
||||
|
||||
#ifndef _INCLUDE_SOURCEMOD_MYSQL_DATABASE_H
|
||||
#define _INCLUDE_SOURCEMOD_MYSQL_DATABASE_H
|
||||
|
||||
#include "MysqlHeaders.h"
|
||||
#include "MysqlDriver.h"
|
||||
|
||||
namespace SourceMod
|
||||
{
|
||||
class MysqlDriver;
|
||||
|
||||
class MysqlDatabase : public IDatabase
|
||||
{
|
||||
friend class MysqlQuery;
|
||||
public:
|
||||
MysqlDatabase(MYSQL *mysql, MysqlDriver *drvr);
|
||||
~MysqlDatabase();
|
||||
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:
|
||||
MYSQL *m_pMysql;
|
||||
MysqlDriver *m_pParent;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#endif //_INCLUDE_SOURCEMOD_MYSQL_DATABASE_H
|
125
modules/mysqlx/mysql/MysqlDriver.cpp
Normal file
125
modules/mysqlx/mysql/MysqlDriver.cpp
Normal file
@ -0,0 +1,125 @@
|
||||
// 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
|
||||
|
||||
//
|
||||
// MySQL Module
|
||||
//
|
||||
|
||||
#include "amxxmodule.h"
|
||||
#include "MysqlDriver.h"
|
||||
#include "MysqlDatabase.h"
|
||||
|
||||
using namespace SourceMod;
|
||||
|
||||
bool MysqlDriver::IsCompatDriver(const char *namestring)
|
||||
{
|
||||
return (strncasecmp(namestring, "mysql", 5) == 0);
|
||||
}
|
||||
|
||||
const char *MysqlDriver::NameString()
|
||||
{
|
||||
return "mysql";
|
||||
}
|
||||
|
||||
IDatabase *MysqlDriver::Connect(DatabaseInfo *info, int *errcode, char *error, size_t maxlength)
|
||||
{
|
||||
return _Connect(info, errcode, error, maxlength, false);
|
||||
}
|
||||
|
||||
IDatabase *MysqlDriver::Connect2(DatabaseInfo *info, int *errcode, char *error, size_t maxlength)
|
||||
{
|
||||
return _Connect(info, errcode, error, maxlength, true);
|
||||
}
|
||||
|
||||
IDatabase *MysqlDriver::_Connect(DatabaseInfo *info, int *errcode, char *error, size_t maxlength, bool do_timeout)
|
||||
{
|
||||
MYSQL *mysql = mysql_init(NULL);
|
||||
|
||||
if (!mysql)
|
||||
{
|
||||
if (errcode)
|
||||
*errcode = -1;
|
||||
if (error && maxlength)
|
||||
{
|
||||
UTIL_Format(error, maxlength, "Initialization failed");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
decltype(info->max_timeout) timeout = atoi(LOCALINFO("mysql_timeout"));
|
||||
|
||||
if (timeout <= 0)
|
||||
{
|
||||
timeout = 60;
|
||||
}
|
||||
|
||||
if (do_timeout && info->max_timeout > 0)
|
||||
{
|
||||
timeout = info->max_timeout;
|
||||
}
|
||||
|
||||
mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&timeout);
|
||||
mysql_options(mysql, MYSQL_OPT_READ_TIMEOUT, (const char *)&timeout);
|
||||
mysql_options(mysql, MYSQL_OPT_WRITE_TIMEOUT, (const char *)&timeout);
|
||||
|
||||
/** Have MySQL automatically reconnect if it times out or loses connection.
|
||||
* This will prevent "MySQL server has gone away" errors after a while.
|
||||
*/
|
||||
my_bool my_true = true;
|
||||
mysql_options(mysql, MYSQL_OPT_RECONNECT, (const char *)&my_true);
|
||||
|
||||
if (mysql_real_connect(mysql,
|
||||
info->host,
|
||||
info->user,
|
||||
info->pass,
|
||||
info->database,
|
||||
info->port,
|
||||
NULL,
|
||||
CLIENT_MULTI_STATEMENTS) == NULL)
|
||||
{
|
||||
if (errcode)
|
||||
{
|
||||
*errcode = mysql_errno(mysql);
|
||||
}
|
||||
if (error && maxlength)
|
||||
{
|
||||
UTIL_Format(error, maxlength, "%s", mysql_error(mysql));
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MysqlDatabase *pMysql = new MysqlDatabase(mysql, this);
|
||||
|
||||
if (info->charset && *info->charset)
|
||||
{
|
||||
pMysql->SetCharacterSet(info->charset);
|
||||
}
|
||||
|
||||
return static_cast<IDatabase *>(pMysql);
|
||||
}
|
||||
|
||||
int MysqlDriver::QuoteString(const char *str, char buffer[], size_t maxlen, size_t *newsize)
|
||||
{
|
||||
unsigned long size = static_cast<unsigned long>(strlen(str));
|
||||
unsigned long needed = size*2 + 1;
|
||||
|
||||
if (maxlen < needed)
|
||||
{
|
||||
return (int)needed;
|
||||
}
|
||||
|
||||
needed = mysql_escape_string(buffer, str, size);
|
||||
if (newsize)
|
||||
{
|
||||
*newsize = static_cast<size_t>(needed);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
34
modules/mysqlx/mysql/MysqlDriver.h
Normal file
34
modules/mysqlx/mysql/MysqlDriver.h
Normal file
@ -0,0 +1,34 @@
|
||||
// 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
|
||||
|
||||
//
|
||||
// MySQL Module
|
||||
//
|
||||
|
||||
#ifndef _INCLUDE_SOURCEMOD_MYSQL_DRIVER_H
|
||||
#define _INCLUDE_SOURCEMOD_MYSQL_DRIVER_H
|
||||
|
||||
#include "MysqlHeaders.h"
|
||||
|
||||
namespace SourceMod
|
||||
{
|
||||
class MysqlDriver : 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 *namestring);
|
||||
int QuoteString(const char *str, char buffer[], size_t maxlen, size_t *newsize);
|
||||
public:
|
||||
IDatabase *_Connect(DatabaseInfo *info, int *errcode, char *error, size_t maxlength, bool do_timeout);
|
||||
};
|
||||
};
|
||||
|
||||
#endif //_INCLUDE_SOURCEMOD_MYSQL_DRIVER_H
|
38
modules/mysqlx/mysql/MysqlHeaders.h
Normal file
38
modules/mysqlx/mysql/MysqlHeaders.h
Normal file
@ -0,0 +1,38 @@
|
||||
// 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
|
||||
|
||||
//
|
||||
// MySQL Module
|
||||
//
|
||||
|
||||
#ifndef _INCLUDE_SOURCEMOD_MYSQL_HEADERS_H
|
||||
#define _INCLUDE_SOURCEMOD_MYSQL_HEADERS_H
|
||||
|
||||
#if _MSC_VER >= 1400
|
||||
/* Disable deprecation warnings concerning unsafe CRT functions */
|
||||
#if !defined _CRT_SECURE_NO_DEPRECATE
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
#endif
|
||||
|
||||
/* Replace the POSIX function with ISO C++ conformant ones as they are now deprecated */
|
||||
#define strnicmp _strnicmp
|
||||
|
||||
/* Disable deprecation warnings because MSVC8 seemingly thinks the ISO C++ conformant
|
||||
* functions above are deprecated. */
|
||||
#pragma warning (disable:4996)
|
||||
#endif
|
||||
|
||||
#include <ISQLDriver.h>
|
||||
#if defined WIN32 || defined _WIN32
|
||||
#include <WinSock2.h>
|
||||
#endif
|
||||
typedef unsigned long ulong;
|
||||
#include <mysql.h>
|
||||
|
||||
#endif //_INCLUDE_SOURCEMOD_MYSQL_HEADERS_H
|
125
modules/mysqlx/mysql/MysqlQuery.cpp
Normal file
125
modules/mysqlx/mysql/MysqlQuery.cpp
Normal file
@ -0,0 +1,125 @@
|
||||
// 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
|
||||
|
||||
//
|
||||
// MySQL Module
|
||||
//
|
||||
|
||||
#include "amxxmodule.h"
|
||||
#include "MysqlQuery.h"
|
||||
#include "MysqlDatabase.h"
|
||||
#include "MysqlResultSet.h"
|
||||
|
||||
using namespace SourceMod;
|
||||
|
||||
MysqlQuery::MysqlQuery(const char *querystring, MysqlDatabase *db) :
|
||||
m_pDatabase(db)
|
||||
{
|
||||
m_QueryLen = strlen(querystring);
|
||||
m_QueryString = new char[m_QueryLen + 1];
|
||||
m_LastRes = NULL;
|
||||
strcpy(m_QueryString, querystring);
|
||||
}
|
||||
|
||||
MysqlQuery::~MysqlQuery()
|
||||
{
|
||||
if (m_LastRes)
|
||||
{
|
||||
m_LastRes->FreeHandle();
|
||||
}
|
||||
|
||||
delete [] m_QueryString;
|
||||
}
|
||||
|
||||
void MysqlQuery::FreeHandle()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
bool MysqlQuery::Execute(QueryInfo *info, char *error, size_t maxlength)
|
||||
{
|
||||
bool res = ExecuteR(info, error, maxlength);
|
||||
|
||||
if (m_LastRes)
|
||||
m_LastRes->FreeHandle();
|
||||
|
||||
m_LastRes = (MysqlResultSet *)info->rs;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool MysqlQuery::Execute2(QueryInfo *info, char *error, size_t maxlength)
|
||||
{
|
||||
bool res = ExecuteR(info, error, maxlength);
|
||||
|
||||
if (m_LastRes)
|
||||
m_LastRes->FreeHandle();
|
||||
|
||||
m_LastRes = (MysqlResultSet *)info->rs;
|
||||
|
||||
if (info->success)
|
||||
{
|
||||
info->insert_id = mysql_insert_id(m_pDatabase->m_pMysql);
|
||||
} else {
|
||||
info->insert_id = 0;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
const char *MysqlQuery::GetQueryString()
|
||||
{
|
||||
return m_QueryString;
|
||||
}
|
||||
|
||||
bool MysqlQuery::ExecuteR(QueryInfo *info, char *error, size_t maxlength)
|
||||
{
|
||||
int err;
|
||||
|
||||
if ( (err=mysql_real_query(m_pDatabase->m_pMysql, m_QueryString, (unsigned long)m_QueryLen)) )
|
||||
{
|
||||
info->errorcode = mysql_errno(m_pDatabase->m_pMysql);
|
||||
info->success = false;
|
||||
info->affected_rows = 0;
|
||||
info->rs = NULL;
|
||||
if (error && maxlength)
|
||||
{
|
||||
UTIL_Format(error, maxlength, "%s", mysql_error(m_pDatabase->m_pMysql));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MYSQL_RES *res = mysql_store_result(m_pDatabase->m_pMysql);
|
||||
if (!res)
|
||||
{
|
||||
if (mysql_field_count(m_pDatabase->m_pMysql) > 0)
|
||||
{
|
||||
//error !111!!11
|
||||
info->errorcode = mysql_errno(m_pDatabase->m_pMysql);
|
||||
info->success = false;
|
||||
info->affected_rows = 0;
|
||||
info->rs = NULL;
|
||||
} else {
|
||||
info->errorcode = 0;
|
||||
info->success = true;
|
||||
info->affected_rows = mysql_affected_rows(m_pDatabase->m_pMysql);
|
||||
info->rs = NULL;
|
||||
}
|
||||
} else {
|
||||
info->errorcode = 0;
|
||||
info->success = true;
|
||||
info->affected_rows = mysql_affected_rows(m_pDatabase->m_pMysql);
|
||||
MysqlResultSet *rs = new MysqlResultSet(res, m_pDatabase->m_pMysql);
|
||||
info->rs = rs;
|
||||
}
|
||||
}
|
||||
|
||||
return info->success;
|
||||
}
|
||||
|
43
modules/mysqlx/mysql/MysqlQuery.h
Normal file
43
modules/mysqlx/mysql/MysqlQuery.h
Normal file
@ -0,0 +1,43 @@
|
||||
// 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
|
||||
|
||||
//
|
||||
// MySQL Module
|
||||
//
|
||||
|
||||
#ifndef _INCLUDE_SOURCEMOD_MYSQL_QUERY_H
|
||||
#define _INCLUDE_SOURCEMOD_MYSQL_QUERY_H
|
||||
|
||||
#include "MysqlHeaders.h"
|
||||
|
||||
namespace SourceMod
|
||||
{
|
||||
class MysqlDatabase;
|
||||
class MysqlResultSet;
|
||||
|
||||
class MysqlQuery : public IQuery
|
||||
{
|
||||
public:
|
||||
MysqlQuery(const char *querystring, MysqlDatabase *db);
|
||||
~MysqlQuery();
|
||||
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:
|
||||
MysqlDatabase *m_pDatabase;
|
||||
char *m_QueryString;
|
||||
size_t m_QueryLen;
|
||||
MysqlResultSet *m_LastRes;
|
||||
};
|
||||
};
|
||||
|
||||
#endif //_INCLUDE_SOURCEMOD_MYSQL_QUERY_H
|
213
modules/mysqlx/mysql/MysqlResultSet.cpp
Normal file
213
modules/mysqlx/mysql/MysqlResultSet.cpp
Normal file
@ -0,0 +1,213 @@
|
||||
// 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
|
||||
|
||||
//
|
||||
// MySQL Module
|
||||
//
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "MysqlResultSet.h"
|
||||
|
||||
using namespace SourceMod;
|
||||
|
||||
MysqlResultRow::MysqlResultRow() :
|
||||
m_CurRow(NULL), m_Columns(0)
|
||||
{
|
||||
}
|
||||
|
||||
const char *MysqlResultRow::GetRaw(unsigned int columnId, size_t *length)
|
||||
{
|
||||
if (columnId >= m_Columns)
|
||||
{
|
||||
if (length)
|
||||
*length = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*length = static_cast<size_t>(m_Lengths[columnId]);
|
||||
return m_CurRow[columnId];
|
||||
}
|
||||
|
||||
bool MysqlResultRow::IsNull(unsigned int columnId)
|
||||
{
|
||||
if (columnId >= m_Columns)
|
||||
return true;
|
||||
|
||||
return (m_CurRow[columnId] == NULL);
|
||||
}
|
||||
|
||||
const char *MysqlResultRow::GetStringSafe(unsigned int columnId)
|
||||
{
|
||||
if (columnId >= m_Columns)
|
||||
return "";
|
||||
|
||||
return (m_CurRow[columnId] ? m_CurRow[columnId] : "");
|
||||
}
|
||||
|
||||
const char *MysqlResultRow::GetString(unsigned int columnId)
|
||||
{
|
||||
if (columnId >= m_Columns)
|
||||
return NULL;
|
||||
|
||||
return m_CurRow[columnId];
|
||||
}
|
||||
|
||||
double MysqlResultRow::GetDouble(unsigned int columnId)
|
||||
{
|
||||
return atof(GetStringSafe(columnId));
|
||||
}
|
||||
|
||||
float MysqlResultRow::GetFloat(unsigned int columnId)
|
||||
{
|
||||
return (float)atof(GetStringSafe(columnId));
|
||||
}
|
||||
|
||||
int MysqlResultRow::GetInt(unsigned int columnId)
|
||||
{
|
||||
return atoi(GetStringSafe(columnId));
|
||||
}
|
||||
|
||||
MysqlResultSet::MysqlResultSet(MYSQL_RES *res, MYSQL *mysql) :
|
||||
m_pRes(res)
|
||||
{
|
||||
m_Rows = (unsigned int)mysql_num_rows(res);
|
||||
m_Columns = (unsigned int)mysql_num_fields(res);
|
||||
m_pMySQL = mysql;
|
||||
|
||||
if (m_Rows > 0)
|
||||
{
|
||||
NextRow();
|
||||
}
|
||||
|
||||
m_kRow.m_Columns = m_Columns;
|
||||
}
|
||||
|
||||
MysqlResultSet::~MysqlResultSet()
|
||||
{
|
||||
if (m_pRes == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mysql_free_result(m_pRes);
|
||||
while (mysql_next_result(m_pMySQL) == 0)
|
||||
{
|
||||
m_pRes = mysql_store_result(m_pMySQL);
|
||||
if (m_pRes != NULL)
|
||||
{
|
||||
mysql_free_result(m_pRes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool MysqlResultSet::NextResultSet()
|
||||
{
|
||||
if (!mysql_more_results(m_pMySQL))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
mysql_free_result(m_pRes);
|
||||
if (mysql_next_result(m_pMySQL) != 0
|
||||
|| (m_pRes = mysql_store_result(m_pMySQL)) == NULL)
|
||||
{
|
||||
m_Rows = 0;
|
||||
m_pRes = NULL;
|
||||
m_Columns = 0;
|
||||
m_kRow.m_CurRow = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_Rows = (unsigned int)mysql_num_rows(m_pRes);
|
||||
m_Columns = (unsigned int)mysql_num_fields(m_pRes);
|
||||
|
||||
if (m_Rows > 0)
|
||||
{
|
||||
NextRow();
|
||||
}
|
||||
|
||||
m_kRow.m_Columns = m_Columns;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MysqlResultSet::FreeHandle()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
IResultRow *MysqlResultSet::GetRow()
|
||||
{
|
||||
return static_cast<IResultRow *>(&m_kRow);
|
||||
}
|
||||
|
||||
unsigned int MysqlResultSet::RowCount()
|
||||
{
|
||||
return m_Rows;
|
||||
}
|
||||
|
||||
const char *MysqlResultSet::FieldNumToName(unsigned int num)
|
||||
{
|
||||
if (num >= m_Columns)
|
||||
return NULL;
|
||||
|
||||
MYSQL_FIELD *field = mysql_fetch_field_direct(m_pRes, num);
|
||||
if (!field || !field->name)
|
||||
return "";
|
||||
|
||||
return field->name;
|
||||
}
|
||||
|
||||
bool MysqlResultSet::FieldNameToNum(const char *name, unsigned int *columnId)
|
||||
{
|
||||
MYSQL_FIELD *field;
|
||||
for (unsigned int i=0; i<m_Columns; i++)
|
||||
{
|
||||
field = mysql_fetch_field_direct(m_pRes, i);
|
||||
if (!field || !field->name)
|
||||
continue;
|
||||
if (strcmp(name, field->name) == 0)
|
||||
{
|
||||
if (columnId)
|
||||
*columnId = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int MysqlResultSet::FieldCount()
|
||||
{
|
||||
return m_Columns;
|
||||
}
|
||||
|
||||
bool MysqlResultSet::IsDone()
|
||||
{
|
||||
return (m_kRow.m_CurRow == NULL);
|
||||
}
|
||||
|
||||
void MysqlResultSet::NextRow()
|
||||
{
|
||||
MYSQL_ROW row = mysql_fetch_row(m_pRes);
|
||||
m_kRow.m_CurRow = row;
|
||||
|
||||
if (row)
|
||||
{
|
||||
unsigned long *lengths = mysql_fetch_lengths(m_pRes);
|
||||
m_kRow.m_Lengths = lengths;
|
||||
}
|
||||
}
|
||||
|
||||
void MysqlResultSet::Rewind()
|
||||
{
|
||||
mysql_data_seek(m_pRes, 0);
|
||||
NextRow();
|
||||
}
|
70
modules/mysqlx/mysql/MysqlResultSet.h
Normal file
70
modules/mysqlx/mysql/MysqlResultSet.h
Normal file
@ -0,0 +1,70 @@
|
||||
// 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
|
||||
|
||||
//
|
||||
// MySQL Module
|
||||
//
|
||||
|
||||
#ifndef _INCLUDE_SOURCEMOD_MYSQL_RESULTSET_H
|
||||
#define _INCLUDE_SOURCEMOD_MYSQL_RESULTSET_H
|
||||
|
||||
#include "MysqlHeaders.h"
|
||||
|
||||
namespace SourceMod
|
||||
{
|
||||
class MysqlResultSet;
|
||||
|
||||
class MysqlResultRow : public IResultRow
|
||||
{
|
||||
friend class MysqlResultSet;
|
||||
public:
|
||||
MysqlResultRow();
|
||||
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);
|
||||
private:
|
||||
const char *GetStringSafe(unsigned int columnId);
|
||||
private:
|
||||
MYSQL_ROW m_CurRow;
|
||||
unsigned long *m_Lengths;
|
||||
unsigned int m_Columns;
|
||||
};
|
||||
|
||||
class MysqlResultSet : public IResultSet
|
||||
{
|
||||
public:
|
||||
MysqlResultSet(MYSQL_RES *res, MYSQL *mysql);
|
||||
~MysqlResultSet();
|
||||
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();
|
||||
bool NextResultSet();
|
||||
private:
|
||||
MYSQL *m_pMySQL;
|
||||
MYSQL_RES *m_pRes;
|
||||
MysqlResultRow m_kRow;
|
||||
unsigned int m_Columns;
|
||||
unsigned int m_Rows;
|
||||
};
|
||||
};
|
||||
|
||||
#endif //_INCLUDE_SOURCEMOD_MYSQL_RESULTSET_H
|
71
modules/mysqlx/mysql2_header.h
Normal file
71
modules/mysqlx/mysql2_header.h
Normal file
@ -0,0 +1,71 @@
|
||||
// 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
|
||||
|
||||
//
|
||||
// MySQL Module
|
||||
//
|
||||
|
||||
#ifndef _INCLUDE_AMXMODX_MYSQL2_HEADER_H
|
||||
#define _INCLUDE_AMXMODX_MYSQL2_HEADER_H
|
||||
|
||||
#include "MysqlDriver.h"
|
||||
#include "amxxmodule.h"
|
||||
#include "ThreadSupport.h"
|
||||
#include "ThreadWorker.h"
|
||||
|
||||
#define MYSQL2_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;
|
||||
unsigned int max_timeout;
|
||||
char *charset;
|
||||
};
|
||||
|
||||
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::MysqlDriver g_Mysql;
|
||||
|
||||
#endif //_INCLUDE_AMXMODX_MYSQL2_HEADER_H
|
465
modules/mysqlx/oldcompat_sql.cpp
Normal file
465
modules/mysqlx/oldcompat_sql.cpp
Normal file
@ -0,0 +1,465 @@
|
||||
// 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
|
||||
|
||||
//
|
||||
// MySQL Module
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include "mysql2_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 *host = MF_GetAmxString(amx, params[1], 0, &len);
|
||||
char *user = MF_GetAmxString(amx, params[2], 1, &len);
|
||||
char *pass = MF_GetAmxString(amx, params[3], 2, &len);
|
||||
char *name = MF_GetAmxString(amx, params[4], 3, &len);
|
||||
|
||||
char *p = strchr(host, ':');
|
||||
if (p)
|
||||
{
|
||||
info.port = atoi(p+1);
|
||||
*p = '\0';
|
||||
} else {
|
||||
info.port = 0;
|
||||
}
|
||||
|
||||
info.host = host;
|
||||
info.user = user;
|
||||
info.pass = pass;
|
||||
info.database = name;
|
||||
|
||||
int err;
|
||||
char error[512];
|
||||
IDatabase *pDatabase = g_Mysql.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)
|
||||
{
|
||||
//special case, fall out!
|
||||
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;
|
||||
if (rs->IsDone())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
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;
|
||||
if (rs->IsDone())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
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], "mysql", 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 }
|
||||
};
|
30
modules/mysqlx/sqlheaders.h
Normal file
30
modules/mysqlx/sqlheaders.h
Normal 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
|
||||
|
||||
//
|
||||
// MySQL 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
|
259
modules/mysqlx/thread/BaseWorker.cpp
Normal file
259
modules/mysqlx/thread/BaseWorker.cpp
Normal file
@ -0,0 +1,259 @@
|
||||
// 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"
|
||||
#include <am-linkedlist.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.length())
|
||||
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.length())
|
||||
return NULL;
|
||||
|
||||
ke::LinkedList<SWThreadHandle *>::iterator begin;
|
||||
SWThreadHandle *swt;
|
||||
|
||||
begin = m_ThreadQueue.begin();
|
||||
swt = (*begin);
|
||||
m_ThreadQueue.erase(begin);
|
||||
|
||||
return swt;
|
||||
}
|
||||
|
||||
void BaseWorker::AddThreadToQueue(SWThreadHandle *pHandle)
|
||||
{
|
||||
m_ThreadQueue.append(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;
|
||||
}
|
81
modules/mysqlx/thread/BaseWorker.h
Normal file
81
modules/mysqlx/thread/BaseWorker.h
Normal 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 <am-linkedlist.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:
|
||||
ke::LinkedList<SWThreadHandle *> m_ThreadQueue;
|
||||
unsigned int m_perFrame;
|
||||
volatile WorkerState m_state;
|
||||
};
|
||||
|
||||
#endif //_INCLUDE_SOURCEMOD_BASEWORKER_H
|
237
modules/mysqlx/thread/IThreader.h
Normal file
237
modules/mysqlx/thread/IThreader.h
Normal 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
|
272
modules/mysqlx/thread/PosixThreads.cpp
Normal file
272
modules/mysqlx/thread/PosixThreads.cpp
Normal 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(¶ms);
|
||||
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;
|
||||
}
|
||||
|
91
modules/mysqlx/thread/PosixThreads.h
Normal file
91
modules/mysqlx/thread/PosixThreads.h
Normal 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_
|
19
modules/mysqlx/thread/ThreadSupport.h
Normal file
19
modules/mysqlx/thread/ThreadSupport.h
Normal 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
|
267
modules/mysqlx/thread/ThreadWorker.cpp
Normal file
267
modules/mysqlx/thread/ThreadWorker.cpp
Normal 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.length())
|
||||
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.length();
|
||||
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.length())
|
||||
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;
|
||||
}
|
49
modules/mysqlx/thread/ThreadWorker.h
Normal file
49
modules/mysqlx/thread/ThreadWorker.h
Normal 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
|
298
modules/mysqlx/thread/WinThreads.cpp
Normal file
298
modules/mysqlx/thread/WinThreads.cpp
Normal 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(¶ms);
|
||||
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;
|
||||
}
|
||||
|
91
modules/mysqlx/thread/WinThreads.h
Normal file
91
modules/mysqlx/thread/WinThreads.h
Normal 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_
|
613
modules/mysqlx/threading.cpp
Normal file
613
modules/mysqlx/threading.cpp
Normal file
@ -0,0 +1,613 @@
|
||||
// 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
|
||||
|
||||
//
|
||||
// MySQL Module
|
||||
//
|
||||
|
||||
#include "amxxmodule.h"
|
||||
#include "mysql2_header.h"
|
||||
#include "threading.h"
|
||||
|
||||
using namespace SourceMod;
|
||||
|
||||
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->host, cn->user, cn->pass, cn->db, cn->port, cn->max_timeout);
|
||||
kmThread->SetForward(fwd);
|
||||
kmThread->SetQuery(MF_GetAmxString(amx, params[3], 1, &len));
|
||||
kmThread->SetCellData(MF_GetAmxAddr(amx, params[4]), (ucell)params[5]);
|
||||
kmThread->SetCharacterSet(cn->charset);
|
||||
|
||||
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 *host, const char *user, const char *pass, const char *db, int port, unsigned int max_timeout)
|
||||
{
|
||||
m_host = host;
|
||||
m_user = user;
|
||||
m_pass = pass;
|
||||
m_db = db;
|
||||
m_max_timeout = max_timeout;
|
||||
m_port = port;
|
||||
m_qrInfo.queue_time = gpGlobals->time;
|
||||
}
|
||||
|
||||
void MysqlThread::SetCharacterSet(const char *charset)
|
||||
{
|
||||
m_charset = charset;
|
||||
}
|
||||
|
||||
void MysqlThread::SetQuery(const char *query)
|
||||
{
|
||||
m_query = query;
|
||||
}
|
||||
|
||||
void MysqlThread::RunThread(IThreadHandle *pHandle)
|
||||
{
|
||||
DatabaseInfo info;
|
||||
|
||||
info.database = m_db.chars();
|
||||
info.pass = m_pass.chars();
|
||||
info.user = m_user.chars();
|
||||
info.host = m_host.chars();
|
||||
info.port = m_port;
|
||||
info.max_timeout = m_max_timeout;
|
||||
info.charset = m_charset.chars();
|
||||
|
||||
float save_time = m_qrInfo.queue_time;
|
||||
|
||||
memset(&m_qrInfo, 0, sizeof(m_qrInfo));
|
||||
|
||||
m_qrInfo.queue_time = save_time;
|
||||
|
||||
IDatabase *pDatabase = g_Mysql.Connect2(&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)
|
||||
{
|
||||
pQuery->FreeHandle();
|
||||
pQuery = NULL;
|
||||
}
|
||||
|
||||
m_qrInfo.amxinfo.pQuery = NULL;
|
||||
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);
|
||||
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 {
|
||||
const char* string = rs->FieldNumToName(i);
|
||||
m_Table[i] = new ke::AString(string ? string : "");
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
const char* string = row->GetString(i);
|
||||
m_Table[idx] = new ke::AString(string ? string : "");
|
||||
}
|
||||
}
|
||||
rs->NextRow();
|
||||
}
|
||||
}
|
||||
|
||||
void AtomicResult::Rewind()
|
||||
{
|
||||
m_CurRow = 1;
|
||||
}
|
||||
|
||||
bool AtomicResult::NextResultSet()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
AMX_NATIVE_INFO g_ThreadSqlNatives[] =
|
||||
{
|
||||
{"SQL_ThreadQuery", SQL_ThreadQuery},
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
105
modules/mysqlx/threading.h
Normal file
105
modules/mysqlx/threading.h
Normal file
@ -0,0 +1,105 @@
|
||||
// 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
|
||||
|
||||
//
|
||||
// MySQL Module
|
||||
//
|
||||
|
||||
#ifndef _INCLUDE_MYSQL_THREADING_H
|
||||
#define _INCLUDE_MYSQL_THREADING_H
|
||||
|
||||
#include "IThreader.h"
|
||||
#include "ISQLDriver.h"
|
||||
#include <am-string.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();
|
||||
virtual bool NextResultSet();
|
||||
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);
|
||||
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 *host, const char *user, const char *pass, const char *db, int port, unsigned int max_timeout);
|
||||
void SetCharacterSet(const char *charset);
|
||||
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_host;
|
||||
ke::AString m_user;
|
||||
ke::AString m_pass;
|
||||
ke::AString m_db;
|
||||
unsigned int m_max_timeout;
|
||||
ke::AString m_charset;
|
||||
int m_port;
|
||||
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/mysqlx/version.rc
Normal file
101
modules/mysqlx/version.rc
Normal 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
|
||||
|
Reference in New Issue
Block a user