[committed] TheSchaf - SendCharacterOverview 1.104

A place to submit .patch fixes for the DOL SVN

Moderator: Developer Team

[committed] TheSchaf - SendCharacterOverview 1.104

Postby Etaew » Tue Apr 19, 2011 11:55 am

He's donated some code to us, this replaces the tons of loops and multiple sql queries, with a single query and less loops, object id will need to be changed to string from int in this code.
Code: Select all
public override void SendCharacterOverview(eRealm realm)
{
if (realm < eRealm.Albion || realm > eRealm.Hibernia)
{
throw new Exception("CharacterOverview requested for unknown realm " + realm);
}

int firstSlot = (byte)realm * 100;

GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(ePackets.CharacterOverview));
pak.FillString(m_gameClient.Account.Name, 28);

if (m_gameClient.Account.Characters == null)
{
pak.Fill(0x0, 1880);
}
else
{
Dictionary<int, Character> charsBySlot = new Dictionary<int, Character>();

string itemQuery = "(";
foreach (Character c in m_gameClient.Account.Characters)
{
charsBySlot.Add(c.AccountSlot, c);

itemQuery += "OwnerID = " + c.ObjectId + " OR ";
}
itemQuery = itemQuery.Substring(0, itemQuery.Length - 4); //remove last OR
itemQuery += ") AND SlotPosition >= " + ((int)eInventorySlot.FirstEquip) + " AND SlotPosition <= " + ((int)eInventorySlot.LastEquip);

var itemsByOwnerID = new Dictionary<int, Dictionary<eInventorySlot, InventoryItem>>();
var allItems = (InventoryItem[])GameServer.Database.SelectObjects(typeof(InventoryItem), itemQuery);
foreach (InventoryItem item in allItems)
{
if (!itemsByOwnerID.ContainsKey(item.OwnerID))
itemsByOwnerID.Add(item.OwnerID, new Dictionary<eInventorySlot, InventoryItem>());

itemsByOwnerID[item.OwnerID].Add((eInventorySlot)item.SlotPosition, item);
}

for (int i = firstSlot; i < (firstSlot + 10); i++)
{
Character c = null;
if (!charsBySlot.TryGetValue(i, out c))
{
pak.Fill(0x0, 188);
}
else
{
Dictionary<eInventorySlot, InventoryItem> charItems = null;

if (!itemsByOwnerID.TryGetValue(c.ObjectId, out charItems))
charItems = new Dictionary<eInventorySlot, InventoryItem>();

byte extensionTorso = 0;
byte extensionGloves = 0;
byte extensionBoots = 0;

InventoryItem item = null;

if (charItems.TryGetValue(eInventorySlot.TorsoArmor, out item))
extensionTorso = item.Extension;

if (charItems.TryGetValue(eInventorySlot.HandsArmor, out item))
extensionGloves = item.Extension;

if (charItems.TryGetValue(eInventorySlot.FeetArmor, out item))
extensionBoots = item.Extension;

pak.FillString(c.Name, 24);
pak.WriteByte(0x01);
pak.WriteByte((byte)c.EyeSize);
pak.WriteByte((byte)c.LipSize);
pak.WriteByte((byte)c.EyeColor);
pak.WriteByte((byte)c.HairColor);
pak.WriteByte((byte)c.FaceType);
pak.WriteByte((byte)c.HairStyle);
pak.WriteByte((byte)((extensionBoots << 4) | extensionGloves));
pak.WriteByte((byte)((extensionTorso << 4) | (c.IsCloakHoodUp ? 0x1 : 0x0)));
pak.WriteByte((byte)c.CustomisationStep); //1 = auto generate config, 2= config ended by player, 3= enable config to player
pak.WriteByte((byte)c.MoodType);
pak.Fill(0x0, 13); //0 String

string locationDescription = "";
Region region = WorldMgr.GetRegion((ushort)c.Region);
Zone zone = null;
if ((zone = region.GetZone(c.Xpos, c.Ypos)) != null)
{
IList areas = zone.GetAreasOfSpot(c.Xpos, c.Ypos, c.Zpos);

foreach (AbstractArea area in areas)
{
if (!area.DisplayMessage)
continue;

locationDescription = area.Description;
break;
}

if (locationDescription == "")
{
locationDescription = zone.Description;
}
}
pak.FillString(locationDescription, 24);

string classname = "";
if (c.Class != 0)
classname = ((eCharacterClass)c.Class).ToString();
pak.FillString(classname, 24);

string racename = GamePlayer.RACENAMES[c.Race];
pak.FillString(racename, 24);

pak.WriteByte((byte)c.Level);
pak.WriteByte((byte)c.Class);
pak.WriteByte((byte)c.Realm);
pak.WriteByte((byte)((((c.Race & 0x10) << 2) + (c.Race & 0x0F)) | (c.Gender << 4))); // race max value can be 0x1F
pak.WriteShortLowEndian((ushort)c.CurrentModel);
pak.WriteByte((byte)c.Region);
if (region == null || (int)m_gameClient.ClientType > region.Expansion)
pak.WriteByte(0x00);
else
pak.WriteByte((byte)(region.Expansion + 1)); //0x04-Cata zone, 0x05 - DR zone
pak.WriteInt(0x0); // Internal database ID
pak.WriteByte((byte)c.Strength);
pak.WriteByte((byte)c.Dexterity);
pak.WriteByte((byte)c.Constitution);
pak.WriteByte((byte)c.Quickness);
pak.WriteByte((byte)c.Intelligence);
pak.WriteByte((byte)c.Piety);
pak.WriteByte((byte)c.Empathy);
pak.WriteByte((byte)c.Charisma);

InventoryItem rightHandWeapon = null;
charItems.TryGetValue(eInventorySlot.RightHandWeapon, out rightHandWeapon);
InventoryItem leftHandWeapon = null;
charItems.TryGetValue(eInventorySlot.LeftHandWeapon, out leftHandWeapon);
InventoryItem twoHandWeapon = null;
charItems.TryGetValue(eInventorySlot.TwoHandWeapon, out twoHandWeapon);
InventoryItem distanceWeapon = null;
charItems.TryGetValue(eInventorySlot.DistanceWeapon, out distanceWeapon);

InventoryItem helmet = null;
charItems.TryGetValue(eInventorySlot.HeadArmor, out helmet);
InventoryItem gloves = null;
charItems.TryGetValue(eInventorySlot.HandsArmor, out gloves);
InventoryItem boots = null;
charItems.TryGetValue(eInventorySlot.FeetArmor, out boots);
InventoryItem torso = null;
charItems.TryGetValue(eInventorySlot.TorsoArmor, out torso);
InventoryItem cloak = null;
charItems.TryGetValue(eInventorySlot.Cloak, out cloak);
InventoryItem legs = null;
charItems.TryGetValue(eInventorySlot.LegsArmor, out legs);
InventoryItem arms = null;
charItems.TryGetValue(eInventorySlot.ArmsArmor, out arms);

pak.WriteShortLowEndian((ushort)(helmet != null ? helmet.Model : 0));
pak.WriteShortLowEndian((ushort)(gloves != null ? gloves.Model : 0));
pak.WriteShortLowEndian((ushort)(boots != null ? boots.Model : 0));

ushort rightHandColor = 0;
if (rightHandWeapon != null)
{
rightHandColor = (ushort)(rightHandWeapon.Emblem != 0 ? rightHandWeapon.Emblem : rightHandWeapon.Color);
}
pak.WriteShortLowEndian(rightHandColor);

pak.WriteShortLowEndian((ushort)(torso != null ? torso.Model : 0));
pak.WriteShortLowEndian((ushort)(cloak != null ? cloak.Model : 0));
pak.WriteShortLowEndian((ushort)(legs != null ? legs.Model : 0));
pak.WriteShortLowEndian((ushort)(arms != null ? arms.Model : 0));

ushort helmetColor = 0;
if (helmet != null)
{
helmetColor = (ushort)(helmet.Emblem != 0 ? helmet.Emblem : helmet.Color);
}
pak.WriteShortLowEndian(helmetColor);

ushort glovesColor = 0;
if (gloves != null)
{
glovesColor = (ushort)(gloves.Emblem != 0 ? gloves.Emblem : gloves.Color);
}
pak.WriteShortLowEndian(glovesColor);

ushort bootsColor = 0;
if (boots != null)
{
bootsColor = (ushort)(boots.Emblem != 0 ? boots.Emblem : boots.Color);
}
pak.WriteShortLowEndian(bootsColor);

ushort leftHandWeaponColor = 0;
if (leftHandWeapon != null)
{
leftHandWeaponColor = (ushort)(leftHandWeapon.Emblem != 0 ? leftHandWeapon.Emblem : leftHandWeapon.Color);
}
pak.WriteShortLowEndian(leftHandWeaponColor);

ushort torsoColor = 0;
if (torso != null)
{
torsoColor = (ushort)(torso.Emblem != 0 ? torso.Emblem : torso.Color);
}
pak.WriteShortLowEndian(torsoColor);

ushort cloakColor = 0;
if (cloak != null)
{
cloakColor = (ushort)(cloak.Emblem != 0 ? cloak.Emblem : cloak.Color);
}
pak.WriteShortLowEndian(cloakColor);

ushort legsColor = 0;
if (legs != null)
{
legsColor = (ushort)(legs.Emblem != 0 ? legs.Emblem : legs.Color);
}
pak.WriteShortLowEndian(legsColor);

ushort armsColor = 0;
if (arms != null)
{
armsColor = (ushort)(arms.Emblem != 0 ? arms.Emblem : arms.Color);
}
pak.WriteShortLowEndian(armsColor);

//weapon models

pak.WriteShortLowEndian((ushort)(rightHandWeapon != null ? rightHandWeapon.Model : 0));
pak.WriteShortLowEndian((ushort)(leftHandWeapon != null ? leftHandWeapon.Model : 0));
pak.WriteShortLowEndian((ushort)(twoHandWeapon != null ? twoHandWeapon.Model : 0));
pak.WriteShortLowEndian((ushort)(distanceWeapon != null ? distanceWeapon.Model : 0));

if (c.ActiveWeaponSlot == (byte)eActiveWeaponSlot.TwoHanded)
{
pak.WriteByte(0x02);
pak.WriteByte(0x02);
}
else if (c.ActiveWeaponSlot == (byte)eActiveWeaponSlot.Distance)
{
pak.WriteByte(0x03);
pak.WriteByte(0x03);
}
else
{
byte righthand = 0xFF;
byte lefthand = 0xFF;

if(rightHandWeapon != null)
righthand = 0x00;

if(leftHandWeapon != null)
lefthand = 0x01;

pak.WriteByte(righthand);
pak.WriteByte(lefthand);
}

if (region == null || region.Expansion != 1)
pak.WriteByte(0x00);
else
pak.WriteByte(0x01); //0x01=char in SI zone, classic client can't "play"

pak.WriteByte((byte)c.Constitution);
pak.Fill(0x00, 4);//new trailing bytes in 1.99
}

}
}
pak.Fill(0x0, 90);
SendTCP(pak);
}
Retired DOL Enthusiast | Blog
User avatar
Etaew
Inactive Staff Member
 
