VGOEmulator.net

A Development Project for the Vanguard:Saga of Heroes MMO

Skip to content

Advanced search
  • Quick links
    • Unanswered topics
    • Active topics
    • Search
  • Portal
  • Project Manager
  • Bug Tracker
  • Server List
  • Wiki
  • Donate
  • Login
  • Register
  • Board index Development Content Development
  • Search

Identifying Unreal bits

VGOEmulator content development topics.

Moderators: Moldew, Jakkal

Post Reply
Advanced search
37 posts
  • 1
  • 2
  • 3
  • 4
  • Next
User avatar
John Adams
Retired
Posts: 4583
Joined: Wed Aug 28, 2013 9:40 am
Location: Phoenix, AZ.
Contact:
Contact John Adams
Website
Identifying Unreal bits
  • Quote

Post by John Adams » Sun Jun 08, 2014 5:26 pm

In looking over the raw data, assuming I'm getting mostly everything that's in the bitstream (though I think there are still a few unknowns), it's time to try and figure out what some of this data does. Xinux and I spent the afternoon playing with some Chickens so I'll use that for my first example.

SGONPCPawn entityTypes
`entity_types` is a bitwise field that tells what "type" of spawn it is. Here's a list of known types we've discovered, with the help of Amadeus' original list:

Code: Select all

$this->VGOEntityTypes = array(
		2 				=> "Corpse",
		4 				=> "CraftingStation",
		8 				=> "Merchant",
		16 				=> "NPC",
		32 				=> "PC",
		64 				=> "Trainer",
		128 			=> "Instructor",
		256 			=> "Banker",
		512 			=> "TaskMaster",
		1024 			=> "Harvestable",
		2048 			=> "Resource",
		4096 			=> "Pet",
		8192 			=> "Charmed",
		16384 		=> "Unknown",
		32768 		=> "Clickable",
		65536 		=> "Stunned",
		131072 		=> "Mailbox",
		2097152		=> "Clone",
		4194304		=> "Charmed2",
		8388608		=> "AssemblyStation",
		16777216	=> "Altar",
		33554432	=> "House Escrow Merchant",
		134217728	=> "Broker",
		268435456	=> "Attackable",
		536870912 => "Unknown536870912",
		1073741824=> "Merchant2"
);
If you know how bitwise values work, these are basically the 0's and 1's in a given position in an integer (32-bit) value. So for an NPC, it has the value of 16, which is 10000 in bits. Tan Fen Greatcloud of Isle of Dawn is entity_type 16, so he's just a plain vanilla NPC.

However, our chickens were a little different. They had an entity_type value of 16, 268435472 and 268468240.
16		= NPC
268435472	= NPC, Attackable
268468240	= NPC, Clickable, Attackable
The NPC (16) we could see it's name and click on the chicken. If Hail worked, we could probably talk to it

The NPC, Attackable (268435472) we could see their names, see the dot representation of their difficulty, and when you moused over them you saw a sword icon (attack).

Now the odd one, the NPC, Clickable, Attackable (268468240) was standing there on the ground with no name, no level info and could not be clicked. This tells me "Clickable" (32768) isn't exactly what it appears

In short, the `entity_types` value governs a few things, like mouseover icon and whether something can be attacked or is even clickable at all.


SGONPCPawn modelNum
This is another value that I do not think means exactly what it says. I played with it a little with Tan Fen Greatcloud (aka, guinea pig boy). Normally, he and his cohorts on Isle of Dawn are modelNum = 2. I changed him to a random chosen value of 10, and loaded my server. He started to float and had a sparkly head:
[attachment=3]ScreenShot_00118.JPG[/attachment]

I then changed it to 86, and boy I sure didn't expect to see this:
[attachment=2]ScreenShot_00120.JPG[/attachment]

His face and hands are distorted. The NPC I got this value from was named "Rift Keeper", so maybe there's some weird appearances about this spawn, or a combo of other settings make this look a little more... normal.


SGONPCPawn gravityPlane and drawScale
I found if I turn either of these on with a 0 (zero) value, the NPCs completely disappear (drawScale) or fall through the terrain (gravityPlane). In the former, if I move around a little I can actually see flashes of the NPC name blink on and off real quick. This makes me think drawScale = 0 might make the NPC super tiny, maybe I cannot see it. I am working to find a default value other than 0 that might make this work. I suspect this may be how to re-size the Pawns. gravityPlane, I honestly have no idea yet... out of all parsings, either the value is 0, or it's 6.

