我正在用C#编写游戏服务器,每当有人用他的用户名发送登录消息时,我将他添加到ID为IDENDPOINT,USERNAME的元组列表中。 我想检查客户端是否与已连接的客户端具有相同的用户名,因此我尝试遍历列表并获取list.Item3'这是用户名'并使用String.Equals(list.Item3,username)检查用户名是否存在。 我的问题是当我循环时,我的代码只比较列表中的第一个元组,如果是真的则发送错误消息,如果没有则发送接受消息,当列表有+1客户端时它只比较第一个也是即使元组号2或3 ...具有该用户名,也接受。 我尝试了很多方法,这是我试过的最后一个代码:
for (int i = 0; i < clientsInfoList.Count; i++)
{
bool isUsed;
if (String.Equals(clientsInfoList[i].Item3, Username))
{
isUsed = true;
}
if (isUsed)
{
Console.WriteLine("Username is already used!");
udpServer.Send(Encoding.ASCII.GetBytes("REFUSED"), Encoding.ASCII.GetByteCount("REFUSED"), remoteEP);
break;
}
else if(!isUsed)
{
clientsInfoList.Add(new Tuple<int, IPEndPoint, string>(id, remoteEP, Username));
Console.WriteLine("Username has been added to the list :)");
udpServer.Send(Encoding.ASCII.GetBytes("ACCEPTED"), Encoding.ASCII.GetByteCount("ACCEPTED"), remoteEP);
}
}
我尝试了许多其他方法,但我无法实现验证。 提前谢谢。
答案 0 :(得分:1)
你把所有东西放在一个循环中。为什么?您应该仅使用循环来检查是否使用了用户名,并将消息发送到其外部。
首先,你想强制你的循环只在它应该的时候工作。您可以通过在它之前声明isUsed
并将其添加到条件中来实现。然后,在循环中,您只检查是否采用名称并更改变量的值。循环将遍历所有客户端,或者在遇到符合条件的第一个名称时结束。循环结束后,您应根据结果决定发送哪个命令。
bool isUsed = false;
for (int i = 0; i < clientsInfoList.Count && !isUsed; i++)
{
isUsed = String.Equals(clientsInfoList[i].Item3, Username);
}
if (isUsed)
{
Console.WriteLine("Username is already used!");
udpServer.Send(Encoding.ASCII.GetBytes("REFUSED"), Encoding.ASCII.GetByteCount("REFUSED"), remoteEP);
}
else
{
clientsInfoList.Add(new Tuple<int, IPEndPoint, string>(id, remoteEP, Username));
Console.WriteLine("Username has been added to the list :)");
udpServer.Send(Encoding.ASCII.GetBytes("ACCEPTED"), Encoding.ASCII.GetByteCount("ACCEPTED"), remoteEP);
}
答案 1 :(得分:1)
你可以做到
var isUsed = clientsInfoList.Any(info => info.Item3 == Username);
if (isUsed)
{
// ...
}
else
{
// ...
}
我假设Item3
(T3
的{{1}})和Tuple<T1, T2, T3>
都有编译时类型Username
。< / p>
答案 2 :(得分:0)
为什么要将整个逻辑放在for循环中?只将下面的代码放在for循环中。
bool isUsed;
if (String.Equals(clientsInfoList[i].Item3, Username))
{
isUsed = true;
}
现在它将验证元组中的所有元素并执行剩余的逻辑。
答案 3 :(得分:0)
你完全以错误的方式解决这个问题,如果我是你,我会做的第一件事就是摆脱元组,创建一个包含你需要的3个属性的类。
同样在这种情况下尝试使用HashSet而不是列表,它们会更好地进行优化,如果您拥有大量客户端,它们将帮助您的游戏更快地运行。
实现您所要求的最简洁的方法是使用LINQ,以下是我将如何重写您上面编写的代码。
public class Game
{
public Game()
{
this.Clients = new HashSet<Clients>();
}
public HashSet<Client> Clients { get; set;}
public void OnClientConnect(Client newClient)
{
// Are there any clients with the username that the newUser is attempting to use?
bool usernameIsFree = this.Clients.Any(clients => clients.UserName == newClient.UserName);
if (usernameIsFree)
{
this.Clients.Add(newClient);
Console.WriteLine("Username has been added to the list :)");
// UDP stuff here...
return;
}
Console.WriteLine("Username is already used!");
// UDP stuff here
}
}
public class Client
{
public int ClientId { get; set; }
public IPEndPoint IPEndPoint { get; set; }
public string UserName { get; set; }
}