Skip to content
This repository was archived by the owner on Apr 25, 2022. It is now read-only.

Commit

Permalink
Added force disconnect when a player makes an invalid request
Browse files Browse the repository at this point in the history
Updated NAT
  • Loading branch information
Dnawrkshp committed Sep 22, 2020
1 parent a52085f commit 30bcef9
Show file tree
Hide file tree
Showing 10 changed files with 61 additions and 54 deletions.
12 changes: 12 additions & 0 deletions RT.Common/Types.cs
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,18 @@ public enum NetConnectionType : int
NetConnectionTypeClientListenerTCP = 4
}

public enum SERVER_FORCE_DISCONNECT_REASON : byte
{
SERVER_FORCED_DISCONNECT_NONE = 0,
SERVER_FORCED_DISCONNECT_ERROR = 1,
SERVER_FORCED_DISCONNECT_SHUTDOWN = 2,
SERVER_FORCED_DISCONNECT_END_SESSION = 3,
SERVER_FORCED_DISCONNECT_END_GAME = 4,
SERVER_FORCED_DISCONNECT_TIME0UT = 5,
SERVER_FORCED_DISCONNECT_BAD_PERF = 6,
SERVER_FORCED_DISCONNECT_BANNED = 7
}

public enum MGCL_EVENT_TYPE : int
{
MGCL_EVENT_CLIENT_DISCONNECT = 0,
Expand Down
5 changes: 3 additions & 2 deletions RT.Models/RT/RT_MSG_SERVER_FORCED_DISCONNECT.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using RT.Common;
using Server.Common;
using System;
using System.Collections.Generic;
using System.IO;
Expand All @@ -11,11 +12,11 @@ public class RT_MSG_SERVER_FORCED_DISCONNECT : BaseScertMessage
{
public override RT_MSG_TYPE Id => RT_MSG_TYPE.RT_MSG_SERVER_FORCED_DISCONNECT;

public byte Reason;
public SERVER_FORCE_DISCONNECT_REASON Reason;

public override void Deserialize(BinaryReader reader)
{
Reason = reader.ReadByte();
Reason = reader.Read<SERVER_FORCE_DISCONNECT_REASON>();
}

protected override void Serialize(BinaryWriter writer)
Expand Down
3 changes: 3 additions & 0 deletions Server.Dme/Models/World.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using DotNetty.Common.Internal.Logging;
using Microsoft.Extensions.Logging;
using Microsoft.Scripting.Ast;
using RT.Common;
using RT.Models;
using Server.Dme.PluginArgs;
Expand Down Expand Up @@ -140,6 +141,8 @@ public async Task Tick()
}
}