Edit: From Unreal code:

Code: Select all

var(Display) const interp float	DrawScale;		// Scaling factor, 1.0=normal size.
Since my default values are always 0.0, I guess my assumption is true - they are too small to see. I'll play with this more and let you know.


SGONPCPawn groundSpeed
This is a player and NPC value, though the NPC parsings have never yielded a value > 0. Xen set our default player groundSpeed to 3000, which is why we zoom through the world so quickly. I found that groundSpeed 0 is, standing still. If you set your player to that, he cannot move. Foof reminded me that 500 is default, so now there is a new Rule in the World for R_Player::DefaultGroundSpeed = 500. In your rule_details, set that to a higher value if you want to haul ass.


SGONPCPawn physics
With values of 0, 1, 3 and 4 (in all our data) I conclude these are the only ones Vanguard uses. Using Tan Fen again, here's what I noticed:
physics = 0, he disappears completely
physics = 1, his default (parsed) value, and when I target him he turns his head and looks me right in the eyes.
physics = 3, when I target him he turns his head and looks me right in the eyes. no other differences in his appearance seen.
physics = 4, he seems to turn and stare at my boobs. Not sure what's up with that.

[attachment=1]ScreenShot_00121.JPG[/attachment]


[attachment=0]ScreenShot_00122.JPG[/attachment]


Edit: From Unreal code:

Code: Select all

enum EPhysics
{
    PHYS_None               =0,
    PHYS_Walking            =1,
    PHYS_Falling            =2,
    PHYS_Swimming           =3,
    PHYS_Flying             =4,
    PHYS_Rotating           =5,
    PHYS_Projectile         =6,
    PHYS_Interpolating      =7,
    PHYS_Spider             =8,
    PHYS_Ladder             =9,
    PHYS_RigidBody          =10,
    PHYS_Articulated        =11,
    PHYS_MAX                =12,
};
Note: I must still be missing something, since my examples up top show 1, 3 and 4 and this guy didn't change much - maybe because we do not yet support motion*.


SGONPCPawn posture
This is turning out to be an annoying setting. Because of this value, I have to duplicate a nearly-identical spawn just because one might be walking (1), or running (2), or doing nothing. Without in-game movement, I'll have to trust that these 2 values do what they say... for now. fwiw, in all our parsed data (million+ of records) the only posture besides 0 was 2.


SGONPCPawn isOnMount
I am assuming this value tells us if the NPC is on a mount, and possibly the mount type. The known values are: 70, 83, 94, 130, 179, 210, 211, 227, 245, 314 with 0 (zero) of course being no mount. I cannot find a reference to what these IDs mean yet, but they may tie to an entity ID of the mount during the session. Might need to get Xinux on this one.


SGONPCPawn pointsValue
These are the dots that represent the impossibleness to kill a spawn They start at 0, so 0 = 1 dot, up to 5 (6 dots).


SGONPCPawn role
0 seems to be NPC, 3 is Players at least so far in parsed data.

Code: Select all

enum ENetRole
{
    ROLE_None               =0,
    ROLE_SimulatedProxy     =1,
    ROLE_AutonomousProxy    =2,
    ROLE_Authority          =3,
    ROLE_MAX                =4,
};
SGONPCPawn ID's
We have raceID, genderID, and factionID. We even have a classID that is always 0 (zero). For gender, we know it's 0 = male, 1 = female, 2 = unknown. Race ID's we'll eventually build a list, unless there is one in the client already (Xinux?) and the same with Faction ID's, which we'll parse with our collections, hopefully getting them all.


SGONPCPawn Locations
This is probably the most perplexing of all the data's so far. There are quite a few, per spawn. The easy one is simply location x,y,z. The values relate to the map surface quite easily.

The FVector for Rotation is blowing my mind. I have no idea how to interpret these values; pitch, yaw, roll. I know it has to do with the 3D aspect, like maybe your visual plane. But the fun doesn't stop there... here's the list of the rest of them

Code: Select all

