Город Мастеров
IPB

Здравствуйте, гость ( Вход | Регистрация )

 Правила этого форума ПРАВИЛА РАЗДЕЛА
 
Ответить в эту темуОткрыть новую тему
> Очищение шарда от мусора
Vanes
сообщение Jan 4 2008, 23:32
Сообщение #1


Level 11
Иконки Групп

Класс: Вор
Характер: Neutral Evil
Раса: Эльф
NWN: Скриптинг [PW]
Validor2



возможно где-то такое уже предлагалось, но я, честно говоря, такие вещи искать не привык - проще самому написать (IMG:style_emoticons/kolobok_light/smile.gif)

в общем в процессе переписывания старых скриптов под нужны нового модуля обратил внимание на убогость своей системы очищения шарда от ненужного шмота (а вместе с ним и лишних лагов (IMG:style_emoticons/kolobok_light/smile.gif) )...
суть задачи: на шарде по локам появляются вещи (лут из мобов и игроков, просто выкинутые шмотки), которые нужно удалять... у каждой шмотки есть параметр - время через которое она должна быть удалена... нужно написать скрипт и засунуть его в такое место, чтобы результат и время выполнения скрипта были наиболее оптимальными...

как пример, я рассматривал такой вариант: харбит локи, который собирает итемы + отдельные харбиты на каждом лутбеге... хотелось лучше (IMG:style_emoticons/kolobok_light/smile.gif)

придумал я вот что...
при создании каждого лутбега или в момент выкидывания игроком шмотки на землю на эти объекты создается своего рода ссылка... а именно - вейпоинты в отдельной локации, на которых хранитятся данные по этому объекту... само собой в локе есть харбит, которые по очереди эти вейпоинты чекает...
т.е. в итоге вместо кучи харбитов получаем один...
с одной стороны, за одним харбитом и следить проще... да к тому же время у меня из внешней бд запрашивается - а одно обращение в 10 сек к БД, это все таки не 100...
с другой, время выполнения скрипта понятно что дольше, да и не понятно вообще насколько все это оптимальней получается (IMG:style_emoticons/kolobok_light/smile.gif)

если кто что может подсказать по сути вопроса - буду рад...
ну или может кто свои системы писал...

собственно скрипты:

процедура, которая создает вейпоинт-ссылку
Neverwinter Script Source

void CreateGarbageLink( object oObject, int nDestroyTime )
{
    object oItem = CreateObject( OBJECT_TYPE_WAYPOINT, GARBAGE_WP, GetLocation( GetObjectByTag( GARBAGE_LOCATION )) );
    SetLocalObject( oObject, "oGarbageLink", oItem );
    SetLocalObject( oItem, "oGarbageItem", oObject );
    if( nDestroyTime>235900 ) nDestroyTime = 235900; // новый день
    SetLocalInt( oItem, "nDestroyTime", nDestroyTime );
}


харбит локи
Neverwinter Script Source

