ShowSyncHudMsg предизвиква краш в Ham_Spawn

Ако имате затруднения при изработката/преработката на даден плъгин - пишете тук, ще се опитаме да ви помогнем!
Аватар
thurinven
Извън линия
Потребител
Потребител
Мнения: 31
Регистриран на: 16 Окт 2019, 10:46
Се отблагодари: 4 пъти
Получена благодарност: 5 пъти

ShowSyncHudMsg предизвиква краш в Ham_Spawn

Мнение от thurinven » 24 Апр 2020, 13:56

Здравейте,

Пиша плъгин за хепи ауър и при Ham_Spawn проверявам дали съм в часовия диапазон - ако да пускам хепи ауъра и искам да покажа съобщение под радара, което да стои постоянно. Следвах кода , свързан с HUD съобщенията от секцията с уроци.

Когато стартирам таска в Ham_Spawn , съобщението се показва и сървърът крашва със segmentation fault - без логове или грешки. Ако стартирам таска в plugin_init няма проблеми.

Предполагам се случва нещо със синк обекта, но не успявам да разбера. hudObject хендъла не е -1 и set_task се извиква само веднъж.

Ето релевантната част от кода:

Код за потвърждение: Избери целия код

new bool: isHappyHourStarted
new hudObject

public plugin_init()
{
    hudObject = CreateHudSyncObj()
            
    //set_task(1.0, "ShowMessage", _, _, _, "b")

    RegisterHam(Ham_Spawn, "player", "OnPlayerSpawn", true)
}

public OnPlayerSpawn(id)
{
    if (IsHappyHour() && !isHappyHourStarted)
    {
                set_task(1.0, "ShowMessage", _, _, _, "b")
                isHappyHourStarted = true
    } 
}

public ShowMessage()
{
    set_hudmessage(255, 255, 255, 0.02, 0.18, 1, 2.0, 1.0, 0.5, 1.0, -1)
    server_print("show message / handle %d", hudObject)
    ShowSyncHudMsg(0, hudObject, "TEST MESSAGE %d", 1)
}
    	

Аватар
OciXCrom
Извън линия
Администратор
Администратор
Мнения: 7206
Регистриран на: 06 Окт 2016, 19:20
Местоположение: /resetscore
Се отблагодари: 117 пъти
Получена благодарност: 1295 пъти
Обратна връзка:

ShowSyncHudMsg предизвиква краш в Ham_Spawn

Мнение от OciXCrom » 24 Апр 2020, 14:17

Ham_Spawn се извиква за всеки играч отделно, а съобщението го показваш за всички играчи. Вероятно се случва overflow. Подай id в set_task и покажи съобщението само за играча, вместо да ползваш 0 като индекс в ShowSyncHudMsg.

Не забравяй да премахнеш таска с remove_task когато вече не е нужен за да не се случи дублиране при повторно извикване на set_task.

Аватар
thurinven
Извън линия
Потребител
Потребител
Мнения: 31
Регистриран на: 16 Окт 2019, 10:46
Се отблагодари: 4 пъти
Получена благодарност: 5 пъти

ShowSyncHudMsg предизвиква краш в Ham_Spawn

Мнение от thurinven » 24 Апр 2020, 17:20

Крашът започна, когато добавих този HUD message, но след доста дебъгване - не е от него.
Имам една функция за премахване на оръжие, която взех:

Код за потвърждение: Избери целия код

ham_strip_user_weaponent(id, weaponEnt, iId=0, bool:bSwitchIfActive = true)
{
    if (bSwitchIfActive && get_pdata_cbase(id, m_pActiveItem) == weaponEnt)
    {
        ExecuteHamB(Ham_Weapon_RetireWeapon, weaponEnt);
    }

    if (ExecuteHamB(Ham_RemovePlayerItem, id, weaponEnt))
    {
        if (!iId)
        {
            iId = cs_get_weapon_id(weaponEnt);
        }
        user_has_weapon(id, iId, 0);
        ExecuteHamB(Ham_Item_Kill, weaponEnt);
        return 1;
    }
    return 0;
} 
При извикване на get_pdata_cbase(id, m_pActiveItem) в Ham_Spawn и крашва, но не всеки път - според документацията е възможно тази функция да предизвика краш, ако не се използва като хората.

Благодаря за мнението

Аватар
OciXCrom
Извън линия
Администратор
Администратор
Мнения: 7206
Регистриран на: 06 Окт 2016, 19:20
Местоположение: /resetscore
Се отблагодари: 117 пъти
Получена благодарност: 1295 пъти
Обратна връзка:

