简体   繁体   中英

PHP - Is this a good method to prevent re-submission?

This is related to preventing webform resubmission , however this time the context is a web-based RPG. After the player defeats a monster, it would drop an item. So I would want to prevent the user from hitting the back button, or keep refreshing, to 'dupe' the item-drop.

As item drop is frequent, using a DB to store a unique 'drop-transaction-id' seems infeasible to me. I am entertaining an idea below:

  1. For each combat, creating an unique value based on the current date-time, user's id and store it into DB and session. It is possible that given a userid, you can fetch the value back

  2. If the value from session exists in the DB, then the 'combat' is valid and allow the user to access all pages relevant to combat. If it does not exist in DB, then a new combat state is started

  3. When combat is over, the unique value is cleared from DB.

  4. Values which is 30mins old in the DB are purged.

Any opinions, improvements, or pitfalls to this method are welcomed

This question is very subjective, there's things you can do or can not do, depending on the already existing data / framework around it.

The solution you've provided should work, but it depends on the unique combat/loot/user data you have available.

I take it this is what you think is best? It's what I think is best :)

  1. Get the userID, along with a unique piece of data from that fight. Something like combat start time, combat end time, etc
  2. Store it in a Database, or what ever storage system you have
  3. Once you collect the loot, delete that record

That way if the that userID, and that unique fight data exists, they haven't got their loot.

And you are right; tracking each piece of loot is too much, you're better off temporarily storing the data.

Seems like a reasonable approach. I assume you're storing the fact that the player is in combat somewhere anyway. Otherwise, they can just close their browser if they want to avoid a fight?

The combat ending and loot dropping should be treated as an atomary operation. If there is no fight, there can't be any dropping loot.

That depends on your game design: Do you go more in the direction of roguelikes where only turns count, and therefore long pauses in between moves are definitely possible (like consulting other people via chatroom, note: in NetHack that is not considered cheating)? Can users only save their games on certain points or at any place? That makes a huge difference in the design, eg making way for exploits similar to the one Thorarin mentions.

If your game goes the traditional roguelike route of only one save, turn basement and permadeath, then it would be possible to save the number of the current turn for any given character along with any game related information (inventory, maps, enemies and their state), and then check against that at any action of the player, therefore to prevent playing the turn twice.

或者你可以在客户端javascript中捆绑所有内容,这样即使他们确实重新提交了表单,也会产生一个全新的战斗/宝藏遭遇。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM