简体   繁体   English

PHP - 这是防止重新提交的好方法吗?

[英]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. 这与阻止webform重新提交有关 ,但这次上下文是基于Web的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. 由于项目丢弃频繁,使用DB存储唯一的“drop-transaction-id”对我来说似乎是不可行的。 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. 对于每次战斗,根据当前日期时间,用户ID创建唯一值,并将其存储到数据库和会话中。 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. 如果会话中的值存在于DB中,则“战斗”有效并允许用户访问与战斗相关的所有页面。 If it does not exist in DB, then a new combat state is started 如果它在DB中不存在,则启动新的战斗状态

  3. When combat is over, the unique value is cleared from DB. 战斗结束后,从DB中清除唯一值。

  4. Values which is 30mins old in the DB are purged. 清除DB中30分钟的值。

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. 获取userID以及该战斗中的唯一数据。 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. 这样,如果那个userID和那个独特的战斗数据存在,他们就没有得到他们的战利品。

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)? 这取决于你的游戏设计:你更倾向于roguelikes的方向,只有转数,因此在两次移动之间的长时间停顿肯定是可能的(比如通过聊天室咨询其他人,注意:在NetHack中不被认为是作弊)? 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. 这在设计上产生了巨大的差异,例如,为类似于Thorarin提到的漏洞做出让步。

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. 如果你的游戏只进行了一次拯救的传统roguelike路线,转动地下室和permadeath,那么就可以为任何给定角色保存当前转弯的数量以及任何与游戏相关的信息(库存,地图,敌人及其状态) ),然后在播放器的任何动作中检查,以防止转弯两次。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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