location_x2, location_y2, location_z2, rotation_pitch2, rotation_yaw2, rotation_roll2, goal_x, goal_y, goal_z, velocity_x, velocity_y, velocity_z, velocity_x2, velocity_y2, velocity_z2, pivot_x, pivot_y, pivot_z
Just being a smart guy, I kind of expect Velocity has something to do with motion and we concluded that Goal was the next set of coordinates in a wandering path (cant' wait to parse those). But the loc 2's, rotation 2's and velocity 2's, no idea.

There's also these pivot coords. If anyone has any ideas, I'm all ears. Without knowing how the values translate to the world, I cannot begin to test values randomly to identify what they do.


PlayerPlacedObjects General
This class uses a few values from the Actor above it, shared by SGONPCPawns. The couple of unique values to this class are:

parent_id = never seen anything > 0
object_id = a static value for the object placed in the game
building_id = a static value for the object placed in the game
building_type = no idea what these are yet
mouseover_display = yay, I know what one is! This is the sign data that pops up when you mouse over an object in-game


SGOSound3DS General
Sounds are those creepy screams, moans and bangs you hear in the game. Probably some sawing too. The data consists of an x,y,z location of where the sound gets triggered. There is what they call a "bounding box" which generally is the entire chunk, and has min/max x,y,z coordinates. Meaning, the sound could happen anywhere in the chunk, triggered by the location_x,y,z values (assumed). As far as where the trigger starts, there's a Radius and zRange (verticle?) and a soundRotation pitch, yaw and roll.

There's a couple extra values I am not sure of yet; reverbType, specialAmbience, _3DSType, and... oneShots. I'm guessing this last one might be "play once, then go away" per trigger.

More on this class as we investigate it. Sounds make the world come alive.


SGOMusic3DS General
Similar to Sounds, these have a location x,y,z, bounding boxes, etc. Just fewer unknown options. There are 3 things that appear like the ogg or filename values for the triggered music effect: excitementIsactFile, primaryIsactFile and secondaryIsactFile

There's an entryIntensity (I guess that's for dramatic moments?) and the entryOgg, which was always blank for me.


I bring up the sounds and music because this is the first game I've worked on where this stuff is sent/triggered from the world to the client, and not within the client itself. Meaning, I'm walking along and all of a sudden something screams at me because I entered a cube on the grid. It's pretty cool.

That's all I have time for today, I'll update this post as I discover more things and if you feel inspired to jump in and analyze something yourself, grab VGVisualParser.exe and parse a log full of "NPCs", and you'll get Spawns, PPOs, Sounds and Music in your database. Thanks in advance if you choose to help.
You do not have the required permissions to view the files attached to this post.
John Adams
VGOEmulator - Project Ghost
"Everything should work now, except the stuff that doesn't" ~Xinux
Top

User avatar
John Adams
Retired
Posts: 4583
Joined: Wed Aug 28, 2013 9:40 am
Location: Phoenix, AZ.
Contact:
Contact John Adams
Website
Crafting Station Levels
  • Quote

Post by John Adams » Mon Jun 09, 2014 5:03 pm

Okay, crafters. Please explain this one to me. In the raw data, I see a Blacksmith Forge with varying "gameplayLevels", ranging from 3 to 100.

[attachment=0]forge.jpg[/attachment]


Any idea why a crafting station has a "level"? If it's too tough, you can't use it? Curious if this value means anything to the game, or left over from an original thought, or just lazy devs pushing random data to the world. Most are 3-dot, with 1 being a 2-dot.

Thanks
You do not have the required permissions to view the files attached to this post.
Top

Odinzz
Community Manager
Posts: 187
Joined: Fri Jan 31, 2014 9:22 pm
Location: Dirty Jersey
Re: Identifying Unreal bits
  • Quote

Post by Odinzz » Mon Jun 09, 2014 6:20 pm

John i have NO IDEA why a forge would have a level ...as long as u are a blacksmith u can use any forge in the world. i would also assume the same would be for the other spheres as well?
The Platinum Order
Alliance of the Griffon
Brains and Brawn
Odinzz 55 Palladin
Psychosiss 54 Cleric ( So Close !)
Femic 55 Sorc
Dorinas 55 Blood Mage
And a mess load of alts!
Top

User avatar
John Adams
Retired
Posts: 4583
Joined: Wed Aug 28, 2013 9:40 am
Location: Phoenix, AZ.
Contact:
Contact John Adams
Website
Re: Identifying Unreal bits
  • Quote

