Ищу помощь с созданием ASI для проверки клиента и передачи auth_key для Flin RP

_Capone

Новичок
Автор темы
3
0
Здравствуйте.

У меня есть gamemode и серверные файлы Flin RP, в которых используется система проверки клиента через auth_key для определения версии клиента и включения функций вроде Real Cars, Real Skins и других кастомных возможностей.

В gamemode используется проверка через RPC_ClientJoin и сравнение полученного auth_key со списком разрешённых версий клиента.
Мне нужно понять, как работает эта система и что именно отвечает за отправку данного ключа от клиента к серверу.

Интересует помощь в создании или настройке ASI-модуля, который будет корректно отправлять нужный auth_key, чтобы сервер определял клиент как поддерживаемую версию и включал необходимые функции.

Также хотелось бы понять как правильно сделать совместимость с системой проверки клиента для Flin RP.
Буду благодарен за объяснение принципа работы или пример реализации.

Прикрепил архив с необходимыми include-файлами

В архиве находятся файлы:
  • custom_models.inc
  • custom_packets.inc
  • custom_sync.inc
  • perplayer.inc
Это файлы, которые используются в gamemode для работы с кастомным клиентом, моделями, пакетами и синхронизацией.

Прикладываю их для ознакомления, чтобы было проще разобраться в структуре системы и понять, как реализована связь между сервером и клиентом.


custom_packets.inc:
/*

    About: custom packets
    Author: Noname

*/
///////////////////////////////////////////////////////////////////////
//new
//11AE1522D623B5CB1C119FDD8D31128765C3BD896B9
new m_szClientVersions[][] = {
    {"14DB9BDE5A38450042D3D72C65952846E2C6826946B"},// flin romanov no actual
    {"39FB2DEEDB49ACFB8D4EECE6953D2507988CCCF4410"}, // sobeit kota 0.03
    {"10EF38095514DBF164C8FD10438A3C9BCB4DA4A9E15"}, //71
    {"15121F6F18550C00AC4B4F8A167D0379BB0ACA99043"}, //70
    {"161186A32578A6E62CBD2BB46D56F7F061EDB3A15B0"}, //69
    {"1031CA8429843C9B8C178B65F3C73602578440D17F8"},// 47
    {"C4B408C3A1C34E2E544EF21678A53108B2B8AE2518"},
    {"1034FEB5335C789FDC51EC085C9C0B2A91DA79E696B"},
    {"10B3D2B1317ADD02CC1F680BC500A8BC0FD7AD42CE7"},
    {"149C15C7E69314B147D55069C245763C07DD8AB4429"}
};
const ClientJoin = 25;
const ID_RPC = 20;
const RPC_CustomHash = 202;
const RPC_CustomUIP = 221;
const RPC_CustomUID = 222;

#define MAX_SUSPICIOUS_IP 10


new suspiciousIp[MAX_SUSPICIOUS_IP][16];

forward LoadIPCheckedCallback(playerid);
public LoadIPCheckedCallback(playerid)
{
    new rows = cache_num_rows();
    if(!rows) return SendError(playerid, "Список IP пустой.");
    for(new i; i < rows; i++)
    {
        if(i >= MAX_SUSPICIOUS_IP) return SendError(playerid, "IP больше лимита - %d, загружено первых %d", MAX_SUSPICIOUS_IP, MAX_SUSPICIOUS_IP);
        cache_get_value_name(i, "ip", suspiciousIp[i], 16);
    }
    SendAccess(playerid, "Загружено %d IP's.", rows);
    return 1;
}

CMD:reloadips(playerid, params[])
{
    if(p_info[playerid][admin] < 5) return 1;
    mysql_pquery(con_bd, "SELECT * FROM `ip_logs_list` WHERE 1", "LoadIPCheckedCallback", "i", playerid);
    return 1;
}

const ID_CUSTOM_MODELS = 244;

IRawPacket:ID_CUSTOM_MODELS(playerid, BitStream:bs)
{
    static version, string[32 + 1], len;

    BS_ReadValue(bs,
    PR_IGNORE_BITS, 8,
    PR_UINT8, version,
    PR_UINT8, len,
    PR_STRING, string, len
    );

    if(!SRV_ID) print(string); // Раскоментируй для получения нового хеш-суммы

    if(strequals(string, "b036abb531e0ba732b863d3d26c04c14"))
    {
        p_temp[playerid][mobile_version] = CLIENT_VERSION_022023;
        p_info[playerid][p_settings][INTERFACE] = 1;
        p_info[playerid][p_settings][LOGO_ID] = 1;

        Logotype_Show(playerid);
        Logotype_Time(playerid);
    }
    else if(strequals(string, "9648a7795fb81931a44bfbff0613d112"))
    {
        p_temp[playerid][mobile_version] = CLIENT_VERSION_20022023;
        p_info[playerid][p_settings][INTERFACE] = 1;
        p_info[playerid][p_settings][LOGO_ID] = 1;

        Logotype_Show(playerid);
        Logotype_Time(playerid);
    }
    else
    {
        p_temp[playerid][mobile_version] = CLIENT_VERSION_112022;
        SendError(playerid, "У вас не последняя версия кэша игры, обновитесь. Скачать: flin-rp.com/pc");
    }
    p_temp[playerid][is_mobile] = false;
    return 1;
}

CMD:setmobilestatus(playerid, params[])
{
    if(p_info[playerid][admin] < 10) return 1;
    p_temp[playerid][is_mobile] = true;
    p_temp[playerid][mobile_version] = CLIENT_VERSION_20022023;

    new nick_name[MAX_PLAYER_NAME];
    f(nick_name, "%s%s", get_name(playerid), "[PC:L]");
    SetPlayerName(playerid, nick_name);
    return 1;
}

