Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.
Страница 1 из 2 1 2 ПоследняяПоследняя
Показано с 1 по 10 из 17

Тема: foreach от ziggi

  1. #1
    Аватар для 123
    Пользователь

    Статус
    Оффлайн
    Регистрация
    09.02.2014
    Сообщений
    93
    Репутация:
    8 ±

    foreach от ziggi

    Использую форк foreach от ziggi. В нем есть интегратор машин, так вот, получаю следующие ошибки:

    PHP код:
    [17:09:30Run time error 4"Array index out of bounds"
    [17:09:30]  Attempted to read/write array element at index 2001 in array of size 2000
    [17:09:30AMX backtrace:
    [
    17:09:30#0 004ade54 in main (params[]=@00000028 "", 9092328) at C:\GRP\gamemodes\grp.pwn:34171
    [20:43:11Run time error 4"Array index out of bounds"
    [20:43:11]  Attempted to read/write array element at index 2001 in array of size 2000
    [20:43:11AMX backtrace:
    [
    20:43:11#0 004ade54 in main (params[]=@00000014 "", 9092328) at C:\GRP\gamemodes\grp.pwn:34171 
    Привожу ниже код команды и функции, которые используются:

    PHP код:
    CMD:spveh(playeridparams[])
    {
        if(
    AdminInfo[playerid][aLevel] < || !AdminInfo[playerid][aLogin])
            return 
    true;

        
    extract params -> new Float:rad 200.0; else
            return 
    SendClientMessage(playerid, -1, !"Введите: /spveh [радиус]");

        if(
    rad 1.0 || rad 200.0)
            return 
    SendClientMessage(playeridCOLOR_GREY, !"Радиус не может быть меньше 1.00 выше 200.0 (области видимости).");

        new
            
    sp_car;

        foreach (new 
    vehicleid Vehicle) {

            if(
    IsPlayerInRangeOfPoint(playeridradVehicleInfo[vehicleid][vX], VehicleInfo[vehicleid][vY], VehicleInfo[vehicleid][vZ]) && !IsVehicleOccupied(vehicleid)) // ошибки
            
    {
                
    SetVehicleToRespawn(vehicleid);
                
    sp_car ++;
            }
        }

        
    format(stringer1sizeof(stringer1), "Администратор %s (%d) зареспавнил весь транспорт в радиусе %f м (%d машин)"PlayerInfo[playerid][pNames], playeridradsp_car);
        return 
    SendAdminMessage(COLOR_LIGHTRED,stringer1);
    }

    stock IsVehicleOccupied(vehicleid)
    {
        foreach(new 
    Player)
            if(
    IsPlayerInVehicle(ivehicleid)) return 1;

        return 
    0;

    Как видно, ошибки нет. До этого использовался оригинальный foreach и собственный интегратор машин, таких проблем не было. Ошибка у ziggi? Пишу сюда, потому что его репозиторий мертв.

  2. #2
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2590 ±
    Я так понимаю, это происходит только когда на сервере заспавнены все 1999 машин? (2000 нельзя из-за криворукости разработчиков SA-MP)
    И если код внутри цикла foreach закомментировать, ошибки всё так же останутся?
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  3. #3
    Аватар для 123
    Пользователь

    Статус
    Оффлайн
    Регистрация
    09.02.2014
    Сообщений
    93
    Репутация:
    8 ±
    Нет. Только что проверил, создал все 1999 машин и испытывал это. Безрезультатно. Но тем не менее изо дня в день я наблюдаю эти ошибки в логах. Да и на моем сервере не может быть такого количества транспорта, даже в часы пик.

  4. #4
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2590 ±
    Немного пальцем в небо, но всё же, попробуйте в инклуде foreach.inc найти такую строку:
    1. new Iterator:Vehicle<MAX_VEHICLES>;

    и заменить "MAX_VEHICLES" на "MAX_VEHICLES + 1". И, возможно, то же самое понадобится проделать с итератором PlayerVehiclesStream, если он тоже используется.
    Я точно помню, что сообщал ziggi об этой проблеме 2 года назад. Как видно, воз и ныне там...

    UPD: Порылся в архиве ЛС; я тогда сообщил ziggi не совсем об этой, но о похожей проблеме: ID транспорта начинаются не с 0, а с 1, и поэтому при попытке добавления в итератор последний возможный ID (2000) может быть отвергнут, и предложил увеличить размер итератора Vehicle на 1, на что он и ответил, что да, смысл в этом есть (не уверен, насколько корректно будет публиковать личную переписку, поэтому вот такой вот пересказ). Но, как оказалось, больше 1999 машин создать нельзя и получить транспорт с ID 2000 невозможно - наверняка поэтому он и оставил размеры итераторов без изменений. Возможно, теперь есть новая причина их увеличить.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  5. #5
    Аватар для Kovshevoy
    Пользователь

    Статус
    Оффлайн
    Регистрация
    11.07.2015
    Сообщений
    190
    Репутация:
    25 ±
    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    Немного пальцем в небо, но всё же, попробуйте в инклуде foreach.inc найти такую строку:


    1. new Iterator:Vehicle<MAX_VEHICLES>;




    и заменить "MAX_VEHICLES" на "MAX_VEHICLES + 1". И, возможно, то же самое понадобится проделать с итератором PlayerVehiclesStream, если он тоже используется.
    Я точно помню, что сообщал ziggi об этой проблеме 2 года назад. Как видно, воз и ныне там...

    UPD: Порылся в архиве ЛС; я тогда сообщил ziggi не совсем об этой, но о похожей проблеме: ID транспорта начинаются не с 0, а с 1, и поэтому при попытке добавления в итератор последний возможный ID (2000) может быть отвергнут, и предложил увеличить размер итератора Vehicle на 1, на что он и ответил, что да, смысл в этом есть (не уверен, насколько корректно будет публиковать личную переписку, поэтому вот такой вот пересказ). Но, как оказалось, больше 1999 машин создать нельзя и получить транспорт с ID 2000 невозможно - наверняка поэтому он и оставил размеры итераторов без изменений. Возможно, теперь есть новая причина их увеличить.
    Весьма интересно
    У меня кстати тоже, при использовании foreach от ziggi такая фигня с машинами. Правда я думал, что это ошибка из-за своего кода.

  6. #6
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2590 ±
    Вопрос к ТС: после предложенного парой постов выше исправления проблема решена?
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  7. #7
    Аватар для 123
    Пользователь

    Статус
    Оффлайн
    Регистрация
    09.02.2014
    Сообщений
    93
    Репутация:
    8 ±
    Только загрузил предложенное Вами исправления, буду наблюдать. О результатах я отпишусь.

  8. #8
    Аватар для Shaolinka
    Пользователь

    Статус
    Оффлайн
    Регистрация
    19.01.2020
    Сообщений
    69
    Репутация:
    8 ±
    Не использую форк от Зигги, однако использую следующее:
    PHP код:
    // раздефайним константу MAX_VEHICLES, установив ей значение 1999, потому что идёт от 1 до 1999
    #if defined MAX_VEHICLES
    #undef MAX_VEHICLES
    #define MAX_VEHICLES 1999
    #else 
    #define MAX_VEHICLES 1999
    #endif

    // создадим итератор для всего транспорта на сервере, как-раз тут нам надо было бы отнимать единицу, однако проще установить новое значение константе
    new IteratorVehicle<MAX_VEHICLES>;

    // рекомендую перехватить нативные функции для работы с транспортом, а именно: (CreateVehicle, AddStaticVehicleEx, DestroyVehicle).
    stock CreateVehicleEx(vehicletypeFloatxFloatyFloatzFloatrotationcolor1color2respawn_delayaddsiren)
    {
          new 
    veh_id CreateVehicle(vehicletypeFloatxFloatyFloatzFloatrotationcolor1color2respawn_delayaddsiren);
          
    Iter_Add(Vehicleveh_id);

          return 
    veh_id;
    }
    #if defined _ALS_CreateVehicle
         #undef CreateVehicle
    #else
         #define _ALS_CreateVehicle
    #endif
    #define CreateVehicle CreateVehicleEx

    stock ac_AddStaticVehicleEx(modelid,  Floatspawn_xFloatspawn_yFloatspawn_zFloat:z_anglecolor1color2respawn_delayaddsiren)
    {
          new 
    veh_id AddStaticVehicleEx(vehicletypespawn_xspawn_yspawn_zz_anglecolor1color2respawn_delayaddsiren);
          
    Iter_Add(Vehicleveh_id);

          return 
    veh_id;
    }
    #if defined _ALS_AddStaticVehicleEx
         #undef AddStaticVehicleEx
    #else
         #define _ALS_AddStaticVehicleEx
    #endif
    #define AddStaticVehicleEx ac_AddStaticVehicleEx

    stock DestroyVehicleEx(vehicleid)
    {
          if(!
    Iter_Contains(Vehiclevehicleid))
             return ;

          return 
    Iter_Remove(Vehiclevehicleid);
    }
    #if defined _ALS_DestroyVehicle
         #undef DestroyVehicle
    #else
         #define _ALS_DestroyVehicle
    #endif
    #define DestroyVehicle DestroyVehicleEx

    // ну и мой вариант команды
    CMD:spveh(playeridparams[])
    {
        if(
    AdminInfo[playerid][aLevel] < || !AdminInfo[playerid][aLogin])
            return ;

        
    extract params -> new Floatrad 200.0; else
              return 
    SendClientMessage(playerid, -1"Введите: /spveh [радиус]");

        if(!(
    1.0 <= rad <= 200.0))
              return 
    SendClientMessage(playeridCOLOR_GREY"Радиус не может быть меньше 1.00 выше 200.0 (области видимости).");

        new 
    count MAX_VEHICLES;

        foreach (new 
    vehicleid Vehicle
        {
            if(
    IsPlayerInRangeOfPoint(playeridradVehicleInfo[vehicleid][vX], VehicleInfo[vehicleid][vY], VehicleInfo[vehicleid][vZ])
                continue;
            
            if(
    IsVehicleOccupied(vehicleid))
                continue;

           
    SetVehicleToRespawn(vehicleid);

           
    count --;
        }

        new const 
    fmt_str[] = "Администратор %s (%d) зареспавнил весь транспорт в радиусе %f м (%d машин)";
        
        new 
    result_str[(((sizeof fmt_str) + ((- MAX_PLAYER_NAME) + (- 3) + (- 5) + (- 4)) + 1))];

        
    format
        
    (
               
    result_strsizeof result_str,
               
    fmt_str,
               
    PlayerInfo[playerid][pNames], 
               
    playerid
               
    rad
               (
    MAX_VEHICLES count)
        );
               
        return 
    SendAdminMessage(COLOR_LIGHTREDresult_str);
    }

    stock IsVehicleOccupied(vehicleid)
    {
        foreach(new 
    playerid Player)
        {
            if(!
    IsPlayerInVehicle(ivehicleid))
                 continue;

            return 
    1;
         }

         return ;

    Собсна как-то так
    Последний раз редактировалось Shaolinka; 23.04.2020 в 23:46. Причина: sorry for tabulation

  9. #9
    Аватар для Nexius_Tailer
    Пользователь

    Статус
    Оффлайн
    Регистрация
    04.01.2015
    Адрес
    Гомель, Беларусь
    Сообщений
    547
    Репутация:
    158 ±
    Цитата Сообщение от Shaolinka Посмотреть сообщение
    Не использую форк от Зигги, однако использую следующее:
    PHP код:
    // раздефайним константу MAX_VEHICLES, установив ей значение 1999, потому что идёт от 1 до 1999
    #if defined MAX_VEHICLES
    #undef MAX_VEHICLES
    #define MAX_VEHICLES 1999
    #else 
    #define MAX_VEHICLES 1999
    #endif

    // создадим итератор для всего транспорта на сервере, как-раз тут нам надо было бы отнимать единицу, однако проще установить новое значение константе
    new IteratorVehicle<MAX_VEHICLES>;

    // рекомендую перехватить нативные функции для работы с транспортом, а именно: (CreateVehicle, AddStaticVehicleEx, DestroyVehicle).
    stock CreateVehicleEx(vehicletypeFloatxFloatyFloatzFloatrotationcolor1color2respawn_delayaddsiren)
    {
          new 
    veh_id CreateVehicle(vehicletypeFloatxFloatyFloatzFloatrotationcolor1color2respawn_delayaddsiren);
          
    Iter_Add(Vehicleveh_id);

          return 
    veh_id;
    }
    #if defined _ALS_CreateVehicle
         #undef CreateVehicle
    #else
         #define _ALS_CreateVehicle
    #endif
    #define CreateVehicle CreateVehicleEx

    stock ac_AddStaticVehicleEx(modelid,  Floatspawn_xFloatspawn_yFloatspawn_zFloat:z_anglecolor1color2respawn_delayaddsiren)
    {
          new 
    veh_id AddStaticVehicleEx(vehicletypespawn_xspawn_yspawn_zz_anglecolor1color2respawn_delayaddsiren);
          
    Iter_Add(Vehicleveh_id);

          return 
    veh_id;
    }
    #if defined _ALS_AddStaticVehicleEx
         #undef AddStaticVehicleEx
    #else
         #define _ALS_AddStaticVehicleEx
    #endif
    #define AddStaticVehicleEx ac_AddStaticVehicleEx

    stock DestroyVehicleEx(vehicleid)
    {
          if(!
    Iter_Contains(Vehiclevehicleid))
             return ;

          return 
    Iter_Remove(Vehiclevehicleid);
    }
    #if defined _ALS_DestroyVehicle
         #undef DestroyVehicle
    #else
         #define _ALS_DestroyVehicle
    #endif
    #define DestroyVehicle DestroyVehicleEx

    // ну и мой вариант команды
    CMD:spveh(playeridparams[])
    {
        if(
    AdminInfo[playerid][aLevel] < || !AdminInfo[playerid][aLogin])
            return ;

        
    extract params -> new Floatrad 200.0; else
              return 
    SendClientMessage(playerid, -1"Введите: /spveh [радиус]");

        if(!(
    1.0 <= rad <= 200.0))
              return 
    SendClientMessage(playeridCOLOR_GREY"Радиус не может быть меньше 1.00 выше 200.0 (области видимости).");

        new 
    count MAX_VEHICLES;

        foreach (new 
    vehicleid Vehicle
        {
            if(
    IsPlayerInRangeOfPoint(playeridradVehicleInfo[vehicleid][vX], VehicleInfo[vehicleid][vY], VehicleInfo[vehicleid][vZ])
                continue;
            
            if(
    IsVehicleOccupied(vehicleid))
                continue;

           
    SetVehicleToRespawn(vehicleid);

           
    count --;
        }

        new const 
    fmt_str[] = "Администратор %s (%d) зареспавнил весь транспорт в радиусе %f м (%d машин)";
        
        new 
    result_str[(((sizeof fmt_str) + ((- MAX_PLAYER_NAME) + (- 3) + (- 5) + (- 4)) + 1))];

        
    format
        
    (
               
    result_strsizeof result_str,
               
    fmt_str,
               
    PlayerInfo[playerid][pNames], 
               
    playerid
               
    rad
               (
    MAX_VEHICLES count)
        );
               
        return 
    SendAdminMessage(COLOR_LIGHTREDresult_str);
    }

    stock IsVehicleOccupied(vehicleid)
    {
        foreach(new 
    playerid Player)
        {
            if(!
    IsPlayerInVehicle(ivehicleid))
                 continue;

            return 
    1;
         }

         return ;

    Собсна как-то так
    Редефайн MAX_VEHICLES можно сделать до подключения foreach не переизобретая итераторы транспорта, эффект во всяком случае тот же должен быть.
    Не хотите постоянно проверять обновления моих скриптов?
    Подключите его последним, после всех остальных
    Nexius's Update Checker

  10. #10
    Аватар для 123
    Пользователь

    Статус
    Оффлайн
    Регистрация
    09.02.2014
    Сообщений
    93
    Репутация:
    8 ±
    PHP код:
    [15:40:32Run time error 4"Array index out of bounds"
    [15:40:32]  Attempted to read/write array element at index 2002 in array of size 2002
    [15:40:32AMX backtrace:
    [
    15:40:32#0 004bf650 in main (params[]=@00000019 !"", 9113472) at C:\GRP\gamemodes\grp.pwn:34453
    [15:40:46Run time error 4"Array index out of bounds"
    [15:40:46]  Attempted to read/write array element at index 2002 in array of size 2002
    [15:40:46AMX backtrace:
    [
    15:40:46#0 004bf650 in main (params[]=@00000019 !"", 9113472) at C:\GRP\gamemodes\grp.pwn:34453
    [15:40:52Run time error 4"Array index out of bounds"
    [15:40:52]  Attempted to read/write array element at index 2002 in array of size 2002 
    Собственно увеличение на один не помогает.
    PHP код:
    foreach(new Vehicle// ошибка 

 

 
Страница 1 из 2 1 2 ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •