private static async Task ManualDevice(IHttpContext context) { //await ControllersLock.WaitAsync(); try { string raw = await context.GetRequestBodyAsStringAsync(); ManualData data = JsonConvert.DeserializeObject <ManualData>(raw); foreach (IDeviceProvider provider in DeviceManager.GetManualDeviceProviders()) { string Name = (Attribute.GetCustomAttribute(provider.GetType(), typeof(DeviceProviderAttribute)) as DeviceProviderAttribute)?.TypeString; string Code = (Attribute.GetCustomAttribute(provider.GetType(), typeof(DeviceProviderAttribute)) as DeviceProviderAttribute)?.TypeCode; if (Code == data.Code) { IDeviceManualTriggerContext retVal = provider.ManualTrigger(data.Data); await context.SendDataAsync(new ManualDataOut() { Code = Code, Data = retVal }); return; } } } finally { //ControllersLock.Release(); } }
/// <summary> /// Returns list of items that have to be decremented to satisfy the /// manual's required materials. Actual return value is whether /// this process was successful, or if materials are missing. /// Handles necessary messages and logs. /// </summary> /// <param name="creature"></param> /// <param name="manualData"></param> /// <param name="materials">List of materials the client supplies.</param> /// <param name="toDecrement"></param> /// <returns></returns> protected bool GetItemsToDecrement(Creature creature, Stage stage, ManualData manualData, List <ProductionMaterialData> requiredMaterials, List <ProductionMaterial> materials, out List <ProductionMaterial> toDecrement) { toDecrement = new List <ProductionMaterial>(); var inUse = new HashSet <long>(); foreach (var reqMat in requiredMaterials) { // Check all selected items for tag matches foreach (var material in materials) { // Satisfy requirement with item, up to the max amount // needed or available if (material.Item.HasTag(reqMat.Tag)) { // Cancel if one item matches multiple materials. // It's unknown how this would be handled, can it even // happen? Can one item maybe only be used as one material? if (inUse.Contains(material.Item.EntityId)) { Send.ServerMessage(creature, Localization.Get("Unable to handle request, please report, with this information: ({0}/{1}:{2})."), material.Item.Info.Id, manualData.Category, manualData.Id); Log.Warning("CreationSkill.GetItemsToDecrement: Item '{0}' matches multiple materials for manual '{1}:{2}'.", material.Item.Info.Id, manualData.Category, manualData.Id); return(false); } var amount = Math.Min(reqMat.Amount, material.Item.Amount); reqMat.Amount -= amount; toDecrement.Add(new ProductionMaterial(material.Item, amount)); inUse.Add(material.Item.EntityId); } // Break once we got what we need if (reqMat.Amount == 0) { break; } } } if (requiredMaterials.Any(a => a.Amount != 0)) { // Unofficial, the client should normally prevent this. Send.ServerMessage(creature, Localization.Get("Insufficient materials.")); return(false); } return(true); }
public void addManualData(int id, ManualData manualClass) { manualData.Add(id, manualClass); }
/// <summary> /// Sets appropriete flags, bonuses, and signatures, and sends /// notices about quality and bonuses. /// </summary> /// <param name="creature"></param> /// <param name="skill"></param> /// <param name="manualData"></param> /// <param name="finishId"> /// The id of the finish to use, make sure to get the actual /// finish id, which in Blacksmithing comes from the Prepare /// that switches to the mini-game. /// </param> /// <param name="item"></param> /// <param name="quality"></param> protected void FinishItem(Creature creature, Skill skill, ManualData manualData, int finishId, Item item, int quality) { var finish = manualData.GetFinish(finishId); if (finish == null) { Log.Error("CreationSkill.FinishItem: Finish '{0}' not found.", finishId); Send.ServerMessage(creature, Localization.Get("Unknown finish recipe, please report.")); return; } // Monday: Increase in quality of output for productions. // +5, unofficial. if (ErinnTime.Now.Month == ErinnMonth.AlbanEiler) quality = Math.Min(100, quality + 5); // Update item item.OptionInfo.Flags &= ~ItemFlags.Incomplete; item.OptionInfo.Flags |= ItemFlags.Reproduction; item.MetaData1.Remove(ProgressVar); item.MetaData1.Remove(StclmtVar); item.MetaData1.SetInt(QualityVar, quality); if (finish.Color1 != null) item.Info.Color1 = (uint)finish.Color1; if (finish.Color2 != null) item.Info.Color2 = (uint)finish.Color2; if (finish.Color3 != null) item.Info.Color3 = (uint)finish.Color3; // Signature if (skill.Info.Rank >= SkillRank.R9 && manualData.Rank >= SkillRank.RA && quality >= 80) { item.MetaData1.SetString(SignNameVar, creature.Name); item.MetaData1.SetByte(SignRankVar, (byte)skill.Info.Rank); } // Get quality based msg var msg = ""; if (quality == 100) // god { msg = Localization.Get("You created a godly {0}! Excellent work!"); } else if (quality >= 80) // best { msg = Localization.Get("Your hard work produced a very nice {0}!"); } else if (quality >= 50) // better { msg = Localization.Get("Your efforts created an above-average {0}!"); } else if (quality >= 20) // reasonable { msg = Localization.Get("Your creation is far superior to anything you can get from a store."); } else if (quality >= -20) // normal { msg = Localization.Get("Your creation is just as good as anything you can get from a store."); } else if (quality >= -50) // worse { msg = Localization.Get("Your creation could be nice with a few repairs."); } else if (quality >= -80) // worst { msg = Localization.Get("You managed to finish the {0}, but it's pretty low quality."); } else { msg = Localization.Get("Your {0} isn't really fit for use. Maybe you could get some decent scrap wood out of it."); } // Apply bonuses and append msgs var bonuses = this.GetBonusesFor(item, quality); if (bonuses.Count != 0) { msg += "\n"; foreach (var bonus in bonuses) { var bonusName = "?"; switch (bonus.Key) { case Bonus.Defense: item.OptionInfo.Defense += bonus.Value; bonusName = "Defense"; break; case Bonus.Protection: item.OptionInfo.Protection += (short)bonus.Value; bonusName = "Protection"; break; case Bonus.Durability: item.OptionInfo.Durability += bonus.Value * 1000; bonusName = "Durability"; break; case Bonus.DurabilityMax: item.OptionInfo.DurabilityMax += bonus.Value * 1000; bonusName = "Max Durability"; break; case Bonus.AttackMin: item.OptionInfo.AttackMin += (ushort)bonus.Value; bonusName = "Min Attack"; break; case Bonus.AttackMax: item.OptionInfo.AttackMax += (ushort)bonus.Value; bonusName = "Max Attack"; break; case Bonus.Critical: item.OptionInfo.Critical += (sbyte)bonus.Value; bonusName = "Critical"; break; case Bonus.Balance: item.OptionInfo.Balance += (byte)bonus.Value; bonusName = "Balance"; break; } if (bonus.Value > 0) msg += string.Format("{0} Increase {1}, ", bonusName, bonus.Value); else msg += string.Format("{0} Decrease {1}, ", bonusName, bonus.Value); } msg = msg.TrimEnd(',', ' '); // Check attack if (item.OptionInfo.AttackMin > item.OptionInfo.AttackMax) item.OptionInfo.AttackMin = item.OptionInfo.AttackMax; // Check durability if (item.OptionInfo.Durability > item.OptionInfo.DurabilityMax) item.OptionInfo.Durability = item.OptionInfo.DurabilityMax; } // Send notice Send.Notice(creature, msg, item.Data.Name); }
/// <summary> /// Returns list of items that have to be decremented to satisfy the /// manual's required materials. Actual return value is whether /// this process was successful, or if materials are missing. /// Handles necessary messages and logs. /// </summary> /// <param name="creature"></param> /// <param name="manualData"></param> /// <param name="materials">List of materials the client supplies.</param> /// <param name="toDecrement"></param> /// <returns></returns> protected bool GetItemsToDecrement(Creature creature, Stage stage, ManualData manualData, List<ProductionMaterialData> requiredMaterials, List<ProductionMaterial> materials, out List<ProductionMaterial> toDecrement) { toDecrement = new List<ProductionMaterial>(); var inUse = new HashSet<long>(); foreach (var reqMat in requiredMaterials) { // Check all selected items for tag matches foreach (var material in materials) { // Satisfy requirement with item, up to the max amount // needed or available if (material.Item.HasTag(reqMat.Tag)) { // Cancel if one item matches multiple materials. // It's unknown how this would be handled, can it even // happen? Can one item maybe only be used as one material? if (inUse.Contains(material.Item.EntityId)) { Send.ServerMessage(creature, Localization.Get("Unable to handle request, please report, with this information: ({0}/{1}:{2})."), material.Item.Info.Id, manualData.Category, manualData.Id); Log.Warning("CreationSkill.GetItemsToDecrement: Item '{0}' matches multiple materials for manual '{1}:{2}'.", material.Item.Info.Id, manualData.Category, manualData.Id); return false; } var amount = Math.Min(reqMat.Amount, material.Item.Amount); reqMat.Amount -= amount; toDecrement.Add(new ProductionMaterial(material.Item, amount)); inUse.Add(material.Item.EntityId); } // Break once we got what we need if (reqMat.Amount == 0) break; } } if (requiredMaterials.Any(a => a.Amount != 0)) { // Unofficial, the client should normally prevent this. Send.ServerMessage(creature, Localization.Get("Insufficient materials.")); return false; } return true; }
/// <summary> /// Sets appropriete flags, bonuses, and signatures, and sends /// notices about quality and bonuses. /// </summary> /// <param name="creature"></param> /// <param name="skill"></param> /// <param name="manualData"></param> /// <param name="finishId"> /// The id of the finish to use, make sure to get the actual /// finish id, which in Blacksmithing comes from the Prepare /// that switches to the mini-game. /// </param> /// <param name="item"></param> /// <param name="quality"></param> protected void FinishItem(Creature creature, Skill skill, ManualData manualData, int finishId, Item item, int quality) { var finish = manualData.GetFinish(finishId); if (finish == null) { Log.Error("CreationSkill.FinishItem: Finish '{0}' not found.", finishId); Send.ServerMessage(creature, Localization.Get("Unknown finish recipe, please report.")); return; } // Update item item.OptionInfo.Flags &= ~ItemFlags.Incomplete; item.OptionInfo.Flags |= ItemFlags.Reproduction; item.MetaData1.Remove(ProgressVar); item.MetaData1.Remove(StclmtVar); item.MetaData1.SetInt(QualityVar, quality); if (finish.Color1 != null) { item.Info.Color1 = (uint)finish.Color1; } if (finish.Color2 != null) { item.Info.Color2 = (uint)finish.Color2; } if (finish.Color3 != null) { item.Info.Color3 = (uint)finish.Color3; } // Signature if (skill.Info.Rank >= SkillRank.R9 && manualData.Rank >= SkillRank.RA && quality >= 80) { item.MetaData1.SetString(SignNameVar, creature.Name); item.MetaData1.SetByte(SignRankVar, (byte)skill.Info.Rank); } // Get quality based msg var msg = ""; if (quality == 100) // god { msg = Localization.Get("You created a godly {0}! Excellent work!"); } else if (quality >= 80) // best { msg = Localization.Get("Your hard work produced a very nice {0}!"); } else if (quality >= 50) // better { msg = Localization.Get("Your efforts created an above-average {0}!"); } else if (quality >= 20) // reasonable { msg = Localization.Get("Your creation is far superior to anything you can get from a store."); } else if (quality >= -20) // normal { msg = Localization.Get("Your creation is just as good as anything you can get from a store."); } else if (quality >= -50) // worse { msg = Localization.Get("Your creation could be nice with a few repairs."); } else if (quality >= -80) // worst { msg = Localization.Get("You managed to finish the {0}, but it's pretty low quality."); } else { msg = Localization.Get("Your {0} isn't really fit for use. Maybe you could get some decent scrap wood out of it."); } // Apply bonuses and append msgs var bonuses = this.GetBonusesFor(item, quality); if (bonuses.Count != 0) { msg += "\n"; foreach (var bonus in bonuses) { var bonusName = "?"; switch (bonus.Key) { case Bonus.Defense: item.OptionInfo.Defense += bonus.Value; bonusName = "Defense"; break; case Bonus.Protection: item.OptionInfo.Protection += (short)bonus.Value; bonusName = "Protection"; break; case Bonus.Durability: item.OptionInfo.Durability += bonus.Value * 1000; bonusName = "Durability"; break; case Bonus.DurabilityMax: item.OptionInfo.DurabilityMax += bonus.Value * 1000; bonusName = "Max Durability"; break; case Bonus.AttackMin: item.OptionInfo.AttackMin += (ushort)bonus.Value; bonusName = "Min Attack"; break; case Bonus.AttackMax: item.OptionInfo.AttackMax += (ushort)bonus.Value; bonusName = "Max Attack"; break; case Bonus.Critical: item.OptionInfo.Critical += (sbyte)bonus.Value; bonusName = "Critical"; break; case Bonus.Balance: item.OptionInfo.Balance += (byte)bonus.Value; bonusName = "Balance"; break; } if (bonus.Value > 0) { msg += string.Format("{0} Increase {1}, ", bonusName, bonus.Value); } else { msg += string.Format("{0} Decrease {1}, ", bonusName, bonus.Value); } } msg = msg.TrimEnd(',', ' '); // Check attack if (item.OptionInfo.AttackMin > item.OptionInfo.AttackMax || item.OptionInfo.AttackMax < item.OptionInfo.AttackMin) { item.OptionInfo.AttackMin = item.OptionInfo.AttackMax; } // Check durability if (item.OptionInfo.Durability > item.OptionInfo.DurabilityMax || item.OptionInfo.DurabilityMax < item.OptionInfo.Durability) { item.OptionInfo.Durability = item.OptionInfo.DurabilityMax; } } // Send notice Send.Notice(creature, msg, item.Data.Name); }
public ActionResult Put([FromBody] ManualData manualDataData) { DataBaseObjectStorage.SaveToDataBase(manualDataData); return(NoContent()); }
public static void CraftItem(MartialClient c, InPacket p) { if (c.getAccount().activeCharacter == null) { Logger.LogCheat(Logger.HackTypes.NullActive, c, "Attempted to hook craftItem while not being ingame."); c.Close(); return; } Character chr = c.getAccount().activeCharacter; int craftingID = p.ReadInt(); int manualInventoryIndex = p.ReadInt(); // better to be sure, than be rzaah XD if (manualInventoryIndex < 0) { Console.WriteLine("manuel < 0"); return; } Inventory inv = chr.getInventory(); inv.updateInv(); List <int> seq = new List <int>(inv.getSeqSaved()); Dictionary <int, Item> items = new Dictionary <int, Item>(inv.getInvSaved()); if (!items.ContainsKey(seq[manualInventoryIndex])) { Console.WriteLine("unknown item at index {0}", manualInventoryIndex); return; } Item item = items[seq[manualInventoryIndex]]; ItemData itemData = ItemDataCache.Instance.getItemData(item.getItemID()); if (itemData == null) { Console.WriteLine("unknown itemdata for item of ID {0}", item.getItemID()); return; } if (itemData.getCategory() != 1010) { Console.WriteLine("dat shit ain't manual"); return; } ManualData manual = ManualDataCache.Instance.getManualData(craftingID); if (manual == null) { Console.WriteLine("manual wasn't found.."); return; } List <Item> providedMaterials = new List <Item>(); List <int> providedMaterialID = new List <int>(); List <int> providedMaterialQa = new List <int>(); List <int> providedMaterialIndex = new List <int>(); for (int i = 0; i < 8; i++) { int tempMaterialIndex = p.ReadInt(); Console.WriteLine("indexez of provided mats {0}", tempMaterialIndex); if (tempMaterialIndex == -1) { break; } if (seq.ElementAt(tempMaterialIndex) == -1) { return; } if (!items.ContainsKey(seq[tempMaterialIndex])) { return; } Item tempMaterial = items[seq[tempMaterialIndex]]; if (tempMaterial == null) { Console.WriteLine("unknown tempMaterial at index {0}", tempMaterialIndex); return; } if (tempMaterial.getQuantity() < 1) { Console.WriteLine("tempMaterial has less than 1 quantity :< {0}", tempMaterialIndex); return; } providedMaterials.Add(tempMaterial); providedMaterialID.Add(tempMaterial.getItemID()); providedMaterialQa.Add(tempMaterial.getQuantity()); providedMaterialIndex.Add(tempMaterialIndex); } if (providedMaterials.Count == 0) { Console.WriteLine("playa doesn't supplied materials at all"); return; } List <int> deductedAmount = new List <int>(providedMaterialQa); List <int> requiredMaterialID = manual.getRequiredMaterials(); List <int> requiredMaterialQa = manual.getRequiredQuantities(); for (int i = 0; i < providedMaterials.Count; i++) // let's check if playa has satisfied our data provided manual <3 { if (providedMaterialQa[i] < 1) { continue; } for (int x = 0; x < requiredMaterialID.Count; x++) { if (requiredMaterialQa[x] <= 0) { continue; } if (requiredMaterialID[x] == providedMaterialID[i]) { if (requiredMaterialQa[x] >= providedMaterialQa[i]) { requiredMaterialQa[x] -= providedMaterialQa[i]; providedMaterialQa[i] = 0; } else { int tempQa = requiredMaterialQa[x]; requiredMaterialQa[x] = 0; providedMaterialQa[i] -= tempQa; } } } } if (requiredMaterialQa.Sum() != 0) { Console.WriteLine("user hasn't applied all of the needed materialz, damn cheatz"); return; } int craftedItemID = manual.getProducedItemID(); p.Position = 73; int row = p.ReadByte(); int line = p.ReadByte(); if (!inv.craftItem(new Item(craftedItemID))) { Console.WriteLine("InvCraftItem > Cannot craft item"); return; } for (int i = 0; i < providedMaterialIndex.Count; i++) { if (!inv._decrementItem(providedMaterialIndex[i], providedMaterialQa[i])) { Console.WriteLine("damn..?"); } } if (!inv._decrementItem(manualInventoryIndex)) { Console.WriteLine("damn man, again, wut happend to u?"); } OutPacket op = new OutPacket(168); // 'it has succeded all the checks n stuff now on to kfc.' - cause we all luv Rzaah op.WriteInt(168); op.WriteShort(0x04); op.WriteShort(0x28); op.WriteInt(0x01); op.WriteInt(chr.getuID()); op.WriteInt(0x01); p.Position = 4; op.WriteBytes(p.ReadBytes(68)); op.WriteInt(1); for (int i = 0; i < 8; i++) { if (providedMaterialIndex.Count > i) { op.WriteInt(deductedAmount[i] - providedMaterialQa[i]); } else { op.WriteInt(0); } } /* end_time - TODO: * op.Position = 153; * op.WriteByte(0xff); */ op.Position = 154; p.Position = 73; op.WriteShort(p.ReadShort()); op.WriteInt(craftedItemID); /* end_time - TODO: * op.WriteInt(craftedItem.getExpiration()); */ op.WriteInt(); // meanwhile.. p.Position = 72; op.WriteBytes(p.ReadBytes(4)); c.WriteRawPacket(op.ToArray()); inv.saveInv(); }