如果玩游戏,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#将角色分配给用户的主要内容,如果未能解决你的问题,请参考以下文章
Ruby‘s Adventrue游戏制作笔记Unity给角色添加简单的特效