[CF-Devel] Alchemy exploit

crossfire-devel at archives.real-time.com crossfire-devel at archives.real-time.com
Mon Aug 16 00:05:15 CDT 2004


Andreas Kirschbaum wrote:
>
     
      Hello,
     
     >
     
     
     >
     
      I'd like to come back to alternate recipes for alchemy and related
     
     >
     
      skills. I think they can be (and currently on metalforge are) abused to
     
     >
     
      make money. (I found 1 million(!) potions of sunfire sold to a shop.)
     
     >
     
     
     >
     
      The common precondition for any valid recipe should be that at least one
     
     >
     
      ingredient is hard to get. This precondition is not valid for many
     
     >
     
      alternate recipes: after writing a small perl script, I recognized that
     
     >
     
      alternate recipes are *very* common, even when using only common
     
     >
     
      ingredients (for example coins or food). Without much effort, I found a
     
     >
     
      recipe that made items with a selling price of 40.000pp while using only
     
     >
     
      400pp of coins as ingredients.
     
     >
     
     
     >
     
      To prevent this particular abuse, I'd like to propose the following fix
     
     >
     
      (see attached diff): do not allow *alternate* recipes with a result
     
     >
     
      value higher than that of the ingredients.
     
     >
     
     
     >
     
      I limited the check for increased value to alternate recipes only
     
     >
     
      because there are some normal recipes that also match. But this should
     
     >
     
      not be a problem because you have to get the uncommon items first.
     
     
  the patch looks good, with only a few minor nits:
1) It seems there is a debug new_draw_info_format left in that prints the 
results of value of the item - presumably that needs to be removed.

2) The block:
  @@ -168,8 +183,14 @@
  		    success_chance, ability, rp->diff, item->level);
  #endif

+		value_item = query_cost(item, NULL, F_TRUE);
+		new_draw_info_format(NDI_UNIQUE, 0, caster, "result value=%llu", value_item);
+		if(attempt_shadow_alchemy && value_item > value_ingredients)
+#ifdef ALCHEMY_DEBUG
+		    LOG(llevDebug, "Forcing failure for shadow alchemy recipe.\n");
+#endif
  		/* roll the dice */
-		if ((float)(random_roll(0, 101, caster, PREFER_LOW)) <= 100.0 * success_chance) {
+		else if ((float)(random_roll(0, 101, caster, PREFER_LOW)) <= 100.0 * 
success_chance) {
  		    change_exp(caster, rp->exp, rp->skill, SK_EXP_NONE);
  		    return;
  		}
@@ -640,4 +661,84 @@

  I'm not sure if it will actually compile of ALCHEMY_DEBUG is not defined, as 
there is then just an empty if () else statement.  This can pretty easily be 
solved by just putting {} in the right places, as an empty block should be OK. 
Wonder if it might also be good to put some message as to why it failed.

3) use of any 'long' or 'unsigned long' variables is discouraged, as past 
experience has shown that there is no guarantee if these will be 64 or 32 bit 
values.  Instead use the uint32 or uint64 types, depending on what you need 
(maybe this has been clarified in more recent versions of the C standard).  But 
in any case, use of the uint/sint types is still preferred - I note that 
object.h defines nrof as a uint32.


_______________________________________________
crossfire-devel mailing list
     
     crossfire-devel at lists.real-time.com
     
     
     https://mailman.real-time.com/mailman/listinfo/crossfire-devel
     
     
    


More information about the crossfire mailing list