nuttheawsome
05-14-2008, 07:45 PM
I am kind of new to this engine so if what im about to explain has already been covered then my apologies!
A friend and I got together and started a server a couple of weeks ago. While testing everything out we noticed a bug in the tradeskills. If you try to combine a recipe that has the exact same ingredients, but a different container type you get a message: "These items cannot be combined in this container type."
Just in case anyone reading doesn't understand the problem, here is an example:
There are two recipes: Boots of Justice and Boots of the Northern Wolf.
Both of these recipes have the exact same ingredients, the only difference is they use two different containers. If you walk through the TradeSkills.cpp you'll notice what is going on.
The code does two checks, first a basic check to find the recipe and if the database returns multiple results it calculates a unique number based on the ingredient id's. This works fine usually, but in the case above, you still get multiple recipes returned because they use the EXACT same ingredients, so instead of validating again, it just returns false thinking you have a duplicate recipe in the table.
Ive fixed this by adding in a third check. Now if it returns multiple recipes a second time, we validate the container type and if the player is using the correct container type it will validate properly.(Or return false if the recipe is truely not unique or the correct container isn't being used)
Here is the code:(It starts around line 900 in the tradeskills.cpp)
//updated this section to fix the tradeskill bug of multiple recipies, but different containers.
/*
if (qcount != 1) {
if(qcount > 1) {
LogFile->write(EQEMuLog::Error, "Combine error: Recipe is not unique!");
}
//else, just not found i guess..
return(false);
}*/
if(qcount < 1)
return(false);
if(qcount > 1)
{
//The recipe is not unique, so we need to compare the container were using.
uint32 containerId = container->GetID();
qlen = MakeAnyLenString(&query,"SELECT tre.recipe_id FROM tradeskill_recipe_entries as tre WHERE tre.recipe_id IN (%s)"
" GROUP BY tre.item_id HAVING tre.item_id = %u;",buf2,containerId);
if (!RunQuery(query, qlen, errbuf, &result)) {
LogFile->write(EQEMuLog::Error, "Error in GetTradeRecipe, re-query: %s", query);
safe_delete_array(query);
LogFile->write(EQEMuLog::Error, "Error in GetTradeRecipe, error: %s", errbuf);
return(false);
}
safe_delete_array(query);
uint32 resultRowTotal = mysql_num_rows(result);
//If all the recipes were correct, but no container type matched, drop out.
if(resultRowTotal == 0 || resultRowTotal > 1){
LogFile->write(EQEMuLog::Error, "Combine error: Recipe is not unique OR incorrect container is being used!");
return(false);
}
}
I am not the best at writing MYSQL queries. So this may be able to be fixed with just a more robust query on the second check, but this fix does the trick(as far as I can tell)
Hope it helps someone here...
-Nut
A friend and I got together and started a server a couple of weeks ago. While testing everything out we noticed a bug in the tradeskills. If you try to combine a recipe that has the exact same ingredients, but a different container type you get a message: "These items cannot be combined in this container type."
Just in case anyone reading doesn't understand the problem, here is an example:
There are two recipes: Boots of Justice and Boots of the Northern Wolf.
Both of these recipes have the exact same ingredients, the only difference is they use two different containers. If you walk through the TradeSkills.cpp you'll notice what is going on.
The code does two checks, first a basic check to find the recipe and if the database returns multiple results it calculates a unique number based on the ingredient id's. This works fine usually, but in the case above, you still get multiple recipes returned because they use the EXACT same ingredients, so instead of validating again, it just returns false thinking you have a duplicate recipe in the table.
Ive fixed this by adding in a third check. Now if it returns multiple recipes a second time, we validate the container type and if the player is using the correct container type it will validate properly.(Or return false if the recipe is truely not unique or the correct container isn't being used)
Here is the code:(It starts around line 900 in the tradeskills.cpp)
//updated this section to fix the tradeskill bug of multiple recipies, but different containers.
/*
if (qcount != 1) {
if(qcount > 1) {
LogFile->write(EQEMuLog::Error, "Combine error: Recipe is not unique!");
}
//else, just not found i guess..
return(false);
}*/
if(qcount < 1)
return(false);
if(qcount > 1)
{
//The recipe is not unique, so we need to compare the container were using.
uint32 containerId = container->GetID();
qlen = MakeAnyLenString(&query,"SELECT tre.recipe_id FROM tradeskill_recipe_entries as tre WHERE tre.recipe_id IN (%s)"
" GROUP BY tre.item_id HAVING tre.item_id = %u;",buf2,containerId);
if (!RunQuery(query, qlen, errbuf, &result)) {
LogFile->write(EQEMuLog::Error, "Error in GetTradeRecipe, re-query: %s", query);
safe_delete_array(query);
LogFile->write(EQEMuLog::Error, "Error in GetTradeRecipe, error: %s", errbuf);
return(false);
}
safe_delete_array(query);
uint32 resultRowTotal = mysql_num_rows(result);
//If all the recipes were correct, but no container type matched, drop out.
if(resultRowTotal == 0 || resultRowTotal > 1){
LogFile->write(EQEMuLog::Error, "Combine error: Recipe is not unique OR incorrect container is being used!");
return(false);
}
}
I am not the best at writing MYSQL queries. So this may be able to be fixed with just a more robust query on the second check, but this fix does the trick(as far as I can tell)
Hope it helps someone here...
-Nut