Add Linux compatibility for LoginServer

- Updated main.cpp with platform-specific code for Windows/Linux
- Modified stdafx.h to include Linux headers and definitions
- Updated signal_handler.cpp for cross-platform signal handling
- Added Linux-compatible types and macros
- Created CMakeLists.txt for Linux build system
- Added build.sh script for automated building
- Added loginserver.sh script for server management
- Created comprehensive README_LINUX.md with deployment instructions
- All changes maintain Windows compatibility using preprocessor directives
This commit is contained in:
Your Name 2025-08-29 21:52:53 +03:00
parent 26a4c99c5c
commit 59b331458c
9 changed files with 967 additions and 15 deletions

View File

@ -0,0 +1,95 @@
cmake_minimum_required(VERSION 3.10)
project(LoginServer)
# Set C++ standard
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Set compiler flags
if(WIN32)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -O2 -pthread")
endif()
# Define preprocessor macros
if(WIN32)
add_definitions(-D_WIN32)
add_definitions(-DWIN32_LEAN_AND_MEAN)
add_definitions(-DVC_EXTRALEAN)
else()
add_definitions(-D__VERSION=1)
endif()
# Include directories
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/../shared
${CMAKE_CURRENT_SOURCE_DIR}/../shared/database
)
# Source files
set(LOGIN_SERVER_SOURCES
main.cpp
LoginServer.cpp
LoginSession.cpp
DBProcess.cpp
stdafx.cpp
)
# Shared library sources
set(SHARED_SOURCES
../shared/globals.cpp
../shared/tstring.cpp
../shared/Thread.cpp
../shared/TimeThread.cpp
../shared/Socket.cpp
../shared/SocketMgr.cpp
../shared/Condition.cpp
../shared/RWLock.cpp
../shared/ReferenceObject.cpp
../shared/signal_handler.cpp
../shared/Ini.cpp
../shared/JvCryption.cpp
../shared/crc32.c
../shared/lzf.c
../shared/HardwareInformation.cpp
../shared/DebugUtils.cpp
../shared/SMDFile.cpp
../shared/CircularBuffer.cpp
)
# Database sources
file(GLOB DATABASE_SOURCES "../shared/database/*.cpp")
# Platform specific sources
if(WIN32)
list(APPEND SHARED_SOURCES
../shared/SocketWin32.cpp
../shared/SocketOpsWin32.cpp
)
endif()
# Create executable
add_executable(LoginServer
${LOGIN_SERVER_SOURCES}
${SHARED_SOURCES}
${DATABASE_SOURCES}
)
# Link libraries
if(WIN32)
target_link_libraries(LoginServer ws2_32 odbc32)
else()
target_link_libraries(LoginServer pthread odbc)
endif()
# Set output directory
set_target_properties(LoginServer PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)
# Copy configuration files
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/LogIn.ini)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/LogIn.ini ${CMAKE_BINARY_DIR}/bin/LogIn.ini COPYONLY)
endif()

View File

@ -20,7 +20,11 @@ bool LoginServer::Startup()
printf("Project : %d\n", GetVersion());
printf("Edited by Levent\n\n");
#ifdef _WIN32
CreateDirectory("Logs",NULL);
#else
mkdir("Logs", 0755);
#endif
m_fpLoginServer = fopen("./Logs/LoginServer.log", "a");
if (m_fpLoginServer == nullptr)

View File