void main( )
{
    int nCurrentTime = GetTime( );
    int nDestroyTime;
    object oGarbageItem;
    int nDebugI = 0;

    object oWP = GetFirstObjectInArea( );
    while( oWP!=OBJECT_INVALID && nDebugI<300 ){
        nDestroyTime = GetLocalInt( oWP, "nDestroyTime" );
        if( nDestroyTime>=0 ){ // если нет переменной nDestroyTime, значит это не GARBAGE_WP
            if( nDebugI>250 ){ // если мусора больше 250 вещей - удаляем все подряд
                oGarbageItem = GetLocalObject( oWP, "oGarbageItem" );           
                DeleteLocalObject( oGarbageItem, "oGarbageLink" );
                DestroyObject( oGarbageItem );
                DeleteLocalObject( oWP, "oGarbageItem" );
                DeleteLocalInt( oWP, "nDestroyTime" );
                DestroyObject( oWP );       
            }else if( nDebugI>150 ){ // если мусора больше 150 вещей - удаляем итемы ( лутпаки не трогаем )
                oGarbageItem = GetLocalObject( oWP, "oGarbageItem" );
                if( GetObjectType( oGarbageItem )==OBJECT_TYPE_ITEM ){
                    DeleteLocalObject( oGarbageItem, "oGarbageLink" );
                    DestroyObject( oGarbageItem );
                    DeleteLocalObject( oWP, "oGarbageItem" );
                    DeleteLocalInt( oWP, "nDestroyTime" );
                    DestroyObject( oWP );                   
                }
            }else if( nDestroyTime<=nCurrentTime ){
                oGarbageItem = GetLocalObject( oWP, "oGarbageItem" );           
                DeleteLocalObject( oGarbageItem, "oGarbageLink" );
                DestroyObject( oGarbageItem );
                DeleteLocalObject( oWP, "oGarbageItem" );
                DeleteLocalInt( oWP, "nDestroyTime" );
                DestroyObject( oWP );
            }
        }
        oWP = GetNextObjectInArea( );
        nDebugI++;
    }
}


скрипт на OnUnacquire модуля
Neverwinter Script Source

void main( )
{
    object oItem = GetModuleItemLost( );
    object oPC = GetModuleItemLostBy( );
    object oNewOwner = GetItemPossessor( oItem );   
   
    // проверяем только вещи игроков + вещь должна быть именно выложена, а не удалена
    if( GetIsPC( oPC ) && oItem!=OBJECT_INVALID && oNewOwner==OBJECT_INVALID ){
        int nCurrentTime = GetTime( );
        CreateGarbageLink( oItem, nCurrentTime+GARBAGE_DESTROY_DELAY );       
    }
}


скрипт на Acquire модуля (ну и по сути теже команды выполняются на скрипте OnDisturb лутбега, когда из него вытаскивают последнюю шмотку)
Neverwinter Script Source

void main( )
{
    object oItem = GetModuleItemAcquired( );

    object oGarbageLink = GetLocalObject( oItem, "oGarbageLink" );
    if( oGarbageLink!=OBJECT_INVALID ){
        DeleteLocalObject( oItem, "oGarbageLink" );
        DeleteLocalObject( oGarbageLink, "oGarbageItem" );
        DeleteLocalInt( oGarbageLink, "nDestroyTime" );
        DestroyObject( oGarbageLink );                   
    }
}
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Lex
сообщение Jan 5 2008, 00:15
Сообщение #2


Level 5
Иконки Групп

Класс: Обыватель
Характер: Lawful Neutral
Раса: Человек
NWN: Модмейкер
Проклятие Левора
Порядок Времени



Цитата(Vanes @ Jan 4 2008, 23:32) *
придумал я вот что...
при создании каждого лутбега или в момент выкидывания игроком шмотки на землю на эти объекты создается своего рода ссылка... а именно - вейпоинты в отдельной локации, на которых хранитятся данные по этому объекту... само собой в локе есть харбит, которые по очереди эти вейпоинты чекает...
т.е. в итоге вместо кучи харбитов получаем один...

а что мешало при создании лутбега его запоминать (SetLocalObject) на какой-нить сторонний объект-анализатор (им у тебя локация выступает) и в ХБ этого объекта бешать по списку запомненных лутбегов? (попутно подчищая список, если какой-то лутбег перестал быть валидным). Или хранение так объекто - нагрузка для сервера?

ну или если влом подчищать - просто освобождать ячейку, чтобы следующий лутбег писался в нее, а не Количество Ячеек + 1.
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Vanes
сообщение Jan 5 2008, 00:44
Сообщение #3


Level 11
Иконки Групп

Класс: Вор
Характер: Neutral Evil
Раса: Эльф
NWN: Скриптинг [PW]
Validor2



