Added recipe resolver

This commit is contained in:
Filip Maj 2021-02-23 15:39:46 -05:00
parent 6e1f13d17a
commit df49eefadb
6 changed files with 244 additions and 1 deletions

View file

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Meteor.Map.DataObjects
{
class Recipe
{
public readonly uint resultItemID;
public readonly uint resultQuantity;
public readonly byte[] allowedCrafters;
public readonly byte tier;
public Recipe(uint resultItemID, uint resultQuantity, byte[] allowedCrafters, byte tier)
{
this.resultItemID = resultItemID;
this.resultQuantity = resultQuantity;
this.allowedCrafters = allowedCrafters;
this.tier = tier;
}
}
}

View file

@ -0,0 +1,69 @@
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
namespace Meteor.Map.DataObjects
{
class RecipeResolver
{
Dictionary<uint, Recipe> recipeList;
Dictionary<string, List<Recipe>> matsToRecipes;
private RecipeResolver(Dictionary<uint, Recipe> recipeList, Dictionary<string, List<Recipe>> matsToRecipes)
{
this.recipeList = recipeList;
this.matsToRecipes = matsToRecipes;
}
public static RecipeResolver Init()
{
var recipeList = new Dictionary<uint, Recipe>();
var matToRecipes = new Dictionary<string, List<Recipe>>();
Database.GetRecipeGamedata(recipeList, matToRecipes);
return new RecipeResolver(recipeList, matToRecipes);
}
public List<Recipe> GetRecipeFromMats(uint mat1 = 0, uint mat2 = 0, uint mat3 = 0, uint mat4 = 0, uint mat5 = 0, uint mat6 = 0, uint mat7 = 0, uint mat8 = 0)
{
uint[] mats = new uint[8];
mats[0] = mat1;
mats[1] = mat2;
mats[2] = mat3;
mats[3] = mat4;
mats[4] = mat5;
mats[5] = mat6;
mats[6] = mat7;
mats[7] = mat8;
Array.Sort(mats);
byte[] result = new byte[8 * sizeof(int)];
Buffer.BlockCopy(mats, 0, result, 0, result.Length);
string hash;
using (MD5 md5 = MD5.Create())
{
hash = BitConverter.ToString(md5.ComputeHash(result));
}
if (matsToRecipes.ContainsKey(hash))
return matsToRecipes[hash];
else
return null;
}
public Recipe GetMatsForRecipe(uint recipeID)
{
if (recipeList.ContainsKey(recipeID))
return recipeList[recipeID];
else
return null;
}
public int GetNumRecipes()
{
return recipeList.Count;
}
}
}

View file

@ -33,6 +33,8 @@ using Meteor.Map.packets.receive.supportdesk;
using Meteor.Map.actors.chara.npc;
using Meteor.Map.actors.chara.ai;
using Meteor.Map.packets.send.actor.battle;
using Meteor.Map.DataObjects;
using System.Security.Cryptography;
namespace Meteor.Map
{
@ -168,6 +170,99 @@ namespace Meteor.Map
}
}
public static bool GetRecipeGamedata(Dictionary<uint, Recipe> recipeList, Dictionary<string, List<Recipe>> matToRecipe)
{
using (var conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD)))
{
try
{
conn.Open();
string query = @"
SELECT
id,
craftedItem,
craftedQuantity,
crystal0ID,
crystal0Quantity,
crystal1ID,
crystal1Quantity,
material0,
material1,
material2,
material3,
material4,
material5,
material6,
material7
FROM gamedata_recipes
ORDER BY craftedItem ASC
";
MySqlCommand cmd = new MySqlCommand(query, conn);
using (MySqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
uint recipeID = reader.GetUInt32("id");
uint craftedItem = reader.GetUInt32("craftedItem");
uint craftedQuantity = reader.GetUInt32("craftedQuantity");
uint crystal0ID = reader.GetUInt32("crystal0ID");
uint crystal0Quantity = reader.GetUInt32("crystal0Quantity");
uint crystal1ID = reader.GetUInt32("crystal1ID");
uint crystal1Quantity = reader.GetUInt32("crystal1Quantity");
uint[] mats = new uint[8];
mats[0] = reader.GetUInt32("material0");
mats[1] = reader.GetUInt32("material1");
mats[2] = reader.GetUInt32("material2");
mats[3] = reader.GetUInt32("material3");
mats[4] = reader.GetUInt32("material4");
mats[5] = reader.GetUInt32("material5");
mats[6] = reader.GetUInt32("material6");
mats[7] = reader.GetUInt32("material7");
Array.Sort(mats);
Recipe recipe = new Recipe(craftedItem, craftedQuantity, new byte[] { }, 1);
//Hash for the Mat -> Recipe Dictionary
byte[] result = new byte[8 * sizeof(int)];
Buffer.BlockCopy(mats, 0, result, 0, result.Length);
string hash;
using (MD5 md5 = MD5.Create())
{
hash = BitConverter.ToString(md5.ComputeHash(result));
}
if (!matToRecipe.ContainsKey(hash))
matToRecipe.Add(hash, new List<Recipe>());
//Add to both Dictionaries
recipeList.Add(recipeID, new Recipe(craftedItem, craftedQuantity, new byte[] { }, 1));
matToRecipe[hash].Add(new Recipe(craftedItem, craftedQuantity, new byte[] { }, 1));
}
}
}
catch (MySqlException e)
{
Program.Log.Error(e.ToString());
return false;
}
finally
{
conn.Dispose();
}
return true;
}
}
public static void SavePlayerAppearance(Player player)
{
string query;
@ -2777,6 +2872,6 @@ namespace Meteor.Map
}
}
}
}
}

View file

@ -37,6 +37,7 @@ using Meteor.Map.actors.area;
using System.Threading;
using Meteor.Map.actors.chara.ai;
using Meteor.Map.actors.chara.ai.controllers;
using Meteor.Map.DataObjects;
namespace Meteor.Map.lua
{
@ -850,6 +851,7 @@ namespace Meteor.Map.lua
script.Globals["GetWorldMaster"] = (Func<Actor>)Server.GetWorldManager().GetActor;
script.Globals["GetItemGamedata"] = (Func<uint, ItemData>)Server.GetItemGamedata;
script.Globals["GetGuildleveGamedata"] = (Func<uint, GuildleveData>)Server.GetGuildleveGamedata;
script.Globals["GetRecipeResolver"] = (Func<RecipeResolver>)Server.ResolveRecipe;
script.Globals["GetLuaInstance"] = (Func<LuaEngine>)LuaEngine.GetInstance;
script.Options.DebugPrint = s => { Program.Log.Debug(s); };

View file

@ -168,6 +168,8 @@
<Compile Include="Actors\StaticActors.cs" />
<Compile Include="Actors\World\WorldMaster.cs" />
<Compile Include="DataObjects\GuildleveData.cs" />
<Compile Include="DataObjects\Recipe.cs" />
<Compile Include="DataObjects\RecipeResolver.cs" />
<Compile Include="DataObjects\TradeTransaction.cs" />
<Compile Include="DataObjects\ZoneConnection.cs" />
<Compile Include="CommandProcessor.cs" />