Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent ignored users from joining games #651

Open
wants to merge 13 commits into
base: develop
Choose a base branch
from
7 changes: 7 additions & 0 deletions DXMainClient/DXGUI/Multiplayer/CnCNet/CnCNetLobby.cs
Original file line number Diff line number Diff line change
Expand Up @@ -993,6 +993,13 @@ private void GameChannel_UserAdded(object sender, Online.ChannelUserEventArgs e)
{
Channel gameChannel = (Channel)sender;

if (e.User.IRCUser.IsIgnored)
{
// Howboutno
Logger.Log("This user is ignored, so we shouldn't let them in");
return;
}

if (e.User.IRCUser.Name == ProgramConstants.PLAYERNAME)
{
ClearGameChannelEvents(gameChannel);
Expand Down
22 changes: 22 additions & 0 deletions DXMainClient/DXGUI/Multiplayer/GameLobby/CnCNetGameLobby.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
using System.Text;
using DTAClient.Domain.Multiplayer.CnCNet;
using ClientCore.Extensions;
using System.Net.NetworkInformation;

namespace DTAClient.DXGUI.Multiplayer.GameLobby
{
Expand Down Expand Up @@ -521,6 +522,15 @@ private void Channel_UserListReceived(object sender, EventArgs e)
private void Channel_UserAdded(object sender, ChannelUserEventArgs e)
{
PlayerInfo pInfo = new PlayerInfo(e.User.IRCUser.Name);

if (e.User.IRCUser.IsIgnored)
{
// If this ignored player constantly rejoins, he could cause the host to floodout using the normal RemovePlayer() functionality.
// So lets Ghost kickban from gameroom instead. This should only be needed once per created room
GhostBanIgnoredUser(pInfo.Name);
return;
}

Players.Add(pInfo);

if (Players.Count + AIPlayers.Count > MAX_PLAYER_COUNT && AIPlayers.Count > 0)
Expand Down Expand Up @@ -1558,6 +1568,18 @@ protected override void BanPlayer(int playerIndex)
}
}

private void GhostBanIgnoredUser(string playerName)
{
var user = connectionManager.UserList.Find(u => u.Name == playerName);
SadPencil marked this conversation as resolved.
Show resolved Hide resolved

if (user != null)
{
// Informing the host like we do when we kick might be annoying. So keep it on the downlow.
channel.SendBanMessage(user.Hostname, 8);
channel.SendKickMessage(user.Name, 8);
SadPencil marked this conversation as resolved.
Show resolved Hide resolved
GrantBartlett marked this conversation as resolved.
Show resolved Hide resolved
}
}

private void HandleCheatDetectedMessage(string sender) =>
AddNotice(string.Format("{0} has modified game files during the client session. They are likely attempting to cheat!".L10N("Client:Main:PlayerModifyFileCheat"), sender), Color.Red);

Expand Down
14 changes: 8 additions & 6 deletions DXMainClient/Online/Channel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,15 @@ public void AddUser(ChannelUser user)
UserAdded?.Invoke(this, new ChannelUserEventArgs(user));
}

public void OnUserJoined(ChannelUser user)
public void OnUserJoined(ChannelUser user, bool silentJoin = false)
{
AddUser(user);

if (notifyOnUserListChange)
{
AddMessage(new ChatMessage(
string.Format("{0} has joined {1}.".L10N("Client:Main:PlayerJoinChannel"), user.IRCUser.Name, UIName)));
if (!silentJoin)
AddMessage(new ChatMessage(
string.Format("{0} has joined {1}.".L10N("Client:Main:PlayerJoinChannel"), user.IRCUser.Name, UIName)));
}

#if !YR
Expand Down Expand Up @@ -152,7 +153,7 @@ public void OnUserListReceived(List<ChannelUser> userList)
UserListReceived?.Invoke(this, EventArgs.Empty);
}

public void OnUserKicked(string userName)
public void OnUserKicked(string userName, bool silentKick = false)
{
if (users.Remove(userName))
{
Expand All @@ -161,8 +162,9 @@ public void OnUserKicked(string userName)
users.Clear();
}

AddMessage(new ChatMessage(
string.Format("{0} has been kicked from {1}.".L10N("Client:Main:PlayerKickedFromChannel"), userName, UIName)));
if (!silentKick)
AddMessage(new ChatMessage(
string.Format("{0} has been kicked from {1}.".L10N("Client:Main:PlayerKickedFromChannel"), userName, UIName)));

UserKicked?.Invoke(this, new UserNameEventArgs(userName));
}
Expand Down
58 changes: 56 additions & 2 deletions DXMainClient/Online/CnCNetManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ public class CnCNetManager : IConnectionManager
public event EventHandler ReconnectAttempt;
public event EventHandler Disconnected;
public event EventHandler Connected;
public event EventHandler UserListInitialized;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The event 'CnCNetManager.UserListInitialized' is never used



public event EventHandler<UserEventArgs> UserAdded;
public event EventHandler<UserEventArgs> UserGameIndexUpdated;
Expand Down Expand Up @@ -114,6 +116,8 @@ public bool IsAttemptingConnection

private bool disconnect = false;

private bool userListInitialized = false;

public bool IsCnCNetInitialized()
{
return Connection.IsIdSet();
Expand Down Expand Up @@ -500,6 +504,7 @@ private void DoDisconnected()

MainChannel.AddMessage(new ChatMessage("You have disconnected from CnCNet.".L10N("Client:Main:CncNetDisconnected")));
connected = false;
userListInitialized = false;

UserList.Clear();

Expand Down Expand Up @@ -619,8 +624,9 @@ private void DoUserJoinedChannel(string channelName, string host, string userNam
channelUser.IsAdmin = isAdmin;
channelUser.IsFriend = cncNetUserData.IsFriend(channelUser.IRCUser.Name);

bool ignoredUser = channelUser.IRCUser.IsIgnored;
ircUser.Channels.Add(channelName);
channel.OnUserJoined(channelUser);
channel.OnUserJoined(channelUser, ignoredUser);

//UserJoinedChannel?.Invoke(this, new ChannelUserEventArgs(channelName, userName));
}
Expand All @@ -645,7 +651,8 @@ private void DoUserKicked(string channelName, string userName)
if (channel == null)
return;

channel.OnUserKicked(userName);
ChannelUser kickedUser = channel.Users.Find(userName);
channel.OnUserKicked(userName, kickedUser.IRCUser.IsIgnored);

if (userName == ProgramConstants.PLAYERNAME)
{
Expand Down Expand Up @@ -770,6 +777,13 @@ private void DoUserListReceived(string channelName, string[] userList)
MultipleUsersAdded?.Invoke(this, EventArgs.Empty);

channel.OnUserListReceived(channelUserList);

// We only need to request user info once, and chat channels only.
SadPencil marked this conversation as resolved.
Show resolved Hide resolved
if (!userListInitialized && channel.IsChatChannel)
{
channel.RequestUserInfo();
userListInitialized = true;
}
}

public void OnUserQuitIRC(string userName)
Expand Down Expand Up @@ -947,6 +961,46 @@ private void DoServerLatencyTested(int candidateCount, int closerCount)
"Lobby servers: {0} available, {1} fast.".L10N("Client:Main:LobbyServerLatencyTestResult"),
candidateCount, closerCount)));
}