использование локи (как вариант еще был инвентарь нпц) удобен тем, что есть команды GetFirstObject/GetFirstItem... т.е. стек по сути формируется автоматически... с инвентарем сложнее, а вот при создании нового объекта в локе он добавляется в стек LIFO, так что я точно уверен где те объекты, которые надо удалить в первую очередь...
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Edwin
сообщение Jan 5 2008, 03:45
Сообщение #4


Level 3
*

Класс: Обыватель
Характер: Chaotic Evil
Раса: Человек



Я не видел нвн 2-3 года, предупреждаю.

Но как мне кажется все это излишне. Сделать можно намного проще.
Создаем очередь FIFO через simply linked lists. При падении обьекта, добавляем в очередь поинтер на обьект.
Задаем максимальную длинну очереди либо константу (скажем 50-70) в зависимости от популярности шарда, либо делаем длинну динамичной, прямопропорциональной кол-ву игроков онлайн (скажем 5-20 лежащих объектов на 1го игрока, ну и тогда меняем длинну на онЕнтер игроков или как там...)
Соответственно когда упавших объектов на шарде становится больше заданого числа, самые старые объекты которые лежат уже несколько минут мы начинаем удалять. Что бы моментально доставать последний элемент, можно все это закодить через doubly linked circular lists, если хочешь.
Если обьект вовремя подобран - находим в очереди и удаляем поинтер. Чаще всего он будет в самом начале листа.
Все просто.

Кодится немножко дольше, зато оптимальнее, на мой взгляд, раз в сто.

Сообщение отредактировал Edwin - Jan 5 2008, 04:24
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Vanes
сообщение Jan 5 2008, 04:10
Сообщение #5


Level 11
Иконки Групп

Класс: Вор
Характер: Neutral Evil
Раса: Эльф
NWN: Скриптинг [PW]
Validor2



Цитата
Создаем очередь типа FIFO через simply linked lists. При падении обьекта, добавляем в очередь поинтер на обьект... Кодится немножко дольше, зато оптимальнее, на мой взгляд, раз в сто...

согласен
другое дело, что это нужно кодить (IMG:style_emoticons/kolobok_light/smile.gif)
да и речь идет, боюсь, не о 50-70, а скорее о 200-300 объектах... в этом плане я по крайней мере уверен, что локация столько объектов выдержит...

Добавлено через 2 минуты 9 секунд

Цитата
через doubly linked circular lists

вопрос - чем это реализовывать в тулсете ??? локалками ???
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Edwin
сообщение Jan 5 2008, 04:37
Сообщение #6


Level 3
*

Класс: Обыватель
Характер: Chaotic Evil
Раса: Человек



QUOTE
вопрос - чем это реализовывать в тулсете ??? локалками ???

Я не уверен что правильно понимаю вопрос, т.к. тулсет в глаза не видел.

Но если я его понимаю правильно, то нет, на весь шард должен быть один лист из 200-300 элементов и он должен быть глобальным.
Обычно "глобал" это синоним "плохо", но не в данном случае.
Не думаю что это займет очень много места в памяти. Что бы узнать примерно, можно посмотреть через std::cout<<300*sizeof(object*); (в том случае если в нвн юзают object для лута, я не знаю). Результат будет в байтах.

Сообщение отредактировал Edwin - Jan 5 2008, 04:41
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
dumbo
сообщение Jan 5 2008, 05:12
Сообщение #7


Level 9
Иконки Групп

Класс: Фея
Характер: Chaotic Evil
Раса: Тварь
NWN: Скриптинг [PW]



Vanes, объекты вешай на локу, при входе первого PC в локу запускай само-повторяющийся скрипт проверки на "старье", при выходе последнего - останавливай. хб - зло.
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Vanes
сообщение Jan 5 2008, 05:58
Сообщение #8


Level 11
Иконки Групп

Класс: Вор
Характер: Neutral Evil
Раса: Эльф
NWN: Скриптинг [PW]
Validor2



