Я не писал эти серверные файлы, они являются частью проекта с открытым исходным кодом, который больше не доступен для загрузки, иначе я бы дал ссылку на страницу github.
Скрипт .nut должен создавать/изменять запись в базе данных SQL со следующей информацией:
UID: идентификатор записи
Символ: идентификатор игрока, прикрепленный к этой записи, если таковой имеется.
RelatedTo: идентификатор клана игрока, если таковой имеется.
Тип: идентификатор счетчика.
Счетчик: значение счетчика.
PreExpireType: Я не уверен на 100 %, что делает это значение.
GroupCounter: Я не уверен на 100 %, что делает это значение.
TimeStamp: Временная метка изменения счетчика.
Сценарий .nut, вызываемый системой событий сервера, выглядит следующим образом: это:
Код: Выделить всё
function define(script)
{
script.Name = "action_eventCounter";
script.Type = "ActionCustom";
return 0;
}
// Create/Modify an event counter
// - params[0]: event counter ID
// - params[1]: value to change/set counter by
// - params[2]: counter should be decreased if 1, set to params[1] if 2, flag
// mask (add) if 3, floored at value if 4
// - params[3]: Option flags, if 1 set the world counter instead, if 2 set
// current clan on RelatedTo field, if 4 retrieve value from zone character
// flag matching param 1 instead
function run(source, cState, dState, zone, server, params)
{
local syncManager = server.GetChannelSyncManager();
local worldDB = server.GetWorldDatabase();
local eCounter = null;
local characterUID = null;
local counterValue = params.len() >= 2 ? params[1].tointeger() : 1;
if(params.len() >= 4 && (params[3].tointeger() & 4) != 0)
{
if(cState == null || zone == null)
{
return Result_t.FAIL;
}
counterValue = zone.GetFlagState(counterValue, 0, cState.GetWorldCID());
}
if(params.len() >= 4 && (params[3].tointeger() & 1) != 0)
{
// Use world counter
eCounter = syncManager.GetWorldEventCounter(params[0].tointeger());
characterUID = UUID();
}
else
{
// Use character counter
local character = cState != null ? cState.GetEntity() : null;
if(character == null)
{
return Result_t.FAIL;
}
eCounter = cState.GetEventCounter(params[0].tointeger(), true);
characterUID = character.GetUUID();
}
if(params.len() == 3)
{
if(params[2].tointeger() == 1)
{
// Decrease
counterValue = counterValue * -1;
}
else if(params[2].tointeger() == 3)
{
// Flag mask (add)
counterValue = 1 = 4 && (params[3].tointeger() & 2) != 0)
{
local character = cState != null ? cState.GetEntity() : null;
local clan = character != null ? character.GetClan().Get() : null;
if(clan != null)
{
relatedTo = clan.GetUUID();
}
}
if(!eCounter || eCounter.GetUUID().IsNull())
{
if(!eCounter)
{
eCounter = EventCounter();
eCounter.SetCharacter(characterUID);
eCounter.SetType(params[0].tointeger());
}
eCounter.SetCounter(counterValue);
eCounter.SetRelatedTo(relatedTo);
if(!PersistentObject.Register(eCounter, UUID()) || !eCounter.Insert(worldDB))
{
return Result_t.FAIL;
}
}
else
{
if(params.len() == 3 && params[2].tointeger() == 2)
{
// Setting
}
else if(params.len() == 3 && params[2].tointeger() == 3)
{
// Flag mask (add)
counterValue = eCounter.GetCounter() | counterValue;
}
else if(params.len() == 3 && params[2].tointeger() == 4)
{
// Flooring
counterValue = eCounter.GetCounter() > counterValue
? eCounter.GetCounter() : counterValue;
}
else
{
// Adding
counterValue = eCounter.GetCounter() + counterValue;
}
if(eCounter.GetCounter() == counterValue &&
eCounter.GetRelatedTo() == relatedTo)
{
// Nothing to do
return Result_t.SUCCESS;
}
eCounter.SetCounter(counterValue);
eCounter.SetRelatedTo(relatedTo);
if(!eCounter.Update(worldDB))
{
return Result_t.FAIL;
}
}
syncManager.UpdateRecord(eCounter, "EventCounter");
syncManager.SyncOutgoing();
return Result_t.SUCCESS;
}
params[0]: идентификатор счетчика
params[1]: значение счетчика
params[2]: перечисление, независимо от того, добавляем ли мы, устанавливаем или вычитаем значение params[1] из счетчика.
params[3]: перечисление, некоторые параметры - в основном, является ли этот счетчик частью мира или прикреплен к игроку и/или его клану.
Проблема:
Когда я пытаюсь вызвать этот скрипт с параметром params[3] установленным в 1, что-то происходит в скрипте с ошибкой и параметры не передаются правильно в базу данных SQL:
action_eventCounter(-101, 1, 2, 1) приводит к тому, что запись в базе данных выглядит следующим образом:
UID
Символ
RelatedTo
Тип
Счетчик
PreExpireType
GroupCounter
TimeStamp
b6e0c504-6705-4414-8ca1-6c8768bac167
00000000-0000-0000-0000-000000000000
00000000-0000-0000-0000-000000000000
-101
0
0
0
0
Character и RelatedTo ожидаются как строки со значением 0. Однако все значения после -101 в конечном итоге равны 0, что заставляет меня думать, что сценарий завершается раньше, когда Для параметра params[3] установлено значение 1. Ожидаемое поведение в этом случае — для Counter иметь значение 1, а для TimeStamp иметь целое число, представляющее время сервера.
Это поведение работает правильно, когда для params[3] установлено значение 0 - что заставляет меня думать, что сценарий каким-то образом не работает, когда params[3] равен 1.
Что я пробовал:
Я пробовал использовать AgentRansack для поиска связанного кода в исходном коде. Однако я не могу сузить проблему и признаю, что я недостаточно хорош как программист, чтобы определить причину проблемы.
В начале сценария .nut он ссылается на syncManager и worldDB. Возможно, что-то идет не так в функциях, вызываемых в других скриптах, но сначала я проверяю, есть ли что-то не так со скриптом .nut, что может привести к неправильной передаче значений.
Подробнее здесь: https://stackoverflow.com/questions/798 ... cript-is-s
Мобильная версия