public void OnWhoQueryComplete(string channelName, List<Tuple<string, string, string, string>> whoDataList)
{
wm.AddCallback(new Action<string, List<Tuple<string, string, string, string>>>(DoWhoQueryComplete), channelName, whoDataList);
}

private void DoWhoQueryComplete(string channelName, List<Tuple<string, string, string, string>> whoDataList)
{
Channel channel = FindChannel(channelName);

if (channel == null)
return;

if (!channel.IsChatChannel)
return;

var channelUserList = new List<ChannelUser>();

foreach (var whoData in whoDataList)
{
(string ident, string host, string userName, string extraInfo) = whoData;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
foreach (var whoData in whoDataList)
{
(string ident, string host, string userName, string extraInfo) = whoData;
foreach ((string ident, string host, string userName, string extraInfo) in whoDataList)
{


IRCUser ircUser = new(userName);
ircUser.Ident = ident;
ircUser.Hostname = host;

UserList.Add(ircUser);

var channelUser = new ChannelUser(ircUser);
channelUser.IsFriend = cncNetUserData.IsFriend(channelUser.IRCUser.Name);

channelUserList.Add(channelUser);
}

UserList = UserList.OrderBy(u => u.Name).ToList();
SadPencil marked this conversation as resolved.
Show resolved Hide resolved
MultipleUsersAdded?.Invoke(this, EventArgs.Empty);
UserListInitialized?.Invoke(this, EventArgs.Empty);

channel.OnUserListReceived(channelUserList);
}
}

public class UserEventArgs : EventArgs
Expand Down
6 changes: 6 additions & 0 deletions DXMainClient/Online/Connection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ private bool disconnect
private static bool idSet = false;
private static string systemId;
private static readonly object idLocker = new object();
private readonly List<Tuple<string, string, string, string>> whoResponseList = [];

public static void SetId(string id)
{
Expand Down Expand Up @@ -618,6 +619,11 @@ private void PerformCommand(string message)
case 311: // Reply to WHOIS NAME query
connectionManager.OnWhoReplyReceived(parameters[2], parameters[3], parameters[1], string.Empty);
break;
case 315: // End of WHO query (RPL_ENDOFWHO)
Logger.Log($"END OF WHO QUERY " + parameters[1] + " COUNT:" + whoResponseList.Count);
connectionManager.OnWhoQueryComplete(parameters[1], new List<Tuple<string, string, string, string>>(whoResponseList));
whoResponseList.Clear();
break;
case 433: // Name already in use
message = serverMessagePart + parameters[1] + ": " + parameters[2];
//connectionManager.OnGenericServerMessageReceived(message);
Expand Down
5 changes: 4 additions & 1 deletion DXMainClient/Online/IConnectionManager.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;

namespace DTAClient.Online
{
Expand All @@ -21,6 +22,8 @@ public interface IConnectionManager

void OnWhoReplyReceived(string ident, string hostName, string userName, string extraInfo);

void OnWhoQueryComplete(string channel, List<Tuple<string, string, string, string>> whoList);

SadPencil marked this conversation as resolved.
Show resolved Hide resolved
void OnChannelFull(string channelName);

void OnTargetChangeTooFast(string channelName, string message);
Expand Down
Loading