// Update last agg time
if (isAggTick)
_lastAggTimeUtc = DateTime.UtcNow;
Expand Down
22 changes: 17 additions & 5 deletions Server.Dme/TcpServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public class TcpServer
protected internal class ChannelData
{
public int ApplicationId { get; set; } = 0;
public bool Ignore { get; set; } = false;
public ClientObject ClientObject { get; set; } = null;
public ConcurrentQueue<BaseScertMessage> RecvQueue { get; } = new ConcurrentQueue<BaseScertMessage>();
public ConcurrentQueue<BaseScertMessage> SendQueue { get; } = new ConcurrentQueue<BaseScertMessage>();
Expand Down Expand Up @@ -86,7 +87,7 @@ public virtual async void Start()
string key = channel.Id.AsLongText();
if (_channelDatas.TryGetValue(key, out var data))
{
if (data.ClientObject == null || !data.ClientObject.IsDestroyed)
if (!data.Ignore && (data.ClientObject == null || !data.ClientObject.IsDestroyed))
{
data.RecvQueue.Enqueue(message);
data.ClientObject?.OnEcho(true, DateTime.UtcNow);
Expand All @@ -103,6 +104,7 @@ public virtual async void Start()
.Group(_bossGroup, _workerGroup)
.Channel<TcpServerSocketChannel>()
.Option(ChannelOption.SoBacklog, 100)
.Option(ChannelOption.SoTimeout, 30000)
.Handler(new LoggingHandler(LogLevel.INFO))
.ChildHandler(new ActionChannelInitializer<ISocketChannel>(channel =>
{
Expand Down Expand Up @@ -163,7 +165,7 @@ private async Task Tick(IChannel clientChannel)
// Disconnect on destroy
if (data.ClientObject != null && data.ClientObject.IsDestroyed)
{
await DisconnectClient(clientChannel);
data.Ignore = true;
return;
}

Expand All @@ -177,6 +179,7 @@ private async Task Tick(IChannel clientChannel)
catch (Exception e)
{
Logger.Error(e);
await ForceDisconnectClient(clientChannel);
}
}

Expand Down Expand Up @@ -363,7 +366,7 @@ protected async Task ProcessMessage(BaseScertMessage message, IChannel clientCha

case RT_MSG_CLIENT_DISCONNECT_WITH_REASON clientDisconnectWithReason:
{
await DisconnectClient(clientChannel);
data.Ignore = true;
break;
}
default:
Expand All @@ -390,11 +393,20 @@ protected virtual void ProcessMediusMessage(BaseMediusMessage message, IChannel
/// <summary>
/// Closes the client channel.
/// </summary>
protected async Task DisconnectClient(IChannel channel)
protected async Task ForceDisconnectClient(IChannel channel)
{
try
{
//await channel.WriteAndFlushAsync(new RT_MSG_SERVER_FORCED_DISCONNECT());
// Give it every reason just to make sure it disconnects
for (byte r = 0; r < 7; ++r)
{
await channel.WriteAsync(new RT_MSG_SERVER_FORCED_DISCONNECT()
{
Reason = (SERVER_FORCE_DISCONNECT_REASON)r
});
}

channel.Flush();
}
catch (Exception)
{
Expand Down
23 changes: 0 additions & 23 deletions Server.Dme/UdpServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -246,29 +246,6 @@ protected virtual void ProcessMediusMessage(BaseMediusMessage message)

#endregion

#region Channel

/// <summary>
/// Closes the client channel.
/// </summary>
protected async Task DisconnectClient(IChannel channel)
{
try
{
//await channel.WriteAndFlushAsync(new RT_MSG_SERVER_FORCED_DISCONNECT());
}
catch (Exception)
{
// Silence exception since the client probably just closed the socket before we could write to it
}
finally
{
await channel.CloseAsync();
}
}

#endregion

#region Send

private void SendTo(BaseScertMessage message, EndPoint target)
Expand Down
26 changes: 21 additions & 5 deletions Server.Medius/Medius/BaseMediusComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ protected internal class ChannelData

public bool? IsBanned { get; set; } = null;

/// <summary>
/// When true, all messages from this client will be ignored.
/// </summary>
public bool Ignore { get; set; } = false;
public DateTime LastSentEcho { get; set; } = DateTime.UnixEpoch;
}

Expand Down Expand Up @@ -148,7 +152,7 @@ public virtual async void Start()
if (_channelDatas.TryGetValue(key, out var data))
{
// Don't queue message if client is ignored
if (data.ClientObject == null || !data.ClientObject.Ignore)
if (!data.Ignore)
{
// Don't queue if banned
if (data.IsBanned == null || data.IsBanned == false)
Expand All @@ -171,6 +175,7 @@ public virtual async void Start()
.Group(_bossGroup, _workerGroup)
.Channel<TcpServerSocketChannel>()
.Option(ChannelOption.SoBacklog, 100)
.Option(ChannelOption.SoTimeout, 30000)
.Handler(new LoggingHandler(LogLevel.INFO))
.ChildHandler(new ActionChannelInitializer<ISocketChannel>(channel =>
{
Expand Down Expand Up @@ -228,7 +233,7 @@ protected virtual async Task Tick(IChannel clientChannel)
if (_channelDatas.TryGetValue(key, out var data))
{
// Ignore
if (data.ClientObject != null && data.ClientObject.Ignore)
if (data.Ignore)
return;

// Process all messages in queue
Expand All @@ -252,6 +257,8 @@ protected virtual async Task Tick(IChannel clientChannel)
catch (Exception e)
{
Logger.Error(e);
await ForceDisconnectClient(clientChannel);
data.Ignore = true;
}
}

Expand Down Expand Up @@ -338,19 +345,28 @@ protected virtual void QueueBanMessage(ChannelData data, string msg = "You have

#region Channel

protected async Task DisconnectClient(IChannel channel)
protected async Task ForceDisconnectClient(IChannel channel)
{
try
{
//await channel.WriteAndFlushAsync(new RT_MSG_SERVER_FORCED_DISCONNECT());
// Give it every reason just to make sure it disconnects
for (byte r = 0; r < 7; ++r)
{
await channel.WriteAsync(new RT_MSG_SERVER_FORCED_DISCONNECT()
{
Reason = (SERVER_FORCE_DISCONNECT_REASON)r
});
}

channel.Flush();
}
catch (Exception)
{
// Silence exception since the client probably just closed the socket before we could write to it
}
finally
{
await channel.DisconnectAsync();

}
}

Expand Down
12 changes: 3 additions & 9 deletions Server.Medius/Medius/MLS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ protected override async Task ProcessMessage(BaseScertMessage message, IChannel
data.ClientObject = Program.Manager.GetClientByAccessToken(clientConnectTcp.AccessToken);
if (data.ClientObject == null)
{
await DisconnectClient(clientChannel);
data.Ignore = true;
}
else
{
Expand Down Expand Up @@ -129,7 +129,7 @@ protected override async Task ProcessMessage(BaseScertMessage message, IChannel

case RT_MSG_CLIENT_DISCONNECT_WITH_REASON clientDisconnectWithReason:
{
await DisconnectClient(clientChannel);
data.Ignore = true;
break;
}
default:
Expand Down Expand Up @@ -2496,12 +2496,9 @@ private async Task ProcessChatMessage(IChannel clientChannel, ClientObject clien
var targetPlayer = channel.Clients.FirstOrDefault(x => x.AccountId == chatMessage.TargetID);
List<BaseScertMessage> chatResponses = new List<BaseScertMessage>();

// ERROR -- Need to be logged in
// Need to be logged in
if (!clientObject.IsLoggedIn)
{
await DisconnectClient(clientChannel);
return;
}

// Need to be in a channel
if (channel == null)
Expand Down Expand Up @@ -2557,10 +2554,7 @@ private async Task ProcessGenericChatMessage(IChannel clientChannel, ClientObjec

// ERROR -- Need to be logged in
if (!clientObject.IsLoggedIn)
{
await DisconnectClient(clientChannel);
return;
}

// Need to be in a channel
if (channel == null)
Expand Down
3 changes: 0 additions & 3 deletions Server.Medius/Medius/MediusManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -394,9 +394,6 @@ private void TickClients()
clientKeyPair.Value.Logout();
clientKeyPair.Value.EndSession();

// Ignore all future messages
clientKeyPair.Value.Ignore = true;

clientsToRemove.Enqueue(clientKeyPair.Key);
}
}
Expand Down
5 changes: 0 additions & 5 deletions Server.Medius/Medius/Models/ClientObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,6 @@ public class ClientObject
/// </summary>
public DateTime UtcLastEcho { get; protected set; } = DateTime.UtcNow;

/// <summary>
/// When true, all messages from this client will be ignored.
/// </summary>
public bool Ignore { get; set; } = false;

public virtual bool IsLoggedIn => !_logoutTime.HasValue && _loginTime.HasValue && IsConnected;
public bool IsInGame => CurrentGame != null && CurrentChannel != null && CurrentChannel.Type == ChannelType.Game;

Expand Down
4 changes: 2 additions & 2 deletions Server.NAT/NAT.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ public async Task Start()
// Queue all incoming messages
_scertHandler.OnChannelMessage += (channel, message) =>
{
// Send ip and port back
if (message.Content.ReadableBytes == 4 && message.Content.GetByte(message.Content.ReaderIndex + 3) < 0x80)
// Send ip and port back if the last byte isn't 0xD4
if (message.Content.ReadableBytes == 4 && message.Content.GetByte(message.Content.ReaderIndex + 3) != 0xD4)
{
var buffer = channel.Allocator.Buffer(6);
buffer.WriteBytes((message.Sender as IPEndPoint).Address.MapToIPv4().GetAddressBytes());
Expand Down

0 comments on commit 30bcef9

Please sign in to comment.