【问题标题】:Removing a GKTurnBasedMatch which is in an invalid state删除处于无效状态的 GKTurnBasedMatch
【发布时间】:2013-04-27 00:11:10
【问题描述】:

我正在做一些实验来尝试了解 GameKit,并制作了一个简单的游戏和一个列出我的玩家比赛的界面。我正在尝试添加在比赛中使用removeWithCompletionHandler: 方法删除游戏的功能,但我无法删除似乎已进入无效状态的GKTurnBasedMatch

有问题的匹配项打印出来:

$0 = 0x1d590d20 <GKTurnBasedMatch 0x1d590d20 id:858d8257-cc49-4060-b1d8-38c09a929e3c status:Ended message: taken:2013-03-08 18:08:47 +0000 created:2013-03-08 03:24:14 +0000
current:<GKTurnBasedParticipant 0x1d58c020 - id:G:1717956303 (local player) status:Invited outcome:None lastTurn:(null)>
participants:
    <GKTurnBasedParticipant 0x1d58bc90 - id:G:1717239488 status:Done outcome:Quit lastTurn:2013-03-08 18:08:47 +0000>
    <GKTurnBasedParticipant 0x1d58c020 - id:G:1717956303 (local player) status:Invited outcome:None lastTurn:(null)>
>

这似乎表明比赛已经结束。然而,其中一位参与者的结果是:无,我被医生引导相信对于结束的游戏是无效的。试图简单地删除游戏给出:

请求的操作无法完成,因为一个或多个参数无效。

在尝试设定结果并结束游戏时:

由于会话处于无效状态,请求的操作无法完成。

我想也许我无法删除游戏,因为本地玩家是积极参与者,但 participantQuitInTurnWithOutcome:...endTurnWithNextParticipants:... 都给出了错误:

由于会话处于无效状态,请求的操作无法完成。

也是。是我做错了什么还是我以某种方式创建了一个无法移除的游戏?

附:我也无法通过 Game Center 提供的界面删除游戏,这些游戏列在“游戏结束”部分下。