@ -0,0 +1,295 @@
# Knight Online Login Server - Linux Version
This directory contains the Linux-compatible version of the Knight Online Login Server.
## Prerequisites
Before building and running the Login Server on Linux, make sure you have the following dependencies installed:
### Ubuntu/Debian
```bash
sudo apt-get update
sudo apt-get install build-essential cmake g++ unixodbc-dev
```
### CentOS/RHEL/Fedora
```bash
# CentOS/RHEL
sudo yum groupinstall "Development Tools"
sudo yum install cmake unixODBC-devel
# Fedora
sudo dnf groupinstall "Development Tools"
sudo dnf install cmake unixODBC-devel
```
## Building the Server
### Quick Start
```bash
# Make build script executable
chmod +x build.sh
# Build everything
./build.sh all
```
### Manual Build Steps
```bash
# 1. Make scripts executable
chmod +x build.sh loginserver.sh
# 2. Build the project
./build.sh build
# 3. Install binaries
./build.sh install
```
### Build Options
```bash
./build.sh clean # Clean build files
./build.sh build # Build project
./build.sh rebuild # Clean and build
./build.sh install # Install binaries
./build.sh all # Full build and install
./build.sh -j 4 build # Build with 4 parallel jobs
```
## Configuration
### Database Setup
1. Install and configure your ODBC driver for your database
2. Edit `LogIn.ini` with your database connection details:
```ini
[ODBC]
DSN=KO_MAIN
UID=your_username
PWD=your_password
```
### Server Configuration
Edit `LogIn.ini` to configure server settings:
```ini
[SETTINGS]
PORT=15100
[SERVER_LIST]
COUNT=1
SERVER_00=192.168.1.104
LANIP_00=192.168.1.104
NAME_00=Your Server Name
ID_00=1
```
## Running the Server
### Start the Server
```bash
./loginserver.sh start
```
### Check Server Status
```bash
./loginserver.sh status
```
### View Server Logs
```bash
./loginserver.sh logs
```
### Stop the Server
```bash
./loginserver.sh stop
```
### Restart the Server
```bash
./loginserver.sh restart
```
## Management Commands
The `loginserver.sh` script provides several management commands:
- `start` - Start the login server
- `stop` - Stop the login server
- `restart` - Restart the login server
- `status` - Show server status and process information
- `logs` - View server logs in real-time
- `config` - Create default configuration file
## File Structure
```
LoginServer/
├── bin/ # Compiled binaries
│ └── LoginServer # Main server executable
├── build/ # CMake build directory
├── Logs/ # Server log files
│ ├── LoginServer.log # Main server log
│ ├── Login_DD_MM_YYYY.log # Daily user login log
│ └── server_output.log # Server console output
├── build.sh # Build script
├── loginserver.sh # Server management script
├── LogIn.ini # Server configuration
├── CMakeLists.txt # CMake configuration
└── README_LINUX.md # This file
```
## Troubleshooting
### Common Issues
#### 1. Build Failures
- Make sure all dependencies are installed
- Check that you have sufficient permissions
- Verify CMake version (3.10 or higher required)
#### 2. ODBC Connection Issues
```bash
# Test ODBC connection
isql -v DSN_NAME username password
# List available ODBC drivers
odbcinst -q -d
# List configured DSNs
odbcinst -q -s
```
#### 3. Permission Issues
```bash
# Make scripts executable
chmod +x build.sh loginserver.sh
# Check binary permissions
chmod +x bin/LoginServer
```
#### 4. Port Already in Use
```bash
# Check what's using the port
sudo netstat -tlnp | grep :15100
# Kill process using the port
sudo kill -9 PID
```
### Debugging
#### Enable Debug Mode
Edit CMakeLists.txt and add debug flags:
```cmake
set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -DDEBUG")
```
#### Run with GDB
```bash
gdb ./bin/LoginServer
(gdb) run
```
#### Monitor System Resources
```bash
# Monitor server process
top -p $(cat loginserver.pid)
# Check memory usage
cat /proc/$(cat loginserver.pid)/status
# Monitor network connections
ss -tlnp | grep LoginServer
```
## Security Considerations
1. **Firewall Configuration**
```bash
# Allow login server port
sudo ufw allow 15100/tcp
```
2. **User Permissions**
- Run the server as a non-root user
- Set appropriate file permissions
- Use a dedicated service user
3. **Database Security**
- Use strong database passwords
- Limit database user permissions
- Enable database connection encryption
## Integration with Gitea
This server is configured to work with the Gitea repository at:
- Local: `http://192.168.1.104:3000/`
- SSH: `ssh://gitea@192.168.1.104:2222/leventferrah/knightonline.git`
### Deployment Workflow
```bash
# Pull latest changes
git pull knight main
# Build and deploy
./build.sh all
# Restart server
./loginserver.sh restart
```
## Performance Tuning
### System Limits
Edit `/etc/security/limits.conf`:
```
username soft nofile 65536
username hard nofile 65536
```
### Network Optimization
Edit `/etc/sysctl.conf`:
```
net.core.somaxconn = 1024
net.ipv4.tcp_max_syn_backlog = 1024
```
## Monitoring
### Log Monitoring
```bash
# Monitor all logs
tail -f Logs/*.log
# Monitor specific log
tail -f Logs/LoginServer.log
```
### Process Monitoring
```bash
# Check if server is running
./loginserver.sh status
# Monitor resource usage
watch -n 1 './loginserver.sh status'
```
## Support
For issues and support:
- Check the server logs in `Logs/` directory
- Verify configuration in `LogIn.ini`
- Test database connectivity
- Check network connectivity and firewall settings
## Version Information
- **Server Version**: Knight Online Login Server v1.0
- **Platform**: Linux (Ubuntu/CentOS/Debian compatible)
- **Build System**: CMake 3.10+
- **Compiler**: GCC 7+
- **Dependencies**: ODBC, pthread