Posts: 7602
Joined: Mon Oct 13, 2003 5:04 pm
Website: http://etaew.net
Location: England

Re: TheSchaf - SendCharacterOverview 1.104

Postby Blue » Tue Apr 19, 2011 5:25 pm

Actually the reason why we started to work on this was that you can't see weapon colors in login screen for some reason. I'm not sure right now whether it only affects 2H weapons or left/righthand too. Still searching for the 2H color byte.
ex DOL Lead Developer
Blue
Uthgard Admin
 
Posts: 961
Joined: Wed Jan 21, 2004 11:07 pm
ICQ: 63977313

Re: TheSchaf - SendCharacterOverview 1.104

Postby Tolakram » Tue Apr 19, 2011 5:27 pm

I noticed that as well. I thought sure I found the code ... there was a comment about not caring about color, but I can't find it anymore.
- Mark
User avatar
Tolakram
Storm / Storm-D2 Admin
 
Posts: 9189
Joined: Tue Jun 13, 2006 1:49 am
Location: Kentucky, USA

Re: TheSchaf - SendCharacterOverview 1.104

Postby Etaew » Tue Apr 19, 2011 5:37 pm

Code: Select all
if (region == null || region.Expansion != 1)
pak.WriteByte(0x00);
else
pak.WriteByte(0x01); //0x01=char in SI zone, classic client can't "play"
This interests me, if set to 0x01 what happens on the character select screen?