IRawPacket:ID_RPC(playerid, BitStream:bs)
{
    new rpcid, numberOfBitsOfData;

    BS_ReadValue(bs,
        PR_IGNORE_BITS, 8, // packet id
        PR_UINT8, rpcid,
        PR_CUINT32, numberOfBitsOfData
    );

    switch(rpcid)
    {
        case RPC_CustomHash:
        {
            new i_bit;
            BS_ReadValue(bs, PR_UINT32, i_bit);
            p_temp[playerid][is_mobile] = true;
            if(i_bit != 0)
            {
                p_temp[playerid][mobile_version] = i_bit;

                p_info[playerid][p_settings][INTERFACE] = 1;
                p_info[playerid][p_settings][LOGO_ID] = 1;

                Logotype_Show(playerid);
                Logotype_Time(playerid);
            }
            if(strequals(get_name(playerid), FD1)) SendInfo(playerid, "%d", i_bit);
        }
        /*
        case RPC_CustomUIP:
        {
            new numberLenString, customUIP[MAX_IP_LENGTH];
            BS_ReadValue(bs, PR_UINT32, numberLenString);
            BS_ReadValue(bs, PR_STRING, customUIP, numberLenString);

            if(!strequals(customUIP, "none"))
            {
                p_temp[playerid][session_IP][0] = EOS;
                strcat(p_temp[playerid][session_IP], customUIP);
            }

            if(!SRV_ID)
            {
                f(STRING_GLOBAL, "[RPC customUIP] ID: %d | UIP: %s", playerid, p_temp[playerid][session_IP]);
                printf(STRING_GLOBAL);
                SendDebug(playerid, STRING_GLOBAL);
            }
        }
        case RPC_CustomUID:
        {
            new numberLenString;
            BS_ReadValue(bs, PR_UINT32, numberLenString);
            BS_ReadValue(bs, PR_STRING, p_temp[playerid][session_UID], numberLenString);

            if(strequals(p_temp[playerid][session_UID], "none"))
            {
                printf("pizda error");
                SendDebug(playerid, "pizda UID");
            }

            if(!SRV_ID)
            {
                f(STRING_GLOBAL, "[RPC CustomUID] ID: %d | UID: %s", playerid, p_temp[playerid][session_UID]);
                printf(STRING_GLOBAL);
                SendDebug(playerid, STRING_GLOBAL);
            }
        }
        */
    }
    return 1;
}

public OnIncomingRPC(playerid, rpcid, BitStream:bs)
{
    if(LOG_PACKETS_IN && p_temp[playerid][is_doss_attack])
    {
        Log(LOG_Incoming, INFO, "ID: <%d> IP: <%s> | RPC: <%s> ",
                playerid, p_temp[playerid][session_IP], rpcid);
    }
    return 1;
}

const ID_PLAYER_SYNC = 207;
public OnIncomingPacket(playerid, packetid, BitStream:bs)
{
    if(LOG_PACKETS_IN && p_temp[playerid][is_doss_attack])
    {
        Log(LOG_Incoming, INFO, "ID: <%d> | IP: <%s> | PKT: <%d>",
                playerid, p_temp[playerid][session_IP], packetid);
    }
    if(packetid == ID_PLAYER_SYNC)
    {
        new onFootData[PR_OnFootSync];
        BS_IgnoreBits(bs, 8);
        BS_ReadOnFootSync(bs, onFootData);
        if(onFootData[PR_specialAction] == SPECIAL_ACTION_ENTER_VEHICLE)
        {
            if(onFootData[PR_keys] & KEY_SPRINT)
            {
                onFootData[PR_keys] = onFootData[PR_keys] & ~KEY_SPRINT;
                BS_SetWriteOffset(bs, 8);
                BS_WriteOnFootSync(bs, onFootData);
            }
        }
    }
    return 1;
}

public OnOutcomingPacket(playerid, packetid, BitStream:bs)
{
    if(LOG_PACKETS_OUT && p_temp[playerid][is_doss_attack])
    {
        Log(LOG_Outcoming, INFO, "ID: <%d> | IP: <%s> | PKT: <%d>",
                playerid, p_temp[playerid][session_IP], packetid);
    }
    return 1;
}

CMD:getver(playerid, params[])
{
    SendInfo(playerid, "version: %d", p_temp[playerid][mobile_version]);
    return 1;
}
CMD:verchecks(playerid)
{
    SendInfo(playerid, "ver=%d realcars=%d", GetPlayerGameVersion(playerid), p_info[playerid][p_settings][REAL_CARS]);
    return 1;
}

IRPC:ClientJoin(playerid, BitStream:bs)
{
    if(playerid == INVALID_PLAYER_ID) return 1;
    p_temp[playerid][time_auth] = timestamp;

    new tmplen, auth_key[65];
    BS_ReadValue(bs, PR_IGNORE_BITS, 40, PR_UINT8, tmplen);
    BS_ReadValue(bs, PR_IGNORE_BITS, (tmplen * 8) + 32, PR_STRING8, auth_key, sizeof(auth_key));
    //printf( "auth_key: %s ", auth_key);

    p_temp[playerid][no_valid_client] =
    p_temp[playerid][is_mobile] = false;
    p_temp[playerid][mobile_version] = 0;//20004

    if(ServerInfo[BlockInvalidClient])
    {
        for(new i; i < sizeof(m_szClientVersions); i++)
        {
            if(strequals(auth_key, m_szClientVersions[i]))
            {
                p_temp[playerid][no_valid_client] = true;
                break;
            }
        }
    }
    if(!SRV_ID) printf(auth_key);
    if(p_temp[playerid][mobile_version] != -1)
    {
        if( strequals(auth_key, "C4B408C3A1C34E2E544EF21678A53108B2B8AE2518") ||
            strequals(auth_key, "1034FEB5335C789FDC51EC085C9C0B2A91DA79E696B") ||
            strequals(auth_key, "10B3D2B1317ADD02CC1F680BC500A8BC0FD7AD42CE7") ||
            strequals(auth_key, "149C15C7E69314B147D55069C245763C07DD8AB4429") ||
            strequals(auth_key, "13DEF05D2240620D328DC8918F763063038AFE16D88") ||
            strequals(auth_key, "D09E46CD6ECDD87BCE275DD1ADE2F001D64C8126B0") ||
            strequals(auth_key, "39FB2DEEDB49ACFB8D4EECE6953D2507988CCCF4410"))
        {
            SendInfo(playerid, "На сервере обновлен клиент, скачать его можно через новый лаунчер "SITE_URL".");
            //SendInfo(playerid, "Нам выдана приставка PC из-за старого клиента.");
            p_temp[playerid][mobile_version] = 145;
            p_temp[playerid][is_mobile] = true;
        }
        if(strequals(auth_key, "E02262CF28BC542486C558D4BE9EFB716592AFAF8B"))
        {
            p_temp[playerid][mobile_version] = 200;
            p_temp[playerid][is_mobile] = true;
        }
    }
    return 1;
}


#define RPC_CUSTOM_AIM 0x30

stock SendChangeAim(playerid, texture_name[])
{
    new BitStream:bitstream = BS_New();
    BS_WriteValue(bitstream, PR_UINT8, PACKET_CUSTOMRPC);
    BS_WriteValue(bitstream, PR_UINT32, RPC_CUSTOM_AIM);

    BS_WriteValue(bitstream, PR_UINT8, strlen(texture_name));
    BS_WriteValue(bitstream, PR_STRING, texture_name);

    PR_SendPacket(bitstream, playerid);

    BS_Delete(bitstream);
}

#define RPC_SET_SKY_SPEED 0x23

CMD:setskyboxspeed(playerid, params[])
{
    if(SRV_ID) return 1;
    if(sscanf(params, "i", params[0])) return SendInfo(playerid, "Используйте: /setskyboxspeed [speed]");
    SetSkySpeed(playerid, params[0]);
    return 1;
}