248
server/LogInServer/build.sh Normal file
View File

@ -0,0 +1,248 @@
#!/bin/bash
# Knight Online Login Server Build Script for Linux
# Author: Levent Ferrah
# Set script directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Configuration
BUILD_DIR="build"
JOBS=$(nproc)
# Functions
log_message() {
echo -e "${BLUE}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $1"
}
log_error() {
echo -e "${RED}[$(date '+%Y-%m-%d %H:%M:%S')] ERROR:${NC} $1"
}
log_success() {
echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')] SUCCESS:${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[$(date '+%Y-%m-%d %H:%M:%S')] WARNING:${NC} $1"
}
# Check dependencies
check_dependencies() {
log_message "Checking build dependencies..."
# Check for cmake
if ! command -v cmake &> /dev/null; then
log_error "cmake is not installed"
echo "Please install cmake: sudo apt-get install cmake"
return 1
fi
# Check for g++
if ! command -v g++ &> /dev/null; then
log_error "g++ is not installed"
echo "Please install g++: sudo apt-get install g++ build-essential"
return 1
fi
# Check for ODBC
if ! pkg-config --exists odbc &> /dev/null; then
log_warning "ODBC development files might not be installed"
echo "Consider installing: sudo apt-get install unixodbc-dev"
fi
log_success "Dependencies check completed"
return 0
}
# Clean build directory
clean_build() {
log_message "Cleaning build directory..."
if [ -d "$BUILD_DIR" ]; then
rm -rf "$BUILD_DIR"
log_success "Build directory cleaned"
fi
}
# Build project
build_project() {
log_message "Starting build process..."
# Create build directory
mkdir -p "$BUILD_DIR"
cd "$BUILD_DIR"
# Configure with cmake
log_message "Configuring project with CMake..."
if ! cmake ..; then
log_error "CMake configuration failed"
return 1
fi
# Build project
log_message "Building project with $JOBS parallel jobs..."
if ! make -j$JOBS; then
log_error "Build failed"
return 1
fi
cd ..
log_success "Build completed successfully"
return 0
}
# Install project
install_project() {
log_message "Installing project..."
# Create bin directory if it doesn't exist
mkdir -p bin
# Copy binary
if [ -f "$BUILD_DIR/bin/LoginServer" ]; then
cp "$BUILD_DIR/bin/LoginServer" bin/
chmod +x bin/LoginServer
log_success "LoginServer binary installed to bin/"
else
log_error "LoginServer binary not found in build directory"
return 1
fi
# Make scripts executable
chmod +x loginserver.sh
log_success "Scripts made executable"
return 0
}
# Show usage
show_usage() {
echo "Knight Online Login Server Build Script"
echo ""
echo "Usage: $0 [OPTIONS] [COMMAND]"
echo ""
echo "Commands:"
echo " build - Build the project (default)"
echo " clean - Clean build directory"
echo " rebuild - Clean and build"
echo " install - Install built binaries"
echo " all - Clean, build, and install"
echo ""
echo "Options:"
echo " -h, --help - Show this help message"
echo " -j, --jobs N - Use N parallel jobs (default: $JOBS)"
echo ""
echo "Examples:"
echo " $0 # Build project"
echo " $0 clean # Clean build files"
echo " $0 rebuild # Clean and rebuild"
echo " $0 all # Full build and install"
echo " $0 -j 4 build # Build with 4 parallel jobs"
}
# Parse command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
show_usage
exit 0
;;
-j|--jobs)
JOBS="$2"
shift 2
;;
clean)
COMMAND="clean"
shift
;;
build)
COMMAND="build"
shift
;;
rebuild)
COMMAND="rebuild"
shift
;;
install)
COMMAND="install"
shift
;;
all)
COMMAND="all"
shift
;;
*)
log_error "Unknown option: $1"
show_usage
exit 1
;;
esac
done
# Default command
if [ -z "$COMMAND" ]; then
COMMAND="build"
fi
# Main execution
log_message "Knight Online Login Server Build Script"
log_message "Build command: $COMMAND"
log_message "Parallel jobs: $JOBS"
echo ""
case "$COMMAND" in
clean)
clean_build
;;
build)
if ! check_dependencies; then
exit 1
fi
if ! build_project; then
exit 1
fi
;;
rebuild)
if ! check_dependencies; then
exit 1
fi
clean_build
if ! build_project; then
exit 1
fi
;;
install)
if ! install_project; then
exit 1
fi
;;
all)
if ! check_dependencies; then
exit 1
fi
clean_build
if ! build_project; then
exit 1
fi
if ! install_project; then
exit 1
fi
log_success "Build and installation completed successfully!"
echo ""
echo "To start the server:"
echo " ./loginserver.sh start"
echo ""
echo "To check server status:"
echo " ./loginserver.sh status"
;;
esac
exit 0