Post by John Adams » Tue Jun 10, 2014 6:40 am

Thanks, Odinzz. Here's another question along the same lines... this is an Artificer Instructor, and is generally in the same location (there are 2 coords for him, so I assume he appears twice). But, his level is all over the place, for the exact same x,y,z

[attachment=0]artificer.jpg[/attachment]


I will double-check my code to make sure I am not holding onto the last guy's data, though I am fairly sure it's a new instance each time.


Edit: the data above is from all separate logs, and I verified the level info is definitely coming from that spawn's packet.
You do not have the required permissions to view the files attached to this post.
Top

Zewtastic
Posts: 527
Joined: Wed Jan 29, 2014 12:28 pm
Location: Sunny Sacramento CA. USA
Re: Identifying Unreal bits
  • Quote

Post by Zewtastic » Tue Jun 10, 2014 9:43 am

There are some crafting stations that you can only use if you have the right "flag"? Such as in APW, Bridge of Destiny, Pota and so forth.
Top

Odinzz
Community Manager
Posts: 187
Joined: Fri Jan 31, 2014 9:22 pm
Location: Dirty Jersey
Re: Identifying Unreal bits
  • Quote

Post by Odinzz » Tue Jun 10, 2014 10:01 am

Ah yes that might explain the levels in the logs . The only thought I have on the instructors is he might be in an area level specific to give recipes for that level ?
Example the artisan saga questline (50+ if I remember right) may only come from one instructor AT lvl 50 ... otherwise he's just a dude standing there .
The Platinum Order
Alliance of the Griffon
Brains and Brawn
Odinzz 55 Palladin
Psychosiss 54 Cleric ( So Close !)
Femic 55 Sorc
Dorinas 55 Blood Mage
And a mess load of alts!
Top

User avatar
John Adams
Retired
Posts: 4583
Joined: Wed Aug 28, 2013 9:40 am
Location: Phoenix, AZ.
Contact:
Contact John Adams
Website
Re: Identifying Unreal bits
  • Quote

Post by John Adams » Sat Jun 21, 2014 8:47 am

Okay, today's quiz is... what exactly are "Attachment Groups"? At first I thought they might be an NPC's "appearance gear" (like a BP or Helm or Weapon). Then I started thinking, maybe they were loot containers with "weighted values" for drop (vs percentages). But some of the "attachment_index" values are duplicated within the same attachmentGroup, so that seems to rule out appearances or loot lists... so what the hell are these things?

Here are some examples of the data, please help me determine what they might be -

An NPC named "Lyta" - the Sultan's Advisor, Advocate of the Qalian Ancestors:
Lyta.jpg
The "attachment_slot" is just the index of the array, so ignore that one. But what are these attachment_index values? Are those item IDs, perhaps?

The package_index, at first I thought maybe those were drop percentages but it turns out there are values like 601, so definitely not a percentage. Maybe a weight? As in, the likelihood of drop vs other items in the list -- not about physical heaviness

And of course, inventory_slot - this is clearly not body parts, and NPCs don't have banks far as I know. Not too sure what this value is either (unless they are wrong coming from Parser).

NOTE: So far of all my NPC parsing, only 7 (out of millions) have 28-30 attachmentGroups. The rest are between 1 and 5, with a majority having 3.
GulgrethorScar.jpg
ImperialScout.jpg
CelestineGuard.jpg
Any ideas, my brilliant players? I tried googling Unreal docs and all I got back were support groups for attachment disorders
You do not have the required permissions to view the files attached to this post.
John Adams
VGOEmulator - Project Ghost
"Everything should work now, except the stuff that doesn't" ~Xinux
Top

TigerTiger
Posts: 99
Joined: Mon Oct 28, 2013 2:14 pm
Re: Identifying Unreal bits
  • Quote

Post by TigerTiger » Sat Jun 21, 2014 3:08 pm

I think I can answer all your questions, but would you like me to upload my unreal Dumper? It will dump all the unreal bits from Everything. For example when I use it in the starter zone, It will dump over 55,000 objects, with each object containing 100's of different values.

Model Number:
Lets load up UEM_wolfdire_M_char.uem in Unreal Package Tool
The formula for the character packages is
UEM_RaceName_Gender_char.uem
For example
UEM_human_M_char.uem
UEM_human_F_char.uem
Some NPC can have different genders
UEM_catLion_M_char.uem
UEM_catLion_F_char.uem