I had some ideas about disabling characters/zones, or more gracefully handling prevented classes / races.
Retired DOL Enthusiast | Blog
User avatar
Etaew
Inactive Staff Member
 
Posts: 7602
Joined: Mon Oct 13, 2003 5:04 pm
Website: http://etaew.net
Location: England

Re: TheSchaf - SendCharacterOverview 1.104

Postby Etaew » Tue Apr 19, 2011 6:11 pm

The above byte, and the other expansion one earlier in the packet don't affect anything, perhaps the first one triggers the load screen that the client is shown.

But sniff, not what I wanted.
Retired DOL Enthusiast | Blog
User avatar
Etaew
Inactive Staff Member
 
Posts: 7602
Joined: Mon Oct 13, 2003 5:04 pm
Website: http://etaew.net
Location: England

Re: TheSchaf - SendCharacterOverview 1.104

Postby Graveen » Tue Apr 19, 2011 7:48 pm

Thank you, Uthgard !
Image
* pm me to contribute in Dawn of Light: code, database *
User avatar
Graveen
Project Leader
 
Posts: 12660
Joined: Fri Oct 19, 2007 9:22 pm
Location: France

Re: TheSchaf - SendCharacterOverview 1.104

Postby Etaew » Wed Apr 20, 2011 9:03 pm

Here is the patch file with the converted and tested code.

I have not updated 1.99, 1.74, 1.73 or 1.68 due to not knowing the exact changed packets.
Attachments
1104_sendcharacteroverview.patch
(24.77 KiB) Downloaded 16 times
Retired DOL Enthusiast | Blog
User avatar
Etaew
Inactive Staff Member
 
Posts: 7602
Joined: Mon Oct 13, 2003 5:04 pm
Website: http://etaew.net
Location: England

Re: TheSchaf - SendCharacterOverview 1.104

Postby Graveen » Wed Apr 20, 2011 9:30 pm

Soon in SVN, Thank you !
Image
* pm me to contribute in Dawn of Light: code, database *
User avatar
Graveen
Project Leader
 
Posts: 12660
Joined: Fri Oct 19, 2007 9:22 pm
Location: France


Return to “%s” DOL Code Contributions

Who is online

Users browsing this forum: No registered users and 1 guest