Цитата
Не думаю что это займет очень много места в памяти. Что бы узнать примерно, можно посмотреть через std::cout<<300*sizeof(object*); (в том случае если в нвн юзают object для лута, я не знаю). Результат будет в байтах.

не думаю что это реально организовать силами тулсета (IMG:style_emoticons/kolobok_light/smile.gif)

Цитата
Vanes, объекты вешай на локу, при входе первого PC в локу запускай само-повторяющийся скрипт проверки на "старье", при выходе последнего - останавливай. хб - зло.

да не вопрос... вместо харбита можно и псевдохарбит организовать.. вопрос не в этом...
вопрос в том, в каком виде хранить эти объекты ??? или точнее как их потом грамотно доставать для проверки...
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Edwin
сообщение Jan 5 2008, 06:43
Сообщение #9


Level 3
*

Класс: Обыватель
Характер: Chaotic Evil
Раса: Человек



QUOTE
не думаю что это реально организовать силами тулсета smile.gif


Если ты про листы, то в чем может быть проблема? Мне просто интересно.

Сообщение отредактировал Edwin - Jan 5 2008, 06:57
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
azathoth
сообщение Jan 5 2008, 10:37
Сообщение #10


Level 12
Иконки Групп

Класс: Оборотень
Характер: Chaotic Neutral
Раса: Нежить
NWN: Скриптинг [Sn]



тупо, просто, быстро: лист (приорити если важно время удаления), на объекты цеплять ссылки ясное дело не стоит -- игрок подберёт и отлогинится -- на инвалид обджекте ссылок на следующий не найти (IMG:style_emoticons/kolobok_light/smile.gif) поинты и инфой -- вариант. ссылка на первый+последний на локации или модуле.

объекты доставать так: если где-то кладётся мусор -- то в том же "онДроп" если превышен лимит на писят штук выбираем первый по ссылке с модуля и дестроим, обновляем ссылки. (тут конечно поле для творчества -- например динамическое кол-во объектов или можно проверить дестрой тайм и не удалять пока если мусора мало, а если дестрой тайм вышел, то проверить ещё и следующего и т.д)

во такая вот продвинутая система сборки -- не обещается что мусор будет удалён через указаное время и не обещается что он сколько-нибудь долго вообще пролежит.

по хорошему надо два списка -- брошеные итемы - мусор как он есть и лутбаги с очередью подлинней.

если же важно ДелетеТайм -- то к каждому ОнДропу прицеплять ДелайКомманд ЭкзекутСкрипт ДестройОбджектСелф.

вот и все идеи на заданую тему (IMG:style_emoticons/kolobok_light/smile.gif)
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
virusman
сообщение Jan 5 2008, 12:19
Сообщение #11


Level 17
Иконки Групп

Класс: Волшебник
Характер: Neutral Good
Раса: Человек
NWN: Скриптинг [PW]
Axistown SR 1.9
NWNX



Цитата(Edwin @ Jan 5 2008, 06:43) *
Если ты про листы, то в чем может быть проблема? Мне просто интересно.
Эдвин, NWScript - это НЕ C++. Работа с памятью в НВН не предусмотрена, классы и STL там тоже напрочь отсутствуют. Чтобы советовать, как оптимальней что-то сделать в NWScript, надо хоть раз открыть тулсет.

Сообщение отредактировал virusman - Jan 5 2008, 12:21
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Edwin
сообщение Jan 5 2008, 12:59
Сообщение #12


Level 3
*

Класс: Обыватель
Характер: Chaotic Evil
Раса: Человек



Херово, разработчики угробили потенциал ООП. Кто ж знал...

Сообщение отредактировал Edwin - Jan 5 2008, 13:01
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
virusman
сообщение Jan 5 2008, 13:18
Сообщение #13


Level 17
Иконки Групп

Класс: Волшебник
Характер: Neutral Good
Раса: Человек
NWN: Скриптинг [PW]
Axistown SR 1.9
NWNX



Цитата(Edwin @ Jan 5 2008, 12:59) *
Херово, разработчики угробили потенциал ООП. Кто ж знал...
Не угробили, а просто не реализовали. NWScript - это не урезанный C++, а самостоятельный язык программирования, со своим компилятором, байт-кодом и виртуальной машиной.
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Existor
сообщение Jan 5 2008, 15:25
Сообщение #14


Level 6
**

Класс: Разведчик Арфистов
Характер: True Neutral
Раса: Животное



Цитата(Vanes @ Jan 4 2008, 23:32) *
придумал я вот что...при создании каждого лутбега или в момент выкидывания игроком шмотки на землю на эти объекты создается своего рода ссылка... а именно - вейпоинты в отдельной локации, на которых хранитятся данные по этому объекту... само собой в локе есть харбит, которые по очереди эти вейпоинты чекает...т.е. в итоге вместо кучи харбитов получаем один...

А что, если при создании каждого конкретного лутбега вешать отложенную на нужное время команду DestroyObject()?
У нас, насколько я помню, именно так и реализовано. То, что скидывают игроки, пропадает раз в 3 часа само собой врезультате релоада модуля. Прецендентов потери производительности врезультате "засирания" в НвН1 замечено нами не было. Хотя по э1 помню, была чистка вообще всех предметов, не помню как Валлео это реализовал, но могу глянуть.
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Vanes
сообщение Jan 5 2008, 15:47
Сообщение #15


Level 11
Иконки Групп

Класс: Вор
Характер: Neutral Evil
Раса: Эльф
NWN: Скриптинг [PW]
Validor2



Цитата
А что, если при создании каждого конкретного лутбега вешать отложенную на нужное время команду DestroyObject()?

не делаю того, за чем не могу проследить (IMG:style_emoticons/kolobok_light/smile.gif)
где, например, гарантия того, что DelayCommand просто не затеряется и вообще не выполнится ???
если уж самое стабильное - харбит, и тот не каждые 6 сек запускается, в случае сильной загруженности сервака, то что уж говорить про DelayCommand, который мы 10 минут назад запустили (IMG:style_emoticons/kolobok_light/smile.gif)
и еще такой вопрос... как прервать выполнение этой команды, если предмет был поднят раньше времени ???

Добавлено через 1 минуту 52 секунды

Цитата
Прецендентов потери производительности врезультате "засирания" в НвН1 замечено нами не было.

не знаю как общая производительность, но то что локация грузится намного дольше, если в ней кучу итемов набросать на пол - это проверено (IMG:style_emoticons/kolobok_light/smile.gif)
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Existor
сообщение Jan 5 2008, 15:55
Сообщение #16


Level 6
**

Класс: Разведчик Арфистов
Характер: True Neutral
Раса: Животное



Цитата(Vanes @ Jan 5 2008, 15:47) *
не делаю того, за чем не могу проследить где, например, гарантия того, что DelayCommand просто не затеряется и вообще не выполнится ???

Практика НвН1 показывает, что все работает нормально. В нвн2 - покажет она же.
Цитата
если уж самое стабильное - харбит, и тот не каждые 6 сек запускается, в случае сильной загруженности сервака

В нвн1 в случае сильной загруженности сервака ХБ не пропадает(по крайней мере не сталкивался), а увеличивается время разницы между срабатыванием. Например увеличивается с 6ти до 10 секунд реалтайма.
Цитата
то что уж говорить про DelayCommand, который мы 10 минут назад

Учитесь доверять машине =)
Цитата
как прервать выполнение этой команды, если предмет был поднят раньше времени ???

Суть метода в том, что создается контейнер с определенным временем жизни, который будет уничтожен со всем оставшимся в нем содержимым, когда его время придет. На содержимом его никаких отложенных дестроев нет.
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Lex
сообщение Jan 5 2008, 16:17
Сообщение #17