Now back to wolfdire
Inside this pack (among other things) are:
wolfDire_M_char_ALL_0_SKELETON.EMFXMesh
wolfDire_M_char_ALL_1_SKELETON.EMFXMesh
wolfDire_M_char_ALL_2_SKELETON.EMFXMesh
wolfDire_M_char_ALL_3_SKELETON.EMFXMesh

The formula is
RaceName_Gender_char_All_ModelNumber_skeleton.EMFXMesh
Model number means that a different EMFXmesh is used.
For the playable races this usally means the skin is changed, for example a white human or a black human.
For monsters this could mean a rescaled mesh (a small wolf or a big wolf), a different color, different attachments (though this is not the main way the game uses for different attachments), or a combination of all 3.

Physics: hard to explain, but with my dumper you can see the true names for these (instead of just a number). Some are GM only, like ghost, bird, stealth ect.

"Attachment Groups"
If you look in your Assets\Characters\Meshes folder, you will see files such as:
BACK_ITEMS.uem
FACE_ITEMS.uem
FEET_ITEMS.uem

The format is
group_ITEMS.uem

I'm still trying to figure out the difference between an sgoattachment, sgoattachmentgroup, SGOAttachmentTemplate
but roughly speaking attachment groups are sets of attachments that can be referenced by number. For example Mount_Items.uem contains references to mounts their armor/tack ect. Its simply a convenience because the server can tell the client to load say mount X from Mount_items, and the client knows that mount X, is species A, Armor B, Saddle C, Skin D.
Don't quote me on this, but some things in the client are redundant so I wouldn't be surprised if say a packet for a mounted NPC, is completly different then the packet for a mounted PC.
Here is a quick dump I did:

Code: Select all

89 ,VGAttachmentTypes ,Enum ,SGOAttachmentTemplate .Engine .None .,179516512 
VGAT_ApronBottom8Mq2 
VGAT_ApronTop8Mq2 
VGAT_Belt8Mq3 
VGAT_Boot8Lh2 
VGAT_Boot8Ry2 
VGAT_Bracer8Lq3 
VGAT_Bracer8Rq3 
VGAT_Glove9Ld1 
VGAT_Glove9Ri1 
VGAT_PantsShort8Mfop2 
VGAT_ShirtLoose9Mt3 
VGAT_SleeveShort9Lq3 
VGAT_SleeveShort9Rq3 
VGAT_TogaBottom8Mq3 
VGAT_Shirt8Mq3 
VGAT_Ra1_SwordBlade 
VGAT_Ra1_SwordGuard 
VGAT_Ra1_SwordHilt 
VGAT_Ra1_SwordPommel 
VGAT_Ra1_KnifeBlade 
VGAT_Ra1_KnifeGuard 
VGAT_Ra1_KnifeHilt 
VGAT_Ra1_KnifePommel 
VGAT_Ra1_AxeBlade 
VGAT_Ra1_AxeHilt 
VGAT_Ra1_AxeStuds 
VGAT_Ra1_AxeTooth 
VGAT_Ra1_ShieldKite 
VGAT_Ra1_ShieldRound 
VGAT_Ra1_ShieldSpike 
VGAT_Ra1_Helm 
VGAT_Ra1_HelmTiara 
VGAT_Ra1_HelmHat 
VGAT_Ra1_HelmHatCrest 
VGAT_Ra1_MaceHead 
VGAT_Ra1_MaceHilt 
VGAT_Ra1_MaceStuds 
VGAT_Ra1_PickBlade 
VGAT_Ra1_PickHilt 
VGAT_Ra1_Scroll 
VGAT_Ra1_ShovelBlade 
VGAT_Ra1_ShovelHilt 
VGAT_Ra1_StaffHead 
VGAT_Ra1_StaffHilt 
VGAT_Ra1_ToolChisel 
VGAT_Ra1_ToolCutter 
VGAT_Ra1_ToolHammerHead 
VGAT_Ra1_ToolHammerHilt 
VGAT_Ra1_ToolSledgeHammerHead 
VGAT_Ra1_ToolSledgeHammerHilt 
VGAT_Ra1_WarhammerHead 
VGAT_Hair 
VGAT_HairBangs 
VGAT_Beard 
VGAT_Moustache 
Top