stock SetSkySpeed(playerid, speed)
{
    new BitStream:bitstream = BS_New();

    BS_WriteValue(bitstream, PR_UINT8, PACKET_CUSTOMRPC);
    BS_WriteValue(bitstream, PR_UINT32, RPC_SET_SKY_SPEED);
    BS_WriteValue(bitstream, PR_UINT8, speed);

    PR_SendPacket(bitstream, playerid);
    BS_Delete(bitstream);
}

#define RPC_SET_SKYBOX 0x24

CMD:setskybox(playerid, params[])
{
    if(SRV_ID) return 1;
    SendChangeSkybox(params);
    return 1;
}

stock SendChangeSkybox(texture_name[])
{
    new BitStream:bitstream = BS_New();
    BS_WriteValue(bitstream, PR_UINT8, PACKET_CUSTOMRPC);
    BS_WriteValue(bitstream, PR_UINT32, RPC_SET_SKYBOX);

    BS_WriteValue(bitstream, PR_UINT8, strlen(texture_name));
    BS_WriteValue(bitstream, PR_STRING, texture_name);

    PR_SendPacket(bitstream, -1);

    BS_Delete(bitstream);
}

#define RPC_SET_RADARLINE 0x25

stock SendChangeRadarLine(playerid, type, texture_name[]) // type 0 - круг, type 1 - квадрат
{
    new BitStream:bitstream = BS_New();

    BS_WriteValue(bitstream, PR_UINT8, PACKET_CUSTOMRPC);
    BS_WriteValue(bitstream, PR_UINT32, RPC_SET_RADARLINE);

    BS_WriteValue(bitstream, PR_UINT8, type);
    BS_WriteValue(bitstream, PR_UINT8, strlen(texture_name));
    BS_WriteValue(bitstream, PR_STRING, texture_name);

    PR_SendPacket(bitstream, playerid);
    BS_Delete(bitstream);
}
/*
IPacket:214(playerid, BitStream:bs)
{
    BS_IgnoreBits(bs, 8);
    new hash1, hash2, hash3, hash4, undreadedBits;
    BS_GetNumberOfUnreadBits(bs, undreadedBits);
    while (undreadedBits > 0) {
        BS_ReadValue(bs, PR_UINT32, hash1);
        BS_ReadValue(bs, PR_UINT32, hash2);
        BS_ReadValue(bs, PR_UINT32, hash3);
        BS_ReadValue(bs, PR_UINT32, hash4);

        BS_GetNumberOfUnreadBits(bs, undreadedBits);

        if(!SRV_ID)
        {
            printf("1: 0x%08x 2: 0x%08x 3: 0x%08x 4: 0x%08x", hash1, hash2, hash3, hash4);
            //printf("1: %d 2: %d 3: %d 4: %d", hash1, hash2, hash3, hash4);
        }
    }
    return 0;
}
*/
#define RPC_CHECK_CASH 0x26

stock SendCheckHash(playerid, texture_name[], cash_name[], cash_version)
{
    new BitStream:bitstream = BS_New();

    BS_WriteValue(bitstream, PR_UINT8, PACKET_CUSTOMRPC);
    BS_WriteValue(bitstream, PR_UINT32, RPC_CHECK_CASH);

    BS_WriteValue(bitstream, PR_UINT8, strlen(texture_name));
    BS_WriteValue(bitstream, PR_STRING, texture_name);

    BS_WriteValue(bitstream, PR_UINT8, strlen(cash_name));
    BS_WriteValue(bitstream, PR_STRING, cash_name);

    BS_WriteValue(bitstream, PR_UINT32, cash_version);

    PR_SendPacket(bitstream, playerid);
    BS_Delete(bitstream);
}


#define RPC_SHOW_DONATE 0x27

stock SendShowDonate(playerid)
{
    new BitStream:bitstream = BS_New();

    BS_WriteValue(bitstream, PR_UINT8, PACKET_CUSTOMRPC);
    BS_WriteValue(bitstream, PR_UINT32, RPC_SHOW_DONATE);

    PR_SendPacket(bitstream, playerid);
    BS_Delete(bitstream);
}

cmd:donateclient(playerid, params[])
{
    SendShowDonate(playerid);
    return 1;
}

enum {
    SKIN_ID, // Скин персонажа (Собественный айди)
    CLOTH_TORSO_PART, // Одежда на торс (Собественный айди) (Чтобы снять используется 0)
    CLOTH_HEAD_PART, // Одежда на голову (Не используется, следует оставить ради смещения числ в enum) (Чтобы снять используется 0)
    CLOTH_LEGS_PART, // Одежда на ноги (Собественный айди) (Чтобы снять используется 0)
    CLOTH_FEET_PART // Обувь (Собественный айди) (Чтобы снять используется 0)
}

#define RPC_SET_CLOTHES 0x28

stock SetPlayerClothes(playerid, forplayerid)
{
    new BitStream:bitstream = BS_New();

    BS_WriteValue(bitstream, PR_UINT8, PACKET_CUSTOMRPC);
    BS_WriteValue(bitstream, PR_UINT32, RPC_SET_CLOTHES);
    BS_WriteValue(bitstream, PR_UINT16, forplayerid);

    BS_WriteValue(bitstream,
        PR_UINT8, p_info[forplayerid][chothes_part][SKIN_ID],
        PR_UINT8, p_info[forplayerid][chothes_part][CLOTH_TORSO_PART],
        //PR_UINT8, p_info[forplayerid][chothes_part][CLOTH_HEAD_PART],
        PR_UINT8, p_info[forplayerid][chothes_part][CLOTH_LEGS_PART],
        PR_UINT8, p_info[forplayerid][chothes_part][CLOTH_FEET_PART]);

    PR_SendPacket(bitstream, playerid);
    BS_Delete(bitstream);
}
/*
CMD:skintest(playerid, params[])
{
    if(SRV_ID) return 1;
    SetPlayerSkin(playerid, 360);
    //p_info[playerid][chothes_part][SKIN_ID] = 360;
    SendInfo(playerid, "SET SKIN ID: %d", GetPlayerSkin(playerid));
    return 1;
}

CMD:setchothes(playerid, params[])
{
    if(SRV_ID) return 1;
    if(GetPlayerSkin(playerid) != 360)
        return SendError(playerid, "У Вас не 360 скин.");
    if(sscanf(params, "iiii", params[0], params[1], params[2], params[3]))
        return SendInfo(playerid, "Используйте: /setchothes [skin ID] [torso ID] [legs ID] [feet ID]");
    if( !(0 <= params[0] <= 1) ||
        !(0 <= params[1] <= 11) ||
        !(0 <= params[2] <= 11) ||
        !(0 <= params[3] <= 5))
        return SendError(playerid, "Используйте: /setchothes [skin ID] [torso ID] [legs ID] [feet ID]");

    p_info[playerid][chothes_part][SKIN_ID] = params[0];
    p_info[playerid][chothes_part][CLOTH_TORSO_PART] = params[1];
    p_info[playerid][chothes_part][CLOTH_LEGS_PART] = params[2];
    p_info[playerid][chothes_part][CLOTH_FEET_PART] = params[3];

    foreach(new targetid: PlayerPlayersStream[playerid])
        SetPlayerClothes(targetid, playerid);
    SetPlayerClothes(playerid, playerid);
    return 1;
}
*/
custom_models.inc:
#define INVALID_OBJECTS_VERSION    0x3

