RakCloud является облачным сервисом, поэтому запуск ботов и хранение данных происходят на наших серверах. Для загрузки файлов используется FTP, а для управления клиент.
В комплект каждого бот-сервера входит:
Важно понимать, что далее в документации все функции, связанные с SA-MP, могут использоваться только в скриптах для бота, так как менеджер не имеет функционала для работы с SA-MP сервером. А скрипты для ботов в свою очередь, не могут использовать функционал, имеющийся в менеджере.
Основной средой разработки является редактор кода Visual Studio Code (VSC), но вы можете использовать любой другой. Для удобства работы рекомендуется установить следующие дополнения:
Для загрузки файлов по FTP, вам потребуется любой FTP-клиент, например FileZilla.
Для удобства разработки, вы можете использовать расширение для своего редактора (при наличии) для синхронизации файлов на локальном компьютере и сервере.
В качестве примера, рассмотрим настройку расширения для VSC, о котром говорилось чуть ранее.
После того как вы установили расширение, выполните следующие действия:
Ctrl
+ Shift
+ P
(или F1
).host
, port
, username
, password
. В поле name
указывайте удобное для вас именование. Если у вас несколько FTP серверов, указывайте их через запятую в главной секции, подробнее смотрите на странице расширения.[
{
"name": "RakCloud",
"host": "",
"port": 21,
"type": "ftp",
"username": "",
"password": "",
"path": "/RakCloud/",
"autosave": true,
"confirm": true,
"secure": true,
"secureOptions": {
"rejectUnauthorized": false,
"secureProtocol": "TLSv1_2_method"
}
}
]
Для открытия директории FTP сервера, вновь нажмите Ctrl
+ Shift
+ P
(или F1
) и выберите "ftp-simple Remote directory open to workspace.".
RakCloud
├───bot
│ ├───data
│ ├───libs
│ ├───logs
│ └───scripts
├───manager
│ ├───data
│ ├───libs
│ ├───logs
│ └───scripts
└───shared
├───data
└───libs
Из названий директорий достаточно очевидно их предназначение:
bot
— Содержит данные RakCloudBot'ов.manager
— Содержит данные RakCloudManager'а.shared
— Содержит общие данные.data
— Предназначена для данных скриптов.libs
— Предназначена для ваших библиотек.logs
— Содержит логи с названием файла составленным из даты и времени запуска в формате name_17-03-2021_16-30-05.log
.scripts
— Предназначена для Lua скриптов имеющих расширение .lua
.Для написания скриптов используется язык программирования Lua, знание основ которого обязательно для дальнейшей работы. Поскольку Lua очень популярен в среде разработки игр и других сферах, по нему достаточно учебных материалов. Ниже приведено несколько ресурсов, позволяющих изучить Lua.
Глобальная область — это основное тело скрипта, то есть всё, что находится вне функций. В основном глобальная область используется для объявления каких-либо глобальных переменных и функций. Она выступает первым этапом загрузки скрипта, код из неё выполняется один раз после загрузки скрипта и не может быть приостановлен.
main
— Основная функция любого скрипта, в котором и происходит основная работа. В отличие от глобальной области, запускается как кооперативный поток после инициализации и загрузки всех скриптов. По завершению, скрипт завершает свою работу и выгружается, если в нём нет активных кооперативных потоков и зарегистрированных событий.
Пример: Раз в 5 секунд выводит в лог текст I'm alive.
function main()
print("Hello World!") -- Выполняется один раз при запуске.
while true do -- Бесконечный цикл.
wait(5000) -- Ждём 5 секунд.
print("I'm alive!") -- Выводим текст в лог.
end
end
С помощью создания кооперативных потоков становится возможным использование задержек, позволяющих приостанавливать исполнение кода на указанное количество миллисекунд. Более подробная информация.
Учтите, что обязательным условием для каждого бесконечного цикла является использование функции wait хотя бы с нулевой задержкой, чтобы предотвратить блокировку планировщика.
Обработчиками событий являются функции, которые вызываются в скриптах автоматически при определенных условиях.
Они могут иметь входящие и возвращаемые параметры: входящие передают информацию скрипту, а возвращаемые позволяют повлиять на дальнейшую обработку после совершения события.
Зарегистрировать обработчик события можно с помощью функции/метода on
в классе/объекте, к которому вы хотите прикрепить обработчик.
Скрипты с зарегистрированными событиями не завершаются самостоятельно.
Пример: playerDeath
— вызывается при смерти любого игрока на SA-MP сервере.
samp.on("playerDeath", function(playerId)
printf("Игрок с ID %d умер.", playerId)
end)
Внутри обработчиков событий нельзя использовать задержки, поскольку вызов события требует немедленного возвращения результата из функции обработчика. Для обхода этого ограничения можно создать кооперативный поток.
Узнать подробнее о системе событий и ознакомиться со списком всех встроенных событий можно на данной странице.
Боты могут посылать менеджеру или друг другу сообщения с помощью IPC.
Пример: Бот сообщает менеджеру, что с сервера вышел админ и пора запустить еще одного бота.
Скрипт для бота:
samp.on("playerQuit", function(playerId, reason)
local player = samp.getPlayer(playerId) -- Получаем игрока из пула по его ID.
if player:getNickName() == "Vladimir_Putin" then
-- С сервера вышел главный админ, сообщаем менеджеру запустить остальных ботов.
ipc.send("GuysTheAdminIsOutItsTimeToWork")
end
end)
Скрипт для менеджера:
ipc.on("GuysTheAdminIsOutItsTimeToWork", function()
print("It's time to work.")
local bot = SampBot.new("TurboBot") -- Создаем нового бота.
bot:start() -- Запускаем его.
end)
При разработке я придерживался мнения, что ядро бота не должно отравлять на сервер что-то, что не очевидно в скриптах. Единственным исключением из этого правила стали пакеты необходимые для начального входа на сервер, но и их можно перехватить с помощью системы событий. Все остальное нужно отправлять самостоятельно, в частности и пакеты синхронизации.
-- Отправляем пакеты согласно частоте который отправит нам сервер в событии InitGame, смотреть ниже.
local netModeNormalOnfootSendRate = 40
local netModeNormalIncarSendRate = 40
function main()
while true do
if samp.isBotConnected() and samp.isBotSpawned() then -- Если бот подключен и заспавнен.
if samp.isBotOnFoot() then -- Если бот на ногах.
samp.sendOnFootData()
wait(netModeNormalOnfootSendRate)
elseif samp.isBotDrivingVehicle() then -- Если бот управляет транспортом.
samp.sendInCarData()
wait(netModeNormalIncarSendRate)
elseif samp.isBotSitsAsPassenger() then -- Если бот является пассажиром транспорта.
samp.sendPassengerData()
wait(netModeNormalIncarSendRate)
else
wait(0)
end
else
wait(0)
end
end
end
samp.on("initGame", function(serverInfo)
-- Меняем частоту отправки пакетов синхронизации на ту, что требует сервер.
netModeNormalOnfootSendRate = serverInfo.netModeNormalOnfootSendRate
netModeNormalIncarSendRate = serverInfo.netModeNormalIncarSendRate
end)
Для управления используется кроссплатформенный клиент который уже доступен на операционных системах Windows и Linux с архитектурами x86 и x64. Также возможно собрать под macOS. Исходный код клиента опубликован на GitHub. В дальнейшем также возможно появление веб-клиента.