Level 5
Иконки Групп

Класс: Обыватель
Характер: Lawful Neutral
Раса: Человек
NWN: Модмейкер
Проклятие Левора
Порядок Времени



Цитата(Existor @ Jan 5 2008, 15:25) *
А что, если при создании каждого конкретного лутбега вешать отложенную на нужное время команду DestroyObject()?

с этим бывают проблемы, если двигать игровое время. Хотя на шардах это не актуально.
Цитата(Vanes @ Jan 5 2008, 15:47) *
и еще такой вопрос... как прервать выполнение этой команды, если предмет был поднят раньше времени ???

а зачем? время придет - удалится, если есть чему удаляться. Нет - ну и слава богу (IMG:style_emoticons/kolobok_light/smile.gif)
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Vanes
сообщение Jan 5 2008, 17:09
Сообщение #18


Level 11
Иконки Групп

Класс: Вор
Характер: Neutral Evil
Раса: Эльф
NWN: Скриптинг [PW]
Validor2



я про ситуацию, когда шмотку выкинули, мы на нее повесили DestroyObject через 5 минут, скажем... а за эти 5 минут шмотку подобрали...
вот в этой ситуации возможно будет отменить удаление шмотки ???
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
virusman
сообщение Jan 5 2008, 17:39
Сообщение #19


Level 17
Иконки Групп

Класс: Волшебник
Характер: Neutral Good
Раса: Человек
NWN: Скриптинг [PW]
Axistown SR 1.9
NWNX



Цитата(Vanes @ Jan 5 2008, 17:09) *
я про ситуацию, когда шмотку выкинули, мы на нее повесили DestroyObject через 5 минут, скажем... а за эти 5 минут шмотку подобрали...
вот в этой ситуации возможно будет отменить удаление шмотки ???
Почему бы и нет? При назначении DelayCommand повесить на шмотку переменную, а на OnItemAcquired её снимать. Если переменная снята - скрипт удаления не удалит шмотку.
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Lex
сообщение Jan 5 2008, 17:40
Сообщение #20


Level 5
Иконки Групп

Класс: Обыватель
Характер: Lawful Neutral
Раса: Человек
NWN: Модмейкер
Проклятие Левора
Порядок Времени



так это.. вешай не на шмотку, а на контейнер. Ты же под все выкидываемое контейнер делаешь (лутбэг).. или я что-то пропустил? Вешай на контейнер исполнение простенькой функции отчистки + удаление контейнера.
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Vanes
сообщение Jan 5 2008, 17:56
Сообщение #21


Level 11
Иконки Групп

Класс: Вор
Характер: Neutral Evil
Раса: Эльф
NWN: Скриптинг [PW]
Validor2



ну по сути понятно...
осталось убедиться, что DelayCommand не сбивается при больших значениях времени задержки...
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения
Existor
сообщение Jan 5 2008, 18:31
Сообщение #22


Level 6
**

Класс: Разведчик Арфистов
Характер: True Neutral
Раса: Животное



НвН1: 3 минуты - в полевых условиях полет нормальный. А больше, имхо, смысла и нет откладывать. Игрокам хватит 3 минуты времени, чтобы понять, нужно ли им содержимое лутбэга.
Если речь идет про дроп с игрока при смерти - так он пропадать не должен вообще. Если игрок дропнул вещь - бывает, но обычно не напрягает(тоесть сознательным завалом локаций дропом обычно никто не занимается, да и не так это страшно во всех возможных смыслах). Основной мусор создается дропом с мобов, а вот с ним задерженный дестрой контейнера справляется на ура.
Вернуться в начало страницы
Скопировать ник в поле быстрого ответа
+Ответить с цитированием данного сообщения

Ответить в эту темуОткрыть новую тему
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



Текстовая версия Сейчас: 28th March 2024 - 11:43