View File

@ -0,0 +1,251 @@
#!/bin/bash
# Knight Online Login Server Linux Startup Script
# Author: Levent Ferrah
# Description: Startup script for Knight Online Login Server on Linux
# Set script directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
# Configuration
SERVER_NAME="LoginServer"
BINARY_PATH="./bin/LoginServer"
LOG_DIR="./Logs"
PID_FILE="./loginserver.pid"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Functions
log_message() {
echo -e "${BLUE}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $1"
}
log_error() {
echo -e "${RED}[$(date '+%Y-%m-%d %H:%M:%S')] ERROR:${NC} $1"
}
log_success() {
echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')] SUCCESS:${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[$(date '+%Y-%m-%d %H:%M:%S')] WARNING:${NC} $1"
}
# Check if server is running
is_running() {
if [ -f "$PID_FILE" ]; then
PID=$(cat "$PID_FILE")
if ps -p $PID > /dev/null 2>&1; then
return 0
else
rm -f "$PID_FILE"
return 1
fi
fi
return 1
}
# Start server
start_server() {
log_message "Starting Knight Online Login Server..."
if is_running; then
log_warning "Login Server is already running (PID: $(cat $PID_FILE))"
return 1
fi
# Check if binary exists
if [ ! -f "$BINARY_PATH" ]; then
log_error "Binary not found: $BINARY_PATH"
log_message "Please compile the server first using: ./build.sh"
return 1
fi
# Create log directory
mkdir -p "$LOG_DIR"
# Check configuration file
if [ ! -f "./LogIn.ini" ]; then
log_warning "Configuration file LogIn.ini not found!"
log_message "Creating default configuration..."
create_default_config
fi
# Start server in background
nohup "$BINARY_PATH" > "$LOG_DIR/server_output.log" 2>&1 &
SERVER_PID=$!
# Save PID
echo $SERVER_PID > "$PID_FILE"
# Wait a moment and check if it started successfully
sleep 2
if is_running; then
log_success "Login Server started successfully (PID: $SERVER_PID)"
log_message "Server output: $LOG_DIR/server_output.log"
return 0
else
log_error "Failed to start Login Server"
return 1
fi
}
# Stop server
stop_server() {
log_message "Stopping Knight Online Login Server..."
if ! is_running; then
log_warning "Login Server is not running"
return 1
fi
PID=$(cat "$PID_FILE")
log_message "Sending SIGTERM to process $PID..."
kill -TERM $PID
# Wait for graceful shutdown
for i in {1..10}; do
if ! is_running; then
log_success "Login Server stopped successfully"
rm -f "$PID_FILE"
return 0
fi
sleep 1
done
# Force kill if necessary
log_warning "Graceful shutdown failed, forcing kill..."
kill -KILL $PID 2>/dev/null
rm -f "$PID_FILE"
log_success "Login Server forcefully stopped"
}
# Restart server
restart_server() {
log_message "Restarting Knight Online Login Server..."
stop_server
sleep 2
start_server
}
# Show server status
status_server() {
if is_running; then
PID=$(cat "$PID_FILE")
log_success "Login Server is running (PID: $PID)"
# Show some process info
echo ""
echo "Process Information:"
ps -p $PID -o pid,ppid,cmd,start,etime
# Show listening ports
echo ""
echo "Listening Ports:"
ss -tlnp | grep $PID 2>/dev/null || echo "No listening ports found"
else
log_error "Login Server is not running"
fi
}
# View logs
view_logs() {
if [ -f "$LOG_DIR/server_output.log" ]; then
tail -f "$LOG_DIR/server_output.log"
else
log_error "Log file not found: $LOG_DIR/server_output.log"
fi
}
# Create default configuration
create_default_config() {
cat > LogIn.ini << EOF
[DOWNLOAD]
URL=ftp.yoursite.net
PATH=/
[ODBC]
DSN=KO_MAIN
UID=username
PWD=password
[SETTINGS]
PORT=15100
[SERVER_LIST]
COUNT=1
SERVER_00=127.0.0.1
LANIP_00=127.0.0.1
NAME_00=Test Server
ID_00=1
GROUPID_00=1
PREMLIMIT_00=1000
FREELIMIT_00=1000
KING1_00=
KING2_00=
KINGMSG1_00=
KINGMSG2_00=
[NEWS]
TITLE_00=Welcome to Knight Online
MESSAGE_00=Welcome to our Knight Online server!
TITLE_01=
MESSAGE_01=
TITLE_02=
MESSAGE_02=
EOF
log_success "Default configuration created: LogIn.ini"
}
# Main script
case "$1" in
start)
start_server
;;
stop)
stop_server
;;
restart)
restart_server
;;
status)
status_server
;;
logs)
view_logs
;;
config)
create_default_config
;;
*)
echo "Knight Online Login Server Management Script"
echo ""
echo "Usage: $0 {start|stop|restart|status|logs|config}"
echo ""
echo "Commands:"
echo " start - Start the login server"
echo " stop - Stop the login server"
echo " restart - Restart the login server"
echo " status - Show server status"
echo " logs - View server logs (real-time)"
echo " config - Create default configuration file"
echo ""
echo "Examples:"
echo " $0 start # Start the server"
echo " $0 status # Check if server is running"
echo " $0 logs # Watch server logs"
echo ""
exit 1
;;
esac
exit $?

