using System; using System.Collections.Generic; using System.Linq; using System.Net.Sockets; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using ServerCore; using ServerBase; using MetaAssets; using ServerControlCenter; using SESSION_ID = System.Int32; using META_ID = System.UInt32; using ENTITY_GUID = System.String; using ACCOUNT_ID = System.String; using OWNER_GUID = System.String; using USER_GUID = System.String; using CHARACTER_GUID = System.String; using ITEM_GUID = System.String; namespace ServerCommon; public static class InventoryRuleHelper { public static Int16 getBagTapMaxSlotCount() { return MetaHelper.GameConfigMeta.MaxItemCategorySlotNum; } // 임시로 관련 메타 정보를 반환 한다. // 추후 인벤토리 메타 정보를 추가하여 처리되도록 개선하자. - kangms public static Int16 getBagTapMaxSlotCountByBagTabType(EntityType entityType, BagTabType tabType) { switch (entityType) { case EntityType.MyHome: return getMyHomeMaxSlotCountByBagTabType(tabType); default: return getNormalMaxSlotCountByBagTabType(tabType); } } public static Int16 getNormalMaxSlotCountByBagTabType(BagTabType tabType) { switch (tabType) { case BagTabType._0: return MetaHelper.GameConfigMeta.Inventory1Slot; case BagTabType._1: return MetaHelper.GameConfigMeta.Inventory3Slot; case BagTabType._2: return MetaHelper.GameConfigMeta.Inventory5Slot; case BagTabType._3: return MetaHelper.GameConfigMeta.Inventory7Slot; case BagTabType._4: return MetaHelper.GameConfigMeta.Inventory9Slot; case BagTabType._5: return MetaHelper.GameConfigMeta.Inventory2Slot; case BagTabType._6: return MetaHelper.GameConfigMeta.Inventory4Slot; case BagTabType._7: return MetaHelper.GameConfigMeta.Inventory6Slot; case BagTabType._8: return MetaHelper.GameConfigMeta.Inventory8Slot; case BagTabType._9: return MetaHelper.GameConfigMeta.Inventory10Slot; default: throw new ArgumentException($"Invalid BagTabType !!!, in getNormalMaxSlotCountByBagTabType() : BagTabType:{tabType}"); } } public static Int16 getMyHomeMaxSlotCountByBagTabType(BagTabType tabType) { switch (tabType) { case BagTabType._0: return MetaHelper.GameConfigMeta.MyHomeInventory1Slot; case BagTabType._1: return MetaHelper.GameConfigMeta.MyHomeInventory3Slot; case BagTabType._2: return MetaHelper.GameConfigMeta.MyHomeInventory5Slot; case BagTabType._3: return MetaHelper.GameConfigMeta.MyHomeInventory7Slot; case BagTabType._4: return MetaHelper.GameConfigMeta.MyHomeInventory9Slot; case BagTabType._5: return MetaHelper.GameConfigMeta.MyHomeInventory2Slot; case BagTabType._6: return MetaHelper.GameConfigMeta.MyHomeInventory4Slot; case BagTabType._7: return MetaHelper.GameConfigMeta.MyHomeInventory6Slot; case BagTabType._8: return MetaHelper.GameConfigMeta.MyHomeInventory8Slot; case BagTabType._9: return MetaHelper.GameConfigMeta.MyHomeInventory10Slot; default: throw new ArgumentException($"Invalid BagTabType !!!, in getMyHomeMaxSlotCountByBagTabType() : BagTabType:{tabType}"); } } public static List findContainDuplicatedItemGuid(List toCheckItemGuids) { return toCheckItemGuids.GroupBy(x => x) .Where(g => g.Count() > 1) .Select(g => g.Key) .ToList(); } public static InvenEquipType toInvenEquipType(this EntityType entityInvenType) { switch (entityInvenType) { case EntityType.ClothEquipInven: return InvenEquipType.Cloth; case EntityType.ToolEquipInven: return InvenEquipType.Tool; case EntityType.TattooEquipInven: return InvenEquipType.Tattoo; default: Log.getLogger().error($"Invalid EntityType !!!, can't convert InvenEquipType : EntityType:{entityInvenType}"); return InvenEquipType.None; } } //========================================================================================= // 해당 가방에 장착 가능한 EItemLargeType 목록을 반환 한다. //========================================================================================= public static List toEquipableItemLargeTypes(this InvenBagType toEquipBagType) { switch (toEquipBagType) { case InvenBagType.Cloth: return new List() { MetaAssets.EItemLargeType.CLOTH }; case InvenBagType.Prop: return new List() { MetaAssets.EItemLargeType.PROP }; case InvenBagType.Beauty: return new List() { MetaAssets.EItemLargeType.BEAUTY }; case InvenBagType.Tattoo: return new List() { MetaAssets.EItemLargeType.TATTOO }; case InvenBagType.Etc: return new List() { MetaAssets.EItemLargeType.TOOL , MetaAssets.EItemLargeType.EXPENDABLE , MetaAssets.EItemLargeType.TICKET , MetaAssets.EItemLargeType.RAND_BOX , MetaAssets.EItemLargeType.SET_BOX }; default: Log.getLogger().error($"Invalid InvenBagType !!!, can't equip EItemLargeType : toEquipInvenBagType:{toEquipBagType}"); return new List(); } } public static BagTabType toUsableBagTabType(this InvenBagType bagType) { switch (bagType) { case InvenBagType.Cloth: return BagTabType._1; case InvenBagType.Prop: return BagTabType._2; case InvenBagType.Beauty: return BagTabType._3; case InvenBagType.Tattoo: return BagTabType._4; case InvenBagType.Etc: return BagTabType._0; default: Log.getLogger().error($"Invalid InvenBagType !!!, can't usable BagTabType : InvenBagType:{bagType}"); return BagTabType.None; } } public static InvenBagType toUsableInvenBagType(this BagTabType bagType) { switch (bagType) { case BagTabType._1: return InvenBagType.Cloth; case BagTabType._2: return InvenBagType.Prop; case BagTabType._3: return InvenBagType.Beauty; case BagTabType._4: return InvenBagType.Tattoo; case BagTabType._0: return InvenBagType.Etc; default: return InvenBagType.None; } } public static string toUsableInvenBagName(this BagTabType bagTabType) { var is_nft = false; var inven_bag_type = InventoryRuleHelper.toUsableInvenBagType(bagTabType); if(InvenBagType.None == inven_bag_type) { if(BagTabType._5 <= bagTabType && bagTabType < BagTabType.MAX) { is_nft = true; bagTabType -= (BagTabType.MAX - BagTabType._5); inven_bag_type = InventoryRuleHelper.toUsableInvenBagType(bagTabType); } } var inven_bag_name = EnumHelper.convertEnumToEnumTypeAndValueString(inven_bag_type); if (false == is_nft) { inven_bag_name += $"_NormalTab"; } else { inven_bag_name += $"_NftTab"; } return inven_bag_name; } public static BagTabType toNFTTabOffset(this BagTabType bagTabType, MetaAssets.ItemMetaData itemMeta) { return bagTabType + (true == itemMeta.IsNFT ? (BagTabType.MAX - BagTabType._5) : 0); } public static EntityDynamoDbSortKeyType toEntitySKType(this InvenEquipType equipType) { switch (equipType) { case InvenEquipType.Cloth: return EntityDynamoDbSortKeyType.Guid; case InvenEquipType.Tool: return EntityDynamoDbSortKeyType.Guid; case InvenEquipType.Tattoo: return EntityDynamoDbSortKeyType.Guid; default: Log.getLogger().error($"Invalid InvenEquipType !!!, can't use EntityDynamoDbSortKeyType : InvenEquipType:{equipType}"); return EntityDynamoDbSortKeyType.None; } } public static List toEquipableItemLargeTypes(this InvenEquipType equipType) { switch (equipType) { case InvenEquipType.Cloth: return new List() { MetaAssets.EItemLargeType.CLOTH }; case InvenEquipType.Tool: return new List() { MetaAssets.EItemLargeType.TOOL }; case InvenEquipType.Tattoo: return new List() { MetaAssets.EItemLargeType.TATTOO }; default: Log.getLogger().error($"Invalid InvenEquipType !!!, can't equip EItemLargeType : InvenEquipType:{equipType}"); return new List(); } } public static List toEquipableItemSmallTypesWithClothSlotType(this InvenEquipType equipType, ClothSlotType clothSlotType) { switch (equipType) { case InvenEquipType.Cloth: return clothSlotType.toEquipableItemSmallTypes(); default: Log.getLogger().error($"Invalid InvenEquipType !!!, can't equip ClothSlotType : InvenEquipType:{equipType}, ClothSlotType:{clothSlotType}"); return new List(); } } public static List toEquipableItemSmallTypes(this ClothSlotType clothSlotType) { var list = new List(); foreach (var equipData in MetaData.Instance.Meta.ClothEquipTypeMetaTable.ClothEquipTypeDataList) { if (false == EnumHelper.tryParse(equipData.EquipSlotType, out var slotType)) continue; if (slotType != clothSlotType) continue; if (false == EnumHelper.tryParse(equipData.SmallType, out var smallType)) continue; list.Add(smallType); } if (list.Count <= 0) { Log.getLogger().warn($"Invalid ClothSlotType !!!, can't equip ClothSlotType : ClothSlotType:{clothSlotType}"); } return list; } public static List toEquipableToolSlotTypes(this InvenEquipType equipType) { switch (equipType) { case InvenEquipType.Tool: return new List() { ToolSlotType._1, ToolSlotType._2, ToolSlotType._3, ToolSlotType._4 }; default: Log.getLogger().error($"Invalid InvenEquipType !!!, can't equip ToolSlotType : InvenEquipType:{equipType}"); return new List(); } } public static List toEquipableTattooSlotTypes(this InvenEquipType equipType, EntityType entityType = EntityType.None) { switch (equipType) { case InvenEquipType.Tattoo: { if( EntityType.UgcNpc == entityType || EntityType.Beacon == entityType ) { return new List() { TattooSlotType._1, TattooSlotType._2, TattooSlotType._3 }; } return new List() { TattooSlotType._1, TattooSlotType._2, TattooSlotType._3, TattooSlotType._4 }; } } Log.getLogger().error($"Invalid InvenEquipType !!!, can't equip TattooSlotType : InvenEquipType:{equipType}"); return new List(); } public static bool isEquipableTattooSlotType(this InvenEquipType equipType, TattooSlotType slotType, EntityType entityType) { var equipable_slot_types = equipType.toEquipableTattooSlotTypes(entityType); var found_slot_type = equipable_slot_types.FirstOrDefault(x => x == slotType, TattooSlotType.None); if (TattooSlotType.None == found_slot_type) { var err_msg = $"Not found TattooSlotType !!! : InvenEquipType:{equipType}, TattooSlotType:{slotType} - entityType:{entityType}"; Log.getLogger().error(err_msg); return false; } return true; } public static ClothSlotType toClothSlotType(this MetaAssets.EItemSmallType smallType) { if (false == MetaData.Instance.Meta.ClothEquipTypeMetaTable.ClothEquipTypeDataListbyId.TryGetValue(smallType.ToString(), out var slotTypeData)) { Log.getLogger().warn($"Invalid EItemSmallType !!!, can't convert ClothSlotType : EItemSmallType:{smallType}"); return ClothSlotType.None; } if (false == EnumHelper.tryParse(slotTypeData.EquipSlotType, out var slotType)) { Log.getLogger().warn($"Invalid EquipSlotType !!!, can't convert ClothSlotType : EquipSlotType:{slotTypeData.EquipSlotType}"); return ClothSlotType.None; } return slotType; } }