From b2e273d7cf1d36771b940653fb8e334bf8b305d5 Mon Sep 17 00:00:00 2001 From: Filip Maj Date: Mon, 4 Dec 2017 22:58:18 -0500 Subject: [PATCH] Finished fixing bugs in the bazaar code. --- FFXIVClassic Common Class Lib/Utils.cs | 6 ++ FFXIVClassic Map Server/Database.cs | 11 +-- FFXIVClassic Map Server/WorldManager.cs | 54 +++++++-------- .../actors/chara/Character.cs | 29 ++++---- .../actors/chara/player/Inventory.cs | 67 +++++++++++++------ .../dataobjects/InventoryItem.cs | 27 +++++++- FFXIVClassic Map Server/lua/LuaUtils.cs | 64 +++++++++++++++--- 7 files changed, 175 insertions(+), 83 deletions(-) diff --git a/FFXIVClassic Common Class Lib/Utils.cs b/FFXIVClassic Common Class Lib/Utils.cs index a6479b78..0008b784 100644 --- a/FFXIVClassic Common Class Lib/Utils.cs +++ b/FFXIVClassic Common Class Lib/Utils.cs @@ -139,6 +139,12 @@ namespace FFXIVClassic.Common return input; } + public static ushort SwapEndian(ushort input) + { + return (ushort)(((input << 8) & 0xff00) | + ((input >> 8) & 0x00ff)); + } + public static uint MurmurHash2(string key, uint seed) { // 'm' and 'r' are mixing constants generated offline. diff --git a/FFXIVClassic Map Server/Database.cs b/FFXIVClassic Map Server/Database.cs index b6e65149..f345256f 100644 --- a/FFXIVClassic Map Server/Database.cs +++ b/FFXIVClassic Map Server/Database.cs @@ -1272,8 +1272,6 @@ namespace FFXIVClassic_Map_Server modifier = new InventoryItem.ItemModifier(reader); InventoryItem item = new InventoryItem(uniqueId, Server.GetItemGamedata(itemId), quantity, qualityNumber, modifier); - item.slot = slot; - slot++; items.Add(item); } } @@ -1471,7 +1469,7 @@ namespace FFXIVClassic_Map_Server FROM characters_inventory_bazaar INNER JOIN server_items ON seekId = server_items.id LEFT JOIN server_items_modifiers ON server_items.id = server_items_modifiers.id - WHERE characterId = @charaId"; + WHERE characterId = @charaId and bazaarMode != 11 and bazaarMode != 12 and bazaarMode != 13"; MySqlCommand cmd2 = new MySqlCommand(query2, conn); cmd2.Parameters.AddWithValue("@charaId", player.actorId); @@ -1595,8 +1593,6 @@ namespace FFXIVClassic_Map_Server modifier = new InventoryItem.ItemModifier(reader); InventoryItem item = new InventoryItem(uniqueId, Server.GetItemGamedata(itemId), quantity, qualityNumber, modifier); - item.slot = slot; - slot++; items.Add(item); } } @@ -1678,9 +1674,9 @@ namespace FFXIVClassic_Map_Server string query = @" INSERT INTO characters_inventory - (characterId, itemPackage, serverItemId, quantity) + (characterId, itemPackage, serverItemId) VALUES - (@charId, @itemPackage, @serverItemId, @quantity) + (@charId, @itemPackage, @serverItemId) "; MySqlCommand cmd = new MySqlCommand(query, conn); @@ -1688,7 +1684,6 @@ namespace FFXIVClassic_Map_Server cmd.Parameters.AddWithValue("@serverItemId", addedItem.uniqueId); cmd.Parameters.AddWithValue("@charId", player.actorId); cmd.Parameters.AddWithValue("@itemPackage", type); - cmd.Parameters.AddWithValue("@quantity", addedItem.quantity); cmd.ExecuteNonQuery(); } diff --git a/FFXIVClassic Map Server/WorldManager.cs b/FFXIVClassic Map Server/WorldManager.cs index 25d3321f..7434f6ca 100644 --- a/FFXIVClassic Map Server/WorldManager.cs +++ b/FFXIVClassic Map Server/WorldManager.cs @@ -1044,27 +1044,30 @@ namespace FFXIVClassic_Map_Server } } - public InventoryItem CreateItem(uint itemId, int amount, byte quality = 1) + public InventoryItem CreateItem(uint itemId, int amount, byte quality = 1, InventoryItem.ItemModifier modifiers = null) { - return Database.CreateItem(itemId, amount, quality); + return Database.CreateItem(itemId, amount, quality, modifiers); } public void AddToBazaar(Player player, InventoryItem reward, InventoryItem seek, int rewardAmount, int seekAmount, byte bazaarMode) { - bool succ = Database.CreateBazaarEntry(player, reward, seek, rewardAmount, seekAmount, bazaarMode); + bool succ = false; + + if (bazaarMode == InventoryItem.TYPE_SINGLE || bazaarMode == InventoryItem.TYPE_MULTI || bazaarMode == InventoryItem.TYPE_STACK) + succ = Database.CreateBazaarEntry(player, reward, seek, rewardAmount, 0, bazaarMode, seekAmount); + else + succ = Database.CreateBazaarEntry(player, reward, seek, rewardAmount, seekAmount, bazaarMode); if (succ) { if (bazaarMode != InventoryItem.TYPE_SINGLE && bazaarMode != InventoryItem.TYPE_MULTI && bazaarMode != InventoryItem.TYPE_STACK) { reward.SetDealingAttached(bazaarMode, seek.uniqueId); + seek.SetHasAttached(true); player.GetItemPackage(Inventory.BAZAAR).StartSendUpdate(); player.GetItemPackage(Inventory.BAZAAR).AddItem(reward); player.GetItemPackage(Inventory.BAZAAR).AddItem(seek); - reward.SetAttachedIndex(Inventory.BAZAAR, seek.slot); - seek.SetHasAttached(true); - player.GetItemPackage(Inventory.BAZAAR).DoneSendUpdate(); } else @@ -1078,36 +1081,33 @@ namespace FFXIVClassic_Map_Server } } - /* - public void RemoveFromBazaar(Player player, ushort position) + + public void RemoveFromBazaar(Player player, InventoryItem rewardRef) { - InventoryItem reward = player.GetInventory(Inventory.BAZAAR).GetItemAtSlot(position); - InventoryItem seek = null; + ushort attachedItemPackage = (ushort)((rewardRef.dealingAttached1 >> 16) & 0xFF); + ushort attachedSlot = (ushort) (rewardRef.dealingAttached1 & 0xFF); - seek = player.GetInventory(Inventory.BAZAAR). + InventoryItem seekRef = rewardRef.IsSelling() ? null : player.GetItemPackage(attachedItemPackage).GetItemAtSlot(attachedSlot); - Database.ClearBazaarEntry(player, reward); + Database.ClearBazaarEntry(player, rewardRef); - player.GetInventory(Inventory.BAZAAR).RemoveItem(reward); - player.GetInventory(Inventory.BAZAAR).RemoveItem(seek); + player.GetItemPackage(Inventory.BAZAAR).RemoveItem(rewardRef); - player.GetInventory(Inventory.NORMAL).StartSendUpdate(); - player.GetInventory(Inventory.CURRENCY_CRYSTALS).StartSendUpdate(); + bool isSelling = rewardRef.IsSelling(); + rewardRef.SetNormal(); - if (reward.itemId == 1000001) - player.GetInventory(Inventory.CURRENCY_CRYSTALS).AddItem(reward.itemId, reward.quantity); - else - player.GetInventory(Inventory.NORMAL).AddItem(reward); + if (seekRef != null) + player.GetItemPackage(Inventory.BAZAAR).RemoveItem(seekRef); - if (reward.itemId == 1000001) - player.GetInventory(Inventory.CURRENCY_CRYSTALS).AddItem(seek.itemId, seek.quantity); - else - player.GetInventory(Inventory.NORMAL).AddItem(seek); + player.AddItem(rewardRef); - player.GetInventory(Inventory.NORMAL).DoneSendUpdate(); - player.GetInventory(Inventory.CURRENCY_CRYSTALS).DoneSendUpdate(); + if (!isSelling) + { + seekRef.SetNormal(); + player.AddItem(seekRef); + } } - + /* public void TransactionBazaar(Player owner, Player other, InventoryItem reward, InventoryItem seek, int rewardAmount, int seekAmount) { Database.ClearBazaarEntry(owner, reward, seek); diff --git a/FFXIVClassic Map Server/actors/chara/Character.cs b/FFXIVClassic Map Server/actors/chara/Character.cs index 0dc77ef3..e9a08c74 100644 --- a/FFXIVClassic Map Server/actors/chara/Character.cs +++ b/FFXIVClassic Map Server/actors/chara/Character.cs @@ -10,7 +10,7 @@ using System.Collections.Generic; namespace FFXIVClassic_Map_Server.Actors { - class Character:Actor + class Character : Actor { public const int SIZE = 0; public const int COLORINFO = 1; @@ -63,8 +63,9 @@ namespace FFXIVClassic_Map_Server.Actors protected Dictionary itemPackages = new Dictionary(); protected Equipment equipment; - public Character(uint actorID) : base(actorID) - { + public Character(uint actorID) + : base(actorID) + { //Init timer array to "notimer" for (int i = 0; i < charaWork.statusShownTime.Length; i++) charaWork.statusShownTime[i] = 0xFFFFFFFF; @@ -78,7 +79,7 @@ namespace FFXIVClassic_Map_Server.Actors public SubPacket CreateInitStatusPacket() { - return (SetActorStatusAllPacket.BuildPacket(actorId, charaWork.status)); + return (SetActorStatusAllPacket.BuildPacket(actorId, charaWork.status)); } public SubPacket CreateSetActorIconPacket() @@ -106,13 +107,13 @@ namespace FFXIVClassic_Map_Server.Actors currentContentGroup = group; ActorPropertyPacketUtil propPacketUtil = new ActorPropertyPacketUtil("charaWork/currentContentGroup", this); - propPacketUtil.AddProperty("charaWork.currentContentGroup"); + propPacketUtil.AddProperty("charaWork.currentContentGroup"); zone.BroadcastPacketsAroundActor(this, propPacketUtil.Done()); - } - + } + public void PlayAnimation(uint animId, bool onlySelf = false) - { + { if (onlySelf) { if (this is Player) @@ -121,7 +122,7 @@ namespace FFXIVClassic_Map_Server.Actors else zone.BroadcastPacketAroundActor(this, PlayAnimationOnActorPacket.BuildPacket(actorId, animId)); } - + #region Inventory public void AddItem(uint catalogID) @@ -148,7 +149,7 @@ namespace FFXIVClassic_Map_Server.Actors { ushort itemPackage = GetPackageForItem(item.GetItemData().catalogID); if (itemPackages.ContainsKey(itemPackage)) - { + { itemPackages[itemPackage].AddItem(item); } } @@ -169,9 +170,9 @@ namespace FFXIVClassic_Map_Server.Actors return; itemPackages[sourcePackage].RemoveItem(item); - itemPackages[destinationPackage].AddItem(item); + itemPackages[destinationPackage].AddItem(item); } - + public void RemoveItem(uint catalogID) { RemoveItem(catalogID, 1); @@ -187,7 +188,7 @@ namespace FFXIVClassic_Map_Server.Actors ushort itemPackage = GetPackageForItem(catalogID); if (itemPackages.ContainsKey(itemPackage)) { - itemPackages[itemPackage].RemoveItem(catalogID, quantity, quantity); + itemPackages[itemPackage].RemoveItem(catalogID, quantity, quality); } } @@ -269,7 +270,7 @@ namespace FFXIVClassic_Map_Server.Actors if (data == null) return Inventory.NORMAL; else - { + { if (data.IsMoney()) return Inventory.CURRENCY_CRYSTALS; else if (data.IsImportant()) diff --git a/FFXIVClassic Map Server/actors/chara/player/Inventory.cs b/FFXIVClassic Map Server/actors/chara/player/Inventory.cs index a793162e..7daff426 100644 --- a/FFXIVClassic Map Server/actors/chara/player/Inventory.cs +++ b/FFXIVClassic Map Server/actors/chara/player/Inventory.cs @@ -56,7 +56,10 @@ namespace FFXIVClassic_Map_Server.actors.chara.player { int i = 0; foreach (InventoryItem item in itemsFromDB) + { + item.RefreshPositioning(itemPackageCode, (ushort) i); list[i++] = item; + } endOfListIndex = i; } @@ -107,7 +110,11 @@ namespace FFXIVClassic_Map_Server.actors.chara.player } public INV_ERROR AddItem(InventoryItem itemRef) - { + { + //If it isn't a single item (ie: armor) just add like normal (not valid for BAZAAR) + if (itemPackageCode != BAZAAR && itemRef.GetItemData().maxStack > 1) + return AddItem(itemRef.itemId, itemRef.quantity, itemRef.quality); + if (!IsSpaceForAdd(itemRef.itemId, itemRef.quantity, itemRef.quality)) return INV_ERROR.INVENTORY_FULL; @@ -133,10 +140,14 @@ namespace FFXIVClassic_Map_Server.actors.chara.player public INV_ERROR AddItem(uint itemId, int quantity, byte quality) { if (!IsSpaceForAdd(itemId, quantity, quality)) - return INV_ERROR.INVENTORY_FULL; + return INV_ERROR.INVENTORY_FULL; + + ItemData gItem = Server.GetItemGamedata(itemId); + + //If it's unique, abort + if (HasItem(itemId) && gItem.isExclusive) + return INV_ERROR.ALREADY_HAS_UNIQUE; - ItemData gItem = Server.GetItemGamedata(itemId); - if (gItem == null) { Program.Log.Error("Inventory.AddItem: unable to find item %u", itemId); @@ -164,10 +175,6 @@ namespace FFXIVClassic_Map_Server.actors.chara.player break; } } - - //If it's unique, abort - if (quantityCount > 0 && gItem.isExclusive) - return INV_ERROR.ALREADY_HAS_UNIQUE; //New item that spilled over while (quantityCount > 0) @@ -180,9 +187,9 @@ namespace FFXIVClassic_Map_Server.actors.chara.player } InventoryItem addedItem = Database.CreateItem(itemId, Math.Min(quantityCount, gItem.maxStack), quality, modifiers); - addedItem.slot = (ushort)endOfListIndex; + addedItem.RefreshPositioning(itemPackageCode, (ushort)endOfListIndex); isDirty[endOfListIndex] = true; - list[endOfListIndex++] = addedItem; + list[endOfListIndex++] = addedItem; quantityCount -= gItem.maxStack; DoDatabaseAdd(addedItem); @@ -197,6 +204,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player { list[slot] = item; SendUpdatePackets(); + item.RefreshPositioning(itemPackageCode, slot); } public void RemoveItem(uint itemId) @@ -260,7 +268,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player public void RemoveItem(InventoryItem item) { - RemoveItemByUniqueId(item.uniqueId, 1); + RemoveItemByUniqueId(item.uniqueId, item.quantity); } public void RemoveItem(InventoryItem item, int quantity) @@ -272,18 +280,18 @@ namespace FFXIVClassic_Map_Server.actors.chara.player { ushort slot = 0; InventoryItem toDelete = null; - for (int i = endOfListIndex - 1; i >= 0; i--) + for (int i = 0; i < endOfListIndex; i++) { InventoryItem item = list[i]; - Debug.Assert(item != null, "Item slot was null!!!"); - - if (item.uniqueId == itemDBId) - { - toDelete = item; - break; - } - slot++; + Debug.Assert(item != null, "Item slot was null!!!"); + + if (item.uniqueId == itemDBId) + { + toDelete = item; + break; + } + slot++; } if (toDelete == null) @@ -292,6 +300,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player if (quantity >= toDelete.quantity) { DoDatabaseRemove(toDelete.uniqueId); + list[slot].RefreshPositioning(0xFFFF, 0xFFFF); list[slot] = null; } else @@ -313,6 +322,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player DoDatabaseRemove(list[slot].uniqueId); + list[slot].RefreshPositioning(0xFFFF, 0xFFFF); list[slot] = null; isDirty[slot] = true; @@ -333,6 +343,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player { DoDatabaseRemove(list[slot].uniqueId); + list[slot].RefreshPositioning(0xFFFF, 0xFFFF); list[slot] = null; DoRealign(); } @@ -348,6 +359,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player { for (int i = 0; i < endOfListIndex; i++) { + list[i].RefreshPositioning(0xFFFF, 0xFFFF); list[i] = null; isDirty[i] = true; } @@ -504,6 +516,9 @@ namespace FFXIVClassic_Map_Server.actors.chara.player if (isTemporary) return; + if (itemPackageCode == BAZAAR) + return; + if (owner is Player) Database.AddItem((Player)owner, addedItem, itemPackageCode); else if (owner is Retainer) @@ -515,6 +530,10 @@ namespace FFXIVClassic_Map_Server.actors.chara.player if (isTemporary) return; + + if (itemPackageCode == BAZAAR) + return; + if (owner is Player) Database.SetQuantity((Player)owner, itemDBId, itemPackageCode); else if (owner is Retainer) @@ -526,6 +545,9 @@ namespace FFXIVClassic_Map_Server.actors.chara.player if (isTemporary) return; + if (itemPackageCode == BAZAAR) + return; + if (owner is Player) Database.RemoveItem((Player)owner, itemDBId); else if (owner is Retainer) @@ -534,7 +556,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player private void SendUpdatePackets() { - if (owner is Player) + if (owner is Player && !holdingUpdates) { SendUpdatePackets((Player)owner); } @@ -560,7 +582,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player } if (!holdingUpdates) - DoneSendUpdate(); + Array.Clear(isDirty, 0, isDirty.Length); player.QueuePacket(InventoryBeginChangePacket.BuildPacket(owner.actorId)); player.QueuePacket(InventorySetBeginPacket.BuildPacket(owner.actorId, itemPackageCapacity, itemPackageCode)); @@ -580,6 +602,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player public void DoneSendUpdate() { holdingUpdates = false; + SendUpdatePackets(); Array.Clear(isDirty, 0, isDirty.Length); } diff --git a/FFXIVClassic Map Server/dataobjects/InventoryItem.cs b/FFXIVClassic Map Server/dataobjects/InventoryItem.cs index 31c8964d..5ce9f0d9 100644 --- a/FFXIVClassic Map Server/dataobjects/InventoryItem.cs +++ b/FFXIVClassic Map Server/dataobjects/InventoryItem.cs @@ -39,8 +39,8 @@ namespace FFXIVClassic_Map_Server.dataobjects public ItemModifier modifiers; public readonly ItemData itemData; - public ushort slot; - public ushort itemPackage; + public ushort slot = 0xFFFF; + public ushort itemPackage = 0xFFFF; public class ItemModifier { @@ -213,6 +213,24 @@ namespace FFXIVClassic_Map_Server.dataobjects tags[0] = isAttached ? TAG_ATTACHED : (byte)0; } + public void SetNormal() + { + for (int i = 0; i < 4; i++) + { + if (tags[i] == TAG_DEALING || tags[i] == TAG_ATTACHED) + { + tags[i] = 0; + tagValues[i] = 0; + attachedTo = 0; + dealingVal = 0; + dealingMode = 0; + dealingAttached1 = 0; + dealingAttached2 = 0; + dealingAttached3 = 0; + } + } + } + public void SetDealing(byte mode, int price) { tags[0] = TAG_DEALING; @@ -264,5 +282,10 @@ namespace FFXIVClassic_Map_Server.dataobjects return 0; } + + public bool IsSelling() + { + return GetBazaarMode() == TYPE_SINGLE || GetBazaarMode() == TYPE_MULTI || GetBazaarMode() == TYPE_STACK; + } } } diff --git a/FFXIVClassic Map Server/lua/LuaUtils.cs b/FFXIVClassic Map Server/lua/LuaUtils.cs index 861f8159..c8207592 100644 --- a/FFXIVClassic Map Server/lua/LuaUtils.cs +++ b/FFXIVClassic Map Server/lua/LuaUtils.cs @@ -28,6 +28,24 @@ namespace FFXIVClassic_Map_Server } } + public class ItemOfferParam + { + public uint actorId; + public ushort offerSlot; + public ushort unknown1; + public ushort seekSlot; + public ushort unknown2; + + public ItemOfferParam(uint actorId, ushort unknown1, ushort offerSlot, ushort seekSlot, ushort unknown2) + { + this.actorId = actorId; + this.unknown1 = unknown1; + this.offerSlot = offerSlot; + this.seekSlot = seekSlot; + this.unknown2 = unknown2; + } + } + public class Type9Param { public ulong item1; @@ -81,13 +99,25 @@ namespace FFXIVClassic_Map_Server case 0x6: //Actor (By Id) value = Utils.SwapEndian(reader.ReadUInt32()); break; - case 0x7: //Weird one used for inventory - uint type7ActorId = Utils.SwapEndian(reader.ReadUInt32()); - byte type7Unknown = reader.ReadByte(); - byte type7Slot = reader.ReadByte(); - byte type7InventoryType = reader.ReadByte(); - value = new ItemRefParam(type7ActorId, type7Unknown, type7Slot, type7InventoryType); + case 0x7: //Item Reference to Inventory Spot + { + uint type7ActorId = Utils.SwapEndian(reader.ReadUInt32()); + byte type7Unknown = reader.ReadByte(); + byte type7Slot = reader.ReadByte(); + byte type7InventoryType = reader.ReadByte(); + value = new ItemRefParam(type7ActorId, type7Unknown, type7Slot, type7InventoryType); + } break; + case 0x8: //Used for offering + { + uint actorId = Utils.SwapEndian(reader.ReadUInt32()); + ushort unk1 = Utils.SwapEndian(reader.ReadUInt16()); + ushort offerSlot = Utils.SwapEndian(reader.ReadUInt16()); + ushort seekSlot = Utils.SwapEndian(reader.ReadUInt16()); + ushort unk2 = Utils.SwapEndian(reader.ReadUInt16()); + value = new ItemOfferParam(actorId, unk1, offerSlot, seekSlot, unk2); + } + break; case 0x9: //Two Longs (only storing first one) value = new Type9Param(Utils.SwapEndian(reader.ReadUInt64()), Utils.SwapEndian(reader.ReadUInt64())); break; @@ -105,7 +135,13 @@ namespace FFXIVClassic_Map_Server if (isDone) break; - if (value != null) + //Special case cause fuck Type8 + if (value != null && value is ItemOfferParam) + { + luaParams.Add(new LuaParam(code, value)); + luaParams.Add(new LuaParam(5, null)); + } + else if (value != null) luaParams.Add(new LuaParam(code, value)); else if (wasNil) luaParams.Add(new LuaParam(code, value)); @@ -355,7 +391,11 @@ namespace FFXIVClassic_Map_Server } else if (o is ItemRefParam) { - luaParams.Add(new LuaParam(0x7, (ItemRefParam)o)); + luaParams.Add(new LuaParam(0x7, (ItemRefParam)o)); + } + else if (o is ItemOfferParam) + { + luaParams.Add(new LuaParam(0x8, (ItemOfferParam)o)); } else if (o is Type9Param) { @@ -413,13 +453,17 @@ namespace FFXIVClassic_Map_Server ItemRefParam type7Param = ((ItemRefParam)lParams[i].value); dumpString += String.Format("Type7 Param: (0x{0:X}, 0x{1:X}, 0x{2:X}, 0x{3:X})", type7Param.actorId, type7Param.unknown, type7Param.slot, type7Param.itemPackage); break; - case 0xC: //Byte - dumpString += String.Format("0x{0:X}", (byte)lParams[i].value); + case 0x8: //Weird one used for inventory + ItemOfferParam itemOfferParam = ((ItemOfferParam)lParams[i].value); + dumpString += String.Format("Type8 Param: (0x{0:X}, 0x{1:X}, 0x{2:X}, 0x{3:X}, 0x{4:X})", itemOfferParam.actorId, itemOfferParam.unknown1, itemOfferParam.offerSlot, itemOfferParam.seekSlot, itemOfferParam.unknown2); break; case 0x9: //Long (+ 8 bytes ignored) Type9Param type9Param = ((Type9Param)lParams[i].value); dumpString += String.Format("Type9 Param: (0x{0:X}, 0x{1:X})", type9Param.item1, type9Param.item2); break; + case 0xC: //Byte + dumpString += String.Format("0x{0:X}", (byte)lParams[i].value); + break; case 0x1B: //Short? dumpString += String.Format("0x{0:X}", (ushort)lParams[i].value); break;