PDA

Просмотр полной версии : [CMD] /veh (ZCMD/DC_CMD + sscanf2 + y_stringhash)



Daniel_Cortez
26.03.2014, 19:45
CMD:veh(playerid, params[])
{ // by Daniel_Cortez \\ pro-pawn.ru
enum e_VEH_ENTRY
{
veHash,
veModel
};
static const veh_name_entries[][e_VEH_ENTRY] =
{
{_I@f<Admiral>, 445},
{_I@f<Alpha>, 602},
{_I@f<Ambulance>, 416},
{_I@f<Andromada>, 592},
{_I@f<Article1>, 435},
{_I@f<Article2>, 450},
{_I@f<Article3>, 591},
{_I@f<AT400>, 577},
{_I@f<Baggage>, 485},
{_I@f<BaggageTrailer1>, 606},
{_I@f<BaggageTrailer2>, 607},
{_I@f<BaggageTrailer3>, 608},
{_I@f<Bandito>, 568},
{_I@f<Banshee>, 429},
{_I@f<Barracks>, 433},
{_I@f<Beagle>, 511},
{_I@f<Benson>, 499},
{_I@f<BF400>, 581},
{_I@f<BFInjection>, 424},
{_I@f<Bike>, 509},
{_I@f<Blade>, 536},
{_I@f<BlistaCompact>, 496},
{_I@f<Bloodring>, 504},
{_I@f<BMX>, 481},
{_I@f<Bobcat>, 422},
{_I@f<Boxville>, 498},
{_I@f<BoxvilleBlack>, 609},
{_I@f<Bravura>, 401},
{_I@f<Broadway>, 575},
{_I@f<Buccaneer>, 518},
{_I@f<Buffalo>, 402},
{_I@f<Bullet>, 541},
{_I@f<Burrito>, 482},
{_I@f<Bus>, 431},
{_I@f<Cabbie>, 438},
{_I@f<Caddy>, 457},
{_I@f<Camper>, 483},
{_I@f<Cardona>, 527},
{_I@f<Cargobob>, 548},
{_I@f<CementTruck>, 524},
{_I@f<Cheetah>, 415},
{_I@f<Clover>, 542},
{_I@f<Club>, 589},
{_I@f<Coach>, 437},
{_I@f<Coastguard>, 472},
{_I@f<Combine>, 532},
{_I@f<Comet>, 480},
{_I@f<Cropduster>, 512},
{_I@f<DFT30>, 578},
{_I@f<Dinghy>, 473},
{_I@f<Dodo>, 593},
{_I@f<Dozer>, 486},
{_I@f<Dumper>, 406},
{_I@f<Dune>, 573},
{_I@f<Elegant>, 507},
{_I@f<Elegy>, 562},
{_I@f<Emperor>, 585},
{_I@f<Enforcer>, 427},
{_I@f<Esperanto>, 419},
{_I@f<Euros>, 587},
{_I@f<Faggio>, 462},
{_I@f<FarmTrailer>, 610},
{_I@f<FBIRancher>, 490},
{_I@f<FBITruck>, 528},
{_I@f<FCR900>, 521},
{_I@f<Feltzer>, 433},
{_I@f<Firetruck>, 407},
{_I@f<FiretruckLA>, 544},
{_I@f<Flash>, 565},
{_I@f<Flatbed>, 455},
{_I@f<Forklift>, 530},
{_I@f<Fortune>, 526},
{_I@f<Freeway>, 463},
//{_I@f<Freight>, 537},
//{_I@f<FreightFlat>, 568},
//{_I@f<FreightBox>, 590},
{_I@f<Glendale>, 466},
{_I@f<Glenshit>, 604},
{_I@f<Greenwood>, 492},
{_I@f<Hermes>, 474},
{_I@f<Hotdog>, 588},
{_I@f<Hotknife>, 434},
{_I@f<Hotring1>, 494},
{_I@f<Hotring2>, 502},
{_I@f<Hotring3>, 503},
{_I@f<HPV1000>, 523},
{_I@f<Hunter>, 425},
{_I@f<Huntley>, 579},
{_I@f<Hustler>, 545},
{_I@f<Hydra>, 520},
{_I@f<Infernus>, 411},
{_I@f<Intruder>, 546},
{_I@f<Jester>, 559},
{_I@f<Jetmax>, 493},
{_I@f<Journey>, 508},
{_I@f<Kart>, 571},
{_I@f<Landstalker>, 400},
{_I@f<Launch>, 595},
{_I@f<Leviathan>, 417},
{_I@f<Linerunner>, 403},
{_I@f<Majestic>, 517},
{_I@f<Manana>, 410},
{_I@f<Marquis>, 484},
{_I@f<Maverick>, 487},
{_I@f<Merit>, 551},
{_I@f<Mesa>, 500},
{_I@f<Monster>, 444},
{_I@f<MonsterA>, 556},
{_I@f<MonsterB>, 557},
{_I@f<Moonbeam>, 418},
{_I@f<MountainBike>, 510},
{_I@f<Mower>, 572},
{_I@f<MrWhoopee>, 423},
{_I@f<Mule>, 414},
{_I@f<Nebula>, 516},
{_I@f<Nevada>, 553},
{_I@f<Newsvan>, 582},
{_I@f<NRG500>, 522},
{_I@f<Oceanic>, 467},
{_I@f<Packer>, 443},
{_I@f<Patriot>, 470},
{_I@f<PCJ600>, 461},
{_I@f<Perenniel>, 404},
{_I@f<PetrolTrailer>, 584},
{_I@f<Phoenix>, 603},
{_I@f<Picador>, 600},
{_I@f<Pizzaboy>, 448},
{_I@f<PoliceCar1>, 596},
{_I@f<PoliceCar2>, 597},
{_I@f<PoliceCar3>, 598},
{_I@f<Pony>, 413},
{_I@f<Predator>, 430},
{_I@f<Premier>, 426},
{_I@f<Previon>, 436},
{_I@f<Primo>, 547},
{_I@f<Quad>, 471},
{_I@f<Raindance>, 563},
{_I@f<Rancher>, 489},
{_I@f<Ranger>, 599},
{_I@f<RCBandit>, 441},
{_I@f<RCGoblin>, 501},
{_I@f<RCBaron>, 464},
{_I@f<RCCam>, 594},
{_I@f<RCRaider>, 465},
{_I@f<RCTiger>, 564},
{_I@f<Reefer>, 453},
{_I@f<Regina>, 479},
{_I@f<Remington>, 534},
{_I@f<Rhino>, 432},
{_I@f<Roadtrain>, 515},
{_I@f<Romero>, 442},
{_I@f<Rumpo>, 440},
{_I@f<Rustler>, 476},
{_I@f<Sabre>, 475},
{_I@f<Sadler>, 543},
{_I@f<Sadshit>, 605},
{_I@f<Sanchez>, 468},
{_I@f<Sandking>, 495},
{_I@f<SANMaverick>, 488},
{_I@f<SAPDMaverick>, 497},
{_I@f<Savanna>, 567},
{_I@f<Seasparrow>, 447},
{_I@f<Securicar>, 428},
{_I@f<Sentinel>, 405},
{_I@f<Shamal>, 519},
{_I@f<Skimmer>, 460},
{_I@f<Slamvan>, 535},
{_I@f<Solair>, 458},
{_I@f<Sparrow>, 469},
{_I@f<Speeder>, 452},
{_I@f<Squalo>, 446},
{_I@f<Stafford>, 580},
{_I@f<Stallion>, 439},
{_I@f<Streak>, 538},
//{_I@f<StreakC>, 570},
{_I@f<Stratum>, 561},
{_I@f<Stretch>, 409},
{_I@f<Stuntplane>, 513},
{_I@f<Sultan>, 560},
{_I@f<Sunrise>, 550},
{_I@f<SuperGT>, 506},
{_I@f<SWAT>, 601},
{_I@f<Sweeper>, 574},
{_I@f<Tahoma>, 566},
{_I@f<Tampa>, 549},
{_I@f<Tanker>, 514},
{_I@f<Taxi>, 420},
{_I@f<Topfun>, 459},
{_I@f<Tornado>, 576},
{_I@f<Towtruck>, 525},
{_I@f<Tractor>, 531},
{_I@f<Trashmaster>, 408},
{_I@f<Tram>, 449},
{_I@f<Tropic>, 454},
{_I@f<Tug>, 583},
{_I@f<Turismo>, 451},
{_I@f<Uranus>, 558},
{_I@f<UtilityTrailer>, 611},
{_I@f<UtilityVan>, 552},
{_I@f<Vincent>, 540},
{_I@f<Virgo>, 491},
{_I@f<Voodoo>, 412},
{_I@f<Vortex>, 539},
{_I@f<Walton>, 478},
{_I@f<Washington>, 421},
{_I@f<Wayfarer>, 586},
{_I@f<Willard>, 529},
{_I@f<Windsor>, 555},
{_I@f<Yankee>, 456},
{_I@f<Yosemite>, 554},
{_I@f<ZR350>, 477}
};
// Проверка на администратора, замените на свою.
if(PlayerInfo[playerid][pAdmin] < 5)
return 0;
static color1, color2, model;
static Float:x, Float:y, Float:z, Float:f;
if(0 == sscanf(params, "ddd", model, color1, color2))
{
if((model < 400) || (611 < model))
return SendClientMessage(
playerid, -1, !"Ошибка: Модель транспорта должна быть от 400 до 611."
);
}
else if(0 == sscanf(params, "s[16]dd", params, color1, color2))
{
if(3 <= strlen(params) <= 15)
{
f = Float:YHash(params, false, hash_fnv1);
for(model = 0; model<sizeof(veh_name_entries); ++model)
if(_:f == veh_name_entries[model][veHash])
{
model = veh_name_entries[model][veModel];
goto found_model;
}
}
return SendClientMessage(playerid, -1, !"Ошибка: Неизвестное название.");
}
else
{
return SendClientMessage(
playerid, -1, !"Использование: /veh [модель авто] [цвет 1] [цвет 2]"
);
}
found_model:
GetPlayerPos(playerid, x, y, z);
GetPlayerFacingAngle(playerid, f);
x = x + (5.0 * floatsin(-f, degrees));
y = y + (5.0 * floatcos(-f, degrees));
if(CreateVehicle(model, x, y, z, f+90.0, color1, color2, -1) == 0)
return SendClientMessage(playerid, -1, !"Ошибка: Не удалось создать транспортное средство.");
static const fmt_str[] = "Транспортное средство %d создано.";
new string[sizeof(fmt_str)-2+5];
format(string, sizeof(string), fmt_str, model);
return SendClientMessage(playerid, COLOR_GREY, string);
}


