如果玩游戏,C#将角色分配给用户

Posted

技术标签:

【中文标题】如果玩游戏,C#将角色分配给用户【英文标题】:C# Assign role to user if playing game 【发布时间】:2021-12-26 03:59:21 【问题描述】:

如果正在玩特定游戏,我正在尝试通过机器人分配 Discord 角色。

这是我的代码:

    private async Task UserUpdated(SocketGuildUser before, SocketGuildUser after)
    
        //fetch guild and user by id
        ulong long2 = ulong.Parse(after.Id.ToString());
        var user = _client.GetGuild(myguildid).GetUser(long2);
        var Game = user.Activity as Game;
        if (user.IsBot)  return; 

        //check if playing a game with the name mygamename          
        if (Game.Name == "mygamename")
        
            //if so, assign the role
            SocketGuild socketGuild = after.Guild;
            SocketRole socketRole = socketGuild.GetRole(myroleid);
            await after.AddRoleAsync(socketRole);
        
        //Check if user isn't playing game with name mygamename
        else if (Game.Name != "mygamename")
        
            //If so, remove role
            SocketGuild socketGuild = after.Guild;
            SocketRole socketRole = socketGuild.GetRole(myroleid);
            await after.RemoveRoleAsync(socketRole);
        
    

但是,如果我尝试使用名称 mygamename 玩游戏,它会分配角色,但如果我停止播放,则会在此行中出现错误:

if (Game.Name == "mygamename")

它抛出了这个错误:

20:31:10 网关 GuildMemberUpdated 处理程序抛出了一个 未处理的异常。:System.NullReferenceException:对象引用 未设置为对象的实例。在 myprogram.Program.d__6.MoveNext() 在 C:\Users\User\Desktop\myprogram\myprogram\Program.cs:第 9 行 --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务 任务)在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)在 Discord.EventExtensions.d__2`2.MoveNext() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务 任务)在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)在 Discord.WebSocket.DiscordSocketClient.d__139.MoveNext()

而且它没有分配角色。我怎么能解决这个问题?有没有更好的方法来获取之前/之后并检查正在玩的游戏?

【问题讨论】:

user.Activity as Game 显然会产生null。活动是游戏吗? @OlivierJacot-Descombes 活动本身是一个自定义的丰富存在,但它显示为游戏。 使用is 模式匹配来确保它是Game @DanielA.White 它给了我“'bool' 不包含 'Name' 的定义” 如果他们完全停止玩游戏,User.Game 不会为空吗?在这种情况下,您应该只删除 else 分支上的 if 【参考方案1】:

也许不需要强制转换为Game 类型? Game 对象默认具有 ActivityType 属性和 Playing 值。所以你可以先试试IActivity,它有Playing活动类型和Name你的游戏:

var game = userAfter.Activities.FirstOrDefault(activity => activity.Type == ActivityType.Playing
                                                        && activity.Name == "MyGameName");

如果您的游戏名称没有任何Playing 活动,则game 变量将为空,因此您只需检查is not null

private async Task UserUpdated(SocketGuildUser userBefore, SocketGuildUser userAfter)

    if (userAfter.IsBot)
        return;

    var myRoleID = 123123123UL;
    var role = userAfter.Guild.GetRole(myRoleID);
    var game = userAfter.Activities.FirstOrDefault(activity => activity.Type == ActivityType.Playing
                                                            && activity.Name == "MyGameName");

    if (game != null)
    
        // No need to add AddRole, if user already have it
        if (!userAfter.Roles.Contains(role))
            await userAfter.AddRoleAsync(role);
    
    else
    
        // No need to call RemoveRole, if user haven't it
        if (userAfter.Roles.Contains(role))
            await userAfter.RemoveRoleAsync(role);
             

没有自己测试代码示例,但你可以试试。

【讨论】:

以上是关于如果玩游戏,C#将角色分配给用户的主要内容,如果未能解决你的问题,请参考以下文章

如何使用我的机器人将角色自动分配给新成员?

用C#编写猜数字游戏,

PyGame-角色离开屏幕

Ruby‘s Adventrue游戏制作笔记Unity给角色添加简单的特效

Ruby‘s Adventrue游戏制作笔记Unity给角色添加简单的特效

Ruby‘s Adventrue游戏制作笔记Unity给角色添加简单的特效