#if defined _invalidobjects_included
    #endinput
#endif
#define _invalidobjects_included

#if !defined PAWNCMD_INC_
    #error "not connected include Pawn.RakNet"
#endif

#if defined RPC_CREATE_OBJECT
    #undef RPC_CREATE_OBJECT
    #define RPC_CREATE_OBJECT 44
#else
    #define RPC_CREATE_OBJECT 44
#endif

#if defined RPC_WORLDVEHICLE_ADD
    #undef RPC_WORLDVEHICLE_ADD
    #define RPC_WORLDVEHICLE_ADD 164
#else
    #define RPC_WORLDVEHICLE_ADD 164
#endif

#if defined RPC_SET_PLAYER_SKIN
    #undef RPC_SET_PLAYER_SKIN
    #define RPC_SET_PLAYER_SKIN 153
#else
    #define RPC_SET_PLAYER_SKIN 153
#endif

#if defined RPC_CLIENT_JOIN
    #undef RPC_CLIENT_JOIN
    #define RPC_CLIENT_JOIN 25
#else
    #define RPC_CLIENT_JOIN 25
#endif

#if defined RPC_CREATE_PICKUP
    #undef RPC_CREATE_PICKUP
    #define RPC_CREATE_PICKUP 95
#else
    #define RPC_CREATE_PICKUP 95
#endif

#define PICKUP_REPLACE_MODEL 1239

#define PLAYER_DEVICE_PC 0
#define PLAYER_DEVICE_ANDROID 1

enum E_PICKUP_STRUCT
{
    dPickupID,       // UINT32
    dModelID,           // UINT32
    dSpawnType,       // UINT32
    Float:pickupX,   // FLOAT
    Float:pickupY,   // FLOAT
    Float:pickupZ    // FLOAT
};

enum E_OBJECT_STRUCT
{
    e_wObjectID,             // INT16
    e_ModelID,                // UINT32
    Float:e_objectX,        // FLOAT
    Float:e_objectY,        // FLOAT
    Float:e_objectZ,        // FLOAT
    Float:e_rotx,            // FLOAT
    Float:e_roty,            // FLOAT
    Float:e_rotz,            // FLOAT
    float:e_DrawDistance,    // FLOAT
    e_NoCameraCol,            // UINT8
    e_attachedObject,        // UINT16
    e_attachedVehicle,        // UINT16
    float:e_AttachOffsetX,    // FLOAT
    float:e_AttachOffsetY,    // FLOAT
    float:e_AttachOffsetZ,    // FLOAT
    float:e_AttachRotX,        // FLOAT
    float:e_AttachRotY,        // FLOAT
    float:e_AttachRotZ,        // FLOAT
    e_SyncRotation             // UINT8

};

enum E_VEHICLE_STRUCT
{
    e_vVehicleID,             // INT16
    e_vModelID,                // UINT32
    Float:e_posX,
    Float:e_posY,
    Float:e_posZ,
    Float:e_rot,
    e_vColor1,
    e_vColor2,
    Float:e_vHealth,
    e_vInterior,
    e_vDoorDamageStatus,
    e_vPanelDamageStatus,
    e_vByteLightDamageStatus,
    e_vByteTimeDamageStatus,
    e_vByteAddSiren
};

enum E_PLAYER_STRUCT
{
    e_usPlayerID,
    e_bTeam,
    e_uiSkin,
    e_pfPosX,
    e_pfPosY,
    e_pfPosZ,
    e_pfRot,
    e_uiColor,
    e_bFighting,
    e_boolVisible
};

static dataObject[E_OBJECT_STRUCT];
static vehicleData[E_VEHICLE_STRUCT];
static playerData[E_PLAYER_STRUCT];

/*
static playerDevice[MAX_PLAYERS char];

stock setDeviceInfo(playerId, deviceType)
{
    playerDevice{playerId} = deviceType;
    return 1;
}

stock isInvalidObject(modelId)
{
    if(modelId < 11000)
        return -1;
    new returnval = -1;
    for(new it; it < sizeof(m_szSampModels); it++)
    {
        if(m_szSampModels[it] == modelId)
        {
            returnval = modelId;
            break;
        }
    }
    return returnval;
}
*/

enum e_customVeh
{
    CustomID,
    ModelID,
    ModelName[40],
    ModelPrice,
    Float:ModelMaxSpeed
}