【问题讨论】:

    标签: ios game-center gamekit


    【解决方案1】:

    这就是我设法删除所有无效匹配项的方法。

    我查看了当前参与者的状态,如果被邀请了,我调用了dendInviteWithCompletionHandler,否则我调用了participantQuitInTurnWithOutcome。

    在两个完成块中,然后我调用 removeWithCompletionHandler 来删除匹配项。

    这产生了一些错误,但匹配项仍被删除,因此我的列表很干净。

    这里有一个关于如何避免进入这种状态的解决方法。这样做的另一个好处是,如果邀请者在完成他/她的第一轮之前退出,被邀请者甚至不会收到通知。

    在 playerQuitForMatch 中,首先结束回合,然后在完成处理程序中,立即退出比赛。像这样,

    [match endTurnWithNextParticipants:[NSArray arrayWithObject:nextParticipant]
                                              turnTimeout:GKTurnTimeoutDefault
                                                matchData:nil completionHandler:^(NSError *error) {
                                                    if (error) {
                                                        NSLog(@"%@", error);
                                                    }
    
                                                    [match participantQuitOutOfTurnWithOutcome:GKTurnBasedMatchOutcomeQuit
                                                                         withCompletionHandler:^(NSError *error) {
                                                                             if (error) {
                                                                                 NSLog(@"%@" ,error);
                                                                             }
                                                                         }];
                                                }];
    

    【讨论】:

      【解决方案2】:

      不幸的是,我遇到了完全相同的错误。为了帮助其他人理解问题,希望研究解决方案,您可以通过邀请朋友参加比赛来重新创建此问题,但然后在第一回合中退出比赛,然后再将该回合提交给被邀请的玩家。然后,托管玩家从 Game Center 中删除比赛。在受邀玩家的设备上,他们将有一场与上面提到的比赛相似的比赛,无法删除。我已经尝试了所有类型的变通解决方案。

      我还没有运气,但如果我找到一个解决方案,我会更新我的答案。我目前正在尝试发布 Game Center 游戏,因此我必须找到解决此问题的方法。我会在一两天内得出结论。

      更新: 我检查了我的不可删除的比赛,它们和你的几乎一样,除了我的邀请状态的球员也有比赛结果赢了。似乎将比赛置于无效状态的关键是让一名玩家状态为 Invited 而不是 Done,但比赛状态为 Ended。这是我们两个案例之间的共同点,也是 Apple 的 bizantine Game Center 代码中的一个边缘案例。如果他们只是搞砸了这个边缘案例并期望你“知道”你不应该让玩家处于那种状态,我不会感到惊讶(毫无疑问,如果你足够仔细地阅读他们的文档,你将能够最终拼凑起来)。

      我的结论是,Apple 有一个很容易被忽视的边缘案例,因为它只有在你退出新比赛时才会发生,而且只有当你邀请朋友时,你可能不会经常测试两个案例。此外,如果您没有正确设置匹配结果,我猜它永远不会发生,所以他们永远不会抓住它。

      由于我还没有发货,我将配置我的应用程序以检测此状态下的匹配项并忽略它们。我将向控制台报告有多少匹配项处于此状态,这样我就可以确保它不会超过这一点。然后,我将分析我的退出代码,并确保在这种边缘情况下,我根本无法再次将匹配项置于此状态。我认为鉴于我们所知道的,我们必须积极主动,并接受一些比赛失败的事实。

      希望您尚未发布,因此错误案例匹配将本地化到 Game Center 沙盒环境。实际上,错误匹配只是在沙盒中本地化给您的测试用户,因此您可以丢弃该用户并在纠正问题后从新用户开始。如果您实施了我的上述建议,您应该能够在执行此步骤之前确认您的应用程序正常运行。

      如果有人真的可以找到一种方法来消除这些错误匹配,请告诉我们,但我希望我的建议和对实际原因的识别足以帮助您继续您的项目。

      【讨论】:

      • 我可以通过为所有参与者设置 participant.matchOutcome = GKTurnBasedMatchOutcomeTied 然后调用 [match removeWithCompletionHandler...] 来删除这些错误匹配。我不会在我的代码中保留它,但它会清除无效的游戏。
      【解决方案3】:

      我找到了解决方案。对于无效匹配,只需使用 -participantQuitOutOfTurn 方法,然后使用 -removeWithCompletionHandler 方法。它将被完全删除。

      【讨论】:

        【解决方案4】:

        我有类似的情况,如果略有不同。我开始比赛,邀请第二个沙盒帐户玩,然后第一个玩家退出并在第二个玩家响应之前删除游戏。当第二个玩家尝试退出游戏时,他们会收到以下错误:

        Error quitting match in turn: Error Domain=GKErrorDomain Code=22 "The requested operation could not be completed because the specified participant is invalid." 
        UserInfo=0x1f5de800 {
            GKServerStatusCode=5097, 
            NSUnderlyingError=0x1f58b610 "The operation couldn’t be completed. 
            status = 5097, 
            Invalid state: turn sent to playerId:1952436619 in slotIndex: 0 for sessionId: 698b074b-fa0b-4505-834f-1b4305b7eecb : expected slot state: Active but found: Inactive", 
            NSLocalizedDescription=The requested operation could not be completed because the specified participant is invalid.
        }
        

        据我所知,这是因为下一个要移动的参与者已经处于“完成”状态,我猜这是因为他们已经退出了:

        <GKTurnBasedMatch 0x1f532b20    id:698b074b-fa0b-4505-834f-1b4305b7eecb status:Open message: taken:2013-03-30 19:53:47 +0000 created:2013-03-30 18:29:09 +0000
        current:<GKTurnBasedParticipant 0x1f532b80 - id:G:1952433332 (local player) status:Active outcome:None lastTurn:2013-03-30 19:53:47 +0000>
        participants:
                <GKTurnBasedParticipant 0x1f532b70 - id:G:1952436619 status:Done outcome:Lost lastTurn:2013-03-30 18:29:10 +0000>
                <GKTurnBasedParticipant 0x1f532b80 - id:G:1952433332 (local player) status:Active outcome:None lastTurn:2013-03-30 19:53:47 +0000>
            >
        

        希望这将有助于其他人进行诊断。希望听到其他人对解决方法或解决方案的见解。如果这是 Apple 的一个错误,那么似乎值得关注。

        【讨论】:

          【解决方案5】:

          Apple 技术开发人员支持确认了该问题。提交错误报告。会及时通知您。

          【讨论】:

          • 这方面有什么更新吗?您能否发布一个跟踪问题的链接。
          猜你喜欢
          • 1970-01-01
          • 2013-07-24
          • 1970-01-01
          • 2015-10-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-06-26
          • 2013-05-06
          相关资源
          最近更新 更多