User avatar
John Adams
Retired
Posts: 4583
Joined: Wed Aug 28, 2013 9:40 am
Location: Phoenix, AZ.
Contact:
Contact John Adams
Website
Re: Identifying Unreal bits
  • Quote

Post by John Adams » Sat Jun 21, 2014 4:21 pm

[quote="TigerTiger"]I think I can answer all your questions[/quote]
Thank you for that information, Tiger. That all makes sense to me, though I still do not see any "logic" in the data coming from my SGOAttachmentGroupInfoPair class. Xinux told me if you're using the in-game editor, the index value increments (changes) every time you add or remove the same item. So what I thought (hoped) was an item_id, is apparently just a global index (???). See my screen shots above to see what I'm talking about.

All that other info does answer most of my other questions about what all these params do, since manually changing the values rarely yields the expected result.

If your dumper is something someone with very little patience (me) can use easily, I would be happy to give it a try. Might unravel some of these mysteries.


btw, what I'm trying to determine is how much of this data needs to come from a datasource, vs what can be calculated and/or randomized before sending, and what the client takes upon itself to work out. Eg., I do not need to send a bunch of 0's if the default value in the client is 0.

Thanks again.
Top

TigerTiger
Posts: 99
Joined: Mon Oct 28, 2013 2:14 pm
Re: Identifying Unreal bits
  • Quote

Post by TigerTiger » Sat Jun 21, 2014 5:10 pm

Attachment Index makes perfect sense. They number them odd (some have 6 digits some have 5 they jump around), but does numbers make sense for example in Chest_items
F_chest_36100 is some type of Kojan Clothing Tier01. F_chest_36100 only contains references to the real mesh. Use the unreal package tool for all the values. (it will be in the export table).
Package index might be hard coded in the BIN's Chest_items would be given a package id which would be the same each time you load the game.
As for inventory slot changing, some stuff always seems to change (increase) when you mess with it in the editor. I'm almost 100% sure this means that something else is "trumping" it and when you change it, the game automatically adds a new instance with the same overridden data. Try changing it to rubbish and it should still work. I don't think the inventory slot needs to be in the packet, except for the fact that the same number can't be used twice (which is why it always increases because that is a trivial way to ensure that it doesn't use the same number twice).
Let me see if I can't get you the names of each package index, though an easy way to do this is to look at the logs when changing it in the editor because it will tell you what its loading by name. Chest 1, Chest 2, Chest 3, Chest 4, are the character creation shirt clothing. I can hack this into any value (but it won't save because character creation uses one byte integers:
offset 00BC45EE has the instruction "push edx"
If you change this then the game will load different clothing
I load Chest_items.uem in UPT
I go to Export Tree
I scroll down to where it says Qalian_pantheon_caster_tier03
Then just for the heck I pick M_Chest_236300
236300 in hex is 00039B0C
So I change the EDX Register, to 00039B0C at the instruction I mentioned before (you need to do it a few times for the whole outfit, but the game does have a
corresponding leg_236300 feet_236300 ect so when can use the same value
Here is the result
[img]http://ps23dformat.wikispaces.com/file/ ... getest.JPG[/img]
Top


Post Reply

37 posts
  • 1
  • 2
  • 3
  • 4
  • Next

Return to “Content Development”

Jump to
  • Information
  • ↳   Announcements
  • ↳   Dev Chats
  • ↳   Events
  • Community
  • ↳   General Discussions
  • ↳   VGO Team Help Requests
  • ↳   Introductions
  • ↳   Game Features
  • ↳   Wish List
  • ↳   Off-Topic
  • Support
  • ↳   How-To's
  • ↳   General Support
  • ↳   Windows
  • ↳   Linux
  • Development
  • ↳   Content Development
  • ↳   Thestra Adventuring
  • ↳   Qalia Adventuring
  • ↳   Kojan Adventuring
  • ↳   Crafting/Harvesting
  • Bugs
  • ↳   Server Bugs
  • ↳   Server Bugs (Closed)
  • ↳   Content Bugs
  • ↳   Content Bugs (Closed)
  • ↳   Database Bugs
  • ↳   Tools Bugs
  • Board index
  • All times are UTC-07:00
  • Delete cookies
  • Contact us
Powered by phpBB® Forum Software © phpBB Limited
*Original Author: Brad Veryard
*Updated to 3.2 by MannixMD