#define MAX_VEH_MODELS_REPLACE (54+14)
new customVehModels[MAX_VEH_MODELS_REPLACE][e_customVeh] = {
    {3215, 411, "Bugatti Chiron",                               12500, 210.0},
    {3610, 579, "Mercedes G63 AMG 6x6 [Бронированный]",         15000, 169.0},
    {4546, 580, "Rolls-Royce Phantom",                          10000, 180.0},
    {3222, 541, "Ferrari Pista 488",                            9500,  193.0},
    {3248, 451, "McLaren 720s",                                 9500,  184.0},
    {3349, 560, "Porsche Panamero Turbo",                       8000,  180.0},
    {3219, 451, "McLaren 600LT",                                8000,  189.0},
    {3201, 411, "Bentley Continental",                          7500,  210.0},
    {3200, 579, "Bentley Bentayga",                             7500,  174.0},
    {3194, 411, "Aston Martin Vantage",                         7500,  209.0},
    {3870, 579, "Mercedes G63",                                 7000,  179.0},
    {3239, 561, "Mercedes-Maybach",                             7000,  185.0},
    {3210, 415, "BMW M8",                                       6500,  189.0},
    {3429, 579, "Range Rover SVR",                              6000,  173.0},
    {3233, 415, "Lexus LC",                                     5500,  188.0},

    {3245, 560, "Tesla Model S",                5000,  176.0},
    {3974, 541, "Nissan GTR",                   4500,  195.0},
    {3217, 579, "Cadillac Escalade",            3500,  174.0},
    {3247, 560, "Mercedes E63 AMG S",           3000,  176.0},
    {3235, 580, "Lexus LX570",                  2750,  173.0},
    {3205, 560, "Mercedes AMG GT63",            2750,  176.0},
    {3231, 579, "Land Cruiser 200",             2500,  174.0},
    {3211, 579, "BMW X5M",                      2500,  173.0},
    {3208, 560, "BMW M5 F90",                   2500,  176.0},
    {3197, 411, "Audi R8",                      2250,  210.0},
    {3204, 402, "BMW M4 F82",                   2000,  188.0},
    {3227, 400, "Jeep Grand Cherokee",          1750,  173.0},
    {3206, 560, "BMW M5 E60",                   1500,  175.0},

    {3199, 560, "Audi RS7",                     1500,  176.0},
    {3202, 550, "BMW E39",                      1250,  176.0},
    {3254, 560, "Mercedes C63 AMG",             1250,  177.0},
    {3234, 560, "Lexus IS",                     1250,  188.0},
    {3218, 560, "Camry XV 70",                  1250,  176.0},
    {4763, 579, "Tesla Cybertruck",             1000,  173.0},
    {3195, 507, "Audi 3",                       750,   196.0},
    {3883, 421, "Mercedes W124",                500,   182.0},
    {3784, 551, "Mercedes 230",                 400,   172.0},
    {3611, 551, "Mercedes 190E",                350,   181.0},
    {4766, 541, "Toyota Celica",                300,   182.0},
    {4764, 426, "Toyota Chaser",                250,   196.0},
    {3236, 551, "Toyota Mark II",               200,   182.0},

    {3196, 561, "ВАЗ 2109",                     2000,  141.0},
    {3207, 560, "Subaru Impreza WRX STI",       2500,  177.0},
    {3416, 550, "Honda Accord",                 3000,  185.0},
    {3251, 562, "Nissan 370Z",                  3500,  200.0},
    {3198, 463, "Harley-Davidson",              4000,  148.0},
    {3224, 475, "Opel GT",                      4500,  210.0},
    {3209, 560, "KIA K5",                       5000,  192.0},
    {3871, 541, "Dodge Challenger SRT 8",       7500,  190.0},
    {3220, 579, "Infiniti QX80",                7500,  170.0},
    {3240, 579, "Hummer H2",                    7500,  190.0},
    {4765, 522, "Suzuki Hayabusa",              10000, 195.0},
    {4545, 541, "Porsche 911",                  12500, 225.0},
    {3212, 541, "Lamborghini Veneno Roadster",  15000, 225.0},
    //Новые от 03.02.2023
    {4785, 541, "Pegassi Lampo CG22",           7500, 225.0},
    {4786, 541, "Benefactor SM-722",            6500, 215.0},
    {4787, 541, "Emperor Vectre",               6000, 215.0},
    {4788, 541, "Imponte Ruiner ZZ",            6500, 210.0},
    {4789, 579, "Mammoth Patriot",              7500, 170.0},
    {4790, 541, "Overflod Zeno",                6500, 225.0},
    {4791, 541, "Pegassi Torero",               6500, 225.0},
    {4794, 579, "BMW X6M",                      2800, 180.0},
    {5090, 405, "VAZ 2102",                     800, 110.0},
    {5092, 504, "Vapid Peyote",                 800, 130.0},
    {5095, 479, "УАЗ",                          800, 110.0},
    {5096, 467, "Волга",                        1000, 160.0},
    {5097, 500, "Нива",                         1000, 145.0},
    {5101, 467, "Ferrari F50",                  4500, 180.0}
};

GetSlotVehicleModelSync(modelid)
{
    for(new i = MAX_VEH_MODELS_REPLACE-1; i != -1; i--)
    {
        if(customVehModels[i][CustomID] == modelid)
            return i;
    }
    return -1;
}

#define MAX_SKIN_MODELS_REPLACE 22
static skinModels[MAX_SKIN_MODELS_REPLACE][] = {
    {793, 287},
    {794, 5},
    {795, 83},
    {796, 283},
    {797, 285},
    {798, 86},
    {799, 103},
    {907, 175},
    {908, 73},
    {909, 81},
    {965, 22},
    {999, 80},
    {1194, 29},
    {1195, 2},
    {1196, 108},
    {1197, 114},
    {1198, 37},
    {1199, 270},
    {1200, 279},
    {1201, 269},
    {1202, 280},
    {1203, 107}
};

stock getDefaultSkinModel(modelId)
{
    for(new i = 0; i < MAX_SKIN_MODELS_REPLACE; i++)
    {
        if(skinModels[i][0] == modelId)
        {
            return skinModels[i][1];
        }
    }
    return -1;
}

/*
#define MAX_OBJECT_MODELS_REPLACE  3
static objModels[MAX_OBJECT_MODELS_REPLACE] = { 1241, 13182, 9183 };

stock isInvalidObjectModel(modelId)
{
    for(new i = 0; i < MAX_OBJECT_MODELS_REPLACE; i++)
    {
        if(objModels[i] == modelId)
        {
            return 1;
        }
    }
    return 0;
}

stock getReplacableObjectModel(modelId)
{
    for(new i = 0; i < MAX_OBJECT_MODELS_REPLACE; i++)
    {
        if(objModels[i][0] == modelId)
        {
            return skinModels[i][1];
        }
    }
    return -1;
}
*/
#if defined _inc_y_hooks || defined _INC_y_hooks
    hook OnIncomingRPC(playerid, rpcid, BitStream:bs)
#else
    public OnIncomingRPC(playerid, rpcid, BitStream:bs)
#endif
    {
        #if defined INCLUDE_OnIncomingRPC
            return INCLUDE_OnIncomingRPC(playerid, rpcid, BitStream:bs);
        #else
            return 1;
        #endif
    }

#if !defined _inc_y_hooks && !defined _INC_y_hooks
    #if defined _ALS_OnIncomingRPC
        #undef OnIncomingRPC
    #else
        #define _ALS_OnIncomingRPC
    #endif

    #define OnIncomingRPC INCLUDE_OnIncomingRPC
    #if defined INCLUDE_OnIncomingRPC
        forward INCLUDE_OnIncomingRPC(playerid, rpcid, BitStream:bs);
    #endif
#endif

#define RPC_ScrGivePlayerWeapon 22
#define RPC_ScrSetPlayerAttachedObject 113
#define RPC_WorldPlayerAdd 32