Команда является примером к моему уроку по использованию y_stringhash (http://pro-pawn.ru/showthread.php?7923).

Преимущество команды перед другими вариантами в том, что в ней можно указывать не только ID модели, но и названия моделей транспорта. При этом секция данных не забита названиями моделей, вместо них используются хеши, каждый из которых занимает всего 1 ячейку.
Кроме того, если сделать поиск имени транспорта без хешей (по строкам с вызовом strcmp по over9000 раз), то кроме замусоренной секции данных можно получить ещё и уязвимость: если указать неправильное название, команда сравнит введённое название с названиями всех моделей (а это ~200 вызовов strcmp), благодаря чему появится возможность создать нагрузку на сервере флудом командой с неправильным названием модели.
Моя реализация с хешами не подвержена этой проблеме, т.к. вычисление хеша и сравнение его с заранее готовыми другими хешами названий моделей транспорта проходит гораздо быстрее, чем 200 вызовов strcmp.

Для работы этой команды подойдёт любой ZCMD-совместимый командный процессор (например, DC_CMD (http://pro-pawn.ru/showthread.php?1028)), плагин sscanf2 и инклуд y_stringhash (http://pro-pawn.ru/showthread.php?7923-%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5-y_stringhash)

Автор: Daniel_Cortez (http://pro-pawn.ru/member.php?100-Daniel_Cortez)


Специально для Pro-Pawn.ru (http://www.pro-pawn.ru)
Копирование данной статьи на других ресурсах без разрешения автора запрещено!