- 3
- 0
Здравствуйте.
У меня есть gamemode и серверные файлы Flin RP, в которых используется система проверки клиента через auth_key для определения версии клиента и включения функций вроде Real Cars, Real Skins и других кастомных возможностей.
В gamemode используется проверка через RPC_ClientJoin и сравнение полученного auth_key со списком разрешённых версий клиента.
Мне нужно понять, как работает эта система и что именно отвечает за отправку данного ключа от клиента к серверу.
Интересует помощь в создании или настройке ASI-модуля, который будет корректно отправлять нужный auth_key, чтобы сервер определял клиент как поддерживаемую версию и включал необходимые функции.
Также хотелось бы понять как правильно сделать совместимость с системой проверки клиента для Flin RP.
Буду благодарен за объяснение принципа работы или пример реализации.
Прикрепил архив с необходимыми include-файлами
В архиве находятся файлы:
Прикладываю их для ознакомления, чтобы было проще разобраться в структуре системы и понять, как реализована связь между сервером и клиентом.
У меня есть 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
Прикладываю их для ознакомления, чтобы было проще разобраться в структуре системы и понять, как реализована связь между сервером и клиентом.
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;
}
Вложения
Последнее редактирование: