mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-17 03:08:26 +00:00
Moved some around, more renames
This commit is contained in:
@@ -0,0 +1 @@
|
||||
Simple utility to modify fields in player profile... far from complete. Right now just sets ldon points to 0 but going to expand it.
|
||||
@@ -0,0 +1,4 @@
|
||||
host=localhost
|
||||
user=root
|
||||
password=pass
|
||||
db=eq
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual C++ Express 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "player_profile_set", "player_profile_set\player_profile_set.vcproj", "{3307DA97-CDDB-4C89-AAE7-BC0AF03D3D6D}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{3307DA97-CDDB-4C89-AAE7-BC0AF03D3D6D}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{3307DA97-CDDB-4C89-AAE7-BC0AF03D3D6D}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{3307DA97-CDDB-4C89-AAE7-BC0AF03D3D6D}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{3307DA97-CDDB-4C89-AAE7-BC0AF03D3D6D}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,331 @@
|
||||
#include "misc_functions.h"
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#ifndef WIN32
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#ifdef WIN32
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
|
||||
#define snprintf _snprintf
|
||||
#if (_MSC_VER < 1500)
|
||||
#define vsnprintf _vsnprintf
|
||||
#endif
|
||||
#define strncasecmp _strnicmp
|
||||
#define strcasecmp _stricmp
|
||||
#else
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#ifdef FREEBSD //Timothy Whitman - January 7, 2003
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <netdb.h>
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
char* strn0cpy(char* dest, const char* source, int32 size) {
|
||||
if (!dest)
|
||||
return 0;
|
||||
if (size == 0 || source == 0) {
|
||||
dest[0] = 0;
|
||||
return dest;
|
||||
}
|
||||
strncpy(dest, source, size);
|
||||
dest[size - 1] = 0;
|
||||
return dest;
|
||||
}
|
||||
|
||||
// String N w/null Copy Truncated?
|
||||
// return value =true if entire string(source) fit, false if it was truncated
|
||||
bool strn0cpyt(char* dest, const char* source, int32 size) {
|
||||
if (!dest)
|
||||
return 0;
|
||||
if (size == 0 || source == 0) {
|
||||
dest[0] = 0;
|
||||
return dest;
|
||||
}
|
||||
strncpy(dest, source, size);
|
||||
dest[size - 1] = 0;
|
||||
return (bool) (source[strlen(dest)] == 0);
|
||||
}
|
||||
|
||||
const char *MakeUpperString(const char *source) {
|
||||
static char str[128];
|
||||
if (!source)
|
||||
return NULL;
|
||||
MakeUpperString(source, str);
|
||||
return str;
|
||||
}
|
||||
|
||||
void MakeUpperString(const char *source, char *target) {
|
||||
if (!source || !target) {
|
||||
*target=0;
|
||||
return;
|
||||
}
|
||||
while (*source)
|
||||
{
|
||||
*target = toupper(*source);
|
||||
target++;source++;
|
||||
}
|
||||
*target = 0;
|
||||
}
|
||||
|
||||
const char *MakeLowerString(const char *source) {
|
||||
static char str[128];
|
||||
if (!source)
|
||||
return NULL;
|
||||
MakeLowerString(source, str);
|
||||
return str;
|
||||
}
|
||||
|
||||
void MakeLowerString(const char *source, char *target) {
|
||||
if (!source || !target) {
|
||||
*target=0;
|
||||
return;
|
||||
}
|
||||
while (*source)
|
||||
{
|
||||
*target = tolower(*source);
|
||||
target++;source++;
|
||||
}
|
||||
*target = 0;
|
||||
}
|
||||
|
||||
int MakeAnyLenString(char** ret, const char* format, ...) {
|
||||
int buf_len = 128;
|
||||
int chars = -1;
|
||||
va_list argptr;
|
||||
va_start(argptr, format);
|
||||
while (chars == -1 || chars >= buf_len) {
|
||||
safe_delete_array(*ret);
|
||||
if (chars == -1)
|
||||
buf_len *= 2;
|
||||
else
|
||||
buf_len = chars + 1;
|
||||
*ret = new char[buf_len];
|
||||
chars = vsnprintf(*ret, buf_len, format, argptr);
|
||||
}
|
||||
va_end(argptr);
|
||||
return chars;
|
||||
}
|
||||
|
||||
int32 AppendAnyLenString(char** ret, int32* bufsize, int32* strlen, const char* format, ...) {
|
||||
if (*bufsize == 0)
|
||||
*bufsize = 256;
|
||||
if (*ret == 0)
|
||||
*strlen = 0;
|
||||
int chars = -1;
|
||||
char* oldret = 0;
|
||||
va_list argptr;
|
||||
va_start(argptr, format);
|
||||
while (chars == -1 || chars >= (sint32)(*bufsize-*strlen)) {
|
||||
if (chars == -1)
|
||||
*bufsize += 256;
|
||||
else
|
||||
*bufsize += chars + 25;
|
||||
oldret = *ret;
|
||||
*ret = new char[*bufsize];
|
||||
if (oldret) {
|
||||
if (*strlen)
|
||||
memcpy(*ret, oldret, *strlen);
|
||||
safe_delete_array(oldret);
|
||||
}
|
||||
chars = vsnprintf(&(*ret)[*strlen], (*bufsize-*strlen), format, argptr);
|
||||
}
|
||||
va_end(argptr);
|
||||
*strlen += chars;
|
||||
return *strlen;
|
||||
}
|
||||
|
||||
int32 hextoi(char* num) {
|
||||
int len = strlen(num);
|
||||
if (len < 3)
|
||||
return 0;
|
||||
|
||||
if (num[0] != '0' || (num[1] != 'x' && num[1] != 'X'))
|
||||
return 0;
|
||||
|
||||
int32 ret = 0;
|
||||
int mul = 1;
|
||||
for (int i=len-1; i>=2; i--) {
|
||||
if (num[i] >= 'A' && num[i] <= 'F')
|
||||
ret += ((num[i] - 'A') + 10) * mul;
|
||||
else if (num[i] >= 'a' && num[i] <= 'f')
|
||||
ret += ((num[i] - 'a') + 10) * mul;
|
||||
else if (num[i] >= '0' && num[i] <= '9')
|
||||
ret += (num[i] - '0') * mul;
|
||||
else
|
||||
return 0;
|
||||
mul *= 16;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64 hextoi64(char* num) {
|
||||
int len = strlen(num);
|
||||
if (len < 3)
|
||||
return 0;
|
||||
|
||||
if (num[0] != '0' || (num[1] != 'x' && num[1] != 'X'))
|
||||
return 0;
|
||||
|
||||
int64 ret = 0;
|
||||
int mul = 1;
|
||||
for (int i=len-1; i>=2; i--) {
|
||||
if (num[i] >= 'A' && num[i] <= 'F')
|
||||
ret += ((num[i] - 'A') + 10) * mul;
|
||||
else if (num[i] >= 'a' && num[i] <= 'f')
|
||||
ret += ((num[i] - 'a') + 10) * mul;
|
||||
else if (num[i] >= '0' && num[i] <= '9')
|
||||
ret += (num[i] - '0') * mul;
|
||||
else
|
||||
return 0;
|
||||
mul *= 16;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool atobool(char* iBool) {
|
||||
if (!strcasecmp(iBool, "true"))
|
||||
return true;
|
||||
if (!strcasecmp(iBool, "false"))
|
||||
return false;
|
||||
if (!strcasecmp(iBool, "yes"))
|
||||
return true;
|
||||
if (!strcasecmp(iBool, "no"))
|
||||
return false;
|
||||
if (!strcasecmp(iBool, "on"))
|
||||
return true;
|
||||
if (!strcasecmp(iBool, "off"))
|
||||
return false;
|
||||
if (!strcasecmp(iBool, "enable"))
|
||||
return true;
|
||||
if (!strcasecmp(iBool, "disable"))
|
||||
return false;
|
||||
if (!strcasecmp(iBool, "enabled"))
|
||||
return true;
|
||||
if (!strcasecmp(iBool, "disabled"))
|
||||
return false;
|
||||
if (!strcasecmp(iBool, "y"))
|
||||
return true;
|
||||
if (!strcasecmp(iBool, "n"))
|
||||
return false;
|
||||
if (atoi(iBool))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* solar: generate a random integer in the range low-high
|
||||
* this should be used instead of the rand()%limit method
|
||||
*/
|
||||
int MakeRandomInt(int low, int high)
|
||||
{
|
||||
if(low >= high)
|
||||
return(low);
|
||||
|
||||
return (rand()%(high-low+1) + (low));
|
||||
}
|
||||
|
||||
double MakeRandomFloat(double low, double high)
|
||||
{
|
||||
if(low >= high)
|
||||
return(low);
|
||||
|
||||
return (rand() / (double)RAND_MAX * (high - low) + low);
|
||||
}
|
||||
|
||||
// solar: removes the crap and turns the underscores into spaces.
|
||||
char *CleanMobName(const char *in, char *out)
|
||||
{
|
||||
unsigned i, j;
|
||||
|
||||
for(i = j = 0; i < strlen(in); i++)
|
||||
{
|
||||
// convert _ to space.. any other conversions like this? I *think* this
|
||||
// is the only non alpha char that's not stripped but converted.
|
||||
if(in[i] == '_')
|
||||
{
|
||||
out[j++] = ' ';
|
||||
}
|
||||
else
|
||||
{
|
||||
if(isalpha(in[i]) || (in[i] == '`')) // numbers, #, or any other crap just gets skipped
|
||||
out[j++] = in[i];
|
||||
}
|
||||
}
|
||||
out[j] = 0; // terimnate the string before returning it
|
||||
return out;
|
||||
}
|
||||
|
||||
const char *ConvertArray(int input, char *returnchar)
|
||||
{
|
||||
sprintf(returnchar, "%i" ,input);
|
||||
return returnchar;
|
||||
}
|
||||
|
||||
const char *ConvertArrayF(float input, char *returnchar)
|
||||
{
|
||||
sprintf(returnchar, "%0.2f", input);
|
||||
return returnchar;
|
||||
}
|
||||
|
||||
float EQ13toFloat(int d)
|
||||
{
|
||||
return ( float(d)/float(1<<2));
|
||||
}
|
||||
|
||||
float NewEQ13toFloat(int d)
|
||||
{
|
||||
return ( float(d)/float(1<<6));
|
||||
}
|
||||
|
||||
float EQ19toFloat(int d)
|
||||
{
|
||||
return ( float(d)/float(1<<3));
|
||||
}
|
||||
|
||||
int FloatToEQ13(float d)
|
||||
{
|
||||
return int(d*float(1<<2));
|
||||
}
|
||||
|
||||
int NewFloatToEQ13(float d)
|
||||
{
|
||||
return int(d*float(1<<6));
|
||||
}
|
||||
|
||||
int FloatToEQ19(float d)
|
||||
{
|
||||
return int(d*float(1<<3));
|
||||
}
|
||||
|
||||
/*
|
||||
Heading of 0 points in the pure positive Y direction
|
||||
|
||||
*/
|
||||
int FloatToEQH(float d)
|
||||
{
|
||||
return(int((360.0f - d) * float(1<<11)) / 360);
|
||||
}
|
||||
|
||||
float EQHtoFloat(int d)
|
||||
{
|
||||
return(360.0f - float((d * 360) >> 11));
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef MISCFUNCTIONS_H
|
||||
#define MISCFUNCTIONS_H
|
||||
|
||||
#include "types.h"
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
#ifndef ERRBUF_SIZE
|
||||
#define ERRBUF_SIZE 1024
|
||||
#endif
|
||||
|
||||
// These are helper macros for dealing with packets of variable length, typically those that contain
|
||||
// variable length strings where it is not convenient to use a fixed length struct.
|
||||
//
|
||||
#define VARSTRUCT_DECODE_TYPE(Type, Buffer) *(Type *)Buffer; Buffer += sizeof(Type);
|
||||
#define VARSTRUCT_DECODE_STRING(String, Buffer) strcpy(String, Buffer); Buffer += strlen(String)+1;
|
||||
#define VARSTRUCT_ENCODE_STRING(Buffer, String) sprintf(Buffer, String); Buffer += strlen(String) + 1;
|
||||
#define VARSTRUCT_ENCODE_INTSTRING(Buffer, Number) sprintf(Buffer, "%i", Number); Buffer += strlen(Buffer) + 1;
|
||||
#define VARSTRUCT_ENCODE_TYPE(Type, Buffer, Value) *(Type *)Buffer = Value; Buffer += sizeof(Type);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// MakeUpperString
|
||||
// i : source - allocated null-terminated string
|
||||
// return: pointer to static buffer with the target string
|
||||
const char *MakeUpperString(const char *source);
|
||||
const char *MakeLowerString(const char *source);
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// MakeUpperString
|
||||
// i : source - allocated null-terminated string
|
||||
// io: target - allocated buffer, at least of size strlen(source)+1
|
||||
void MakeUpperString(const char *source, char *target);
|
||||
void MakeLowerString(const char *source, char *target);
|
||||
|
||||
|
||||
int MakeAnyLenString(char** ret, const char* format, ...);
|
||||
int32 AppendAnyLenString(char** ret, int32* bufsize, int32* strlen, const char* format, ...);
|
||||
int32 hextoi(char* num);
|
||||
int64 hextoi64(char* num);
|
||||
bool atobool(char* iBool);
|
||||
void CoutTimestamp(bool ms = true);
|
||||
char* strn0cpy(char* dest, const char* source, int32 size);
|
||||
// return value =true if entire string(source) fit, false if it was truncated
|
||||
bool strn0cpyt(char* dest, const char* source, int32 size);
|
||||
int MakeRandomInt(int low, int high);
|
||||
double MakeRandomFloat(double low, double high);
|
||||
char *CleanMobName(const char *in, char *out);
|
||||
const char *ConvertArray(int input, char *returnchar);
|
||||
const char *ConvertArrayF(float input, char *returnchar);
|
||||
float EQ13toFloat(int d);
|
||||
float NewEQ13toFloat(int d);
|
||||
float EQ19toFloat(int d);
|
||||
float EQHtoFloat(int d);
|
||||
int FloatToEQ13(float d);
|
||||
int NewFloatToEQ13(float d);
|
||||
int FloatToEQ19(float d);
|
||||
int FloatToEQH(float d);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
#include "database.h"
|
||||
#include "main.h"
|
||||
#include "eq_player_structs.h"
|
||||
#include <vector>
|
||||
|
||||
extern std::vector<player_entry> player_list;
|
||||
|
||||
EQEmuDatabase::EQEmuDatabase(std::string ServerName, std::string DatabaseName, std::string DBUsername, std::string DBPassword) {
|
||||
SetServerName(ServerName);
|
||||
SetDatabaseName(DatabaseName);
|
||||
SetDBUsername(DBUsername);
|
||||
SetDBPassword(DBPassword);
|
||||
|
||||
_mysql = mysql_init(NULL);
|
||||
if(_mysql)
|
||||
{
|
||||
if (!mysql_real_connect(_mysql, GetServerName().c_str(), GetDBUsername().c_str(),
|
||||
GetDBPassword().c_str(), GetDatabaseName().c_str(), 0, NULL, 0))
|
||||
{
|
||||
cout << "MYSQL CONNECT FAILED: " << endl;
|
||||
cout << GetServerName() << endl;
|
||||
cout << GetDBUsername() << endl;
|
||||
cout << GetDBPassword() << endl;
|
||||
cout << GetDatabaseName() << endl;
|
||||
mysql_close(_mysql);
|
||||
_mysql = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EQEmuDatabase::~EQEmuDatabase()
|
||||
{
|
||||
if(_mysql)
|
||||
{
|
||||
mysql_close(_mysql);
|
||||
}
|
||||
}
|
||||
|
||||
void EQEmuDatabase::GetPlayer(std::string name)
|
||||
{
|
||||
bool result = false;
|
||||
if(!_mysql)
|
||||
{
|
||||
cout << "NOT CONNECTED TO MYQSL: " << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
MYSQL_RES *res;
|
||||
MYSQL_ROW row;
|
||||
char * mQuery = 0;
|
||||
MakeAnyLenString(&mQuery, "SELECT profile, id FROM character_ WHERE name='%s'", name.c_str());
|
||||
if (mysql_query(_mysql, mQuery)) {
|
||||
cout << "Query failed: " << mQuery << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
res = mysql_use_result(_mysql);
|
||||
if(res)
|
||||
{
|
||||
while ((row = mysql_fetch_row(res)) != NULL)
|
||||
{
|
||||
player_entry pe;
|
||||
pe.id = atoi(row[1]);
|
||||
pe.data = new char[sizeof(PlayerProfile_Struct)];
|
||||
memcpy(pe.data, row[0], sizeof(PlayerProfile_Struct));
|
||||
player_list.push_back(pe);
|
||||
|
||||
PlayerProfile_Struct *m_pp = (PlayerProfile_Struct*)pe.data;
|
||||
}
|
||||
mysql_free_result(res);
|
||||
}
|
||||
delete[] mQuery;
|
||||
mQuery = 0;
|
||||
}
|
||||
|
||||
void EQEmuDatabase::GetPlayers()
|
||||
{
|
||||
bool result = false;
|
||||
if(!_mysql)
|
||||
{
|
||||
cout << "NOT CONNECTED TO MYQSL: " << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
MYSQL_RES *res;
|
||||
MYSQL_ROW row;
|
||||
char * mQuery = 0;
|
||||
MakeAnyLenString(&mQuery, "SELECT profile, id FROM character_");
|
||||
if (mysql_query(_mysql, mQuery)) {
|
||||
cout << "Query failed: " << mQuery << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
res = mysql_use_result(_mysql);
|
||||
if(res)
|
||||
{
|
||||
while ((row = mysql_fetch_row(res)) != NULL)
|
||||
{
|
||||
player_entry pe;
|
||||
pe.id = atoi(row[1]);
|
||||
pe.data = new char[sizeof(PlayerProfile_Struct)];
|
||||
memcpy(pe.data, row[0], sizeof(PlayerProfile_Struct));
|
||||
player_list.push_back(pe);
|
||||
|
||||
PlayerProfile_Struct *m_pp = (PlayerProfile_Struct*)pe.data;
|
||||
}
|
||||
mysql_free_result(res);
|
||||
}
|
||||
delete[] mQuery;
|
||||
mQuery = 0;
|
||||
}
|
||||
|
||||
void EQEmuDatabase::StorePlayer(int32 charid, char* data)
|
||||
{
|
||||
if(!_mysql)
|
||||
{
|
||||
cout << "NOT CONNECTED TO MYQSL: " << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
char *outbuffer = new char[2*sizeof(PlayerProfile_Struct) + 512];
|
||||
char *bptr = outbuffer;
|
||||
bptr += snprintf(bptr, 128, "UPDATE character_ SET profile='");
|
||||
bptr += mysql_real_escape_string(_mysql, bptr, (const char *) data, sizeof(PlayerProfile_Struct));
|
||||
snprintf(bptr, 128, "' WHERE id=%lu", charid);
|
||||
|
||||
if (mysql_query(_mysql, outbuffer)) {
|
||||
cout << "Query failed: " << outbuffer << endl;
|
||||
}
|
||||
|
||||
delete[] outbuffer;
|
||||
outbuffer = 0;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
#if !defined(_L__EQDATAB__H)
|
||||
#define _L__EQDATAB__H
|
||||
|
||||
#include "misc_functions.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <mysql.h>
|
||||
#include <string>
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#pragma comment ( lib, "libmysql" )
|
||||
|
||||
class EQEmuDatabase {
|
||||
public:
|
||||
EQEmuDatabase(string serverName, string databaseName, string dbUsername, string dbPassword);
|
||||
~EQEmuDatabase();
|
||||
|
||||
bool Connected() { if(_mysql){ return true; }else{ return false; } }
|
||||
|
||||
void SetDBUsername(string dbUsername) { _dbUsername = dbUsername; };
|
||||
void SetDBPassword(string dbPassword) { _dbPassword = dbPassword; };
|
||||
void SetDatabaseName(string databaseName) { _databaseName = databaseName; };
|
||||
void SetServerName(string serverName) { _serverName = serverName; };
|
||||
string GetDBUsername() { return _dbUsername; };
|
||||
string GetDBPassword() { return _dbPassword; };
|
||||
string GetDatabaseName() { return _databaseName; };
|
||||
string GetServerName() { return _serverName; };
|
||||
|
||||
void GetPlayer(std::string name);
|
||||
void GetPlayers();
|
||||
void StorePlayer(int32 charid, char* data);
|
||||
|
||||
private:
|
||||
string _dbUsername;
|
||||
string _dbPassword;
|
||||
string _databaseName;
|
||||
string _serverName;
|
||||
MYSQL *_mysql;
|
||||
};
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,21 @@
|
||||
#ifndef EQEMU_STRING_H
|
||||
#define EQEMU_STRING_H
|
||||
|
||||
#include <string>
|
||||
#include <cctype>
|
||||
|
||||
namespace EQEmuString
|
||||
{
|
||||
|
||||
std::string ToUpper(std::string in_string)
|
||||
{
|
||||
std::string out_string = in_string;
|
||||
for(unsigned int i = 0; i < in_string.size(); ++i)
|
||||
{
|
||||
out_string[i] = std::toupper(in_string[i]);
|
||||
}
|
||||
return out_string;
|
||||
}
|
||||
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,118 @@
|
||||
#include "ini.h"
|
||||
|
||||
INIParser::INIParser(const char *filename)
|
||||
{
|
||||
memset(file, 0, 128);
|
||||
if(strlen(filename) > 128)
|
||||
{
|
||||
strncpy(file, filename, 128);
|
||||
}
|
||||
else
|
||||
{
|
||||
strncpy(file, filename, strlen(filename));
|
||||
}
|
||||
Parse();
|
||||
}
|
||||
|
||||
INIParser::~INIParser()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void INIParser::Parse()
|
||||
{
|
||||
FILE *fp;
|
||||
if(fp = fopen(file, "r"))
|
||||
{
|
||||
char Option[255], Param[255];
|
||||
while(!feof(fp))
|
||||
{
|
||||
ReadLine(fp, Option, Param);
|
||||
AddOption(std::string(Option), std::string(Param));
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
void INIParser::ReadLine(FILE *fp, char *Option, char *Param)
|
||||
{
|
||||
typedef enum ReadingState { ReadingOption, ReadingParameter };
|
||||
|
||||
ReadingState State = ReadingOption;
|
||||
|
||||
int StrIndex = 0;
|
||||
char ch;
|
||||
|
||||
strcpy(Option, "");
|
||||
strcpy(Param, "");
|
||||
|
||||
while(true) {
|
||||
ch = fgetc(fp);
|
||||
if((ch=='#')&&(StrIndex==0)) { // Discard comment lines beginning with a hash
|
||||
while((ch!=EOF)&&(ch!='\n'))
|
||||
ch = fgetc(fp);
|
||||
|
||||
continue;
|
||||
}
|
||||
if(ch=='\r') continue;
|
||||
if((ch==EOF)||(ch=='\n')) {
|
||||
switch(State) {
|
||||
case ReadingOption: {
|
||||
Option[StrIndex]='\0';
|
||||
break;
|
||||
}
|
||||
case ReadingParameter: {
|
||||
Param[StrIndex] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
if(ch=='=') {
|
||||
if(State==ReadingOption) {
|
||||
Option[StrIndex] = '\0';
|
||||
State = ReadingParameter;
|
||||
StrIndex = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
switch(State) {
|
||||
case ReadingOption: {
|
||||
Option[StrIndex++]=tolower(ch);
|
||||
break;
|
||||
}
|
||||
case ReadingParameter: {
|
||||
Param[StrIndex++]=ch;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!strcmp(Param,"true")) strcpy(Param,"1");
|
||||
if(!strcmp(Param,"false")) strcpy(Param,"0");
|
||||
}
|
||||
|
||||
void INIParser::AddOption(std::string option, std::string param)
|
||||
{
|
||||
for(unsigned int x = 0; x < options.size(); ++x)
|
||||
{
|
||||
if(options[x].option == option)
|
||||
return;
|
||||
}
|
||||
|
||||
iniData d;
|
||||
d.option = option;
|
||||
d.param = param;
|
||||
options.push_back(d);
|
||||
}
|
||||
|
||||
std::string INIParser::GetOption(std::string option)
|
||||
{
|
||||
for(unsigned int x = 0; x < options.size(); ++x)
|
||||
{
|
||||
if(options[x].option == option)
|
||||
return options[x].param;
|
||||
}
|
||||
return std::string("Not Found");
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#ifndef INI__H
|
||||
#define INI__H
|
||||
|
||||
#include <string>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <vector>
|
||||
|
||||
struct iniData
|
||||
{
|
||||
std::string option;
|
||||
std::string param;
|
||||
};
|
||||
|
||||
class INIParser
|
||||
{
|
||||
public:
|
||||
INIParser(const char *filename);
|
||||
~INIParser();
|
||||
void Parse();
|
||||
void ReadLine(FILE *fp, char *Option, char *Param);
|
||||
|
||||
void AddOption(std::string option, std::string param);
|
||||
std::string GetOption(std::string option);
|
||||
|
||||
|
||||
protected:
|
||||
char file[128];
|
||||
std::vector<iniData> options;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,143 @@
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
#include "eq_player_structs.h"
|
||||
#include "database.h"
|
||||
#include "ini.h"
|
||||
#include "main.h"
|
||||
#include "eqemu_string.h"
|
||||
|
||||
EQEmuDatabase *emu_db;
|
||||
std::vector<player_entry> player_list;
|
||||
|
||||
//player_profile_set [SET/VIEW] [Field] [Name/*]
|
||||
//ex: player_profile_set VIEW LDON_MMC Jess
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
INIParser *ini = new INIParser("database.ini");
|
||||
std::string host = ini->GetOption("host");
|
||||
std::string user = ini->GetOption("user");
|
||||
std::string pass = ini->GetOption("password");
|
||||
std::string datab = ini->GetOption("db");
|
||||
|
||||
if(argc != 5)
|
||||
{
|
||||
std::cout << "Usage: player_profile_set [SET/VIEW] [Field] [Value] [Name/*]" << std::endl;
|
||||
std::cout << "Ex: player_profile_set VIEW LDON_MMC 0 Jess" << std::endl;
|
||||
std::cout << "Would view the number of LDoN MMC points earned by Jess" << std::endl << std::endl;
|
||||
std::cout << "Ex: player_profile_set SET LDON_TOTAL 0 *" << std::endl;
|
||||
std::cout << "Would view the number of LDoN MMC points earned by All players to 0" << std::endl;
|
||||
delete ini;
|
||||
ini = 0;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
std::string program_action = argv[1];
|
||||
std::string program_field = argv[2];
|
||||
std::string program_value = argv[3];
|
||||
std::string player_name = argv[4];
|
||||
program_action = EQEmuString::ToUpper(program_action);
|
||||
program_field = EQEmuString::ToUpper(program_field);
|
||||
|
||||
emu_db = new EQEmuDatabase(host.c_str(), datab.c_str(), user.c_str(), pass.c_str());
|
||||
if(!emu_db->Connected())
|
||||
{
|
||||
delete ini;
|
||||
ini = 0;
|
||||
delete emu_db;
|
||||
emu_db = 0;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(player_name == "*")
|
||||
emu_db->GetPlayers();
|
||||
else
|
||||
emu_db->GetPlayer(player_name);
|
||||
|
||||
std::vector<player_entry>::iterator iter = player_list.begin();
|
||||
|
||||
while(iter != player_list.end())
|
||||
{
|
||||
player_entry pe = (*iter);
|
||||
PlayerProfile_Struct *m_pp = (PlayerProfile_Struct*)pe.data;
|
||||
|
||||
if(program_action == "SET")
|
||||
{
|
||||
m_pp->ldon_points_available = 0;
|
||||
m_pp->ldon_points_guk = 0;
|
||||
m_pp->ldon_points_mir = 0;
|
||||
m_pp->ldon_points_mmc = 0;
|
||||
m_pp->ldon_points_ruj = 0;
|
||||
m_pp->ldon_points_tak = 0;
|
||||
emu_db->StorePlayer(pe.id, pe.data);
|
||||
}
|
||||
else if(program_action == "VIEW")
|
||||
{
|
||||
std::cout << m_pp->name << std::endl;
|
||||
std::cout << m_pp->ldon_points_available << std::endl;
|
||||
std::cout << m_pp->ldon_points_guk << std::endl;
|
||||
std::cout << m_pp->ldon_points_mir << std::endl;
|
||||
std::cout << m_pp->ldon_points_mmc << std::endl;
|
||||
std::cout << m_pp->ldon_points_ruj << std::endl;
|
||||
std::cout << m_pp->ldon_points_tak << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Unknown action specified" << std::endl;
|
||||
}
|
||||
delete[] pe.data;
|
||||
pe.data = 0;
|
||||
iter++;
|
||||
}
|
||||
player_list.clear();
|
||||
|
||||
delete ini;
|
||||
ini = 0;
|
||||
delete emu_db;
|
||||
emu_db = 0;
|
||||
|
||||
std::cout << "Press enter to exit...";
|
||||
std::cin.get();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
std::string ConvertFieldToValue(PlayerProfile_Struct *m_pp, std::string field)
|
||||
{
|
||||
if(!m_pp)
|
||||
{
|
||||
return std::string("Unable to convert field to value");
|
||||
}
|
||||
|
||||
std::stringstream ss(std::stringstream::out | std::stringstream::in);
|
||||
|
||||
if(field == "LASTNAME")
|
||||
{
|
||||
ss << m_pp->last_name;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
if(field == "GENDER")
|
||||
{
|
||||
ss << m_pp->gender;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
if(field == "RACE")
|
||||
{
|
||||
ss << m_pp->race;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
if(field == "CLASS")
|
||||
{
|
||||
ss << m_pp->class_;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
return std::string("Unable to convert field to value");
|
||||
}
|
||||
|
||||
void ConvertValueToField(PlayerProfile_Struct *m_pp, std::string field, std::string value)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef EQ_MAIN_H
|
||||
#define EQ_MAIN_H
|
||||
|
||||
#include "types.h"
|
||||
#include "eq_player_structs.h"
|
||||
|
||||
struct player_entry
|
||||
{
|
||||
int32 id;
|
||||
char *data;
|
||||
};
|
||||
|
||||
std::string ConvertFieldToValue(PlayerProfile_Struct *m_pp, std::string field);
|
||||
void ConvertValueToField(PlayerProfile_Struct *m_pp, std::string field, std::string value);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,233 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="player_profile_set"
|
||||
ProjectGUID="{3307DA97-CDDB-4C89-AAE7-BC0AF03D3D6D}"
|
||||
RootNamespace="player_profile_set"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\database.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ini.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\main.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\MiscFunctions.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\database.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\eq_player_structs.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\eqemu_string.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ini.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\main.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\MiscFunctions.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\types.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -0,0 +1,110 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef TYPES_H
|
||||
#define TYPES_H
|
||||
|
||||
// TODO: If we require signed or unsigned we should the s and u types..
|
||||
|
||||
typedef unsigned char int8;
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short int16;
|
||||
typedef unsigned int int32;
|
||||
|
||||
typedef unsigned char uint8;
|
||||
typedef signed char sint8;
|
||||
typedef unsigned short uint16;
|
||||
typedef signed short sint16;
|
||||
typedef unsigned int uint32;
|
||||
typedef signed int sint32;
|
||||
|
||||
#ifdef WIN32
|
||||
#if defined(_INTEGRAL_MAX_BITS) && _INTEGRAL_MAX_BITS >= 64
|
||||
typedef unsigned __int64 int64;
|
||||
typedef unsigned __int64 uint64;
|
||||
typedef signed __int64 sint64;
|
||||
#else
|
||||
#error __int64 not supported
|
||||
#endif
|
||||
#else
|
||||
typedef unsigned long long int64;
|
||||
typedef unsigned long long uint64;
|
||||
typedef signed long long sint64;
|
||||
//typedef __u64 int64;
|
||||
//typedef __u64 uint64;
|
||||
//typedef __s64 sint64;
|
||||
#endif
|
||||
|
||||
#ifndef __cplusplus
|
||||
typedef enum { true, false } bool;
|
||||
#endif
|
||||
|
||||
typedef unsigned long ulong;
|
||||
typedef unsigned short ushort;
|
||||
typedef unsigned char uchar;
|
||||
|
||||
typedef const char Const_char; //for perl XS
|
||||
|
||||
#ifdef WIN32
|
||||
#define snprintf _snprintf
|
||||
#if (_MSC_VER < 1500)
|
||||
#define vsnprintf _vsnprintf
|
||||
#endif
|
||||
#define strncasecmp _strnicmp
|
||||
#define strcasecmp _stricmp
|
||||
typedef void ThreadReturnType;
|
||||
// #define THREAD_RETURN(x) return;
|
||||
#define THREAD_RETURN(x) _endthread(); return;
|
||||
#else
|
||||
typedef void* ThreadReturnType;
|
||||
// typedef int SOCKET;
|
||||
#define THREAD_RETURN(x) return(x);
|
||||
#endif
|
||||
|
||||
#define safe_delete(d) if(d) { delete d; d=0; }
|
||||
#define safe_delete_array(d) if(d) { delete[] d; d=0; }
|
||||
#define L32(i) ((int32) i)
|
||||
#define H32(i) ((int32) (i >> 32))
|
||||
#define L16(i) ((int16) i)
|
||||
|
||||
#ifndef WIN32
|
||||
// More WIN32 compatability
|
||||
typedef unsigned long DWORD;
|
||||
typedef unsigned char BYTE;
|
||||
typedef char CHAR;
|
||||
typedef unsigned short WORD;
|
||||
typedef float FLOAT;
|
||||
typedef FLOAT *PFLOAT;
|
||||
typedef BYTE *PBYTE,*LPBYTE;
|
||||
typedef int *PINT,*LPINT;
|
||||
typedef WORD *PWORD,*LPWORD;
|
||||
typedef long *LPLONG, LONG;
|
||||
typedef DWORD *PDWORD,*LPDWORD;
|
||||
typedef int INT;
|
||||
typedef unsigned int UINT,*PUINT,*LPUINT;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
#define DLLFUNC extern "C" __declspec(dllexport)
|
||||
#else
|
||||
#define DLLFUNC extern "C"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user