Проблема с KeyValues

Тема в разделе "Программирование / Скриптинг", создана пользователем MAGNAT2645, 31 май 2016.

  1. MAGNAT2645

    MAGNAT2645

    Сообщения:
    33
    Симпатии:
    0
    У меня появилась проблема с получением строк из конфига.

    Вот конфиг:
    PHP:
    "PlayerType"
    {
        
    "1"
        
    {
            
    "string"    "Player"
            "rgba"        "255 255 255 255"
            "chat"        "0xFFFFFF"
        
    }
        
    "2"
        
    {
            
    "string"    "Elite"
            "rgba"        "255 255 255 255"
            "chat"        "0xFFFFFF"
        
    }
        
    "3"
        
    {
            
    "string"    "Elite II"
            "rgba"        "255 255 0 255"
            "chat"        "0xFFFF00"
        
    }
        
    "4"
        
    {
            
    "string"    "Elite III"
            "rgba"        "205 204 0 255"
            "chat"        "0xFFCC00"
        
    }
        
    "5"
        
    {
            
    "string"    "Retired Moderator"
            "rgba"        "102 102 153 255"
            "chat"        "0x666699"
        
    }
        
    "6"
        
    {
            
    "string"    "Moderator"
            "rgba"        "0 92 255 255"
            "chat"        "0x005CFF"
        
    }
        
    "7"
        
    {
            
    "string"    "Super Moderator"
            "rgba"        "255 0 71 255"
            "chat"        "0xFF0047"
        
    }
        
    "8"
        
    {
            
    "string"    "Very Super Moderator"
            "rgba"        "187 9 9 255"
            "chat"        "0xBB0909"
        
    }
        
    "9"
        
    {
            
    "string"    "Veteran Moderator"
            "rgba"        "255 51 0 255"
            "chat"        "0xFF3300"
        
    }
        
    "10"
        
    {
            
    "string"    "Head Moder"
            "rgba"        "221 74 74 255"
            "chat"        "0xDD4A4A"
        
    }
        
    "11"
        
    {
            
    "string"    "Admin"
            "rgba"        "1 177 29 255"
            "chat"        "0x01B11D"
        
    }
        
    "12"
        
    {
            
    "string"    "Elite Admin"
            "rgba"        "255 133 0 255"
            "chat"        "0xFF8500"
        
    }
        
    "13"
        
    {
            
    "string"    "Veteran Admin"
            "rgba"        "2 68 143 255"
            "chat"        "0x02448F"
        
    }
        
    "14"
        
    {
            
    "string"    "Head Admin"
            "rgba"        "0 6 158 255"
            "chat"        "0x00069E"
        
    }
        
    "15"
        
    {
            
    "string"    "Co-Owner"
            "rgba"        "75 255 5 255"
            "chat"        "0x4BFF05"
        
    }
        
    "16"
        
    {
            
    "string"    "Owner"
            "rgba"        "142 27 206 255"
            "chat"        "0x8E1BCE"
        
    }
    }
    Вот отрывки из кода:

    PHP:
    new String:sPlayerType[MAXPLAYERS 1][300],
    String:sPlayerTypeHex[MAXPLAYERS 1][300];

    int iPlayerType[MAXPLAYERS 1];

    public 
    APLRes AskPluginLoad2(Handle myselfbool lateString:error[], err_max)

     
    CreateNative("GetPlayerIntType"PlayerGetIntType);
     
    CreateNative("GetPlayerStringType"PlayerGetStringType);
     
    CreateNative("GetPlayerTypeHex"PlayerGetTypeHex);
     
     return 
    APLRes_Success;
    }

    public 
    PlayerGetIntType(Handle pluginnumParams)
    {
     
    int client GetNativeCell(1);
     if (
    client <= MaxClients && IsClientInGame(client))
     {
     return 
    iPlayerType[client];
     }
     return 
    false;
    }

    public 
    PlayerGetStringType(Handle pluginnumParams)
    {
     
    int client GetNativeCell(1);
     if (
    client <= MaxClients && IsClientInGame(client))
     {
     
    decl String:str[16];
     
    IntToString(iPlayerType[client], strsizeof(str));
     if (!
    KvJumpToKey(kvPlayerTypestr))
     {
     return 
    false;
     }
     
    KvGetString(kvPlayerType"string"sPlayerType[client], sizeof(sPlayerType[])); 
     
     
    SetNativeString(2sPlayerType[client], sizeof(sPlayerType[]), true);
     return 
    true;
     }
     return 
    false;
    }

    public 
    PlayerGetTypeHex(Handle pluginnumParams)
    {
     
    int client GetNativeCell(1);
     if (
    client <= MaxClients && IsClientInGame(client))
     {
     
    decl String:str[16];
     
    IntToString(iPlayerType[client], strsizeof(str));
     if (!
    KvJumpToKey(kvPlayerTypestr))
     {
     return 
    false;
     }
     
    KvGetString(kvPlayerType"chat"sPlayerTypeHex[client], sizeof(sPlayerTypeHex[]));
     
     
    SetNativeString(2sPlayerTypeHex[client], sizeof(sPlayerTypeHex[]), true);
     return 
    true;
     }
     return 
    false;
    }

    public 
    Action TMR_Connected(Handle timerHandle pack)
    {
     
    int iClient;

     
    ResetPack(pack);
     
    iClient ReadPackCell(pack);
     
     if (
    IsValidClient(iClient))
     {
     
    GetPlayerStringType(iClientsPlayerType[iClient]);
     
    GetPlayerTypeHex(iClientsPlayerTypeHex[iClient]);
     
    CPrintToChatAll("{lime}[+] {gold}%N {default}- \x07%06X%s {default}подключился{lime}!"iClientsPlayerTypeHex[iClient], sPlayerType[iClient]);
     }
     return 
    Plugin_Continue;
    }
    Почему при подключении игрока мне пишет:
    [+] Игрок - DD подключился!

    То есть иногда строку из "string" вообще не берёт, а иногда просто не берёт HEX цвет.

    ЭТО НЕ ВЕСЬ ПЛАГИН, А ТОЛЬКО ОТРЫВКИ. iPlayerType СОХРАНЯЕТСЯ В БД БЕЗ ОШИБОК!!!
     
  2. R1KO

    R1KO Супер-модератор

    Сообщения:
    5.971
    Симпатии:
    2.977
    0x вроде как не нужно писать.
    Добавь после
    KvGetString(kvPlayerType, "string", sPlayerType[client], sizeof(sPlayerType[]));
    LogMessage("string: '%s'", sPlayerType[client]);

    и
    KvGetString(kvPlayerType, "chat", sPlayerTypeHex[client], sizeof(sPlayerTypeHex[]));
    LogMessage("chat: '%s'", sPlayerTypeHex[client]);
    Посмотри что выдаст именно в те моменты когда не верно в чат пишет
     
  3. MAGNAT2645

    MAGNAT2645

    Сообщения:
    33
    Симпатии:
    0
    Щас, попробую...
    --- Добавлено позже ---
    У меня вообще нету последних логов с этим сообщением. (Запись в Логи включена)
    Я попробую LogMessage("string: '%s'", sPlayerType[client]) использовать в TMR_Connected, т.е., после моего подключения проверю в логах.
    --- Добавлено позже ---
    Кароче у меня просто логи закрылись последние, пришлось перезапустить сервер. Вот что выдал в логах:
    L 05/31/2016 - 09:16:39: [my\levels.smx] string: 'Основатель', chat: ''
    --- Добавлено позже ---
    Может, мне просто надо убрать из конфига что-то, например префикс 0x, а в коде просто сделать формат простым: "%X%s", sPlayerTypeHex[client], sPlayerType[client];
    --- Добавлено позже ---
    А вообще мне кажется, что это всё из-за того, что у меня в коде в нативе PlayerGetStringType и PlayerGetTypeHex обычный просмотр конфига, а не повторяющийся (т.е. do, while и т.д.)
    --- Добавлено позже ---
    Там, кстати, ещё один игрок подключился и после него в логах это, хотя в БД у него PlayerType = 1:
    L 05/31/2016 - 09:22:32: [my\levels.smx] string: '', chat: ''
     
    Последнее редактирование: 31 май 2016
  4. R1KO

    R1KO Супер-модератор

    Сообщения:
    5.971
    Симпатии:
    2.977
    нет

    попробуй

    сделай вообще полный лог.
    После IntToString(iPlayerType[client], str, sizeof(str)), после KvJumpToKey(kvPlayerType, str)

    @MAGNAT2645, Стоп. Зачем ты делаешь SetNativeString(2, sPlayerTypeHex[client], sizeof(sPlayerTypeHex[]), true) ???

    Ты ж получил уже в глобальную переменную.


    Сделай так:
    PHP:
    new String:sPlayerType[MAXPLAYERS 1][300],
    String:sPlayerTypeHex[MAXPLAYERS 1][300];

    int iPlayerType[MAXPLAYERS 1];

    public 
    APLRes AskPluginLoad2(Handle myselfbool lateString:error[], err_max)

        
    CreateNative("GetPlayerIntType"PlayerGetIntType);
        
    CreateNative("GetPlayerStringType"PlayerGetStringType);
        
    CreateNative("GetPlayerTypeHex"PlayerGetTypeHex);

        return 
    APLRes_Success;
    }

    public 
    PlayerGetIntType(Handle pluginnumParams)
    {
        
    int client GetNativeCell(1);
        if (
    client <= MaxClients && IsClientInGame(client))
        {
            return 
    iPlayerType[client];
        }
        return 
    false;
    }

    public 
    PlayerGetStringType(Handle pluginnumParams)
    {
        
    int client GetNativeCell(1);
        if (
    client <= MaxClients && IsClientInGame(client))
        {
            
    decl String:str[16];
            
    IntToString(iPlayerType[client], strsizeof(str));
            if (
    KvJumpToKey(kvPlayerTypestr))
            {
                
    KvGetString(kvPlayerType"string"sPlayerType[client], sizeof(sPlayerType[])); 
                return 
    true;
            }
        }
        return 
    false;
    }

    public 
    PlayerGetTypeHex(Handle pluginnumParams)
    {
        
    int client GetNativeCell(1);
        if (
    client <= MaxClients && IsClientInGame(client))
        {
            
    decl String:str[16];
            
    IntToString(iPlayerType[client], strsizeof(str));
            if (
    KvJumpToKey(kvPlayerTypestr))
            {
                
    KvGetString(kvPlayerType"chat"sPlayerTypeHex[client], sizeof(sPlayerTypeHex[]));
                return 
    true;
            }
        }

        return 
    false;
    }

    public 
    Action TMR_Connected(Handle timerHandle pack)
    {
        
    ResetPack(pack);
        
    int iClient ReadPackCell(pack);

        if (
    IsValidClient(iClient))
        {
            
    GetPlayerStringType(iClient);
            
    GetPlayerTypeHex(iClient);
            
    CPrintToChatAll("{lime}[+] {gold}%N {default}- \x07%06X%s {default}подключился{lime}!"iClientsPlayerTypeHex[iClient], sPlayerType[iClient]);
        }
        return 
    Plugin_Continue;
    }

    А еще лучше было бы вместо кучи нативов сделать 1, что-то типа:
    PHP:
    GetPlayerData(iClient"chat"sPlayerTypeHex[client], sizeof(sPlayerTypeHex[]));

    public 
    GetPlayerData(Handle pluginnumParams)
    {
        
    int client GetNativeCell(1);
        if (
    client <= MaxClients && IsClientInGame(client))
        {
            
    decl String:str[128];
            
    IntToString(iPlayerType[client], str16);
            if (
    KvJumpToKey(kvPlayerTypestr))
            {
                
    decl String:sBuffer[256];
                
    GetNativeString(2strsizeof(str));
                
    KvGetString(kvPlayerTypestrsBuffersizeof(sBuffer));
               
                
    SetNativeString(3sBufferGetNativeCell(4), true);
                return 
    true;
            }
        }

        return 
    false;
    }
     
  5. MAGNAT2645

    MAGNAT2645

    Сообщения:
    33
    Симпатии:
    0
    Я уже всё исправил, просто надо было вместо %X использовать %s, т.к., я получаю строку, а она стоит перед \x07, а там уже HEX цвет сам пойдёт... И ещё в конфиге надо было убрать префикс 0x (не знаю, почему, но у меня теперь цвета и у других в чате отображаются точно также, как указано в конфиге)
    Но спасибо за помощь, я потом наверно сделаю так, как ты указал, для небольшой оптимизации.
     
  6. R1KO

    R1KO Супер-модератор

    Сообщения:
    5.971
    Симпатии:
    2.977
    @MAGNAT2645, перед KvJumpToKey нужно KvRewind делать.
     
  7. MAGNAT2645

    MAGNAT2645

    Сообщения:
    33
    Симпатии:
    0
    У меня ещё один вопрос:

    Я не понял, как работает KvGetColor.

    У меня есть натив GetPlayerTypeRGB(client, int r, int g, int b, int a);

    И ещё, если я уже получил глобальную переменную, то как тогда записать эту переменную в другую (buffer). Мне надо, чтобы натив GetPlayerStringType и GetPlayerTypeHex имели возможность записи глобальной переменной в другие, например, для отображения текста из других плагинов.
     
  8. R1KO

    R1KO Супер-модератор

    Сообщения:
    5.971
    Симпатии:
    2.977
    PHP:
    int rgba;
    KvGetColor(kv"color"rgba);
    PHP:
    strcopy(buffersizeof(buffer), g_sVal);
    SetNativeString(3, g_sVal, GetNativeCell(3), true);
     
    Последнее редактирование: 31 май 2016
  9. MAGNAT2645

    MAGNAT2645

    Сообщения:
    33
    Симпатии:
    0
    Я лучше буду использовать GetPlayerData, описанный выше, потому что так действительно проще, но есть маленькая проблема:

    Если во втором параметре натива я вставлю "rgba", значит надо использовать KvGetColor вместо KvGetString и надо добавить r, g, b и a, как параметры натива. Я не могу придумать, как будет лучше это сделать.
    --- Добавлено позже ---
    И вот ещё одна вещь, есть плагин Aim Names (v0.8) - AlliedModders, там в коде есть:

    PHP:
    public Action:Timer_SyncHud(Handle:timerany:client)
    {
     if (
    g_bEnabled && g_aPlayers[client][bHudEnabled])
     {
     if(
    IsClientObserver(client))
     {
     return 
    Plugin_Continue;
     }
     
     new 
    iTarget GetClientAimTarget(clienttrue);
     if (!
    IsValidClient(iTargetfalse))
     {
     return 
    Plugin_Continue;
     }
     
     new 
    Team_Player GetClientTeam(client);
     new 
    Team_Target GetClientTeam(iTarget);
     
     if (
    Team_Player == Team_Target)
     {
     return 
    Plugin_Continue;
     }
     
     new 
    Float:client_pos[3], Float:target_pos[3];
     
    GetClientEyePosition(clientclient_pos);
     
    GetClientEyePosition(iTargettarget_pos);
     
     if (
    CanSeeTarget(clientclient_posiTargettarget_posg_fDistance))
     {
     if (
    g_CurrentMod == GameType_TF
     
    && TF2_GetPlayerCond(iTarget) & (TF2_PLAYERCOND_DISGUISING|TF2_PLAYERCOND_DISGUISED|TF2_PLAYERCOND_SPYCLOAK))
     {
     return 
    Plugin_Continue;
     }
     else
     {
     
    SetHudTextParams(-1.00.59g_fHoldtimeg_iColors[e_ColorNames:g_aPlayers[client][eColor]][iRed], g_iColors[e_ColorNames:g_aPlayers[client][eColor]][iGreen], g_iColors[e_ColorNames:g_aPlayers[client][eColor]][iBlue], 2551);
     if (
    g_bShowHealth && g_aPlayers[client][bHealthEnabled])
     {
     
    ShowSyncHudText(clientg_hHud"%N [%d]"iTargetGetClientHealth(iTarget));
     }
     else
     {
     
    ShowSyncHudText(clientg_hHud"%N"iTarget);
     }
     }
     }
     }
     else
     {
     
    g_aPlayers[client][hHudTimer] = INVALID_HANDLE;
     return 
    Plugin_Stop;
     }
     return 
    Plugin_Continue;
    }
    Я пробовал заменить текст в ShowSyncHudText и использовал натив GetPlayerTypeRGB в качестве цвета этого текста, но текст всё равно не отображается при наводке на игрока, а другой текст отображается:

    PHP:
    Client_PrintKeyHintText(client"%N (userid: %i)\nЗдоровье: %i"iTargetTargetIdTargetHP);
    --- Добавлено позже ---
    Также я удалил весь текст, связанный с здоровьем в HUD тексте, и использую Client_PrintKeyHintText для отображения здоровья.
     
    Последнее редактирование: 31 май 2016
  10. R1KO

    R1KO Супер-модератор

    Сообщения:
    5.971
    Симпатии:
    2.977
    Юзай KvGetString
    И
    PHP:
    stock UTIL_GetRGBFromString(String:sBuffer[], iColor[3])
    {
        
    decl String:sBuffers[3][4];
        
    ExplodeString(sBuffer" "sBufferssizeof(sBuffers), sizeof(sBuffers[]));
        
    iColor[0] = StringToInt(sBuffers[0]);
        
    iColor[1] = StringToInt(sBuffers[1]);
        
    iColor[2] = StringToInt(sBuffers[2]);
    }

    stock UTIL_GetRGBAFromString(String:sBuffer[], iColor[4])
    {
        
    decl String:sBuffers[4][4];
        
    ExplodeString(sBuffer" "sBufferssizeof(sBuffers), sizeof(sBuffers[]));
        
    iColor[0] = StringToInt(sBuffers[0]);
        
    iColor[1] = StringToInt(sBuffers[1]);
        
    iColor[2] = StringToInt(sBuffers[2]);
        
    iColor[3] = StringToInt(sBuffers[3]);
    }
    KvGetColor получает rgba цвет. То есть в таком виде "200 25 25 250"
    А для hex юзай KvGetString
     
  11. MAGNAT2645

    MAGNAT2645

    Сообщения:
    33
    Симпатии:
    0
    HEX мне больше не нужен, он теперь нормально отображается в зависимости от типа игрока, который прописан в "string". Мне теперь надо в плагине, указанном выше изменить ShowSyncHudText, чтобы он отображал информацию игрока в нужном цвете в зависимости от "string". Я пробовал KvGetColor, но HUD текст вообще не отображается, никаких ошибок и предупреждений в логах нет.
    --- Добавлено позже ---
    Если я буду использовать стоки выше, мне оставлять в конфиге "rgba" "255 255 255 255" или мне надо поделить (т.е. сначала "r" "255", потом "g" "255" и т.д.) ?
     
    Последнее редактирование: 1 июн 2016
  12. R1KO

    R1KO Супер-модератор

    Сообщения:
    5.971
    Симпатии:
    2.977
    @MAGNAT2645, у тебя hex в строке, передай в ф-ю StringToInt(sHEX, 16)
    16 это система числения
     
  13. MAGNAT2645

    MAGNAT2645

    Сообщения:
    33
    Симпатии:
    0
    Если честно, я совсем запутался, где и откуда брать и что передавать в StringToInt() (Можно подробнее, я не с первого раза соображаю)
     
  14. R1KO

    R1KO Супер-модератор

    Сообщения:
    5.971
    Симпатии:
    2.977
    В SetHudTextParams в цвет передавай StringToInt("ff44aa", 16)
     
  15. MAGNAT2645

    MAGNAT2645

    Сообщения:
    33
    Симпатии:
    0
    То есть мне можно вообще избавиться от "rgba" в конфиге и использовать "chat" ?
    --- Добавлено позже ---
    Просто ShowSyncHudText находится в другом плагине, а GetPlayerTypeData в моём и текст из "string" и цвет из "chat" хорошо отображаются в чате, но мне надо в плагине AimNames (который выше был), чтобы при наводке на игрока высвечивался HUD текст цвета в зависимости от типа игрока в "string": [Игрок]\n[Тип игрока] [Уровень] уровня\n[Подпись игрока]
    --- Добавлено позже ---
    Почему при наводке на игрока отображается HUD-текст либо красного цвета, либо прозрачного, либо его вообще нет.

    Вот инклюд:
    PHP:
    stock GetRGBFromHex(char[] sBufferint iColor[3])
    {
     
    char sBuffers[3][4];
     
    ExplodeString(sBuffer" "sBufferssizeof(sBuffers), sizeof(sBuffers[]));
     
    iColor[0] = StringToInt(sBuffers[0], 16);
     
    iColor[1] = StringToInt(sBuffers[1], 16);
     
    iColor[2] = StringToInt(sBuffers[2], 16);
    }
    Вот из плагина AimNames:
    PHP:
    int intColor[MAXPLAYERS 1][3];

    new 
    String:PlayerType[MAXPLAYERS 1][500], String:PlayerTypeHex[MAXPLAYERS 1][500];

    public 
    Action:Timer_SyncHud(Handle:timerany:client)
    {
     if (
    g_bEnabled && g_aPlayers[client][bHudEnabled])
     {
     if (
    IsClientObserver(client))
     {
     return 
    Plugin_Continue;
     }
     
     new 
    iTarget GetClientAimTarget(clienttrue);
     if (!
    IsValidClient(iTargetfalse))
     {
     return 
    Plugin_Continue;
     }
     
     new 
    Float:client_pos[3], Float:target_pos[3];
     
    GetClientEyePosition(clientclient_pos);
     
    GetClientEyePosition(iTargettarget_pos);
     
     
    TargetHP GetClientHealth(iTarget);
     
    TargetId GetClientUserId(iTarget);
     
    AimPlayerLevel[iTarget] = GetPlayerLevel(iTarget);
     
    GetPlayerSign(iTargetAimPlayerSign[iTarget]);
     
    GetPlayerTypeData(iTarget"string"PlayerType[iTarget], sizeof(PlayerType[]));
     
    GetPlayerTypeData(iTarget"chat"PlayerTypeHex[iTarget], sizeof(PlayerTypeHex[]));
     
    GetRGBFromHex(PlayerTypeHex[iTarget], intColor[iTarget]);
     
     if (
    CanSeeTarget(clientclient_posiTargettarget_posg_fDistance))
     {
     if (
    g_CurrentMod == GameType_TF
     
    && TF2_GetPlayerCond(iTarget) & (TF2_PLAYERCOND_DISGUISING TF2_PLAYERCOND_DISGUISED TF2_PLAYERCOND_SPYCLOAK))
     {
     return 
    Plugin_Continue;
     }
     else
     {
     
    Client_PrintKeyHintText(client"%N (userid: %i)\nЗдоровье: %i"iTargetTargetIdTargetHP);
     
     
    SetHudTextParams(-1.00.59g_fHoldtimeintColor[iTarget][0], intColor[iTarget][1], intColor[iTarget][2], 2551);
     
    ShowSyncHudText(clientg_hHud"%N\n%s %i уровня\n\"%s\""iTargetPlayerType[iTarget], AimPlayerLevel[iTarget], AimPlayerSign[iTarget]);
     }
     }
     }
     else
     {
     
    g_aPlayers[client][hHudTimer] = INVALID_HANDLE;
     return 
    Plugin_Stop;
     }
     return 
    Plugin_Continue;
    }
    --- Добавлено позже ---
    Всё, я кажется догадался!
     
    Последнее редактирование: 6 июн 2016