|
1
|
| MichaÅ Tatarynowicz · 技术社区 · 16 年前 |
|
|
1
5
在阅读了你的问题、其他答案和讨论之后,我想我终于掌握了你的问题(因此有了一个新的答案)。 首先,您需要跟踪最终用户的会话。当游戏开始时,您必须启动一个新的PHP会话,并向flash游戏发送某种会话标识符。每当flash游戏ping服务器时,它都会传递会话标识符,以便PHP知道它使用的是哪个游戏实例。 PHP服务器本身将是一个被动实体——flash客户端将执行数据推拉操作。假设一个用户将事件X、Y和Z排队,每一个都需要20秒。。。一旦用户尝试对每个事件排队,flash客户端就会通知服务器,服务器要么将其记录在队列中,要么由于验证而返回错误(即,队列中的事件太多)。 此外,客户端将每隔几秒钟轮询服务器以检查事件的状态。每次客户端注册新事件或轮询状态时,服务器都会检查队列中的时间戳,并将事件标记为已完成/etc,然后向客户端发送响应。这比试图在后台运行脚本(试图每秒实时更新数据库)更干净、更实用。唯一的缺点是,如果由于任何原因发生断开连接,则在客户端重新连接之前,不会处理特定会话的事件。但无论连接之间的时间长短,用户仍会认为服务器在实时更新,因为数据总是在发送回客户端之前刷新。 如果您有任何特定于实现的问题,请随时发布您的数据库模式和/或服务器代码。 更新:
无论您将如何使用数据(高分表等),将这两种技术结合起来可能是最好的主意。新鲜数据总是一个加号,来自cron脚本的定期增量刷新不会伤害任何人。
|
|
|
2
2
使用“time left”字段是个坏主意,因为它可以在客户端使用作弊引擎之类的程序进行黑客攻击。 在数据库中,记录上次事件的时间。您的中间件(请参阅 Tim's Answer )仍然执行验证,但告诉客户端是否可以执行请求的操作。所有验证都需要在中间件的服务器端完成。在新请求出现时,中间件可以检查数据库时间戳,查看所需的时间是否已过,并执行请求或向客户端返回错误。在服务器端和服务器端执行间隔检查可以防止客户端验证因内存修补程序而受损。 让客户自行验证。 |
|
|
3
1
CafeWorld、FarmVille、YoVille等游戏使用三层架构。flash应用程序是一个胖(ish!)客户端,内置了一些逻辑,使用存储在服务器上的数据,中间层提供数据接口并处理验证规则(例如不能同时使用两个炉子),持久层处理数据存储。 状态由客户端维护,但重要的是客户端不能将状态写入服务器,只有客户端上的事件才能触发服务器(中间层)中的更改。通过这种方式,中间层和客户机都保持单独的定时,并以一定的间隔进行同步。当这些时间间隔没有对齐时,您会在FarmVille之类的游戏中注意到,您会收到一条消息,通知您“游戏不同步”。 |
|
|
4
1
如果我正确理解了你的问题——游戏规则是由服务器实现的;定时器在客户端启动;重要的是“用户的运行时间”,而不是“服务器上的运行时间”(即用户不会因为连接延迟而受到惩罚);但它不能让假客户端假装存在高延迟。
在服务器上,仅存储客户端发送给您的信息和您发送给客户端的信息。(也就是说,我不打算存储服务器计算的“剩余时间”,因为它几乎肯定是错误的。取而代之的是,只存储“启动操作”事件的“客户端启动时间”和“允许的持续时间”。) http://www.freechess.nl/timeseal.htm 确保作弊的客户更难写。例如,在客户端使用私钥加密时间戳(或整个消息),在服务器上检查接收到的时间戳是否由有效密钥加密。 根据可容忍的意外延迟程度,您可能希望向客户端发送“潜在触发器”而不是“即时触发器”。也就是说,不要发送客户“现在客户B不付款就离开(因为玩家先照顾客户A)”,而是发送“如果玩家先照顾客户A,客户B不付款就离开”。 在服务器上检查这些规则是否在客户端正确发生,只需根据数据库中的选项验证接收到的事件顺序。因此,对于上面的示例,如果您看到事件“关注客户A”,则您希望下一个事件是“客户B不付款离开”。 玩家游戏的数据库表最终成为一个美化的事件日志——除了它还存储“接下来会发生什么”。您从游戏规则引擎获取规则,并将其存储为“下一个可用操作状态”事件。
|
|
|
5
1
在阅读了您的问题和给出的答案之后,我建议您重新思考您的应用程序体系结构。在我看来,您应该在客户端应用程序(flash)中实现整个游戏逻辑。服务器端应用程序应该只处理用户登录和游戏状态的管理。例如,玩家登录到您的flash应用程序->在服务器端检查用户是否存在,然后返回该用户的实际游戏状态。 1.让用户机器做繁重的工作,而不是服务器机器 2.限制进出服务器的流量 为了解决安全问题,我建议您在数据流量中实现一个简单的“质询-响应身份验证” challenge response on wiki |