stock ReplaceSkinToDefault(playerid, BitStream:bs)
{
    new player, skinid;
    BS_ReadValue(
        bs,
        PR_UINT32, player,
        PR_UINT32, skinid);

    if(skinid > 311 &&
        (!ServerInfo[RealSkinsStatus] ||
        GetPlayerGameVersion(playerid) < CLIENT_VERSION_20022023 ||
        !p_info[playerid][p_settings][REAL_SKINS]))
    {
        skinid = getDefaultSkinModel(skinid);
        if(skinid == -1) skinid = 0;
        new BitStream:bitstream = BS_New();
        BS_WriteValue( bitstream, PR_UINT32, player, PR_UINT32, skinid);
        PR_SendRPC(bitstream, playerid, RPC_SET_PLAYER_SKIN, PR_HIGH_PRIORITY, PR_RELIABLE_SEQUENCED);
        BS_Delete(bitstream);
        return 1;
    }
    return 0;
}

stock ReplaceSkinToDefaultAdd(playerid, BitStream:bs)
{
    static clearPlayerData[E_PLAYER_STRUCT];
    playerData = clearPlayerData;

    BS_ReadValue(
        bs,
        PR_INT16, playerData[e_usPlayerID],
        PR_UINT8, playerData[e_bTeam],
        PR_UINT32, playerData[e_uiSkin],
        PR_FLOAT, playerData[e_pfPosX],
        PR_FLOAT, playerData[e_pfPosY],
        PR_FLOAT, playerData[e_pfPosZ],
        PR_FLOAT, playerData[e_pfRot],
        PR_UINT32, playerData[e_uiColor],
        PR_UINT8, playerData[e_bFighting],
        PR_BOOL, playerData[e_boolVisible]);

    if(playerData[e_uiSkin] > 311 &&
        (!ServerInfo[RealSkinsStatus] ||
        GetPlayerGameVersion(playerid) < CLIENT_VERSION_20022023 ||
        !p_info[playerid][p_settings][REAL_SKINS]))
    {
        playerData[e_uiSkin] = getDefaultSkinModel(playerData[e_uiSkin]);
        if(playerData[e_uiSkin] == -1) playerData[e_uiSkin] = 0;
        new BitStream:bitstream = BS_New();
        BS_WriteValue(
            bitstream,
            PR_INT16, playerData[e_usPlayerID],
            PR_UINT8, playerData[e_bTeam],
            PR_UINT32, playerData[e_uiSkin],
            PR_FLOAT, playerData[e_pfPosX],
            PR_FLOAT, playerData[e_pfPosY],
            PR_FLOAT, playerData[e_pfPosZ],
            PR_FLOAT, playerData[e_pfRot],
            PR_UINT32, playerData[e_uiColor],
            PR_UINT8, playerData[e_bFighting],
            PR_BOOL, playerData[e_boolVisible]);

        PR_SendRPC(bitstream, playerid, RPC_WorldPlayerAdd, PR_HIGH_PRIORITY, PR_RELIABLE_SEQUENCED);
        BS_Delete(bitstream);
        return 1;
    }
    return 0;
}

stock ProcessReplaceVehicle(playerid, BitStream:bs)
{
    static clearVehicleData[E_VEHICLE_STRUCT];
    vehicleData = clearVehicleData;
    new modSlots[14];
    new bytePaintJob;
    new color1, color2;

    BS_ReadValue(bs,
        PR_INT16, vehicleData[e_vVehicleID],
        PR_UINT32, vehicleData[e_vModelID],
        PR_FLOAT, vehicleData[e_posX],
        PR_FLOAT, vehicleData[e_posY],
        PR_FLOAT, vehicleData[e_posZ],
        PR_FLOAT, vehicleData[e_rot],
        PR_UINT8, vehicleData[e_vColor1],
        PR_UINT8, vehicleData[e_vColor2],
        PR_FLOAT, vehicleData[e_vHealth],
        PR_UINT8, vehicleData[e_vInterior],
        PR_UINT32, vehicleData[e_vDoorDamageStatus],
        PR_UINT32, vehicleData[e_vPanelDamageStatus],
        PR_UINT8, vehicleData[e_vByteLightDamageStatus],
        PR_UINT8, vehicleData[e_vByteTimeDamageStatus],
        PR_UINT8, vehicleData[e_vByteAddSiren]);
    for(new i = 0; i < 14; i++)
    {
        BS_ReadValue(bs, PR_UINT8, modSlots[i]);
    }
    BS_ReadValue(bs, PR_UINT8, bytePaintJob);
    BS_ReadValue(bs, PR_UINT32, color1, PR_UINT32, color2);

    new custom_model = veh_info[vehicleData[e_vVehicleID]][v_model];

    if(!(400 <= custom_model <= 611))
    {
        new BitStream:bitstream = BS_New();

        BS_WriteValue(
            bitstream,
            PR_INT16, vehicleData[e_vVehicleID],
            PR_UINT32, custom_model,
            PR_FLOAT, vehicleData[e_posX],
            PR_FLOAT, vehicleData[e_posY],
            PR_FLOAT, vehicleData[e_posZ],
            PR_FLOAT, vehicleData[e_rot],
            PR_UINT8, vehicleData[e_vColor1],
            PR_UINT8, vehicleData[e_vColor2],
            PR_FLOAT, vehicleData[e_vHealth],
            PR_UINT8, vehicleData[e_vInterior],
            PR_UINT32, vehicleData[e_vDoorDamageStatus],
            PR_UINT32, vehicleData[e_vPanelDamageStatus],
            PR_UINT8, vehicleData[e_vByteLightDamageStatus],
            PR_UINT8, vehicleData[e_vByteTimeDamageStatus],
            PR_UINT8, vehicleData[e_vByteAddSiren]);

        for(new i = 0; i < 14; i++)
        {
            BS_WriteValue(bitstream, PR_UINT8, modSlots[i]);
        }
        BS_WriteValue(bitstream, PR_UINT8, bytePaintJob);
        BS_WriteValue(bitstream, PR_UINT32, color1, PR_UINT32, color2);

        PR_SendRPC(bitstream, playerid, RPC_WORLDVEHICLE_ADD, PR_HIGH_PRIORITY, PR_RELIABLE_SEQUENCED);
        BS_Delete(bitstream);
        return 1;
    }
    return 0;
}
stock IsShouldSendCreateObject(playerid, BitStream:bs)
{
    static clearDataObject[E_OBJECT_STRUCT];
    dataObject = clearDataObject;

    BS_ReadValue(
        bs,
        PR_INT16, dataObject[e_wObjectID],
        PR_UINT32, dataObject[e_ModelID],
        PR_FLOAT, dataObject[e_objectX],
        PR_FLOAT, dataObject[e_objectY],
        PR_FLOAT, dataObject[e_objectZ],
        PR_FLOAT, dataObject[e_rotx],
        PR_FLOAT, dataObject[e_roty],
        PR_FLOAT, dataObject[e_rotz],
        PR_FLOAT, dataObject[e_DrawDistance],
        PR_UINT8, dataObject[e_NoCameraCol],
        PR_UINT16, dataObject[e_attachedObject],
        PR_UINT16, dataObject[e_attachedVehicle],
        PR_FLOAT, dataObject[e_AttachOffsetX],
        PR_FLOAT, dataObject[e_AttachOffsetY],
        PR_FLOAT, dataObject[e_AttachOffsetZ],
        PR_FLOAT, dataObject[e_AttachRotX],
        PR_FLOAT, dataObject[e_AttachRotY],
        PR_FLOAT, dataObject[e_AttachRotZ],
        PR_UINT8, dataObject[e_SyncRotation]);

    if(isInvalidObjectModel(dataObject[e_ModelID]))
    {
        return 0;
    }
    return 1;
}

