Articles > Internal docs > SAMP internals
SAMP internals
Everything on this page is about SA-MP 0.3.7-R4
- Client console commands
- Vehicle categories (client)
- Vehicle damage status
- Player position and server streaming
- Packet priority, reliability, ordering channel
- Misc
Client console commands
See samp.dll+690D0.
/audiomsg- toggles whether messages are printed when audio streams are played/cmpstat- does absolutely nothing/ctd- toggles camera target debug (what is the effect?)/dl- toggles debug labels on vehicles/fontsize <size>- changes chat window's font size/fpslimit <limit>- set fps limit of the game. only has effect if "Frame limiter" in game settings is enabled./headmove- toggles whether other players' character head will move to the direction they're looking at/hudscalefix- toggles a fix that ensures the minimap radar is a circle on widescreen resolutions/interior- prints the current game interior/logurls- toggles whether messages are printend when files are downloaded. file downloading is leftover code that is not usable./mem- prints the game's streaming memory limit/nametagstatus- toggles whether the "hourglass" icon is shown next to players' nametags when they are paused/pagesize <size>- sets amount of lines that the chat window shows on screen/q- alias of/quit/quit- quit the game/rcon <command>- sends rcon commands to the server-
/rs [comment]- saves current position, depending on your state:- when on foot, saves
x,y,z,facingAngle ; commentinDocuments\GTA San Andreas User Files\SAMP\rawpositions.txt - when in car, saves
model,x,y,z,heading,col1,col2 ; commentinrawvehicles.txtin your game folder (this seems like an oversight and was probably supposed to be in User Files too)
- when on foot, saves
-
/save [comment]- saves current position inDocuments\GTA San Andreas User Files\SAMP\savedpositions.txtformatted as aAddPlayerClass
or
AddStaticVehicle
function call, depending on your state.
/testdw- send test values to the death message list (death message list may be hidden with F9)/timestamp- toggles whether to show timestamp before chat messages/togobjlight- seems unused
samp_debug.exe), following commands are also available:
/player_skin <skinid>/set_weather <weatherid>/set_time <hour> <minute>/v <model>- alias of/vehicle/vehicle <modelid>- spawns a vehicle next to you.modelvalue is unchecked, so this will crash the client if it's invalid/vsel- opens vehicle selection UI. Use theJUMP/SPRINTkeys to select the model andENTER VEHICLEkey to spawn
Vehicle Categories (client)
Some vehicle things are handled differently by the client depending on the category of the vehicle. The category of a vehicle is determined at runtime by its vtable. SAMP defines following categories:
- 0: other, which effectively is: trailer/monstertruck(+dune/dumper)/quadbike(1)
- 1: automobile (vtable
0x871120) - 2: motorcycle (vtable
0x871360) - 3: heli (vtable
0x871680) - 4: boat (vtable
0x8721A0) - 5: plane (vtable
0x871948) - 6: bike (vtable
0x871528) - 7: train (vtable
0x872370)
Full vehicle list
| model | actual vtable | assigned category | vehicle name |
|---|---|---|---|
| 400 | 0x871120 | 1 | Landstalker |
| 401 | 0x871120 | 1 | Bravura |
| 402 | 0x871120 | 1 | Buffalo |
| 403 | 0x871120 | 1 | Linerunner |
| 404 | 0x871120 | 1 | Perennial |
| 405 | 0x871120 | 1 | Sentinel |
| 406 | 0x8717D8 | 0(1) | Dumper |
| 407 | 0x871120 | 1 | Fire Truck |
| 408 | 0x871120 | 1 | Trashmaster |
| 409 | 0x871120 | 1 | Stretch |
| 410 | 0x871120 | 1 | Manana |
| 411 | 0x871120 | 1 | Infernus |
| 412 | 0x871120 | 1 | Voodoo |
| 413 | 0x871120 | 1 | Pony |
| 414 | 0x871120 | 1 | Mule |
| 415 | 0x871120 | 1 | Cheetah |
| 416 | 0x871120 | 1 | Ambulance |
| 417 | 0x871680 | 3 | Leviathan |
| 418 | 0x871120 | 1 | Moonbeam |
| 419 | 0x871120 | 1 | Esperanto |
| 420 | 0x871120 | 1 | Taxi |
| 421 | 0x871120 | 1 | Washington |
| 422 | 0x871120 | 1 | Bobcat |
| 423 | 0x871120 | 1 | Mr Whoopee |
| 424 | 0x871120 | 1 | BF Injection |
| 425 | 0x871680 | 3 | Hunter |
| 426 | 0x871120 | 1 | Premier |
| 427 | 0x871120 | 1 | Enforcer |
| 428 | 0x871120 | 1 | Securicar |
| 429 | 0x871120 | 1 | Banshee |
| 430 | 0x8721A0 | 4 | Predator |
| 431 | 0x871120 | 1 | Bus |
| 432 | 0x871120 | 1 | Rhino |
| 433 | 0x871120 | 1 | Barracks |
| 434 | 0x871120 | 1 | Hotknife |
| 435 | 0x871C28 | 0 | Artic Trailer 1 |
| 436 | 0x871120 | 1 | Previon |
| 437 | 0x871120 | 1 | Coach |
| 438 | 0x871120 | 1 | Cabbie |
| 439 | 0x871120 | 1 | Stallion |
| 440 | 0x871120 | 1 | Rumpo |
| 441 | 0x871120 | 1 | RC Bandit |
| 442 | 0x871120 | 1 | Romero |
| 443 | 0x871120 | 1 | Packer |
| 444 | 0x8717D8 | 0(1) | Monster |
| 445 | 0x871120 | 1 | Admiral |
| 446 | 0x8721A0 | 4 | Squalo |
| 447 | 0x871680 | 3 | Seasparrow |
| 448 | 0x871360 | 2 | Pizzaboy |
| 449 | 0x872370 | 7 | Tram |
| 450 | 0x871C28 | 0 | Artic Trailer 2 |
| 451 | 0x871120 | 1 | Turismo |
| 452 | 0x8721A0 | 4 | Speeder |
| 453 | 0x8721A0 | 4 | Reefer |
| 454 | 0x8721A0 | 4 | Tropic |
| 455 | 0x871120 | 1 | Flatbed |
| 456 | 0x871120 | 1 | Yankee |
| 457 | 0x871120 | 1 | Caddy |
| 458 | 0x871120 | 1 | Solair |
| 459 | 0x871120 | 1 | Berkley's RC Van |
| 460 | 0x871948 | 5 | Skimmer |
| 461 | 0x871360 | 2 | PCJ-600 |
| 462 | 0x871360 | 2 | Faggio |
| 463 | 0x871360 | 2 | Freeway |
| 464 | 0x871948 | 5 | RC Baron |
| 465 | 0x871680 | 3 | RC Raider |
| 466 | 0x871120 | 1 | Glendale |
| 467 | 0x871120 | 1 | Oceanic |
| 468 | 0x871360 | 2 | Sanchez |
| 469 | 0x871680 | 3 | Sparrow |
| 470 | 0x871120 | 1 | Patriot |
| 471 | 0x871AE8 | 0(1) | Quadbike |
| 472 | 0x8721A0 | 4 | Coast Guard |
| 473 | 0x8721A0 | 4 | Dinghy |
| 474 | 0x871120 | 1 | Hermes |
| 475 | 0x871120 | 1 | Sabre |
| 476 | 0x871948 | 5 | Rustler |
| 477 | 0x871120 | 1 | ZR-350 |
| 478 | 0x871120 | 1 | Walton |
| 479 | 0x871120 | 1 | Regina |
| 480 | 0x871120 | 1 | Comet |
| 481 | 0x871528 | 6 | BMX |
| 482 | 0x871120 | 1 | Burrito |
| 483 | 0x871120 | 1 | Camper |
| 484 | 0x8721A0 | 4 | Marquis |
| 485 | 0x871120 | 1 | Baggage |
| 486 | 0x871120 | 1 | Dozer |
| 487 | 0x871680 | 3 | Maverick |
| 488 | 0x871680 | 3 | News Chopper |
| 489 | 0x871120 | 1 | Rancher |
| 490 | 0x871120 | 1 | FBI Rancher |
| 491 | 0x871120 | 1 | Virgo |
| 492 | 0x871120 | 1 | Greenwood |
| 493 | 0x8721A0 | 4 | Jetmax |
| 494 | 0x871120 | 1 | Hotring Racer |
| 495 | 0x871120 | 1 | Sandking |
| 496 | 0x871120 | 1 | Blista Compact |
| 497 | 0x871680 | 3 | Police Maverick |
| 498 | 0x871120 | 1 | Boxville |
| 499 | 0x871120 | 1 | Benson |
| 500 | 0x871120 | 1 | Mesa |
| 501 | 0x871680 | 3 | RC Goblin |
| 502 | 0x871120 | 1 | Hotring Racer A |
| 503 | 0x871120 | 1 | Hotring Racer B |
| 504 | 0x871120 | 1 | Bloodring Banger |
| 505 | 0x871120 | 1 | Lure Rancher |
| 506 | 0x871120 | 1 | Super GT |
| 507 | 0x871120 | 1 | Elegant |
| 508 | 0x871120 | 1 | Journey |
| 509 | 0x871528 | 6 | Bike |
| 510 | 0x871528 | 6 | Mountain Bike |
| 511 | 0x871948 | 5 | Beagle |
| 512 | 0x871948 | 5 | Cropduster |
| 513 | 0x871948 | 5 | Stuntplane |
| 514 | 0x871120 | 1 | Tanker |
| 515 | 0x871120 | 1 | Roadtrain |
| 516 | 0x871120 | 1 | Nebula |
| 517 | 0x871120 | 1 | Majestic |
| 518 | 0x871120 | 1 | Buccaneer |
| 519 | 0x871948 | 5 | Shamal |
| 520 | 0x871948 | 5 | Hydra |
| 521 | 0x871360 | 2 | FCR-900 |
| 522 | 0x871360 | 2 | NRG-500 |
| 523 | 0x871360 | 2 | HPV1000 |
| 524 | 0x871120 | 1 | Cement Truck |
| 525 | 0x871120 | 1 | Towtruck |
| 526 | 0x871120 | 1 | Fortune |
| 527 | 0x871120 | 1 | Cadrona |
| 528 | 0x871120 | 1 | FBI Truck |
| 529 | 0x871120 | 1 | Willard |
| 530 | 0x871120 | 1 | Forklift |
| 531 | 0x871120 | 1 | Tractor |
| 532 | 0x871120 | 1 | Combine Harvester |
| 533 | 0x871120 | 1 | Feltzer |
| 534 | 0x871120 | 1 | Remington |
| 535 | 0x871120 | 1 | Slamvan |
| 536 | 0x871120 | 1 | Blade |
| 539 | 0x871948 | 5 | Vortex |
| 540 | 0x871120 | 1 | Vincent |
| 541 | 0x871120 | 1 | Bullet |
| 542 | 0x871120 | 1 | Clover |
| 543 | 0x871120 | 1 | Sadler |
| 544 | 0x871120 | 1 | Fire Truck Ladder |
| 545 | 0x871120 | 1 | Hustler |
| 546 | 0x871120 | 1 | Intruder |
| 547 | 0x871120 | 1 | Primo |
| 548 | 0x871680 | 3 | Cargobob |
| 549 | 0x871120 | 1 | Tampa |
| 550 | 0x871120 | 1 | Sunrise |
| 551 | 0x871120 | 1 | Merit |
| 552 | 0x871120 | 1 | Utility Van |
| 553 | 0x871948 | 5 | Nevada |
| 554 | 0x871120 | 1 | Yosemite |
| 555 | 0x871120 | 1 | Windsor |
| 556 | 0x8717D8 | 0(1) | Monster A |
| 557 | 0x8717D8 | 0(1) | Monster B |
| 558 | 0x871120 | 1 | Uranus |
| 559 | 0x871120 | 1 | Jester |
| 560 | 0x871120 | 1 | Sultan |
| 561 | 0x871120 | 1 | Stratum |
| 562 | 0x871120 | 1 | Elegy |
| 563 | 0x871680 | 3 | Raindance |
| 564 | 0x871120 | 1 | RC Tiger |
| 565 | 0x871120 | 1 | Flash |
| 566 | 0x871120 | 1 | Tahoma |
| 567 | 0x871120 | 1 | Savanna |
| 568 | 0x871120 | 1 | Bandito |
| 569 | 0x871120 | 7 | Freight flat |
| 570 | 0x871120 | 7 | Brown Streak Carriage |
| 571 | 0x871120 | 1 | Kart |
| 572 | 0x871120 | 1 | Mower |
| 573 | 0x8717D8 | 0(1) | Dune |
| 574 | 0x871120 | 1 | Sweeper |
| 575 | 0x871120 | 1 | Broadway |
| 576 | 0x871120 | 1 | Tornado |
| 577 | 0x871948 | 5 | AT-400 |
| 578 | 0x871120 | 1 | DFT-30 |
| 579 | 0x871120 | 1 | Huntley |
| 580 | 0x871120 | 1 | Stafford |
| 581 | 0x871360 | 2 | BF-400 |
| 582 | 0x871120 | 1 | Newsvan |
| 583 | 0x871120 | 1 | Tug |
| 584 | 0x871C28 | 0 | Tanker Trailer |
| 585 | 0x871120 | 1 | Emperor |
| 586 | 0x871360 | 2 | Wayfarer |
| 587 | 0x871120 | 1 | Euros |
| 588 | 0x871120 | 1 | Hotdog |
| 589 | 0x871120 | 1 | Club |
| 590 | 0x872370 | 7 | Freight box |
| 591 | 0x871C28 | 0 | Artic Trailer 3 |
| 592 | 0x871948 | 5 | Andromada |
| 593 | 0x871948 | 5 | Dodo |
| 594 | 0x871120 | 1 | RC Cam |
| 595 | 0x8721A0 | 4 | Launch |
| 596 | 0x871120 | 1 | Police LS |
| 597 | 0x871120 | 1 | Police SF |
| 598 | 0x871120 | 1 | Police LV |
| 599 | 0x871120 | 1 | Ranger |
| 600 | 0x871120 | 1 | Picador |
| 601 | 0x871120 | 1 | S.W.A.T. |
| 602 | 0x871120 | 1 | Alpha |
| 603 | 0x871120 | 1 | Phoenix |
| 604 | 0x871120 | 1 | Damaged Glendale |
| 605 | 0x871120 | 1 | Damaged Sadler |
| 606 | 0x871C28 | 0 | Baggage Box A |
| 607 | 0x871C28 | 0 | Baggage Box B |
| 608 | 0x871C28 | 0 | Tug Stairs |
| 609 | 0x871120 | 1 | Black Boxville |
| 610 | 0x871C28 | 0 | Farm Trailer |
| 611 | 0x871C28 | 0 | Utility Trailer |
Notes
(1) vehicles with a vtable that isn't one of the explicitely checked values
are put in category 0. Besides all trailers, this also (maybe unexpectedly) includes
Dumper, Monster, Monster A, Monster B, Quadbike, Dune. This is because the Dumper, Dune
and all Monster vehicles are instances of CMonsterTruck and the Quadbike has its own unique
CQuadBike class.
Vehicle damage status
See
https://basdon.github.io/documented-samp-pawn-api/main.xml#Appendix_Vehicle_Damage_Status
for an overview of vehicle support, behavior, and some quirks.
Server receiving damage from client
Server ignores damage status updates if it's not coming from the driver of the vehicle,
otherwise it's applied and synced unconditionally and OnVehicleDamageStatusUpdate
is invoked.
Client receiving damage from server
Behavior depends on the vehicle model it's being applied to, see also Vehicle categories. Most import to take into account: Dumper, Monster, Monster A, Monster B, Quadbike, Dune are categorized as "unknown", meaning none of their damage gets synced. The bumper may get damaged in the driver's game (or tires of a quad bike), but none of the other players will see any damage to that vehicle.
Client applies tire damage at CSampVehicle::ApplyVehicleDamageTires(char) with
following behavior:
- for CHeli/CPlane/CBmx/CBoat/CTrain/Unknown: nop
- for CAutomobile: apply to
CAutomobile.m_damageManager.wheel[] - for CBike: apply to
CBike.m_acWheelDamageState[]
Client applies other damage at CSampVehicle::ApplyVehicleDamagePanelsDoorsLights(int,int,char)
with following behavior:
- for CBike/CHeli/CPlane/CBmx/CBoat/CTrain/Unknown: nop
-
for CAutomobile/CPlane:
-
if not all values are
0:- apply panels doors lights to
CAutomobile::m_damageManager - call
CAutomobile::mCC()(seems to apply damage status things, spawn flying components if things are detached, ...)
- apply panels doors lights to
-
if all values are
0: callCAutomobile::Fix(1)(3)
-
if not all values are
Notes
(1) while CPlane inherits from CAutomobile,
it overrides the Fix method yet SAMP still calls the base CAutomobile::Fix for
CPlane instances. This is what causes the 'ghost door' effect(6) on some planes after doing
RepairVehicle()(2) or updating damage status to 0 on planes.
For comparison, MTA dispatches to specific overridden methods based on the vehicle's model info:
if (pModelInfo->IsCar() || pModelInfo->IsMonsterTruck() || pModelInfo->IsTrailer())
dwFunc = FUNC_CAutomobile__Fix(3);
else if (pModelInfo->IsPlane())
dwFunc = FUNC_CPlane__Fix(3);
else if (pModelInfo->IsHeli())
dwFunc = FUNC_CHeli__Fix(3);
else if (pModelInfo->IsBike())
dwFunc = FUNC_CBike_Fix(3);
It also defines FUNC_CQuadBike__Fix(3), yet that is not used in the above.
(2) RepairVehicle(vehicleid) is implemented in SAMP by doing SetVehicleHealth(vehicleid, 1000.0); UpdateVehicleDamageStatus(vehicleid, 0, 0, 0, 0);.
(3) Implementations of the Fix proc:
-
CAutomobile::Fixdoes the following:CAutomobile::m_damageManager.reset()if (!(CVehicle::pHandlingData->uiModelFlags & 0x100(4))) m_damageManager.door[2] = door[3] = door[4] = door[5] = 4(5);- clump stuff
CVehicle::m_nVehicleFlags[1] &= 0xFE;(clearsbIsDamaged)- matrix stuff
m_damageManager.wheel[0] = wheel[1] = wheel[2] = wheel[3] = 0;(seems unnecessary asm_damageManager.reset()already did this)- reset bouncing panels[citation needed]
-
CPlane::Fixdoes the following:CAutomobile::m_damageManager.reset()if (!(CVehicle::pHandlingData->uiModelFlags & 0x100(4))) m_damageManager.door[2] = door[3] = door[4] = door[5] = 4(5);CVehicle::m_nVehicleFlags[1] &= 0xFE;(clearsbIsDamaged)
-
CHeli::Fixdoes the following:CAutomobile::m_damageManager.reset()CVehicle::m_nVehicleFlags[1] &= 0xFE;(clearsbIsDamaged)
-
CBike::Fixdoes the following:CVehicle::m_nVehicleFlags[1] &= 0xFE;(clearsbIsDamaged)CBike::m_cDamageFlags &= 0xBF;(unknown)CBike::m_acWheelDamageState[0] = CBike::m_acWheelDamageState[1] = 0;
-
CQuadBike::Fixdoes the following:CAutomobile::m_damageManager.reset()m_damageManager.door[2] = door[3] = door[4] = door[5] = 4(5);- clump stuff
m_damageManager.wheel[0] = wheel[1] = wheel[2] = wheel[3] = 0;(seems unnecessary asm_damageManager.reset()already did this)CVehicle::m_nVehicleFlags[1] &= 0xFE;(clearsbIsDamaged)
(4) uiModelFlags mask 0x100 means NO_DOORS, as per data/handling.cfg comments (field modelFlags (af)).
(5) a damagemanager door value of 4 means that the door is removed/detached.
Player position and server streaming
Player position and streaming is processed when:
- receiving spectating sync data from that player
- receiving passenger sync data from that player
- receiving driver sync data from that player
- receiving onfoot sync data from that player
PlayerSpectateVehicle
is called
PlayerSpectatePlayer
is called
PutPlayerInVehicle
is called
First it will unconditionally store the passed position into the player's data.
Then it checks if the player has an expected location after being teleported (which gets set when calling either of:
PlayerSpectateVehicle
/
PlayerSpectatePlayer
/
PutPlayerInVehicle
/
SetVehiclePos
(only for the driver of the vehicle*)).
If the expected position has been set less than 5000ms ago (not configurable), streaming will be
aborted if the player is not yet within stream_distance of it.
*there is some inconsistent/unexpected behavior regarding this, it seems that tracking of who is driver of the vehicle isn't always reset correctly (it seems to be relying on receiving onuccupied sync packets). This results in the following behavior: when teleporting a vehicle with SetVehiclePos to a location further than the configured stream distance from the last driver of that vehicle, that player may experience a 5 second period where streaming may not be processed.
When triggered by receiving sync data, it will first check if enough time has passed since the last
time streaming was processed (stream_rate console/server.cfg variable) and skip if this
is not the case.
When triggered by the script functions, streaming is processed immediately. Note that this completely
bypasses the stream rate check, so it is possible that next streaming processing will occur much earlier
than what the normal stream_rate delay would be from this moment.
After streaming, the checkpoint and race checkpoint are tested. If one is active and the player is now inside and
was not before, the appropriate callback is called (OnPlayerEnterCheckpoint/OnPlayerEnterRaceCheckpoint).
If one is active and the player is not inside, and was before, the "Leave" callback is called. Note that state seems
to be reset when disabling a checkpoint, so disabling the checkpoint while a player is in it will not trigger the
"Leave" callback.
Streaming
Player markers
Player markers are streamed if the global setting for marker mode is not set to 0. Markers are updated every 2500ms (not configurable). Markers are included of players who are in the same virtual world, are not in state "none" or "spectating", not NPCs, and within the distance limit if marker mode is "streamed".
Vehicles
A vehicle is streamed in when it exists, has field_7A set to 1, is in the same virtual world, is not of model
FREIFLAT or STREAKC (those are never streamed to the client, the client always automatically creates 3 carriages
when the train engine vehicle is created), and is within stream_distance.
If that is not the case and the vehicle is still streamed in, it will be streamed out.
(note that no more vehicles will be streamed in if a client already has 700 vehicles streamed in)
Trivia: when it decides to stream in a vehicle, the function to stream in the vehicle checks the stream distance condition again even though we know it already passed that check. This doesn't happen for any of the other elements being streamed in this section.
Players
A player is streamed in when they exist, are not in state "none" or "spectating", are in the same virtual world,
and is within stream_distance (calculated from the player position, except if the player is a passenger
of a vehicle because then the position of the vehicle is used).
If that is not the case and the player is still streamed in, they will be streamed out.
(note that no more players will be streamed in if a client already has 200 players streamed in)
TextLabels
A 3D text label is streamed in when it is in use and, if attached to a player or vehicle: if that player or vehicle is streamed in, if not attached: if the label is in the same virtual world and the player is within its draw distance.
If that is not the case and the text label is still streamed in, it will be streamed out.
Pickups
A pickup is streamed in when it is in use, is in the same virtual world, and within stream_distance.
If that is not the case and the pickup is still streamed in, it will be streamed out.
Actors
An actor is streamed in when they are in use, are in the same virtual world, and within stream_distance.
If that is not the case and the actor is still streamed in, they will be streamed out.
Packet priority, reliability, ordering channel
| packet | priority | reliability | ord |
|---|---|---|---|
| Connection rejected | HIGH_PRIORITY | UNRELIABLE | 0 |
| Legacy destroy pickup (151) | HIGH_PRIORITY | RELIABLE | 0 |
| Scores & pings update | HIGH_PRIORITY | RELIABLE | 0 |
| Request Class | HIGH_PRIORITY | RELIABLE | 0 |
| On foot sync | HIGH_PRIORITY | UNRELIABLE_SEQUENCED | 1 |
| (all other scripting functions) | HIGH_PRIORITY | RELIABLE_ORDERED | 2 |
| Chat message | HIGH_PRIORITY | RELIABLE | 3 |
Misc
Scoreboard: the client periodically requests an update for player scores & pings (rpc 155). The server only responds if it has been more than 2000ms since the last request.
Legacy pickup rpcs: the server can receive rpc 97 which reads a single 2-byte pickup id, to which the server will broadcast rpc 151 to all clients (containing that 2-byte pickup id). Clients receiving rpc 151 will read a 1-byte value and delete a pickup identified by that value. It doesn't seem like clients ever send rpc 97.
rpc 102: when sent by the client (no payload), the server will respond (if player is rcon admin) with 196 bytes of raknet stats (assumption) (stats of UNASSIGNED_PLAYER_ID, so does this mean global stats?).
| Category: Internal docs | |
|---|---|
| SAMP internals • Tables | |
| Code | Preprocessor Definitions |
| File formats | Flight file format • Map file format • Textdraw file format |
| Services | Echo • Flighttracker |
This article has been accessed 249 time(s).
Main page Article index