View File

@ -5,13 +5,19 @@ LoginServer * g_pMain;
static Condition s_hEvent;
bool g_bRunning = true;
#ifdef _WIN32
BOOL WINAPI _ConsoleHandler(DWORD dwCtrlType);
#endif
int main()
{
#ifdef _WIN32
SetConsoleTitle("Login Server Knight v" STRINGIFY(__VERSION));
// Override the console handler
SetConsoleCtrlHandler(_ConsoleHandler, TRUE);
#else
printf("Login Server Knight v%s\n", STRINGIFY(__VERSION));
#endif
HookSignals(&s_hEvent);
@ -27,7 +33,12 @@ int main()
}
else
{
#ifdef _WIN32
system("pause");
#else
printf("Press Enter to continue...");
getchar();
#endif
}
printf("Server shutting down, please wait...\n");
@ -39,6 +50,7 @@ int main()
return 0;
}
#ifdef _WIN32
BOOL WINAPI _ConsoleHandler(DWORD dwCtrlType)
{
s_hEvent.BeginSynchronized();
@ -47,3 +59,4 @@ BOOL WINAPI _ConsoleHandler(DWORD dwCtrlType)
sleep(10000); // Win7 onwards allows 10 seconds before it'll forcibly terminate
return TRUE;
}
#endif