stock IsShouldSendCreateAttached(playerid, BitStream:bs)
{
    new sPlayerID, iSlot, bCreate;
       BS_ReadValue(
        bs,
        PR_UINT16, sPlayerID,
        PR_UINT32, iSlot,
        PR_BOOL,   bCreate);
    if(bCreate)
    {
         new modelid;
           BS_ReadValue(bs, PR_UINT32, modelid);
        if(isInvalidObjectModel(modelid))
        {
            return 0;
           }
    }
    return 1;
}

#define WEAPON_SECURE 0x100
#define WEAPON_SECURE_KEY    0x15

#if defined _inc_y_hooks || defined _INC_y_hooks
    hook OnOutcomingRPC(playerid, rpcid, BitStream:bs)
#else
    public OnOutcomingRPC(playerid, rpcid, BitStream:bs)
#endif
    {
        if(playerid == -1) return 1;
/*
        if(rpcid == RPC_CREATE_OBJECT)
        {
            if(IsPlayerMobile(playerid)) // если игрок с ведра
            {
                //if(getPlayerAndroidVers(playerid) < server_invalid_client) // если у игрока версия, которая ниже версии клиента с лимитом и модпаком
                {
                    if(!IsShouldSendCreateObject(playerid, bs)) // если модель невалидная, то не отсылаем
                    {
                        new _frmtsrt[50];
                        format(_frmtsrt, sizeof(_frmtsrt), "[Warning] Bad object model: 32");
                        SendClientMessage(playerid, 0xa9c4e4FF, _frmtsrt);
                        return 0;
                    }
                }
            }
            else // иначе игрок с ПК
            {
                if(!IsShouldSendCreateObject(playerid, bs)) // если модель невалидная, то не отсылаем
                {
                    new _frmtsrt[50];
                    format(_frmtsrt, sizeof(_frmtsrt), "[Warning] Bad object model: 32");
                    SendClientMessage(playerid, 0xa9c4e4FF, _frmtsrt);
                    return 0;
                }
            }
        }
        else if(rpcid == RPC_ScrGivePlayerWeapon) // серверная защита
        {
            new val1, val2;
            BS_ReadValue(
                 bs,
                   PR_UINT32, val1,
                PR_UINT32, val2);

            new BitStream:bitstream = BS_New();
            BS_WriteValue(
                  bitstream,
                PR_UINT32, val1,     //id
                PR_UINT32, val2,        //model
                PR_UINT32, WEAPON_SECURE ^ WEAPON_SECURE_KEY
            );
            PR_SendRPC(bitstream, playerid, RPC_ScrGivePlayerWeapon, PR_HIGH_PRIORITY, PR_RELIABLE_SEQUENCED);
            BS_Delete(bitstream);
            return 0;
        }
        else if(rpcid == RPC_ScrSetPlayerAttachedObject)
        {
            if(IsPlayerMobile(playerid)) // если игрок с ведра
            {
                //if(getPlayerAndroidVers(playerid) < server_invalid_client) // если у игрока версия, которая ниже версии клиента с лимитом и модпаком
                {
                    if(!IsShouldSendCreateAttached(playerid, bs)) // если модель невалидная, то не отсылаем
                    {
                        new _frmtsrt[50];
                        format(_frmtsrt, sizeof(_frmtsrt), "[Warning] Bad object mode1: 33");
                        SendClientMessage(playerid, 0xa9c4e4FF, _frmtsrt);
                        return 0;
                    }
                }
            }
            else // иначе игрок с ПК
            {
                if(!IsShouldSendCreateAttached(playerid, bs)) // если модель невалидная, то не отсылаем
                {
                       new _frmtsrt[50];
                    format(_frmtsrt, sizeof(_frmtsrt), "[Warning] Bad object model: 33");
                    SendClientMessage(playerid, 0xa9c4e4FF, _frmtsrt);
                    return 0;
                }
            }
        }
        */

        if(rpcid == RPC_WORLDVEHICLE_ADD)
        {
            if(ServerInfo[RealCarsStatus] && GetPlayerGameVersion(playerid) >= CLIENT_VERSION_022023 && p_info[playerid][p_settings][REAL_CARS]) // если у игрока версия, которая нужна для работы реал карс
            {
                if(ProcessReplaceVehicle(playerid, bs)) // если модель была заменена успешно, то оригинальный пакет не отсылаем
                    return 0;
            }
        }
        else if(rpcid == RPC_SET_PLAYER_SKIN)
        {
            if(ReplaceSkinToDefault(playerid, bs)) // если модель заменена на дефолтную то пакет не отправляем
                return 0;
        }
        else if(rpcid == RPC_WorldPlayerAdd)
        {
            if(ReplaceSkinToDefaultAdd(playerid, bs)) // если модель заменена на дефолтную то пакет не отправляем
                return 0;
        }
        /*
        else if(rpcid == RPC_CREATE_PICKUP)
        {
            if(IsPlayerMobile(playerid))
            {
                if(getPlayerAndroidVers(playerid) < server_invalid_client)
                {
                    new dataPickup[E_PICKUP_STRUCT];
                    BS_ReadValue(
                        bs,
                        PR_UINT32, dataPickup[dPickupID],
                        PR_UINT32, dataPickup[dModelID],
                        PR_UINT32, dataPickup[dSpawnType],
                        PR_FLOAT, dataPickup[pickupX],
                        PR_FLOAT, dataPickup[pickupY],
                        PR_FLOAT, dataPickup[pickupZ]
                        );

                    if(isInvalidObject(dataPickup[dModelID]) != -1)
                    {
                        new _frmtsrt[50];
                        format(_frmtsrt, sizeof(_frmtsrt), "[Warning] Bad pickup model: %d(%d)", dataPickup[dModelID], dataPickup[dPickupID]);
                        SendClientMessage(playerid, 0xa9c4e4FF, _frmtsrt);
                        // переписать модель
                        new BitStream:bitstream = BS_New();
                        BS_WriteValue(
                            bitstream,
                            PR_UINT32, dataPickup[dPickupID],     //id
                            PR_UINT32, PICKUP_REPLACE_MODEL,    //model
                            PR_UINT32, dataPickup[dSpawnType],  //type.
                            PR_FLOAT, dataPickup[pickupX],         //x.
                            PR_FLOAT, dataPickup[pickupY],         //y.
                            PR_FLOAT, dataPickup[pickupZ]         //z.
                        );
                        PR_SendRPC(bitstream, playerid, RPC_CREATE_PICKUP, PR_HIGH_PRIORITY, PR_RELIABLE_SEQUENCED);
                        BS_Delete(bitstream);
                        return 0;
                    }
                }
            }
        }
*/
        if(LOG_PACKETS_OUT && p_temp[playerid][is_doss_attack])
        {
            Log(LOG_Outcoming, INFO, "ID: <%d> | IP: <%s> | RPC: <%d>",
                    playerid, p_temp[playerid][session_IP], rpcid);
        }
        #if defined INCLUDE_OnOutcomingRPC
            return INCLUDE_OnOutcomingRPC(playerid, rpcid, BitStream:bs);
        #else
            return 1;
        #endif
    }