ShowSyncHudMsg предизвиква краш в Ham_Spawn

Мнение от OciXCrom » 24 Апр 2020, 20:57

Дай да видим как точно я ползваш? Ако ползваш ReHLDS, възможно е да не работи.

Аватар
thurinven
Извън линия
Потребител
Потребител
Мнения: 31
Регистриран на: 16 Окт 2019, 10:46
Се отблагодари: 4 пъти
Получена благодарност: 5 пъти

ShowSyncHudMsg предизвиква краш в Ham_Spawn

Мнение от thurinven » 25 Апр 2020, 13:03

Ползвам rehlds и regamedll.

Разглеждайки код от <reapi> видях, че мога да напиша логиката много по-просто и пренаписах нещото с reapi - стана много по-изчистено и без get_pdata_cbase

С цел да си дадем отговор защо крашваше преди това пускам кода отдолу. Аз си мисля, че може поинтърът да не е сетнат към оръжие все още в момента на изпълнението.

Код за потвърждение: Избери целия код


new const m_rgpPlayerItems_CBasePlayer[6] = {367,368,...}
const m_pActiveItem = 373

// Ham_Spawn callback
public OnPlayerSpawned(id)
{
    if (isHappyHourStarted && is_user_alive(id))
    {
        new weapons = pev(id, pev_weapons);
        if (~weapons & CSW_FLASHBANG)
        {
            give_item(id, "weapon_flashbang")
        }
        cs_set_user_bpammo(id, CSW_FLASHBANG, 2)

        if (~weapons & CSW_HEGRENADE)
        {
            give_item(id, "weapon_hegrenade")
        }

        new gun = get_pdata_cbase(id, m_rgpPlayerItems_CBasePlayer[2]);
        
        if (gun > 0)
        {
            new iId = cs_get_weapon_id(gun);
            if (iId == CSW_DEAGLE)
            {
                cs_set_weapon_ammo(gun, 7);
            }
            else
            {
                ham_strip_user_weaponent(id, gun, iId, true);
                give_item(id, "weapon_deagle");
            }
        }
}
        
ham_strip_user_weaponent(id, weaponEnt, iId=0, bool:bSwitchIfActive = true)
{
    // Ей тук понякога гърмеше
    // new d = get_pdata_cbase(id, m_pActiveItem)

    // if (bSwitchIfActive && d == weaponEnt)
    // {
    //     ExecuteHamB(Ham_Weapon_RetireWeapon, weaponEnt);
    // }

    if (ExecuteHamB(Ham_RemovePlayerItem, id, weaponEnt))
    {
        if (!iId)
        {
            iId = cs_get_weapon_id(weaponEnt);
        }
        user_has_weapon(id, iId, 0);
        ExecuteHamB(Ham_Item_Kill, weaponEnt);
        return 1;
    }
    return 0;
}

Аватар
mi0
Извън линия
AMXX Скриптър
AMXX Скриптър
Мнения: 534
Регистриран на: 09 Дек 2016, 22:02
Се отблагодари: 97 пъти
Получена благодарност: 120 пъти
Обратна връзка:

ShowSyncHudMsg предизвиква краш в Ham_Spawn

Мнение от mi0 » 25 Апр 2020, 13:48

Ето какво бих направил аз.

Код за потвърждение: Избери целия код

#include <amxmodx>
#include <reapi>

public plugin_init()
{
	register_plugin("Deagle On Spawn", "", "")

	RegisterHookChain(RG_CBasePlayer_OnSpawnEquip, "OnSpawnEquip")
}

public OnSpawnEquip(id)
{
	rg_give_item(id, "weapon_deagle")
	return HC_SUPERCEDE
}
Какво се случва всъщност, е че, вместо да му премахваме уръжията, ние спираме функцията, която ги дава от началото на рунда. И преди спирането на функцията, даваме deagle.
А, ако искаш да вземеш item-ите, можеш да използваш

Код за потвърждение: Избери целия код

get_member(id, m_rgpPlayerItems, ID)
Като 3-ти аргумент(ID) даваш-

Код за потвърждение: Избери целия код

enum InventorySlotType
{
    NONE_SLOT,
    PRIMARY_WEAPON_SLOT,
    PISTOL_SLOT,
    KNIFE_SLOT,
    GRENADE_SLOT,
    C4_SLOT,
};
aka kurdokoleno
Catch Mod - 87.121.112.232:27021

Публикувай отговор
  • Подобни теми
    Отговори
    Преглеждания
     Последно мнение

Обратно към “Помощ в скриптирането”

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 7 госта