private static void HandleEquipMedal(GameSession session, PacketReader packet) { MedalSlot slot = (MedalSlot)packet.ReadByte(); int effectId = packet.ReadInt(); if (effectId == 0) { session.Player.Account.UnequipMedal(slot); return; } Medal newMedal = session.Player.Account.Medals.FirstOrDefault(x => x.EffectId == effectId); if (newMedal is null) { return; } // unequip medal if present session.Player.Account.UnequipMedal(slot); // equip new medal session.Player.Account.EquippedMedals[slot] = newMedal; newMedal.IsEquipped = true; DatabaseManager.MushkingRoyaleMedals.Update(newMedal); session.Send(MushkingRoyaleSystemPacket.LoadMedals(session.Player.Account)); }
public Medal(int effectId, Item item, long accountId, MedalSlot slot) { EffectId = effectId; Item = item; AccountId = accountId; Slot = slot; ExpirationTimeStamp = 2524608000; // setting all expirations to 2050. Unsure how it's determined. Uid = DatabaseManager.MushkingRoyaleMedals.Insert(this); }
public Medal(long uid, int effectId, bool isEquipped, long expiration, Item item, MedalSlot slot, long accountId) { Uid = uid; EffectId = effectId; IsEquipped = isEquipped; ExpirationTimeStamp = expiration; Item = item; Slot = slot; AccountId = accountId; }
private static void ParseFunctions(Function function, ItemMetadata metadata) { switch (function.name) { // selection boxes are SelectItemBox and 1,boxid // normal boxes are OpenItemBox and 0,1,0,boxid // fragments are OpenItemBox and 0,1,0,boxid,required_amount case "OpenItemBox" when function.parameter.Contains('l'): return; // TODO: Implement these CN items. Skipping for now case "OpenItemBox": { List <string> parameters = new(function.parameter.Split(',')); OpenItemBox box = new() { RequiredItemId = int.Parse(parameters[0]), ReceiveOneItem = parameters[1] == "1", BoxId = int.Parse(parameters[3]), AmountRequired = 1 }; if (parameters.Count == 5) { box.AmountRequired = int.Parse(parameters[4]); } metadata.Function.OpenItemBox = box; break; } case "SelectItemBox" when function.parameter.Contains('l'): return; // TODO: Implement these CN items. Skipping for now case "SelectItemBox": { List <string> parameters = new(function.parameter.Split(',')); parameters.RemoveAll(param => param.Length == 0); SelectItemBox box = new() { GroupId = int.Parse(parameters[0]), BoxId = int.Parse(parameters[1]) }; metadata.Function.SelectItemBox = box; break; } case "ChatEmoticonAdd": { string rawParameter = function.parameter; string decodedParameter = HttpUtility.HtmlDecode(rawParameter); XmlDocument xmlParameter = new(); xmlParameter.LoadXml(decodedParameter); XmlNode functionParameters = xmlParameter.SelectSingleNode("v"); ChatEmoticonAdd sticker = new() { Id = byte.Parse(functionParameters.Attributes["id"].Value), Duration = int.Parse(functionParameters.Attributes["durationSec"]?.Value ?? "0") }; metadata.Function.ChatEmoticonAdd = sticker; break; } case "OpenMassive": { string rawParameter = function.parameter; string cleanParameter = rawParameter.Remove(1, 1); // remove the unwanted space string decodedParameter = HttpUtility.HtmlDecode(cleanParameter); XmlDocument xmlParameter = new(); xmlParameter.LoadXml(decodedParameter); XmlNode functionParameters = xmlParameter.SelectSingleNode("v"); OpenMassiveEvent massiveEvent = new() { FieldId = int.Parse(functionParameters.Attributes["fieldID"].Value), Duration = int.Parse(functionParameters.Attributes["portalDurationTick"].Value), Capacity = byte.Parse(functionParameters.Attributes["maxCount"].Value) }; metadata.Function.OpenMassiveEvent = massiveEvent; break; } case "LevelPotion": { string rawParameter = function.parameter; string decodedParameter = HttpUtility.HtmlDecode(rawParameter); XmlDocument xmlParameter = new(); xmlParameter.LoadXml(decodedParameter); XmlNode functionParameters = xmlParameter.SelectSingleNode("v"); LevelPotion levelPotion = new() { TargetLevel = byte.Parse(functionParameters.Attributes["targetLevel"].Value) }; metadata.Function.LevelPotion = levelPotion; break; } case "VIPCoupon": { string rawParameter = function.parameter; string decodedParameter = HttpUtility.HtmlDecode(rawParameter); XmlDocument xmlParameter = new(); xmlParameter.LoadXml(decodedParameter); XmlNode functionParameters = xmlParameter.SelectSingleNode("v"); VIPCoupon coupon = new() { Duration = int.Parse(functionParameters.Attributes["period"].Value) }; metadata.Function.VIPCoupon = coupon; break; } case "HongBao": { string rawParameter = function.parameter; string decodedParameter = HttpUtility.HtmlDecode(rawParameter); XmlDocument xmlParameter = new(); xmlParameter.LoadXml(decodedParameter); XmlNode functionParameters = xmlParameter.SelectSingleNode("v"); HongBaoData hongBao = new() { Id = int.Parse(functionParameters.Attributes["itemId"].Value), Count = short.Parse(functionParameters.Attributes["totalCount"].Value), TotalUsers = byte.Parse(functionParameters.Attributes["totalUser"].Value), Duration = int.Parse(functionParameters.Attributes["durationSec"].Value) }; metadata.Function.HongBao = hongBao; break; } case "SuperWorldChat": { string[] parameters = function.parameter.Split(","); metadata.Function.Id = int.Parse(parameters[0]); // only storing the first parameter. Not sure if the server uses the other 2. break; } case "OpenGachaBox": { string[] parameters = function.parameter.Split(","); metadata.Function.Id = int.Parse(parameters[0]); // only storing the first parameter. Unknown what the second parameter is used for. break; } case "OpenCoupleEffectBox": { string[] parameters = function.parameter.Split(","); OpenCoupleEffectBox box = new() { Id = int.Parse(parameters[0]), Rarity = byte.Parse(parameters[1]) }; metadata.Function.OpenCoupleEffectBox = box; break; } case "InstallBillBoard": { string rawParameter = function.parameter; string decodedParameter = HttpUtility.HtmlDecode(rawParameter); XmlDocument xmlParameter = new(); xmlParameter.LoadXml(decodedParameter); XmlNode functionParameters = xmlParameter.SelectSingleNode("v"); InstallBillboard balloon = new() { InteractId = int.Parse(functionParameters.Attributes["interactID"].Value), Duration = int.Parse(functionParameters.Attributes["durationSec"].Value), Model = functionParameters.Attributes["model"].Value, Asset = functionParameters.Attributes["asset"]?.Value ?? "", NormalState = functionParameters.Attributes["normal"].Value, Reactable = functionParameters.Attributes["reactable"].Value, Scale = float.Parse(functionParameters.Attributes["scale"]?.Value ?? "0") }; metadata.Function.InstallBillboard = balloon; break; } case "SurvivalSkin": { string rawParameter = function.parameter; string decodedParameter = HttpUtility.HtmlDecode(rawParameter); XmlDocument xmlParameter = new(); xmlParameter.LoadXml(decodedParameter); XmlNode functionParameters = xmlParameter.SelectSingleNode("v"); MedalSlot medalSlot = functionParameters.Attributes["type"].Value switch { "effectTail" => MedalSlot.Tail, "riding" => MedalSlot.GroundMount, "gliding" => MedalSlot.Glider, _ => throw new ArgumentException($"Unknown slot for: {functionParameters.Attributes["type"].Value}") }; metadata.Function.SurvivalSkin = new() { Id = int.Parse(functionParameters.Attributes["id"].Value), Slot = medalSlot }; } break; case "SurvivalLevelExp": { string rawParameter = function.parameter; string decodedParameter = HttpUtility.HtmlDecode(rawParameter); XmlDocument xmlParameter = new(); xmlParameter.LoadXml(decodedParameter); XmlNode functionParameters = xmlParameter.SelectSingleNode("v"); metadata.Function.SurvivalLevelExp = new() { SurvivalExp = int.Parse(functionParameters.Attributes["SurvivalExp"].Value) }; } break; case "TitleScroll": case "ItemExchangeScroll": case "OpenInstrument": case "StoryBook": case "FishingRod": case "ItemChangeBeauty": case "ItemRePackingScroll": case "ItemSocketScroll": case "EnchantScroll": metadata.Function.Id = int.Parse(function.parameter); break; } }