#if !defined _inc_y_hooks && !defined _INC_y_hooks
    #if defined _ALS_OnOutcomingRPC
        #undef OnOutcomingRPC
    #else
        #define _ALS_OnOutcomingRPC
    #endif

    #define OnOutcomingRPC INCLUDE_OnOutcomingRPC
    #if defined INCLUDE_OnOutcomingRPC
        forward INCLUDE_OnOutcomingRPC(playerid, rpcid, BitStream:bs);
    #endif
#endif

CMD:skintags(playerid)
{
    if(GetPlayerVirtualWorld(playerid) == playerid+1000 || p_info[playerid][pfreeze] == 0) return 1;
    Fix_TogglePlayerControllable(playerid, false);
    p_info[playerid][p_settings][REAL_SKINS] ^= 1;
    SetTimerEx("ToggleVisibleSync", 2500, false, "ii", playerid, GetPlayerVirtualWorld(playerid));
    SetPlayerVirtualWorld(playerid, playerid+1000);
    SendAccess(playerid, "Вы %s отображение новых скинов.", p_info[playerid][p_settings][REAL_SKINS] == 0 ? "выключили" : "включили");
    UpdatePlayerSetting(playerid);
    return 1;
}


CMD:vehicletags(playerid)
{
    if(GetPlayerVirtualWorld(playerid) == playerid+1000 || p_info[playerid][pfreeze] == 0) return 1;
    Fix_TogglePlayerControllable(playerid, false);
    p_info[playerid][p_settings][REAL_CARS] ^= 1;
    SetTimerEx("ToggleVisibleSync", 2500, false, "ii", playerid, GetPlayerVirtualWorld(playerid));
    SetPlayerVirtualWorld(playerid, playerid+1000);
    SendAccess(playerid, "Вы %s отображение новых моделей т/с.", p_info[playerid][p_settings][REAL_CARS] == 0 ? "выключили" : "включили");
    UpdatePlayerSetting(playerid);
    return 1;
}

CMD:vehnumtags(playerid)
{
    if(GetPlayerVirtualWorld(playerid) == playerid+1000 || p_info[playerid][pfreeze] == 0) return 1;
    Fix_TogglePlayerControllable(playerid, false);
    p_info[playerid][p_settings][NUMBER_VEHICLES] ^= 1;
    SetTimerEx("ToggleVisibleSync", 2500, false, "ii", playerid, GetPlayerVirtualWorld(playerid));
    SetPlayerVirtualWorld(playerid, playerid+1000);
    SendAccess(playerid, "Вы %s отображение номеров на т/с.", p_info[playerid][p_settings][NUMBER_VEHICLES] == 0 ? "выключили" : "включили");
    UpdatePlayerSetting(playerid);
    return 1;
}

forward ToggleVisibleSync(playerid, old_vw_id);
public ToggleVisibleSync(playerid, old_vw_id)
{
    SetPlayerVirtualWorld(playerid, old_vw_id);
    Fix_TogglePlayerControllable(playerid, true);
    return 1;
}
/*
CMD:testcar(playerid, params[])
{
    new vehicleid = GetPlayerVehicleID(playerid);
    SetVehicleMaxSpeed(vehicleid, 40.0);
    SetVehicleGear(vehicleid, 3.1);
    SetVehicleAcceleration(vehicleid, 25.0);
    SetVehicleMass(vehicleid, 10000.0);
    return 1;
}
*/
cmd:setmass(playerid, params[])
{
    if(SRV_ID) return 1;
    new Float:fValue;
    if(sscanf(params, "f", fValue)) return SendError(playerid, "error");
    new vehicleid = GetPlayerVehicleID(playerid);
    SetVehicleMass(vehicleid, fValue);
    return 1;
}

cmd:setacc(playerid, params[])
{
    if(SRV_ID) return 1;
    new Float:fValue;
    if(sscanf(params, "f", fValue)) return SendError(playerid, "error");
    new vehicleid = GetPlayerVehicleID(playerid);
    SetVehicleAcceleration(vehicleid, fValue);
    return 1;
}

cmd:setgear(playerid, params[])
{
    if(SRV_ID) return 1;
    new Float:fValue;
    if(sscanf(params, "f", fValue)) return SendError(playerid, "error");
    new vehicleid = GetPlayerVehicleID(playerid);
    SetVehicleGear(vehicleid, fValue);
    return 1;
}

cmd:setspeed(playerid, params[])
{
    if(SRV_ID) return 1;
    new Float:fValue;
    if(sscanf(params, "f", fValue)) return SendError(playerid, "error");
    new vehicleid = GetPlayerVehicleID(playerid);
    SetVehicleMaxSpeed(vehicleid, fValue);
    return 1;
}

cmd:settcoef(playerid, params[])
{
    if(SRV_ID) return 1;
    new Float:fValue;
    if(sscanf(params, "f", fValue)) return SendError(playerid, "error");
    new vehicleid = GetPlayerVehicleID(playerid);
    SetVehicleTractionCoef(vehicleid, fValue);
    return 1;
}

cmd:setbias(playerid, params[])
{
    if(SRV_ID) return 1;
    new Float:fValue;
    if(sscanf(params, "f", fValue)) return SendError(playerid, "error");
    new vehicleid = GetPlayerVehicleID(playerid);
    SetVehicleSuspensionBias(vehicleid, fValue);
    return 1;
}

cmd:setlower(playerid, params[])
{
    if(SRV_ID) return 1;
    new Float:fValue;
    if(sscanf(params, "f", fValue)) return SendError(playerid, "error");
    new vehicleid = GetPlayerVehicleID(playerid);
    SetVehicleSuspensionLower(vehicleid, fValue);
    return 1;
}
 

Вложения

  • raknet.rar
    14 KB · Просмотры: 0
Последнее редактирование: