SA-MP (San Andreas Multiplayer) Software Development Kit (SDK) представляет собой комплексную коллекцию C-файлов и headers, которые позволяют разработчикам создавать плагины для сервера SA-MP. Этот SDK предоставляет основу для расширения функциональности сервера SA-MP через нативные функции, позволяя разработчикам реализовывать функции, выходящие за рамки того, что доступно в скриптах Pawn.
- Português: README
- Deutsch: README
- English: README
- Español: README
- Français: README
- Italiano: README
- Polski: README
- Svenska: README
- Türkçe: README
- SA-MP SDK
AMX (Abstract Machine eXecutor) - это виртуальная машина, которая выполняет скрипты Pawn в SA-MP. SDK предоставляет обширную поддержку для взаимодействия с AMX через различные C-файлы и headers:
-
amx.h
Основной header-файл, который объединяет всю функциональность, связанную с AMX. Включает:
- Основные функции AMX для выполнения скриптов
- Управление памятью
- Регистрация нативных функций
- Обработка строк
- Поддержка UTF-8
Ключевые функции включают:
int AMXAPI amx_Init(AMX* amx, void* program); int AMXAPI amx_Exec(AMX* amx, cell* retval, int index); int AMXAPI amx_Register(AMX* amx, const AMX_NATIVE_INFO* nativelist, int number);
-
amx_cell.h
Определяет фундаментальные типы данных, используемые в системе AMX:
#if PAWN_CELL_SIZE==32 typedef uint32_t ucell; typedef int32_t cell; #elif PAWN_CELL_SIZE==64 typedef uint64_t ucell; typedef int64_t cell; #endif
-
amx_structures.h
Содержит основные структуры для работы AMX:
typedef struct tagAMX { unsigned char _FAR *base; // Базовый адрес unsigned char _FAR *data; // Сегмент данных AMX_CALLBACK callback; // Функция обратного вызова AMX_DEBUG debug; // Отладочный callback cell cip; // Указатель инструкции кода cell frm; // База кадра стека cell hea; // База кучи cell stk; // Указатель стека // ... дополнительные поля } AMX;
SDK включает надежную обработку специфики платформ через различные headers:
-
amx_platform.h
Обеспечивает определение платформы и конфигурацию:
#if (defined __linux || defined __linux__) && !defined __LINUX__ #define __LINUX__ #endif #if defined FREEBSD && !defined __FreeBSD__ #define __FreeBSD__ #endif
-
osdefs.h
Обрабатывает определения, специфичные для операционной системы:
#if defined(__WATCOMC__) #if defined(__WINDOWS__) || defined(__NT__) #define _Windows 1 #endif #ifdef __386__ #define __32BIT__ 1 #endif #endif
Определяет основной интерфейс плагина и вспомогательные структуры:
#define SAMP_PLUGIN_VERSION 0x0200
enum SUPPORTS_FLAGS {
SUPPORTS_VERSION = SAMP_PLUGIN_VERSION,
SUPPORTS_VERSION_MASK = 0xffff,
SUPPORTS_AMX_NATIVES = 0x10000
};
enum PLUGIN_DATA_TYPE {
PLUGIN_DATA_LOGPRINTF = 0x00,
PLUGIN_DATA_AMX_EXPORTS = 0x10,
PLUGIN_DATA_CALLPUBLIC_FS = 0x11,
PLUGIN_DATA_CALLPUBLIC_GM = 0x12
};
Файл amxplugin.c
является важным компонентом SA-MP SDK, который предоставляет платформо-зависимые реализации функций AMX. Он реализует два различных подхода в зависимости от платформы и компилятора:
-
Реализация для Windows MSVC (32-bit)
- Использует naked функции с ассемблером для прямого доступа к таблице функций
- Обеспечивает оптимизированную производительность через прямые переходы к функциям AMX
- Пример структуры:
#define NUDE __declspec(naked) #define AMX_JUMP_HELPER(index) { _asm { mov eax, pAMXFunctions } _asm { jmp dword ptr[eax + index * 4] } }
-
Кросс-платформенная реализация
- Использует указатели на функции для платформенной независимости
- Реализует систему, основанную на макросах, для определения функций
- Пример структуры:
#define DEFINE_AMX_FN_TYPE(name, ret_type, ...) \ typedef ret_type AMXAPI (*name##_t)(__VA_ARGS__); \ ret_type AMXAPI name(__VA_ARGS__) { \ name##_t fn = ((name##_t*)pAMXFunctions)[PLUGIN_AMX_EXPORT_##name]; \ return fn(__VA_ARGS__); \ }
Ключевые особенности:
-
Управление таблицей функций
- Использует статический указатель
pAMXFunctions
для хранения таблицы функций AMX - Обеспечивает доступ ко всем основным функциям AMX
- Обрабатывает разрешение функций во время выполнения
- Использует статический указатель
-
Платформо-специфичные оптимизации
- Windows 32-bit: Использует naked функции для прямой реализации на ассемблере
- Другие платформы: Использует косвенные указатели на функции
- Специальная обработка для 64-битных систем
-
Реализованные категории функций
a. Функции управления памятью:
amx_Align16
,amx_Align32
,amx_Align64
amx_Allot
,amx_Release
b. Функции выполнения:
amx_Exec
,amx_Callback
amx_Init
,amx_InitJIT
amx_Cleanup
,amx_Clone
c. Управление символами:
amx_FindPublic
,amx_FindPubVar
amx_FindNative
,amx_FindTagId
amx_GetPublic
,amx_GetPubVar
d. Обработка строк:
amx_GetString
,amx_SetString
amx_StrLen
- Функции поддержки UTF-8
e. Отладка и информация:
amx_SetDebugHook
amx_Flags
,amx_MemInfo
amx_NameLength
-
Условная компиляция
- Обрабатывает различные платформы через директивы препроцессора
- Специальная обработка для 64-битных систем
- Опциональная поддержка JIT
#if defined _I64_MAX || defined HAVE_I64 DEFINE_AMX_NAKED_FN(uint64_t* AMXAPI amx_Align64(uint64_t* v), PLUGIN_AMX_EXPORT_Align64) #endif
-
Интеграция обработки ошибок
- Реализует
amx_RaiseError
для отчетов об ошибках - Сохраняет коды ошибок между вызовами функций
- Интегрируется с системой отладки AMX
- Реализует
SDK предоставляет комплексную поддержку для создания и управления нативными функциями:
typedef cell (AMX_NATIVE_CALL *AMX_NATIVE)(struct tagAMX *amx, const cell *params);
typedef struct tagAMX_NATIVE_INFO {
const char _FAR *name;
AMX_NATIVE func;
} AMX_NATIVE_INFO;
Ключевые операции с нативными функциями:
- Регистрация через
amx_Register
- Доступ к параметрам и валидация
- Обработка возвращаемых значений
- Отчеты об ошибках
SDK предоставляет комплексные средства управления памятью:
-
amx_memory.h
Обрабатывает выделение памяти и платформо-зависимые операции с памятью:
#if defined HAVE_ALLOCA_H #include <alloca.h> #elif defined __BORLANDC__ #include <malloc.h> #endif
-
amx_alignment.h
Управляет требованиями выравнивания памяти:
#if (defined SN_TARGET_PS2 || defined __GNUC__) && !defined AMX_NO_ALIGN #define AMX_NO_ALIGN #endif
SDK включает несколько функций для манипуляции памятью:
-
Выделение памяти
int AMXAPI amx_Allot(AMX* amx, int cells, cell* amx_addr, cell** phys_addr);
- Выделяет память в куче AMX
- Возвращает как AMX, так и физические адреса
- Обрабатывает требования выравнивания
-
Доступ к памяти
int AMXAPI amx_GetAddr(AMX* amx, cell amx_addr, cell** phys_addr);
- Преобразует AMX адреса в физические адреса
- Проверяет доступ к памяти
- Обрабатывает границы памяти
-
Информация о памяти
int AMXAPI amx_MemInfo(AMX* amx, long* codesize, long* datasize, long* stackheap);
- Получает информацию о размещении памяти
- Сообщает размеры сегментов
- Полезно для отладки и оптимизации
SDK включает комплексную систему обработки ошибок, определенную в amx_constants.h
:
enum {
AMX_ERR_NONE,
AMX_ERR_EXIT,
AMX_ERR_ASSERT,
AMX_ERR_STACKERR,
AMX_ERR_BOUNDS,
AMX_ERR_MEMACCESS,
AMX_ERR_INVINSTR,
AMX_ERR_STACKLOW,
AMX_ERR_HEAPLOW,
AMX_ERR_CALLBACK,
AMX_ERR_NATIVE,
AMX_ERR_DIVIDE,
AMX_ERR_SLEEP,
AMX_ERR_INVSTATE,
AMX_ERR_MEMORY = 16,
AMX_ERR_FORMAT,
AMX_ERR_VERSION,
AMX_ERR_NOTFOUND,
AMX_ERR_INDEX,
AMX_ERR_DEBUG,
AMX_ERR_INIT,
AMX_ERR_USERDATA,
AMX_ERR_INIT_JIT,
AMX_ERR_PARAMS,
AMX_ERR_DOMAIN,
AMX_ERR_GENERAL,
};
SDK предоставляет надежные возможности обработки строк через различные макросы и функции:
#define amx_StrParam(amx,param,result) \
do { \
int result##_length_; \
amx_StrLen(amx_Address(amx,param),&result##_length_); \
if (result##_length_>0 && \
((result)=(type)alloca((result##_length_+1)*sizeof(*(result))))!=NULL) \
amx_GetString((char*)(result),amx_Address(amx,param), \
sizeof(*(result))>1,result##_length_+1); \
else (result)=NULL; \
} while(0)
-
Длина строки
int AMXAPI amx_StrLen(const cell* cstring, int* length);
- Вычисляет длину строки
- Обрабатывает упакованные и неупакованные строки
- Возвращает длину в символах
-
Преобразование строк
int AMXAPI amx_SetString(cell* dest, const char* source, int pack, int use_wchar, size_t size);
- Преобразует C-строки в AMX-строки
- Поддерживает упакованные и неупакованные форматы
- Обрабатывает преобразование Unicode
SDK включает комплексную поддержку Unicode через функции обработки UTF-8:
int AMXAPI amx_UTF8Check(const char* string, int* length);
int AMXAPI amx_UTF8Get(const char* string, const char** endptr, cell* value);
int AMXAPI amx_UTF8Len(const cell* cstr, int* length);
int AMXAPI amx_UTF8Put(char* string, char** endptr, int maxchars, cell value);
-
Проверка UTF-8
int AMXAPI amx_UTF8Check(const char* string, int* length);
- Проверяет UTF-8 кодированные строки
- Сообщает длину строки в символах
- Обнаруживает ошибки кодирования
-
Преобразование символов
int AMXAPI amx_UTF8Get(const char* string, const char** endptr, cell* value);
- Извлекает Unicode символы
- Обрабатывает многобайтовые последовательности
- Сообщает об ошибках разбора
SDK обеспечивает кросс-платформенную совместимость через:
-
Обработка порядка байтов
#ifndef BYTE_ORDER #if defined(UCLINUX) #define BYTE_ORDER BIG_ENDIAN #else #define BYTE_ORDER LITTLE_ENDIAN #endif #endif
-
Обработка путей
#if defined(__MSDOS__) || defined(__WIN32__) || defined(_Windows) #define DIRSEP_CHAR '\\' #elif defined(macintosh) #define DIRSEP_CHAR ':' #else #define DIRSEP_CHAR '/' #endif
SDK поддерживает несколько платформ и компиляторов:
- Windows (MSVC, MinGW)
- Linux (GCC)
- FreeBSD
- OpenBSD
- macOS
-
Microsoft Visual C++
- Обработка pragma
- Подавление предупреждений
- Соглашения о вызовах
-
GCC
- Управление диагностикой
- Спецификации атрибутов
- Платформо-специфичные оптимизации
-
Clang
- Конфигурации предупреждений
- Кросс-платформенная совместимость
- Современные функции C++
При использовании SA-MP SDK учитывайте следующие лучшие практики:
-
Управление памятью
- Всегда очищайте выделенные ресурсы
- Используйте правильное выравнивание памяти
- Корректно обрабатывайте ошибки памяти
- Отслеживайте использование кучи
- Реализуйте правильную проверку границ памяти
- Используйте пулы памяти для частых выделений
- Очищайте ресурсы в обратном порядке выделения
-
Обработка ошибок
- Проверяйте возвращаемые значения функций AMX
- Реализуйте правильную обработку ошибок в нативных функциях
- Используйте предоставленные константы ошибок
- Корректно логируйте ошибки
- Реализуйте механизмы восстановления после ошибок
- Предоставляйте осмысленные сообщения об ошибках
- Обрабатывайте системно-специфичные ошибки
-
Кросс-платформенная разработка
- Используйте платформо-независимые типы
- Используйте предоставленные макросы для платформо-специфичного кода
- Тестируйте на нескольких платформах
- Обрабатывайте различия в порядке байтов
- Используйте правильные разделители путей
- Учитывайте различия файловых систем
- Реализуйте платформо-специфичные оптимизации
-
Соображения производительности
- Используйте подходящие размеры ячеек
- Реализуйте эффективную обработку строк
- Оптимизируйте вызовы нативных функций
- Минимизируйте выделения памяти
- Используйте подходящие структуры данных
- Реализуйте кэширование где уместно
- Профилируйте критические пути кода
При работе с функционалом amxplugin.c
:
-
Платформо-специфичная разработка
- Учитывайте различия платформ в реализациях функций
- Тестируйте на 32-битных и 64-битных системах
- Обрабатывайте платформо-специфичные требования выравнивания
- Проверяйте указатель таблицы функций перед использованием
- Реализуйте соответствующую проверку ошибок для каждой платформы
- Учитывайте влияние различных реализаций на производительность
-
Управление таблицей функций
- Инициализируйте таблицу функций перед использованием
- Проверяйте доступность функций
- Корректно обрабатывайте отсутствующие функции
- Реализуйте правильные процедуры очистки
- Кэшируйте часто используемые указатели на функции
- Проверяйте целостность таблицы функций
-
Обработка ошибок
- Реализуйте правильную проверку ошибок для платформо-специфичного кода
- Корректно обрабатывайте ошибки выравнивания
- Проверяйте записи таблицы функций
- Предоставляйте осмысленные сообщения об ошибках
- Реализуйте механизмы восстановления
- Логируйте платформо-специфичные ошибки
typedef struct tagAMX_HEADER {
int32_t size; // Размер "файла"
uint16_t magic; // Сигнатура
char file_version; // Версия формата файла
char amx_version; // Требуемая версия AMX
int16_t flags; // Флаги
int16_t defsize; // Размер записи определения
int32_t cod; // Начальное значение COD - блок кода
int32_t dat; // Начальное значение DAT - блок данных
int32_t hea; // Начальное значение HEA - начало кучи
int32_t stp; // Начальное значение STP - вершина стека
int32_t cip; // Начальное значение CIP - указатель инструкции кода
int32_t publics; // Смещение до публичных функций
int32_t natives; // Смещение до таблицы нативных функций
int32_t libraries; // Смещение до библиотек
int32_t pubvars; // Смещение до публичных переменных
int32_t tags; // Смещение до тегов
int32_t nametable; // Смещение до таблицы имен
} AMX_HEADER;
Эта структура критически важна для понимания формата файла AMX и того, как виртуальная машина загружает и выполняет скрипты.
SDK включает поддержку Just-In-Time компиляции:
int AMXAPI amx_InitJIT(AMX* amx, void* reloc_table, void* native_code);
Поддержка отладки предоставляется через:
typedef int (AMXAPI *AMX_DEBUG)(struct tagAMX *amx);
int AMXAPI amx_SetDebugHook(AMX* amx, AMX_DEBUG debug);
SDK предоставляет комплексную поддержку для работы с публичными функциями:
-
Поиск публичных функций
int AMXAPI amx_FindPublic(AMX* amx, const char* funcname, int* index);
- Находит публичные функции по имени
- Возвращает индекс функции
- Проверяет существование функции
-
Выполнение публичных функций
int AMXAPI amx_Exec(AMX* amx, cell* retval, int index);
- Выполняет публичные функции
- Обрабатывает возвращаемые значения
- Управляет контекстом выполнения
SDK включает константы версий для проверки совместимости:
#define CUR_FILE_VERSION 9
#define MIN_FILE_VERSION 6
#define MIN_AMX_VERSION 10
#define MAX_FILE_VER_JIT 8
#define MIN_AMX_VER_JIT 8
SDK поддерживает совместимость через:
- Проверку версии файла
- Проверку версии AMX
- Проверку совместимости JIT
- Определение функций
- Обработку версий для конкретных платформ