Compare commits
2
Commits
1e47731d7a
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0884cab294 | ||
|
|
1998bf4273 |
No files matched your search
@@ -17,6 +17,9 @@ PUBLIC_HOST=127.0.0.1
|
||||
LOGIN_PORT=29000
|
||||
CHAR_PORT=29100
|
||||
WORLD_PORT=29200
|
||||
# Web tools + admin panel (http://<host>:<this port>/). Change this if port 80
|
||||
# is already taken by something else on the host.
|
||||
WEBTOOLS_PORT=80
|
||||
|
||||
# --- Server / channel naming -----------------------------------------------
|
||||
LOGIN_SERVER_NAME=ROSE Login
|
||||
|
||||
@@ -2,6 +2,11 @@ build/
|
||||
build-*/
|
||||
.env
|
||||
|
||||
# MariaDB data directory -- now a bind mount (was a Docker named volume) so
|
||||
# it's visible/backup-able from the host, but that also means it lives
|
||||
# inside the repo checkout and must never be committed.
|
||||
/docker/data/
|
||||
|
||||
# Windows game client + data assets, kept locally for end-to-end login/game
|
||||
# testing but not part of the server source tree. Binary/3DData is the
|
||||
# separate, already-pruned subset of this data the server itself actually
|
||||
|
||||
+12
-1
@@ -34,17 +34,28 @@ add_compile_options(
|
||||
# in Release builds only). -fwrapv makes overflow well-defined instead
|
||||
# of auditing every arithmetic expression in the tree.
|
||||
-fwrapv
|
||||
# x86-64-v2 (SSE4.2/POPCNT baseline, ~2009+ CPUs) is safe for any real
|
||||
# deployment target and gets a bit more codegen than the generic x86-64
|
||||
# baseline GCC defaults to.
|
||||
-march=x86-64-v2
|
||||
-include "${CMAKE_SOURCE_DIR}/Src/Common/compat.h"
|
||||
)
|
||||
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
|
||||
|
||||
# Link-time optimization: lets GCC inline/optimize across the many small
|
||||
# .cpp translation units instead of only within each one.
|
||||
include(CheckIPOSupported)
|
||||
check_ipo_supported(RESULT IPO_SUPPORTED OUTPUT IPO_ERROR)
|
||||
if(IPO_SUPPORTED AND CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
|
||||
endif()
|
||||
|
||||
set(COMMON_SOURCES
|
||||
"Src/Common/config.cpp"
|
||||
"Src/Common/database/database.cpp"
|
||||
"Src/Common/globals.cpp"
|
||||
"Src/Common/log.cpp"
|
||||
"Src/Common/rosecrypt.cpp"
|
||||
"Src/Common/seh.cpp"
|
||||
"Src/Common/SocketBase.cpp"
|
||||
"Src/Common/SocketClient.cpp"
|
||||
"Src/Common/SocketServer.cpp"
|
||||
|
||||
@@ -9,11 +9,20 @@ shimmed out so it builds and runs correctly under Linux/glibc/POSIX threads.
|
||||
|
||||
## Quick start
|
||||
|
||||
Needs Docker + the Compose plugin (`docker compose version` should work) on the host. Nothing else — the C++ servers,
|
||||
their build toolchain, and the database all live inside the containers.
|
||||
|
||||
```sh
|
||||
git clone <this repo> ross && cd ross
|
||||
cp .env.example .env # edit PUBLIC_HOST at minimum if clients connect from another machine
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
`docker compose up -d --build` builds the `rose-server` image (compiles all three C++ servers inside a throwaway
|
||||
builder stage, see `Dockerfile`), then starts every service in `docker-compose.yml` in the background. First start
|
||||
takes a minute or two (compiling + MariaDB initializing and loading `database sql files/`); `docker compose logs -f`
|
||||
to watch it happen.
|
||||
|
||||
That brings up:
|
||||
|
||||
| Service | Container | Port | What it is |
|
||||
@@ -22,12 +31,42 @@ That brings up:
|
||||
| `loginserver` | `ross-loginserver-1` | `29000` | Account login |
|
||||
| `charserver` | `ross-charserver-1` | `29100` | Character select/create/delete |
|
||||
| `worldserver` | `ross-worldserver-1` | `29200` | The actual game world |
|
||||
| `webtools` | `ross-webtools-1` | `80` | Static GM toolbox (see below) + reverse-proxies `/admin/` |
|
||||
| `webtools` | `ross-webtools-1` | `80` (`WEBTOOLS_PORT`) | Static GM toolbox (see below) + reverse-proxies `/admin/` |
|
||||
| `webadmin` | `ross-webadmin-1` | — (behind webtools) | Account/character/server admin panel |
|
||||
|
||||
Point a KTRose pre-evo client at `PUBLIC_HOST:29000` and log in — `LOGIN_CREATE_ACCOUNT=1` (the default) auto-creates an
|
||||
account on first login with that username/password.
|
||||
|
||||
A default GM account is seeded into a fresh database by `database sql files/gm_account.sql`:
|
||||
|
||||
- username `gmadmin`, password `changeme`, `accesslevel 900` — logs into both the game (as a GM) and the web admin
|
||||
panel below. **Change this password** (via the web admin panel, or `docker compose exec db mariadb ...`) on anything
|
||||
other than a throwaway local instance — it's a public default sitting in git.
|
||||
|
||||
### `docker-compose.yml`, briefly
|
||||
|
||||
- `x-app` at the top is a YAML anchor: a template block (image, restart policy, the full list of `environment:`
|
||||
variables read from `.env`) that `loginserver`, `charserver`, and `worldserver` each pull in with `<<: *app` so the
|
||||
three definitions don't repeat themselves. They differ only in `command:` (which server to run) and which port they
|
||||
publish.
|
||||
- `db` is stock MariaDB; anything in `database sql files/` gets executed once, alphabetically, the first time the
|
||||
container starts with an empty data volume (mounted read-only at `/docker-entrypoint-initdb.d`, MariaDB's standard
|
||||
init-script hook). If you change schema files after the first start, they won't re-run automatically — either
|
||||
`docker compose down -v` to wipe the `db-data` volume and reinitialize, or apply the change by hand.
|
||||
- `webtools` (nginx) is what clients' browsers hit; it serves the static GM toolbox directly and reverse-proxies
|
||||
`/admin/*` to the `webadmin` container, which isn't published to the host itself.
|
||||
- `.env` (copied from `.env.example`) is where every port, server name, and shared inter-server password gets set —
|
||||
`docker-compose.yml` itself should not need editing for a normal deploy.
|
||||
|
||||
Useful commands once it's up:
|
||||
|
||||
```sh
|
||||
docker compose logs -f worldserver # tail one server's logs
|
||||
docker compose restart worldserver # restart just one service (or use the webadmin Server tab)
|
||||
docker compose down # stop everything, keep the DB volume
|
||||
docker compose down -v # stop everything AND wipe the database
|
||||
```
|
||||
|
||||
## Web tools — `http://<host>/`
|
||||
|
||||
A static, no-build-step GM toolbox, generated from the same STB/DB data the server itself reads:
|
||||
|
||||
@@ -49,9 +49,6 @@ int main(int argc, char *argv[])
|
||||
else
|
||||
{
|
||||
delete server;
|
||||
#ifdef _WIN32
|
||||
system("pause");
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
server->LoadEncryption ();
|
||||
|
||||
@@ -38,9 +38,6 @@ void StartSignal( )
|
||||
signal( SIGFPE, HandleSignal );
|
||||
signal( SIGSEGV, HandleSignal );
|
||||
signal( SIGTERM, HandleSignal );
|
||||
#ifdef _WIN32
|
||||
signal( SIGBREAK, HandleSignal );
|
||||
#endif
|
||||
signal( SIGABRT, HandleSignal );
|
||||
}
|
||||
|
||||
@@ -51,9 +48,6 @@ void StopSignal( )
|
||||
signal( SIGFPE, 0 );
|
||||
signal( SIGSEGV, 0 );
|
||||
signal( SIGTERM, 0 );
|
||||
#ifdef _WIN32
|
||||
signal( SIGBREAK, 0 );
|
||||
#endif
|
||||
signal( SIGABRT, 0 );
|
||||
}
|
||||
|
||||
@@ -63,21 +57,13 @@ void HandleSignal( int num )
|
||||
{
|
||||
case SIGINT:/* Interactive attention */
|
||||
Log( MSG_ERROR, "Signal received: SIGINT" );
|
||||
#ifdef _WIN32
|
||||
Sleep(1000);
|
||||
#else
|
||||
usleep(1000);
|
||||
#endif
|
||||
raise(num);
|
||||
break;
|
||||
case SIGILL:/* Illegal instruction */
|
||||
Log( MSG_ERROR, "Signal received: SIGILL, Server will be closed, Trying to save..." );
|
||||
GServer->isActive = false;
|
||||
#ifdef _WIN32
|
||||
Sleep(1000);
|
||||
#else
|
||||
usleep(1000);
|
||||
#endif
|
||||
raise(num);
|
||||
break;
|
||||
case SIGFPE:/* Floating point error */
|
||||
@@ -88,11 +74,7 @@ void HandleSignal( int num )
|
||||
case SIGSEGV:/* Segmentation violation */
|
||||
Log( MSG_ERROR, "Signal received: SIGSEGV, Server will be closed, Trying to save..." );
|
||||
GServer->isActive = false;
|
||||
#ifdef _WIN32
|
||||
Sleep(1000);
|
||||
#else
|
||||
usleep(1000);
|
||||
#endif
|
||||
raise(num);
|
||||
break;
|
||||
|
||||
@@ -100,12 +82,6 @@ void HandleSignal( int num )
|
||||
Log( MSG_INFO, "Signal received: SIGTERM, Server will be closed" );
|
||||
GServer->isActive = false;
|
||||
break;
|
||||
#ifdef _WIN32
|
||||
case SIGBREAK:/* Control-break */
|
||||
Log( MSG_INFO, "Signal received: SIGBREAK, Server will be closed" );
|
||||
GServer->isActive = false;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
cout << "Unknown Signal Number: " << num << endl;
|
||||
raise(num);
|
||||
|
||||
@@ -45,23 +45,14 @@ void CBaseSocket::CloseSocket( void )
|
||||
isActive = false;
|
||||
}
|
||||
|
||||
// Init winsocket, if we are using Windows
|
||||
// No-op on Linux; kept so call sites don't need to special-case platforms.
|
||||
bool InitWinSocket ( void )
|
||||
{
|
||||
#ifdef _WIN32
|
||||
WSADATA wsa;
|
||||
return (WSAStartup(MAKEWORD(2,0),&wsa)==0);
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Close winsocket, if we are using Windows
|
||||
void CloseWinSocket( void )
|
||||
{
|
||||
#ifdef _WIN32
|
||||
WSACleanup( );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
developed with Main erose/hrose source server + some change from the original eich source
|
||||
*/
|
||||
#include "sockets.h"
|
||||
#include "seh.hpp"
|
||||
#include "config.h"
|
||||
|
||||
// Constructor
|
||||
@@ -183,16 +182,6 @@ void CClientSocket::SendPacket( CPacket *P )
|
||||
Log(MSG_WARNING,"tried to send a packet to a socket that doesn't exist any more");
|
||||
return;
|
||||
}
|
||||
//__seh_try
|
||||
//{
|
||||
// EncryptBuffer( CryptTable, Buffer );
|
||||
//}
|
||||
//__seh_except(info, context)
|
||||
//{
|
||||
// Log(MSG_WARNING,"Caught a bad packet %s. Send cancelled", Buffer);
|
||||
// return;
|
||||
//}
|
||||
//__seh_end
|
||||
EncryptBuffer( CryptTable, Buffer2 );
|
||||
#endif
|
||||
send( sock, (char*)Buffer2, Size, 0 );
|
||||
|
||||
@@ -289,21 +289,13 @@ void CServerSocket::ServerLoop( )
|
||||
if ( activity == 0 )continue;
|
||||
if ( activity < 0 && errno != EINTR )
|
||||
{
|
||||
#ifdef _WIN32
|
||||
Log( MSG_ERROR, "Select command failed. Error #%i", WSAGetLastError() );
|
||||
#else
|
||||
Log( MSG_ERROR, "Select command failed. Error #%i", errno );
|
||||
#endif
|
||||
isActive = false;
|
||||
}
|
||||
if ( LOG_THISSERVER != LOG_LOGIN_SERVER && FD_ISSET( sckISC, &fds ) )
|
||||
{
|
||||
int clientinfolen = sizeof( sockaddr_in );
|
||||
#ifdef _WIN32
|
||||
NewSocket = accept( sckISC, (sockaddr*)&ClientInfo, (int*)&clientinfolen );
|
||||
#else
|
||||
NewSocket = accept( sckISC, (sockaddr*)&ClientInfo, (socklen_t*)&clientinfolen );
|
||||
#endif
|
||||
// TODO: check if server is full
|
||||
if (NewSocket != INVALID_SOCKET)
|
||||
{
|
||||
@@ -312,42 +304,26 @@ void CServerSocket::ServerLoop( )
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef _WIN32
|
||||
Log( MSG_ERROR, "Error accepting socket: %i", WSAGetLastError() );
|
||||
#else
|
||||
Log( MSG_ERROR, "Error accepting socket: %i", errno );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( activity < 0 && errno != EINTR )
|
||||
{
|
||||
#ifdef _WIN32
|
||||
Log( MSG_ERROR, "Select command failed. Error #%i", WSAGetLastError() );
|
||||
#else
|
||||
Log( MSG_ERROR, "Select command failed. Error #%i", errno );
|
||||
#endif
|
||||
isActive = false;
|
||||
}
|
||||
if ( FD_ISSET( sock, &fds ) )
|
||||
{
|
||||
int clientinfolen = sizeof( sockaddr_in );
|
||||
#ifdef _WIN32
|
||||
NewSocket = accept( sock, (sockaddr*)&ClientInfo, (int*)&clientinfolen );
|
||||
#else
|
||||
NewSocket = accept( sock, (sockaddr*)&ClientInfo, (socklen_t*)&clientinfolen );
|
||||
#endif
|
||||
// TODO: check if server is full
|
||||
if (NewSocket != INVALID_SOCKET)
|
||||
AddUser( NewSocket, &ClientInfo, false );
|
||||
else
|
||||
{
|
||||
#ifdef _WIN32
|
||||
Log( MSG_ERROR, "Error accepting socket: %i", WSAGetLastError() );
|
||||
#else
|
||||
Log( MSG_ERROR, "Error accepting socket: %i", errno );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if(!Config.usethreads)
|
||||
|
||||
@@ -45,18 +45,6 @@ bool ConfigGetEntry( const char *pcFile, const char *pcNameMust, char* &pcResult
|
||||
while ( *pcPar==' ' || *pcPar=='\t' || *pcPar=='=' ) ++pcPar;
|
||||
*pcPoint=0;
|
||||
|
||||
#ifdef _WIN32
|
||||
if ( !_strcmpi( pcName, pcNameMust ) )
|
||||
{
|
||||
pcResult = _strdup( pcPar );
|
||||
pcPoint = pcResult + strlen( pcPar );
|
||||
if ( *pcPoint==0 ) return true;
|
||||
--pcPoint;
|
||||
while( *pcPoint==' ' || *pcPoint=='\t' ) *pcPoint--=0;
|
||||
return true;
|
||||
}
|
||||
|
||||
#else
|
||||
if ( strcasecmp( pcName, pcNameMust )==0 )
|
||||
{
|
||||
pcResult = _strdup( pcPar );
|
||||
@@ -66,7 +54,6 @@ bool ConfigGetEntry( const char *pcFile, const char *pcNameMust, char* &pcResult
|
||||
while( *pcPoint==' ' || *pcPoint=='\t' ) *pcPoint--=0;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
} while ( !feof( fh ) );
|
||||
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
#ifdef _WIN32
|
||||
#include <conio.h>
|
||||
#include <windows.h>
|
||||
#include <cstdio>
|
||||
#endif
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <cstring>
|
||||
@@ -38,12 +33,6 @@ static int __FOREGROUND = LIGHTGRAY;
|
||||
// Change console text color
|
||||
void textcolor(int color)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
__FOREGROUND = color;
|
||||
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color + (__BACKGROUND << 4));
|
||||
#else
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
// This function logs based on flags
|
||||
|
||||
+1
-7
@@ -6,13 +6,7 @@
|
||||
#define __ROSE_LOGGING_FUNCTIONS__
|
||||
|
||||
// Log path
|
||||
#ifdef _WIN32
|
||||
# define LOG_DIRECTORY "log/"
|
||||
#endif
|
||||
|
||||
#ifdef __unix__
|
||||
# define LOG_DIRECTORY "/var/log/roseserver/"
|
||||
#endif
|
||||
#define LOG_DIRECTORY "/var/log/roseserver/"
|
||||
|
||||
#define LOG_LOGIN_SERVER 0x01
|
||||
#define LOG_CHARACTER_SERVER 0x02
|
||||
|
||||
@@ -1,739 +0,0 @@
|
||||
/* Copyright (C) 2000-2003 MySQL AB
|
||||
|
||||
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; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; 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 _mysql_h
|
||||
#define _mysql_h
|
||||
|
||||
#ifdef __CYGWIN__ /* CYGWIN implements a UNIX API */
|
||||
#undef WIN
|
||||
#undef _WIN
|
||||
#undef _WIN32
|
||||
#undef _WIN64
|
||||
#undef __WIN__
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef _global_h /* If not standard header */
|
||||
#include <sys/types.h>
|
||||
#ifdef __LCC__
|
||||
#include <winsock.h> /* For windows */
|
||||
#endif
|
||||
typedef char my_bool;
|
||||
#if (defined(_WIN32) || defined(_WIN64)) && !defined(__WIN__)
|
||||
#define __WIN__
|
||||
#endif
|
||||
#if !defined(__WIN__)
|
||||
#define STDCALL
|
||||
#else
|
||||
#define STDCALL __stdcall
|
||||
#endif
|
||||
typedef char * gptr;
|
||||
|
||||
#ifndef my_socket_defined
|
||||
#ifdef __WIN__
|
||||
#define my_socket SOCKET
|
||||
#else
|
||||
typedef int my_socket;
|
||||
#endif /* __WIN__ */
|
||||
#endif /* my_socket_defined */
|
||||
#endif /* _global_h */
|
||||
|
||||
#include "mysql_com.h"
|
||||
#include "mysql_time.h"
|
||||
#include "mysql_version.h"
|
||||
#include "typelib.h"
|
||||
|
||||
#include "my_list.h" /* for LISTs used in 'MYSQL' and 'MYSQL_STMT' */
|
||||
|
||||
extern unsigned int mysql_port;
|
||||
extern char *mysql_unix_port;
|
||||
|
||||
#define CLIENT_NET_READ_TIMEOUT 365*24*3600 /* Timeout on read */
|
||||
#define CLIENT_NET_WRITE_TIMEOUT 365*24*3600 /* Timeout on write */
|
||||
|
||||
#ifdef __NETWARE__
|
||||
#pragma pack(push, 8) /* 8 byte alignment */
|
||||
#endif
|
||||
|
||||
#define IS_PRI_KEY(n) ((n) & PRI_KEY_FLAG)
|
||||
#define IS_NOT_NULL(n) ((n) & NOT_NULL_FLAG)
|
||||
#define IS_BLOB(n) ((n) & BLOB_FLAG)
|
||||
#define IS_NUM(t) ((t) <= FIELD_TYPE_INT24 || (t) == FIELD_TYPE_YEAR)
|
||||
#define IS_NUM_FIELD(f) ((f)->flags & NUM_FLAG)
|
||||
#define INTERNAL_NUM_FIELD(f) (((f)->type <= FIELD_TYPE_INT24 && ((f)->type != FIELD_TYPE_TIMESTAMP || (f)->length == 14 || (f)->length == 8)) || (f)->type == FIELD_TYPE_YEAR)
|
||||
|
||||
|
||||
typedef struct st_mysql_field {
|
||||
char *name; /* Name of column */
|
||||
char *org_name; /* Original column name, if an alias */
|
||||
char *table; /* Table of column if column was a field */
|
||||
char *org_table; /* Org table name, if table was an alias */
|
||||
char *db; /* Database for table */
|
||||
char *catalog; /* Catalog for table */
|
||||
char *def; /* Default value (set by mysql_list_fields) */
|
||||
unsigned long length; /* Width of column (create length) */
|
||||
unsigned long max_length; /* Max width for selected set */
|
||||
unsigned int name_length;
|
||||
unsigned int org_name_length;
|
||||
unsigned int table_length;
|
||||
unsigned int org_table_length;
|
||||
unsigned int db_length;
|
||||
unsigned int catalog_length;
|
||||
unsigned int def_length;
|
||||
unsigned int flags; /* Div flags */
|
||||
unsigned int decimals; /* Number of decimals in field */
|
||||
unsigned int charsetnr; /* Character set */
|
||||
enum enum_field_types type; /* Type of field. See mysql_com.h for types */
|
||||
} MYSQL_FIELD;
|
||||
|
||||
typedef char **MYSQL_ROW; /* return data as array of strings */
|
||||
typedef unsigned int MYSQL_FIELD_OFFSET; /* offset to current field */
|
||||
|
||||
#ifndef _global_h
|
||||
#if defined(NO_CLIENT_LONG_LONG)
|
||||
typedef unsigned long my_ulonglong;
|
||||
#elif defined (__WIN__)
|
||||
typedef unsigned __int64 my_ulonglong;
|
||||
#else
|
||||
typedef unsigned long long my_ulonglong;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define MYSQL_COUNT_ERROR (~(my_ulonglong) 0)
|
||||
|
||||
typedef struct st_mysql_rows {
|
||||
struct st_mysql_rows *next; /* list of rows */
|
||||
MYSQL_ROW data;
|
||||
unsigned long length;
|
||||
} MYSQL_ROWS;
|
||||
|
||||
typedef MYSQL_ROWS *MYSQL_ROW_OFFSET; /* offset to current row */
|
||||
|
||||
#include "my_alloc.h"
|
||||
|
||||
typedef struct st_mysql_data {
|
||||
my_ulonglong rows;
|
||||
unsigned int fields;
|
||||
MYSQL_ROWS *data;
|
||||
MEM_ROOT alloc;
|
||||
#if !defined(CHECK_EMBEDDED_DIFFERENCES) || defined(EMBEDDED_LIBRARY)
|
||||
MYSQL_ROWS **prev_ptr;
|
||||
#endif
|
||||
} MYSQL_DATA;
|
||||
|
||||
enum mysql_option
|
||||
{
|
||||
MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_COMPRESS, MYSQL_OPT_NAMED_PIPE,
|
||||
MYSQL_INIT_COMMAND, MYSQL_READ_DEFAULT_FILE, MYSQL_READ_DEFAULT_GROUP,
|
||||
MYSQL_SET_CHARSET_DIR, MYSQL_SET_CHARSET_NAME, MYSQL_OPT_LOCAL_INFILE,
|
||||
MYSQL_OPT_PROTOCOL, MYSQL_SHARED_MEMORY_BASE_NAME, MYSQL_OPT_READ_TIMEOUT,
|
||||
MYSQL_OPT_WRITE_TIMEOUT, MYSQL_OPT_USE_RESULT,
|
||||
MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION,
|
||||
MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH
|
||||
};
|
||||
|
||||
struct st_mysql_options {
|
||||
unsigned int connect_timeout, read_timeout, write_timeout;
|
||||
unsigned int port, protocol;
|
||||
unsigned long client_flag;
|
||||
char *host,*user,*password,*unix_socket,*db;
|
||||
struct st_dynamic_array *init_commands;
|
||||
char *my_cnf_file,*my_cnf_group, *charset_dir, *charset_name;
|
||||
char *ssl_key; /* PEM key file */
|
||||
char *ssl_cert; /* PEM cert file */
|
||||
char *ssl_ca; /* PEM CA file */
|
||||
char *ssl_capath; /* PEM directory of CA-s? */
|
||||
char *ssl_cipher; /* cipher to use */
|
||||
char *shared_memory_base_name;
|
||||
unsigned long max_allowed_packet;
|
||||
my_bool use_ssl; /* if to use SSL or not */
|
||||
my_bool compress,named_pipe;
|
||||
/*
|
||||
On connect, find out the replication role of the server, and
|
||||
establish connections to all the peers
|
||||
*/
|
||||
my_bool rpl_probe;
|
||||
/*
|
||||
Each call to mysql_real_query() will parse it to tell if it is a read
|
||||
or a write, and direct it to the slave or the master
|
||||
*/
|
||||
my_bool rpl_parse;
|
||||
/*
|
||||
If set, never read from a master, only from slave, when doing
|
||||
a read that is replication-aware
|
||||
*/
|
||||
my_bool no_master_reads;
|
||||
#if !defined(CHECK_EMBEDDED_DIFFERENCES) || defined(EMBEDDED_LIBRARY)
|
||||
my_bool separate_thread;
|
||||
#endif
|
||||
enum mysql_option methods_to_use;
|
||||
char *client_ip;
|
||||
/* Refuse client connecting to server if it uses old (pre-4.1.1) protocol */
|
||||
my_bool secure_auth;
|
||||
|
||||
/* function pointers for local infile support */
|
||||
int (*local_infile_init)(void **, const char *, void *);
|
||||
int (*local_infile_read)(void *, char *, unsigned int);
|
||||
void (*local_infile_end)(void *);
|
||||
int (*local_infile_error)(void *, char *, unsigned int);
|
||||
void *local_infile_userdata;
|
||||
};
|
||||
|
||||
enum mysql_status
|
||||
{
|
||||
MYSQL_STATUS_READY,MYSQL_STATUS_GET_RESULT,MYSQL_STATUS_USE_RESULT
|
||||
};
|
||||
|
||||
enum mysql_protocol_type
|
||||
{
|
||||
MYSQL_PROTOCOL_DEFAULT, MYSQL_PROTOCOL_TCP, MYSQL_PROTOCOL_SOCKET,
|
||||
MYSQL_PROTOCOL_PIPE, MYSQL_PROTOCOL_MEMORY
|
||||
};
|
||||
/*
|
||||
There are three types of queries - the ones that have to go to
|
||||
the master, the ones that go to a slave, and the adminstrative
|
||||
type which must happen on the pivot connectioin
|
||||
*/
|
||||
enum mysql_rpl_type
|
||||
{
|
||||
MYSQL_RPL_MASTER, MYSQL_RPL_SLAVE, MYSQL_RPL_ADMIN
|
||||
};
|
||||
|
||||
struct st_mysql_methods;
|
||||
|
||||
typedef struct st_mysql
|
||||
{
|
||||
NET net; /* Communication parameters */
|
||||
gptr connector_fd; /* ConnectorFd for SSL */
|
||||
char *host,*user,*passwd,*unix_socket,*server_version,*host_info,*info;
|
||||
char *db;
|
||||
struct charset_info_st *charset;
|
||||
MYSQL_FIELD *fields;
|
||||
MEM_ROOT field_alloc;
|
||||
my_ulonglong affected_rows;
|
||||
my_ulonglong insert_id; /* id if insert on table with NEXTNR */
|
||||
my_ulonglong extra_info; /* Used by mysqlshow */
|
||||
unsigned long thread_id; /* Id for connection in server */
|
||||
unsigned long packet_length;
|
||||
unsigned int port;
|
||||
unsigned long client_flag,server_capabilities;
|
||||
unsigned int protocol_version;
|
||||
unsigned int field_count;
|
||||
unsigned int server_status;
|
||||
unsigned int server_language;
|
||||
unsigned int warning_count;
|
||||
struct st_mysql_options options;
|
||||
enum mysql_status status;
|
||||
my_bool free_me; /* If free in mysql_close */
|
||||
my_bool reconnect; /* set to 1 if automatic reconnect */
|
||||
|
||||
/* session-wide random string */
|
||||
char scramble[SCRAMBLE_LENGTH+1];
|
||||
|
||||
/*
|
||||
Set if this is the original connection, not a master or a slave we have
|
||||
added though mysql_rpl_probe() or mysql_set_master()/ mysql_add_slave()
|
||||
*/
|
||||
my_bool rpl_pivot;
|
||||
/*
|
||||
Pointers to the master, and the next slave connections, points to
|
||||
itself if lone connection.
|
||||
*/
|
||||
struct st_mysql* master, *next_slave;
|
||||
|
||||
struct st_mysql* last_used_slave; /* needed for round-robin slave pick */
|
||||
/* needed for send/read/store/use result to work correctly with replication */
|
||||
struct st_mysql* last_used_con;
|
||||
|
||||
LIST *stmts; /* list of all statements */
|
||||
const struct st_mysql_methods *methods;
|
||||
void *thd;
|
||||
/*
|
||||
Points to boolean flag in MYSQL_RES or MYSQL_STMT. We set this flag
|
||||
from mysql_stmt_close if close had to cancel result set of this object.
|
||||
*/
|
||||
my_bool *unbuffered_fetch_owner;
|
||||
} MYSQL;
|
||||
|
||||
typedef struct st_mysql_res {
|
||||
my_ulonglong row_count;
|
||||
MYSQL_FIELD *fields;
|
||||
MYSQL_DATA *data;
|
||||
MYSQL_ROWS *data_cursor;
|
||||
unsigned long *lengths; /* column lengths of current row */
|
||||
MYSQL *handle; /* for unbuffered reads */
|
||||
MEM_ROOT field_alloc;
|
||||
unsigned int field_count, current_field;
|
||||
MYSQL_ROW row; /* If unbuffered read */
|
||||
MYSQL_ROW current_row; /* buffer to current row */
|
||||
my_bool eof; /* Used by mysql_fetch_row */
|
||||
/* mysql_stmt_close() had to cancel this result */
|
||||
my_bool unbuffered_fetch_cancelled;
|
||||
const struct st_mysql_methods *methods;
|
||||
} MYSQL_RES;
|
||||
|
||||
#define MAX_MYSQL_MANAGER_ERR 256
|
||||
#define MAX_MYSQL_MANAGER_MSG 256
|
||||
|
||||
#define MANAGER_OK 200
|
||||
#define MANAGER_INFO 250
|
||||
#define MANAGER_ACCESS 401
|
||||
#define MANAGER_CLIENT_ERR 450
|
||||
#define MANAGER_INTERNAL_ERR 500
|
||||
|
||||
#if !defined(MYSQL_SERVER) && !defined(MYSQL_CLIENT)
|
||||
#define MYSQL_CLIENT
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct st_mysql_manager
|
||||
{
|
||||
NET net;
|
||||
char *host,*user,*passwd;
|
||||
unsigned int port;
|
||||
my_bool free_me;
|
||||
my_bool eof;
|
||||
int cmd_status;
|
||||
int last_errno;
|
||||
char* net_buf,*net_buf_pos,*net_data_end;
|
||||
int net_buf_size;
|
||||
char last_error[MAX_MYSQL_MANAGER_ERR];
|
||||
} MYSQL_MANAGER;
|
||||
|
||||
typedef struct st_mysql_parameters
|
||||
{
|
||||
unsigned long *p_max_allowed_packet;
|
||||
unsigned long *p_net_buffer_length;
|
||||
} MYSQL_PARAMETERS;
|
||||
|
||||
#if !defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY)
|
||||
#define max_allowed_packet (*mysql_get_parameters()->p_max_allowed_packet)
|
||||
#define net_buffer_length (*mysql_get_parameters()->p_net_buffer_length)
|
||||
#endif
|
||||
|
||||
/*
|
||||
Set up and bring down the server; to ensure that applications will
|
||||
work when linked against either the standard client library or the
|
||||
embedded server library, these functions should be called.
|
||||
*/
|
||||
int STDCALL mysql_server_init(int argc, char **argv, char **groups);
|
||||
void STDCALL mysql_server_end(void);
|
||||
/*
|
||||
mysql_server_init/end need to be called when using libmysqld or
|
||||
libmysqlclient (exactly, mysql_server_init() is called by mysql_init() so
|
||||
you don't need to call it explicitely; but you need to call
|
||||
mysql_server_end() to free memory). The names are a bit misleading
|
||||
(mysql_SERVER* to be used when using libmysqlCLIENT). So we add more general
|
||||
names which suit well whether you're using libmysqld or libmysqlclient. We
|
||||
intend to promote these aliases over the mysql_server* ones.
|
||||
*/
|
||||
#define mysql_library_init mysql_server_init
|
||||
#define mysql_library_end mysql_server_end
|
||||
|
||||
MYSQL_PARAMETERS *STDCALL mysql_get_parameters(void);
|
||||
|
||||
/*
|
||||
Set up and bring down a thread; these function should be called
|
||||
for each thread in an application which opens at least one MySQL
|
||||
connection. All uses of the connection(s) should be between these
|
||||
function calls.
|
||||
*/
|
||||
my_bool STDCALL mysql_thread_init(void);
|
||||
void STDCALL mysql_thread_end(void);
|
||||
|
||||
/*
|
||||
Functions to get information from the MYSQL and MYSQL_RES structures
|
||||
Should definitely be used if one uses shared libraries.
|
||||
*/
|
||||
|
||||
my_ulonglong STDCALL mysql_num_rows(MYSQL_RES *res);
|
||||
unsigned int STDCALL mysql_num_fields(MYSQL_RES *res);
|
||||
my_bool STDCALL mysql_eof(MYSQL_RES *res);
|
||||
MYSQL_FIELD *STDCALL mysql_fetch_field_direct(MYSQL_RES *res,
|
||||
unsigned int fieldnr);
|
||||
MYSQL_FIELD * STDCALL mysql_fetch_fields(MYSQL_RES *res);
|
||||
MYSQL_ROW_OFFSET STDCALL mysql_row_tell(MYSQL_RES *res);
|
||||
MYSQL_FIELD_OFFSET STDCALL mysql_field_tell(MYSQL_RES *res);
|
||||
|
||||
unsigned int STDCALL mysql_field_count(MYSQL *mysql);
|
||||
my_ulonglong STDCALL mysql_affected_rows(MYSQL *mysql);
|
||||
my_ulonglong STDCALL mysql_insert_id(MYSQL *mysql);
|
||||
unsigned int STDCALL mysql_errno(MYSQL *mysql);
|
||||
const char * STDCALL mysql_error(MYSQL *mysql);
|
||||
const char *STDCALL mysql_sqlstate(MYSQL *mysql);
|
||||
unsigned int STDCALL mysql_warning_count(MYSQL *mysql);
|
||||
const char * STDCALL mysql_info(MYSQL *mysql);
|
||||
unsigned long STDCALL mysql_thread_id(MYSQL *mysql);
|
||||
const char * STDCALL mysql_character_set_name(MYSQL *mysql);
|
||||
int STDCALL mysql_set_character_set(MYSQL *mysql, char *csname);
|
||||
|
||||
MYSQL * STDCALL mysql_init(MYSQL *mysql);
|
||||
my_bool STDCALL mysql_ssl_set(MYSQL *mysql, const char *key,
|
||||
const char *cert, const char *ca,
|
||||
const char *capath, const char *cipher);
|
||||
my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
|
||||
const char *passwd, const char *db);
|
||||
MYSQL * STDCALL mysql_real_connect(MYSQL *mysql, const char *host,
|
||||
const char *user,
|
||||
const char *passwd,
|
||||
const char *db,
|
||||
unsigned int port,
|
||||
const char *unix_socket,
|
||||
unsigned long clientflag);
|
||||
int STDCALL mysql_select_db(MYSQL *mysql, const char *db);
|
||||
int STDCALL mysql_query(MYSQL *mysql, const char *q);
|
||||
int STDCALL mysql_send_query(MYSQL *mysql, const char *q,
|
||||
unsigned long length);
|
||||
int STDCALL mysql_real_query(MYSQL *mysql, const char *q,
|
||||
unsigned long length);
|
||||
MYSQL_RES * STDCALL mysql_store_result(MYSQL *mysql);
|
||||
MYSQL_RES * STDCALL mysql_use_result(MYSQL *mysql);
|
||||
|
||||
/* perform query on master */
|
||||
my_bool STDCALL mysql_master_query(MYSQL *mysql, const char *q,
|
||||
unsigned long length);
|
||||
my_bool STDCALL mysql_master_send_query(MYSQL *mysql, const char *q,
|
||||
unsigned long length);
|
||||
/* perform query on slave */
|
||||
my_bool STDCALL mysql_slave_query(MYSQL *mysql, const char *q,
|
||||
unsigned long length);
|
||||
my_bool STDCALL mysql_slave_send_query(MYSQL *mysql, const char *q,
|
||||
unsigned long length);
|
||||
|
||||
/* local infile support */
|
||||
|
||||
#define LOCAL_INFILE_ERROR_LEN 512
|
||||
|
||||
void
|
||||
mysql_set_local_infile_handler(MYSQL *mysql,
|
||||
int (*local_infile_init)(void **, const char *,
|
||||
void *),
|
||||
int (*local_infile_read)(void *, char *,
|
||||
unsigned int),
|
||||
void (*local_infile_end)(void *),
|
||||
int (*local_infile_error)(void *, char*,
|
||||
unsigned int),
|
||||
void *);
|
||||
|
||||
void
|
||||
mysql_set_local_infile_default(MYSQL *mysql);
|
||||
|
||||
|
||||
/*
|
||||
enable/disable parsing of all queries to decide if they go on master or
|
||||
slave
|
||||
*/
|
||||
void STDCALL mysql_enable_rpl_parse(MYSQL* mysql);
|
||||
void STDCALL mysql_disable_rpl_parse(MYSQL* mysql);
|
||||
/* get the value of the parse flag */
|
||||
int STDCALL mysql_rpl_parse_enabled(MYSQL* mysql);
|
||||
|
||||
/* enable/disable reads from master */
|
||||
void STDCALL mysql_enable_reads_from_master(MYSQL* mysql);
|
||||
void STDCALL mysql_disable_reads_from_master(MYSQL* mysql);
|
||||
/* get the value of the master read flag */
|
||||
my_bool STDCALL mysql_reads_from_master_enabled(MYSQL* mysql);
|
||||
|
||||
enum mysql_rpl_type STDCALL mysql_rpl_query_type(const char* q, int len);
|
||||
|
||||
/* discover the master and its slaves */
|
||||
my_bool STDCALL mysql_rpl_probe(MYSQL* mysql);
|
||||
|
||||
/* set the master, close/free the old one, if it is not a pivot */
|
||||
int STDCALL mysql_set_master(MYSQL* mysql, const char* host,
|
||||
unsigned int port,
|
||||
const char* user,
|
||||
const char* passwd);
|
||||
int STDCALL mysql_add_slave(MYSQL* mysql, const char* host,
|
||||
unsigned int port,
|
||||
const char* user,
|
||||
const char* passwd);
|
||||
|
||||
int STDCALL mysql_shutdown(MYSQL *mysql,
|
||||
enum mysql_enum_shutdown_level
|
||||
shutdown_level);
|
||||
int STDCALL mysql_dump_debug_info(MYSQL *mysql);
|
||||
int STDCALL mysql_refresh(MYSQL *mysql,
|
||||
unsigned int refresh_options);
|
||||
int STDCALL mysql_kill(MYSQL *mysql,unsigned long pid);
|
||||
int STDCALL mysql_set_server_option(MYSQL *mysql,
|
||||
enum enum_mysql_set_option
|
||||
option);
|
||||
int STDCALL mysql_ping(MYSQL *mysql);
|
||||
const char * STDCALL mysql_stat(MYSQL *mysql);
|
||||
const char * STDCALL mysql_get_server_info(MYSQL *mysql);
|
||||
const char * STDCALL mysql_get_client_info(void);
|
||||
unsigned long STDCALL mysql_get_client_version(void);
|
||||
const char * STDCALL mysql_get_host_info(MYSQL *mysql);
|
||||
unsigned long STDCALL mysql_get_server_version(MYSQL *mysql);
|
||||
unsigned int STDCALL mysql_get_proto_info(MYSQL *mysql);
|
||||
MYSQL_RES * STDCALL mysql_list_dbs(MYSQL *mysql,const char *wild);
|
||||
MYSQL_RES * STDCALL mysql_list_tables(MYSQL *mysql,const char *wild);
|
||||
MYSQL_RES * STDCALL mysql_list_processes(MYSQL *mysql);
|
||||
int STDCALL mysql_options(MYSQL *mysql,enum mysql_option option,
|
||||
const char *arg);
|
||||
void STDCALL mysql_free_result(MYSQL_RES *result);
|
||||
void STDCALL mysql_data_seek(MYSQL_RES *result,
|
||||
my_ulonglong offset);
|
||||
MYSQL_ROW_OFFSET STDCALL mysql_row_seek(MYSQL_RES *result,
|
||||
MYSQL_ROW_OFFSET offset);
|
||||
MYSQL_FIELD_OFFSET STDCALL mysql_field_seek(MYSQL_RES *result,
|
||||
MYSQL_FIELD_OFFSET offset);
|
||||
MYSQL_ROW STDCALL mysql_fetch_row(MYSQL_RES *result);
|
||||
unsigned long * STDCALL mysql_fetch_lengths(MYSQL_RES *result);
|
||||
MYSQL_FIELD * STDCALL mysql_fetch_field(MYSQL_RES *result);
|
||||
MYSQL_RES * STDCALL mysql_list_fields(MYSQL *mysql, const char *table,
|
||||
const char *wild);
|
||||
unsigned long STDCALL mysql_escape_string(char *to,const char *from,
|
||||
unsigned long from_length);
|
||||
unsigned long STDCALL mysql_hex_string(char *to,const char *from,
|
||||
unsigned long from_length);
|
||||
unsigned long STDCALL mysql_real_escape_string(MYSQL *mysql,
|
||||
char *to,const char *from,
|
||||
unsigned long length);
|
||||
void STDCALL mysql_debug(const char *debug);
|
||||
char * STDCALL mysql_odbc_escape_string(MYSQL *mysql,
|
||||
char *to,
|
||||
unsigned long to_length,
|
||||
const char *from,
|
||||
unsigned long from_length,
|
||||
void *param,
|
||||
char *
|
||||
(*extend_buffer)
|
||||
(void *, char *to,
|
||||
unsigned long *length));
|
||||
void STDCALL myodbc_remove_escape(MYSQL *mysql,char *name);
|
||||
unsigned int STDCALL mysql_thread_safe(void);
|
||||
my_bool STDCALL mysql_embedded(void);
|
||||
MYSQL_MANAGER* STDCALL mysql_manager_init(MYSQL_MANAGER* con);
|
||||
MYSQL_MANAGER* STDCALL mysql_manager_connect(MYSQL_MANAGER* con,
|
||||
const char* host,
|
||||
const char* user,
|
||||
const char* passwd,
|
||||
unsigned int port);
|
||||
void STDCALL mysql_manager_close(MYSQL_MANAGER* con);
|
||||
int STDCALL mysql_manager_command(MYSQL_MANAGER* con,
|
||||
const char* cmd, int cmd_len);
|
||||
int STDCALL mysql_manager_fetch_line(MYSQL_MANAGER* con,
|
||||
char* res_buf,
|
||||
int res_buf_size);
|
||||
my_bool STDCALL mysql_read_query_result(MYSQL *mysql);
|
||||
|
||||
|
||||
/*
|
||||
The following definitions are added for the enhanced
|
||||
client-server protocol
|
||||
*/
|
||||
|
||||
/* statement state */
|
||||
enum enum_mysql_stmt_state
|
||||
{
|
||||
MYSQL_STMT_INIT_DONE= 1, MYSQL_STMT_PREPARE_DONE, MYSQL_STMT_EXECUTE_DONE,
|
||||
MYSQL_STMT_FETCH_DONE
|
||||
};
|
||||
|
||||
|
||||
/* bind structure */
|
||||
typedef struct st_mysql_bind
|
||||
{
|
||||
unsigned long *length; /* output length pointer */
|
||||
my_bool *is_null; /* Pointer to null indicator */
|
||||
void *buffer; /* buffer to get/put data */
|
||||
enum enum_field_types buffer_type; /* buffer type */
|
||||
unsigned long buffer_length; /* buffer length, must be set for str/binary */
|
||||
|
||||
/* Following are for internal use. Set by mysql_stmt_bind_param */
|
||||
unsigned char *inter_buffer; /* for the current data position */
|
||||
unsigned long offset; /* offset position for char/binary fetch */
|
||||
unsigned long internal_length; /* Used if length is 0 */
|
||||
unsigned int param_number; /* For null count and error messages */
|
||||
unsigned int pack_length; /* Internal length for packed data */
|
||||
my_bool is_unsigned; /* set if integer type is unsigned */
|
||||
my_bool long_data_used; /* If used with mysql_send_long_data */
|
||||
my_bool internal_is_null; /* Used if is_null is 0 */
|
||||
void (*store_param_func)(NET *net, struct st_mysql_bind *param);
|
||||
void (*fetch_result)(struct st_mysql_bind *, unsigned char **row);
|
||||
void (*skip_result)(struct st_mysql_bind *, MYSQL_FIELD *,
|
||||
unsigned char **row);
|
||||
} MYSQL_BIND;
|
||||
|
||||
|
||||
/* statement handler */
|
||||
typedef struct st_mysql_stmt
|
||||
{
|
||||
MEM_ROOT mem_root; /* root allocations */
|
||||
LIST list; /* list to keep track of all stmts */
|
||||
MYSQL *mysql; /* connection handle */
|
||||
MYSQL_BIND *params; /* input parameters */
|
||||
MYSQL_BIND *bind; /* output parameters */
|
||||
MYSQL_FIELD *fields; /* result set metadata */
|
||||
MYSQL_DATA result; /* cached result set */
|
||||
MYSQL_ROWS *data_cursor; /* current row in cached result */
|
||||
/* copy of mysql->affected_rows after statement execution */
|
||||
my_ulonglong affected_rows;
|
||||
my_ulonglong insert_id; /* copy of mysql->insert_id */
|
||||
/*
|
||||
mysql_stmt_fetch() calls this function to fetch one row (it's different
|
||||
for buffered, unbuffered and cursor fetch).
|
||||
*/
|
||||
int (*read_row_func)(struct st_mysql_stmt *stmt,
|
||||
unsigned char **row);
|
||||
unsigned long stmt_id; /* Id for prepared statement */
|
||||
unsigned int last_errno; /* error code */
|
||||
unsigned int param_count; /* input parameter count */
|
||||
unsigned int field_count; /* number of columns in result set */
|
||||
enum enum_mysql_stmt_state state; /* statement state */
|
||||
char last_error[MYSQL_ERRMSG_SIZE]; /* error message */
|
||||
char sqlstate[SQLSTATE_LENGTH+1];
|
||||
/* Types of input parameters should be sent to server */
|
||||
my_bool send_types_to_server;
|
||||
my_bool bind_param_done; /* input buffers were supplied */
|
||||
my_bool bind_result_done; /* output buffers were supplied */
|
||||
/* mysql_stmt_close() had to cancel this result */
|
||||
my_bool unbuffered_fetch_cancelled;
|
||||
/*
|
||||
Is set to true if we need to calculate field->max_length for
|
||||
metadata fields when doing mysql_stmt_store_result.
|
||||
*/
|
||||
my_bool update_max_length;
|
||||
} MYSQL_STMT;
|
||||
|
||||
enum enum_stmt_attr_type
|
||||
{
|
||||
/*
|
||||
When doing mysql_stmt_store_result calculate max_length attribute
|
||||
of statement metadata. This is to be consistent with the old API,
|
||||
where this was done automatically.
|
||||
In the new API we do that only by request because it slows down
|
||||
mysql_stmt_store_result sufficiently.
|
||||
*/
|
||||
STMT_ATTR_UPDATE_MAX_LENGTH
|
||||
};
|
||||
|
||||
|
||||
typedef struct st_mysql_methods
|
||||
{
|
||||
my_bool (*read_query_result)(MYSQL *mysql);
|
||||
my_bool (*advanced_command)(MYSQL *mysql,
|
||||
enum enum_server_command command,
|
||||
const char *header,
|
||||
unsigned long header_length,
|
||||
const char *arg,
|
||||
unsigned long arg_length,
|
||||
my_bool skip_check);
|
||||
MYSQL_DATA *(*read_rows)(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
|
||||
unsigned int fields);
|
||||
MYSQL_RES * (*use_result)(MYSQL *mysql);
|
||||
void (*fetch_lengths)(unsigned long *to,
|
||||
MYSQL_ROW column, unsigned int field_count);
|
||||
void (*flush_use_result)(MYSQL *mysql);
|
||||
#if !defined(MYSQL_SERVER) || defined(EMBEDDED_LIBRARY)
|
||||
MYSQL_FIELD * (*list_fields)(MYSQL *mysql);
|
||||
my_bool (*read_prepare_result)(MYSQL *mysql, MYSQL_STMT *stmt);
|
||||
int (*stmt_execute)(MYSQL_STMT *stmt);
|
||||
int (*read_binary_rows)(MYSQL_STMT *stmt);
|
||||
int (*unbuffered_fetch)(MYSQL *mysql, char **row);
|
||||
void (*free_embedded_thd)(MYSQL *mysql);
|
||||
const char *(*read_statistics)(MYSQL *mysql);
|
||||
my_bool (*next_result)(MYSQL *mysql);
|
||||
int (*read_change_user_result)(MYSQL *mysql, char *buff, const char *passwd);
|
||||
#endif
|
||||
} MYSQL_METHODS;
|
||||
|
||||
|
||||
MYSQL_STMT * STDCALL mysql_stmt_init(MYSQL *mysql);
|
||||
int STDCALL mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query,
|
||||
unsigned long length);
|
||||
int STDCALL mysql_stmt_execute(MYSQL_STMT *stmt);
|
||||
int STDCALL mysql_stmt_fetch(MYSQL_STMT *stmt);
|
||||
int STDCALL mysql_stmt_fetch_column(MYSQL_STMT *stmt, MYSQL_BIND *bind,
|
||||
unsigned int column,
|
||||
unsigned long offset);
|
||||
int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt);
|
||||
unsigned long STDCALL mysql_stmt_param_count(MYSQL_STMT * stmt);
|
||||
my_bool STDCALL mysql_stmt_attr_set(MYSQL_STMT *stmt,
|
||||
enum enum_stmt_attr_type attr_type,
|
||||
const void *attr);
|
||||
my_bool STDCALL mysql_stmt_attr_get(MYSQL_STMT *stmt,
|
||||
enum enum_stmt_attr_type attr_type,
|
||||
void *attr);
|
||||
my_bool STDCALL mysql_stmt_bind_param(MYSQL_STMT * stmt, MYSQL_BIND * bnd);
|
||||
my_bool STDCALL mysql_stmt_bind_result(MYSQL_STMT * stmt, MYSQL_BIND * bnd);
|
||||
my_bool STDCALL mysql_stmt_close(MYSQL_STMT * stmt);
|
||||
my_bool STDCALL mysql_stmt_reset(MYSQL_STMT * stmt);
|
||||
my_bool STDCALL mysql_stmt_free_result(MYSQL_STMT *stmt);
|
||||
my_bool STDCALL mysql_stmt_send_long_data(MYSQL_STMT *stmt,
|
||||
unsigned int param_number,
|
||||
const char *data,
|
||||
unsigned long length);
|
||||
MYSQL_RES *STDCALL mysql_stmt_result_metadata(MYSQL_STMT *stmt);
|
||||
MYSQL_RES *STDCALL mysql_stmt_param_metadata(MYSQL_STMT *stmt);
|
||||
unsigned int STDCALL mysql_stmt_errno(MYSQL_STMT * stmt);
|
||||
const char *STDCALL mysql_stmt_error(MYSQL_STMT * stmt);
|
||||
const char *STDCALL mysql_stmt_sqlstate(MYSQL_STMT * stmt);
|
||||
MYSQL_ROW_OFFSET STDCALL mysql_stmt_row_seek(MYSQL_STMT *stmt,
|
||||
MYSQL_ROW_OFFSET offset);
|
||||
MYSQL_ROW_OFFSET STDCALL mysql_stmt_row_tell(MYSQL_STMT *stmt);
|
||||
void STDCALL mysql_stmt_data_seek(MYSQL_STMT *stmt, my_ulonglong offset);
|
||||
my_ulonglong STDCALL mysql_stmt_num_rows(MYSQL_STMT *stmt);
|
||||
my_ulonglong STDCALL mysql_stmt_affected_rows(MYSQL_STMT *stmt);
|
||||
my_ulonglong STDCALL mysql_stmt_insert_id(MYSQL_STMT *stmt);
|
||||
unsigned int STDCALL mysql_stmt_field_count(MYSQL_STMT *stmt);
|
||||
|
||||
my_bool STDCALL mysql_commit(MYSQL * mysql);
|
||||
my_bool STDCALL mysql_rollback(MYSQL * mysql);
|
||||
my_bool STDCALL mysql_autocommit(MYSQL * mysql, my_bool auto_mode);
|
||||
my_bool STDCALL mysql_more_results(MYSQL *mysql);
|
||||
int STDCALL mysql_next_result(MYSQL *mysql);
|
||||
void STDCALL mysql_close(MYSQL *sock);
|
||||
|
||||
|
||||
/* status return codes */
|
||||
#define MYSQL_NO_DATA 100
|
||||
|
||||
#define mysql_reload(mysql) mysql_refresh((mysql),REFRESH_GRANT)
|
||||
|
||||
#ifdef USE_OLD_FUNCTIONS
|
||||
MYSQL * STDCALL mysql_connect(MYSQL *mysql, const char *host,
|
||||
const char *user, const char *passwd);
|
||||
int STDCALL mysql_create_db(MYSQL *mysql, const char *DB);
|
||||
int STDCALL mysql_drop_db(MYSQL *mysql, const char *DB);
|
||||
#define mysql_reload(mysql) mysql_refresh((mysql),REFRESH_GRANT)
|
||||
#endif
|
||||
#define HAVE_MYSQL_REAL_CONNECT
|
||||
|
||||
/*
|
||||
The following functions are mainly exported because of mysqlbinlog;
|
||||
They are not for general usage
|
||||
*/
|
||||
|
||||
#define simple_command(mysql, command, arg, length, skip_check) \
|
||||
(*(mysql)->methods->advanced_command)(mysql, command, \
|
||||
NullS, 0, arg, length, skip_check)
|
||||
unsigned long net_safe_read(MYSQL* mysql);
|
||||
|
||||
#ifdef __NETWARE__
|
||||
#pragma pack(pop) /* restore alignment */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _mysql_h */
|
||||
@@ -1,29 +0,0 @@
|
||||
|
||||
//#include <cstring>
|
||||
#include "seh.hpp"
|
||||
|
||||
#ifdef __WIN32__
|
||||
|
||||
EXCEPTION_DISPOSITION __SEH_HANDLER::ExceptionRouter(PEXCEPTION_RECORD pRecord,
|
||||
__SEH_EXCEPTION_REGISTRATION* pReg,
|
||||
PCONTEXT pContext,
|
||||
PEXCEPTION_RECORD pRecord2)
|
||||
{
|
||||
return pReg->exthandler->ExceptionHandler(pRecord, pReg, pContext, pRecord2);
|
||||
}
|
||||
|
||||
EXCEPTION_DISPOSITION __SEH_HANDLER::ExceptionHandler(PEXCEPTION_RECORD pRecord,
|
||||
__SEH_EXCEPTION_REGISTRATION* pReg,
|
||||
PCONTEXT pContext,
|
||||
PEXCEPTION_RECORD pRecord2)
|
||||
{
|
||||
/*std::memcpy(&excContext, pContext, sizeof(_CONTEXT));
|
||||
std::memcpy(&excRecord, pRecord, sizeof(_EXCEPTION_RECORD));*/
|
||||
memcpy(&excContext, pContext, sizeof(_CONTEXT));
|
||||
memcpy(&excRecord, pRecord, sizeof(_EXCEPTION_RECORD));
|
||||
longjmp(context, 1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
|
||||
#ifndef __FV_SEH_H__
|
||||
#define __FV_SEH_H__
|
||||
|
||||
#ifdef __WIN32__
|
||||
#include <windows.h>
|
||||
#include <excpt.h>
|
||||
#endif
|
||||
|
||||
#include <setjmp.h>
|
||||
//#include <fv/defs.hpp>
|
||||
|
||||
//NAMESPACE_BEGIN(PU)
|
||||
//NAMESPACE_BEGIN(SEH)
|
||||
|
||||
#ifdef __WIN32__
|
||||
|
||||
class __SEH_HANDLER;
|
||||
|
||||
typedef struct tag__SEH_EXCEPTION_REGISTRATION
|
||||
{
|
||||
tag__SEH_EXCEPTION_REGISTRATION* prev;
|
||||
PEXCEPTION_HANDLER handler;
|
||||
__SEH_HANDLER* exthandler;
|
||||
} __SEH_EXCEPTION_REGISTRATION;
|
||||
|
||||
|
||||
class __SEH_HANDLER
|
||||
{
|
||||
public:
|
||||
__SEH_HANDLER() { }
|
||||
static EXCEPTION_DISPOSITION ExceptionRouter(PEXCEPTION_RECORD pRecord,
|
||||
__SEH_EXCEPTION_REGISTRATION* pReg,
|
||||
PCONTEXT pContext,
|
||||
PEXCEPTION_RECORD pRecord2);
|
||||
|
||||
virtual EXCEPTION_DISPOSITION ExceptionHandler(PEXCEPTION_RECORD pRecord,
|
||||
__SEH_EXCEPTION_REGISTRATION* pReg,
|
||||
PCONTEXT pContext,
|
||||
PEXCEPTION_RECORD pRecord2);
|
||||
|
||||
jmp_buf context;
|
||||
EXCEPTION_RECORD excRecord;
|
||||
CONTEXT excContext;
|
||||
};
|
||||
|
||||
#define __seh_try \
|
||||
{ \
|
||||
__SEH_EXCEPTION_REGISTRATION _lseh_er; \
|
||||
__SEH_HANDLER _lseh_handler; \
|
||||
\
|
||||
_lseh_er.handler = \
|
||||
reinterpret_cast<PEXCEPTION_HANDLER>(__SEH_HANDLER::ExceptionRouter); \
|
||||
_lseh_er.exthandler = &_lseh_handler; \
|
||||
asm volatile ("movl %%fs:0, %0" : "=r" (_lseh_er.prev)); \
|
||||
asm volatile ("movl %0, %%fs:0" : : "r" (&_lseh_er)); \
|
||||
int _lseh_setjmp_res = setjmp(_lseh_handler.context); \
|
||||
while(true) { \
|
||||
if(_lseh_setjmp_res != 0) { \
|
||||
break; \
|
||||
} \
|
||||
|
||||
#define __seh_finally \
|
||||
break; \
|
||||
} \
|
||||
while(true) {
|
||||
|
||||
|
||||
#define __seh_except(rec, ctx) \
|
||||
break; \
|
||||
} \
|
||||
PEXCEPTION_RECORD rec = &_lseh_handler.excRecord; \
|
||||
PCONTEXT ctx = &_lseh_handler.excContext; \
|
||||
\
|
||||
asm volatile ("movl %0, %%fs:0" : : "r" (_lseh_er.prev)); \
|
||||
if(_lseh_setjmp_res != 0)
|
||||
|
||||
#define __seh_end }
|
||||
|
||||
#else
|
||||
|
||||
#define __seh_try
|
||||
|
||||
#define __seh_except(rec, ctx) if(false) {
|
||||
|
||||
#define __seh_end }
|
||||
|
||||
#define __seh_finally
|
||||
|
||||
#endif
|
||||
|
||||
//NAMESPACE_END(SEH)
|
||||
//NAMESPACE_END(PU)
|
||||
|
||||
#endif
|
||||
|
||||
+17
-39
@@ -22,33 +22,23 @@
|
||||
#ifndef __ROSE_SOCKETS__
|
||||
#define __ROSE_SOCKETS__
|
||||
#define USEIFO
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <windows.h>
|
||||
#define close closesocket
|
||||
#ifdef FD_SETSIZE
|
||||
#undef FD_SETSIZE
|
||||
#endif
|
||||
#define FD_SETSIZE 1024
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <cstdarg>
|
||||
#include <errno.h>
|
||||
#define WSAGetLastError() errno
|
||||
#define SOCKET int
|
||||
#define INVALID_SOCKET -1
|
||||
#define SOCKET_ERROR -1
|
||||
#define PVOID void *
|
||||
#define ioctlsocket ioctl
|
||||
#define SOCKADDR struct sockaddr
|
||||
#define closesocket close
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <cstdarg>
|
||||
#include <errno.h>
|
||||
#define WSAGetLastError() errno
|
||||
#define SOCKET int
|
||||
#define INVALID_SOCKET -1
|
||||
#define SOCKET_ERROR -1
|
||||
#define PVOID void *
|
||||
#define ioctlsocket ioctl
|
||||
#define SOCKADDR struct sockaddr
|
||||
#define closesocket close
|
||||
|
||||
#include "mysql.h"
|
||||
#include <cstdio>
|
||||
@@ -63,7 +53,6 @@
|
||||
#include <math.h>
|
||||
#include <cmath>
|
||||
|
||||
#ifndef _WIN32
|
||||
// The entire codebase was written against Windows' clock(), which returns a
|
||||
// monotonic MILLISECOND counter (CLOCKS_PER_SEC == 1000) that closely tracks
|
||||
// wall-clock time for a normal single-threaded process. POSIX clock() is
|
||||
@@ -84,7 +73,6 @@ static inline long __rose_portable_clock()
|
||||
#undef CLOCKS_PER_SEC
|
||||
#define CLOCKS_PER_SEC 1000
|
||||
#define clock() __rose_portable_clock()
|
||||
#endif
|
||||
#include <map>
|
||||
#include "pthread.h"
|
||||
#include <vector>
|
||||
@@ -93,9 +81,6 @@ static inline long __rose_portable_clock()
|
||||
#include "rosecrypt.hpp"
|
||||
#include "config.h"
|
||||
#include "database/database.h"
|
||||
#ifdef _WIN32
|
||||
#pragma comment(lib, "Ws2_32.lib")
|
||||
#endif
|
||||
// Just some defs for easier use
|
||||
typedef char SBYTE;
|
||||
typedef unsigned char BYTE;
|
||||
@@ -105,18 +90,11 @@ typedef int SDWORD;
|
||||
typedef unsigned int DWORD;
|
||||
typedef long long SQWORD;
|
||||
typedef unsigned long long QWORD;
|
||||
#ifdef _WIN32
|
||||
typedef unsigned __int8 byte;
|
||||
typedef unsigned __int16 word;
|
||||
typedef unsigned __int32 dword;
|
||||
typedef unsigned __int64 qword;
|
||||
#else
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
typedef unsigned int dword;
|
||||
typedef unsigned long long qword;
|
||||
typedef unsigned int UINT;
|
||||
#endif
|
||||
typedef char* strings;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
@@ -58,12 +58,7 @@ bool CLoginServer::pakUserLogin( CLoginClient* thisclient, CPacket* P )
|
||||
if( mysql_num_rows( result ) == 1 )
|
||||
{
|
||||
row = mysql_fetch_row(result);
|
||||
int res = 0;
|
||||
#ifdef _WIN32
|
||||
res = _stricmp( row[1], thisclient->password.c_str() );
|
||||
#else
|
||||
res = strcasecmp( row[1], thisclient->password.c_str() );
|
||||
#endif
|
||||
int res = strcasecmp( row[1], thisclient->password.c_str() );
|
||||
if ( res == 0 )
|
||||
{
|
||||
if(atoi(row[3])==1)
|
||||
|
||||
@@ -50,9 +50,6 @@ int main(int argc, char *argv[])
|
||||
else
|
||||
{
|
||||
delete server;
|
||||
#ifdef _WIN32
|
||||
system("pause");
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
server->LoadEncryption ();
|
||||
|
||||
@@ -38,9 +38,6 @@ void StartSignal( )
|
||||
signal( SIGFPE, HandleSignal );
|
||||
signal( SIGSEGV, HandleSignal );
|
||||
signal( SIGTERM, HandleSignal );
|
||||
#ifdef _WIN32
|
||||
signal( SIGBREAK, HandleSignal );
|
||||
#endif
|
||||
signal( SIGABRT, HandleSignal );
|
||||
}
|
||||
|
||||
@@ -51,9 +48,6 @@ void StopSignal( )
|
||||
signal( SIGFPE, 0 );
|
||||
signal( SIGSEGV, 0 );
|
||||
signal( SIGTERM, 0 );
|
||||
#ifdef _WIN32
|
||||
signal( SIGBREAK, 0 );
|
||||
#endif
|
||||
signal( SIGABRT, 0 );
|
||||
}
|
||||
|
||||
@@ -63,21 +57,13 @@ void HandleSignal( int num )
|
||||
{
|
||||
case SIGINT:/* Interactive attention */
|
||||
Log( MSG_ERROR, "Signal received: SIGINT" );
|
||||
#ifdef _WIN32
|
||||
Sleep(1000);
|
||||
#else
|
||||
usleep(1000);
|
||||
#endif
|
||||
raise(num);
|
||||
break;
|
||||
case SIGILL:/* Illegal instruction */
|
||||
Log( MSG_ERROR, "Signal received: SIGILL, Server will be closed, Trying to save..." );
|
||||
GServer->isActive = false;
|
||||
#ifdef _WIN32
|
||||
Sleep(1000);
|
||||
#else
|
||||
usleep(1000);
|
||||
#endif
|
||||
raise(num);
|
||||
break;
|
||||
case SIGFPE:/* Floating point error */
|
||||
@@ -88,11 +74,7 @@ void HandleSignal( int num )
|
||||
case SIGSEGV:/* Segmentation violation */
|
||||
Log( MSG_ERROR, "Signal received: SIGSEGV, Server will be closed, Trying to save..." );
|
||||
GServer->isActive = false;
|
||||
#ifdef _WIN32
|
||||
Sleep(1000);
|
||||
#else
|
||||
usleep(1000);
|
||||
#endif
|
||||
raise(num);
|
||||
break;
|
||||
|
||||
@@ -100,12 +82,6 @@ void HandleSignal( int num )
|
||||
Log( MSG_INFO, "Signal received: SIGTERM, Server will be closed" );
|
||||
GServer->isActive = false;
|
||||
break;
|
||||
#ifdef _WIN32
|
||||
case SIGBREAK:/* Control-break */
|
||||
Log( MSG_INFO, "Signal received: SIGBREAK, Server will be closed" );
|
||||
GServer->isActive = false;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
cout << "Unknown Signal Number: " << num << endl;
|
||||
raise(num);
|
||||
|
||||
@@ -356,11 +356,7 @@ PVOID MapProcess( PVOID TS )
|
||||
}
|
||||
pthread_mutex_unlock( &GServer->MapMutex );
|
||||
pthread_mutex_unlock( &GServer->PlayerMutex );
|
||||
#ifdef _WIN32
|
||||
Sleep(GServer->Config.MapDelay);
|
||||
#else
|
||||
usleep(GServer->Config.MapDelay * 1000); // MapDelay is in milliseconds; usleep wants microseconds
|
||||
#endif
|
||||
}
|
||||
pthread_exit( NULL );
|
||||
return 0;
|
||||
@@ -390,11 +386,7 @@ PVOID VisibilityProcess(PVOID TS)
|
||||
}
|
||||
pthread_mutex_unlock( &GServer->MapMutex );
|
||||
pthread_mutex_unlock( &GServer->PlayerMutex );
|
||||
#ifdef _WIN32
|
||||
Sleep(GServer->Config.VisualDelay);
|
||||
#else
|
||||
usleep(GServer->Config.VisualDelay * 1000); // VisualDelay is in milliseconds; usleep wants microseconds
|
||||
#endif
|
||||
}
|
||||
pthread_exit(NULL);
|
||||
return 0;
|
||||
@@ -429,11 +421,7 @@ PVOID WorldProcess( PVOID TS )
|
||||
}
|
||||
pthread_mutex_unlock( &GServer->MapMutex );
|
||||
GServer->RefreshFairy( );
|
||||
#ifdef _WIN32
|
||||
Sleep(GServer->Config.WorldDelay);
|
||||
#else
|
||||
usleep(GServer->Config.WorldDelay * 1000); // WorldDelay is in milliseconds; usleep wants microseconds
|
||||
#endif
|
||||
}
|
||||
pthread_exit(NULL);
|
||||
return 0;
|
||||
@@ -443,11 +431,7 @@ PVOID WorldProcess( PVOID TS )
|
||||
void ShutdownServer(PVOID TS)
|
||||
{
|
||||
int minutes = (int)(intptr_t)TS;
|
||||
#ifdef _WIN32
|
||||
Sleep(minutes*60000);
|
||||
#else
|
||||
sleep(minutes*60); // minutes*60000 was milliseconds; sleep() wants seconds
|
||||
#endif
|
||||
Log( MSG_INFO, "Saving User Information... " );
|
||||
GServer->DisconnectAll();
|
||||
Log( MSG_INFO, "Waiting Process to ShutDown... " );
|
||||
|
||||
@@ -38,9 +38,6 @@ void StartSignal( )
|
||||
signal( SIGFPE, HandleSignal );
|
||||
signal( SIGSEGV, HandleSignal );
|
||||
signal( SIGTERM, HandleSignal );
|
||||
#ifdef _WIN32
|
||||
signal( SIGBREAK, HandleSignal );
|
||||
#endif
|
||||
signal( SIGABRT, HandleSignal );
|
||||
}
|
||||
|
||||
@@ -51,9 +48,6 @@ void StopSignal( )
|
||||
signal( SIGFPE, 0 );
|
||||
signal( SIGSEGV, 0 );
|
||||
signal( SIGTERM, 0 );
|
||||
#ifdef _WIN32
|
||||
signal( SIGBREAK, 0 );
|
||||
#endif
|
||||
signal( SIGABRT, 0 );
|
||||
}
|
||||
|
||||
@@ -63,22 +57,14 @@ void HandleSignal( int num )
|
||||
{
|
||||
case SIGINT:/* Interactive attention */
|
||||
Log( MSG_ERROR, "Signal received: SIGINT" );
|
||||
#ifdef _WIN32
|
||||
Sleep(1000);
|
||||
#else
|
||||
usleep(1000);
|
||||
#endif
|
||||
delete GServer;
|
||||
raise(num);
|
||||
break;
|
||||
case SIGILL:/* Illegal instruction */
|
||||
Log( MSG_ERROR, "Signal received: SIGILL, Server will be closed, Trying to save..." );
|
||||
GServer->DisconnectAll();
|
||||
#ifdef _WIN32
|
||||
Sleep(1000);
|
||||
#else
|
||||
usleep(1000);
|
||||
#endif
|
||||
delete GServer;
|
||||
raise(num);
|
||||
break;
|
||||
@@ -91,11 +77,7 @@ void HandleSignal( int num )
|
||||
case SIGSEGV:/* Segmentation violation */
|
||||
Log( MSG_ERROR, "Signal received: SIGSEGV, Server will be closed, Trying to save..." );
|
||||
GServer->DisconnectAll();
|
||||
#ifdef _WIN32
|
||||
Sleep(1000);
|
||||
#else
|
||||
usleep(1000);
|
||||
#endif
|
||||
delete GServer;
|
||||
raise(num);
|
||||
break;
|
||||
@@ -104,12 +86,6 @@ void HandleSignal( int num )
|
||||
Log( MSG_INFO, "Signal received: SIGTERM, Server will be closed" );
|
||||
pthread_create( &GServer->WorldThread[SHUTDOWN_THREAD], NULL, (void *(__cdecl *)(void *))ShutdownServer, (PVOID)0);
|
||||
break;
|
||||
#ifdef _WIN32
|
||||
case SIGBREAK:/* Control-break */
|
||||
Log( MSG_INFO, "Signal received: SIGBREAK, Server will be closed" );
|
||||
pthread_create( &GServer->WorldThread[SHUTDOWN_THREAD], NULL, (void *(__cdecl *)(void *))ShutdownServer, (PVOID)0);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
cout << "Unknown Signal Number: " << num << endl;
|
||||
raise(num);
|
||||
|
||||
@@ -60,9 +60,6 @@ int main(int argc, char *argv[])
|
||||
else
|
||||
{
|
||||
delete server;
|
||||
#ifdef _WIN32
|
||||
system("pause");
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,11 +13,7 @@ public:
|
||||
unsigned dataoffset = 0;
|
||||
unsigned short fieldlen = 0;
|
||||
|
||||
#ifdef _WIN32
|
||||
if ( (fh = fopen( filename, "rb" )) == 0 ) {
|
||||
#else
|
||||
if ( (fh = rose_fopen( filename, "rb" )) == 0 ) {
|
||||
#endif
|
||||
Log( MSG_ERROR, "Could not load STB '%s'", filename );
|
||||
return 1;
|
||||
}else{
|
||||
|
||||
@@ -215,17 +215,8 @@ class CRoseFile
|
||||
{
|
||||
ftype = FT_BINARY;
|
||||
}
|
||||
#ifndef CFILE_NODEPRECATE
|
||||
if( fopen_s( &fh, fname, fasciimode ) == 0 )
|
||||
{
|
||||
#else
|
||||
#ifdef _WIN32
|
||||
if( ( fh = fopen( fname, fasciimode ) ) != NULL )
|
||||
#else
|
||||
if( ( fh = rose_fopen( fname, fasciimode ) ) != NULL )
|
||||
#endif
|
||||
{
|
||||
#endif
|
||||
delete[] fasciimode;
|
||||
//Check if unicode or ascii
|
||||
if( ftype != FT_BINARY )
|
||||
@@ -244,13 +235,7 @@ class CRoseFile
|
||||
DoError( FE_INTERNALERROR );
|
||||
return false;
|
||||
}
|
||||
#ifndef CFILE_NODEPRECATE
|
||||
fopen_s( &fh, fname, fasciimode );
|
||||
#elif defined(_WIN32)
|
||||
fh = fopen( fname, fasciimode );
|
||||
#else
|
||||
fh = rose_fopen( fname, fasciimode );
|
||||
#endif
|
||||
SetAbsPos( 2 );
|
||||
ftype = FT_UNICODE;
|
||||
#else
|
||||
@@ -561,12 +546,7 @@ class CRoseFile
|
||||
CFILE_CHAR buf;
|
||||
wchar_t buffer;
|
||||
buffer = fgetwc( fh );
|
||||
#ifndef CFILE_NODEPRECATE
|
||||
size_t tmp;
|
||||
wcstombs_s( &tmp, &buf, (size_t)(sizeof(buf)), &buffer, 1 );
|
||||
#else
|
||||
wcstombs( &buf, &buffer, 1 );
|
||||
#endif
|
||||
return (CFILE_CHAR)buf;
|
||||
#else
|
||||
DoError( FE_UNICODENOTALLOWED );
|
||||
@@ -610,12 +590,7 @@ class CRoseFile
|
||||
#ifndef CFILE_NOUNICODE
|
||||
wchar_t* buffer = new wchar_t[max_count];
|
||||
fgetws( buffer, max_count, fh );
|
||||
#ifndef CFILE_NODEPRECATE
|
||||
size_t tmp;
|
||||
wcstombs_s( &tmp, buf->arr, (size_t)(buf->absSize()), buffer, max_count );
|
||||
#else
|
||||
wcstombs( buf->arr, buffer, max_count );
|
||||
#endif
|
||||
return NULL;
|
||||
#else
|
||||
DoError( FE_UNICODENOTALLOWED );
|
||||
@@ -861,12 +836,7 @@ class CRoseFile
|
||||
{
|
||||
#ifndef CFILE_NOUNICODE
|
||||
wchar_t buffer;
|
||||
#ifndef CFILE_NODEPRECATE
|
||||
size_t tmp;
|
||||
mbstowcs_s( &tmp, &buffer, 1, (CFILE_CHAR*)(&chr), 1 );
|
||||
#else
|
||||
mbstowcs( &buffer, (CFILE_CHAR*)(&chr), 1 );
|
||||
#endif
|
||||
return (CFILE_SCHAR)(fputwc( buffer, fh ));
|
||||
#else
|
||||
DoError( FE_UNICODENOTALLOWED );
|
||||
@@ -904,12 +874,7 @@ class CRoseFile
|
||||
{
|
||||
#ifndef CFILE_NOUNICODE
|
||||
wchar_t* buffer = new wchar_t[ (size_t)(str->size()) ];
|
||||
#ifndef CFILE_NODEPRECATE
|
||||
size_t tmp;
|
||||
mbstowcs_s( &tmp, buffer, (size_t)(str->size()), str->arr, (size_t)(str->size()) );
|
||||
#else
|
||||
mbstowcs( buffer, str->arr, str->size() );
|
||||
#endif
|
||||
return (fputws( buffer, fh )!=EOF)?(true):(false);
|
||||
#else
|
||||
DoError( FE_UNICODENOTALLOWED );
|
||||
|
||||
@@ -2052,13 +2052,6 @@ bool CWorldServer::pakNPCBuy ( CPlayer* thisclient, CPacket* P )
|
||||
thisclient->client->SendPacket( &pak );
|
||||
thisclient->saveinventory();
|
||||
return true;
|
||||
//}
|
||||
//__seh_except(info, context)
|
||||
//{
|
||||
// Log( MSG_ERROR, "Error in pakNPCBuy");
|
||||
// return false;
|
||||
//}
|
||||
//__seh_end
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -360,80 +360,48 @@ void CWorldServer::ServerLoop( )
|
||||
if ( activity == 0 )
|
||||
{
|
||||
pthread_mutex_unlock( &PlayerMutex );
|
||||
#ifdef _WIN32
|
||||
Sleep(1);
|
||||
#else
|
||||
usleep(1);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
if ( activity < 0 && errno != EINTR )
|
||||
{
|
||||
#ifdef _WIN32
|
||||
Log( MSG_ERROR, "Select command failed. Error #%i", WSAGetLastError() );
|
||||
#else
|
||||
Log( MSG_ERROR, "Select command failed. Error #%i", errno );
|
||||
#endif
|
||||
isActive = false;
|
||||
}
|
||||
if ( FD_ISSET( sckISCII, &fds ) )
|
||||
{
|
||||
int clientinfolen = sizeof( sockaddr_in );
|
||||
#ifdef _WIN32
|
||||
NewSocket = accept( sckISCII, (sockaddr*)&ClientInfo, (int*)&clientinfolen );
|
||||
#else
|
||||
NewSocket = accept( sckISCII, (sockaddr*)&ClientInfo, (socklen_t*)&clientinfolen );
|
||||
#endif
|
||||
// TODO: check if server is full
|
||||
if (NewSocket != INVALID_SOCKET)
|
||||
AddUser( NewSocket, &ClientInfo, true);
|
||||
else
|
||||
{
|
||||
#ifdef _WIN32
|
||||
Log( MSG_ERROR, "Error accepting socket: %i", WSAGetLastError() );
|
||||
#else
|
||||
Log( MSG_ERROR, "Error accepting socket: %i", errno );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( activity < 0 && errno != EINTR )
|
||||
{
|
||||
#ifdef _WIN32
|
||||
Log( MSG_ERROR, "Select command failed. Error #%i", WSAGetLastError() );
|
||||
#else
|
||||
Log( MSG_ERROR, "Select command failed. Error #%i", errno );
|
||||
#endif
|
||||
isActive = false;
|
||||
}
|
||||
if ( FD_ISSET( sock, &fds ) )
|
||||
{
|
||||
int clientinfolen = sizeof( sockaddr_in );
|
||||
#ifdef _WIN32
|
||||
NewSocket = accept( sock, (sockaddr*)&ClientInfo, (int*)&clientinfolen );
|
||||
#else
|
||||
NewSocket = accept( sock, (sockaddr*)&ClientInfo, (socklen_t*)&clientinfolen );
|
||||
#endif
|
||||
// TODO: check if server is full
|
||||
if (NewSocket != INVALID_SOCKET)
|
||||
AddUser( NewSocket, &ClientInfo, false);
|
||||
else
|
||||
{
|
||||
#ifdef _WIN32
|
||||
Log( MSG_ERROR, "Error accepting socket: %i", WSAGetLastError() );
|
||||
#else
|
||||
Log( MSG_ERROR, "Error accepting socket: %i", errno );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if(!Config.usethreads)
|
||||
HandleClients( &fds );
|
||||
pthread_mutex_unlock( &PlayerMutex );
|
||||
#ifdef _WIN32
|
||||
Sleep(1);
|
||||
#else
|
||||
usleep(1);
|
||||
#endif
|
||||
} while( isActive );
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
-- Default GM account so a fresh deploy has something to log into the
|
||||
-- web admin panel and the game with. Change the password immediately on
|
||||
-- any server that isn't purely local/dev -- see README.md.
|
||||
--
|
||||
-- username: gmadmin
|
||||
-- password: changeme (stored as md5, matching Src/Login Server/loginpackets.cpp
|
||||
-- and webadmin/app.py's hash_password())
|
||||
INSERT INTO `accounts` (`username`, `password`, `accesslevel`, `lastlogin`, `logtime`)
|
||||
VALUES ('gmadmin', MD5('changeme'), 900, '', 0);
|
||||
+2
-3
@@ -42,7 +42,7 @@ services:
|
||||
MYSQL_USER: ${DB_USER:-rose}
|
||||
MYSQL_PASSWORD: ${DB_PASSWORD:-change_me}
|
||||
volumes:
|
||||
- db-data:/var/lib/mysql
|
||||
- "./docker/data/mysql:/var/lib/mysql"
|
||||
- "./database sql files:/docker-entrypoint-initdb.d:ro"
|
||||
healthcheck:
|
||||
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
|
||||
@@ -85,7 +85,7 @@ services:
|
||||
image: nginx:alpine
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "80:80"
|
||||
- "${WEBTOOLS_PORT:-80}:80"
|
||||
volumes:
|
||||
- "./webtools:/usr/share/nginx/html:ro"
|
||||
- "./docker/conf/webtools-nginx.conf:/etc/nginx/conf.d/default.conf:ro"
|
||||
@@ -118,6 +118,5 @@ services:
|
||||
condition: service_healthy
|
||||
|
||||
volumes:
|
||||
db-data:
|
||||
logs:
|
||||
clanmark:
|
||||
Reference in new issue
Block a user