View File

@ -11,7 +11,9 @@ void HookSignals(Condition * notifier)
signal(SIGINT, OnSignal);
signal(SIGTERM, OnSignal);
signal(SIGABRT, OnSignal);
#ifdef _WIN32
signal(SIGBREAK, OnSignal);
#endif
}
void OnSignal(int s)
@ -21,7 +23,9 @@ void OnSignal(int s)
case SIGINT:
case SIGTERM:
case SIGABRT:
#ifdef _WIN32
case SIGBREAK:
#endif
g_hNotifier->BeginSynchronized();
g_hNotifier->Signal();
g_hNotifier->EndSynchronized();
@ -36,5 +40,7 @@ void UnhookSignals()
signal(SIGINT, 0);
signal(SIGTERM, 0);
signal(SIGABRT, 0);
#ifdef _WIN32
signal(SIGBREAK, 0);
#endif
}

View File

@ -2,19 +2,49 @@
#include <queue>
#define VC_EXTRALEAN
#define WIN32_LEAN_AND_MEAN
#ifdef _WIN32
#define VC_EXTRALEAN
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <Windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#define THREADCALL WINAPI
#define STRCASECMP _stricmp
#define THREADCALL WINAPI
#define STRCASECMP _stricmp
#define I64FMT "%016I64X"
#define I64FMTD "%I64u"
#define SI64FMTD "%I64d"
#define I64FMT "%016I64X"
#define I64FMTD "%I64u"
#define SI64FMTD "%I64d"
#else
// Linux includes
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#define THREADCALL
#define STRCASECMP strcasecmp
#define Sleep(ms) usleep((ms) * 1000)
#define CreateDirectory(path, attr) mkdir(path, 0755)
#define _snprintf snprintf
#define I64FMT "%016lX"
#define I64FMTD "%lu"
#define SI64FMTD "%ld"
// Windows types for Linux
typedef int BOOL;
typedef unsigned long DWORD;
#define TRUE 1
#define FALSE 0
#endif
#if defined(_DEBUG) || defined(DEBUG)
# include <cassert>
@ -42,9 +72,11 @@
# define TRACE
#endif
// Ignore the warning "nonstandard extension used: enum '<enum name>' used in qualified name"
// Sometimes it's necessary to avoid collisions, but aside from that, specifying the enumeration helps make code intent clearer.
#pragma warning(disable: 4482)
#ifdef _WIN32
// Ignore the warning "nonstandard extension used: enum '<enum name>' used in qualified name"
// Sometimes it's necessary to avoid collisions, but aside from that, specifying the enumeration helps make code intent clearer.
#pragma warning(disable: 4482)
#endif
#define STR(str) #str
#define STRINGIFY(str) STR(str)
@ -65,7 +97,11 @@ protected:
std::recursive_mutex& target;
};
#define sleep(ms) Sleep(ms)
#ifdef _WIN32
#define sleep(ms) Sleep(ms)
#else
#define sleep(ms) usleep((ms) * 1000)
#endif
#ifdef min
#undef min

View File

@ -1,6 +1,10 @@
#pragma once
#define INLINE __forceinline
#ifdef _WIN32
#define INLINE __forceinline
#else
#define INLINE inline __attribute__((always_inline))
#endif
typedef int64_t int64;
typedef int32_t int32;