using System.Collections.Generic;
using System.Threading.Tasks;
+using Impostor.Api.Innersloth;
using Impostor.Api.Net.Messages;
namespace Impostor.Api.Net
ValueTask HandleMessageAsync(IMessageReader message, MessageType messageType);
ValueTask HandleDisconnectAsync(string reason);
+
+ /// <summary>
+ /// Disconnect the client with a <see cref="DisconnectReason"/>.
+ /// </summary>
+ /// <param name="reason">
+ /// The message to show to the player.
+ /// </param>
+ /// <param name="message">
+ /// Only used when <see cref="reason"/> is set to <see cref="DisconnectReason.Custom"/>.
+ /// </param>
+ /// <returns>
+ /// A <see cref="ValueTask"/> representing the asynchronous operation.
+ /// </returns>
+ ValueTask DisconnectAsync(DisconnectReason reason, string? message = null);
}
-}
\ No newline at end of file
+}
-using System;
+using System;
using System.Threading;
using System.Threading.Channels;
using System.Threading.Tasks;
// Signal cancellation to methods.
_stoppingCts.Cancel();
- // Cancel reader.
- Pipeline.Writer.Complete();
+ try
+ {
+ // Cancel reader.
+ Pipeline.Writer.Complete();
+ }
+ catch (ChannelClosedException)
+ {
+ // Already done.
+ }
// Remove references.
if (!_isDisposing)
/// <summary>
/// Sends a disconnect message to the end point.
/// </summary>
- protected override ValueTask<bool> SendDisconnect(MessageWriter data = null)
+ protected override async ValueTask<bool> SendDisconnect(MessageWriter data = null)
{
lock (this)
{
- if (this._state != ConnectionState.Connected) return ValueTask.FromResult(false);
+ if (this._state != ConnectionState.Connected) return false;
this._state = ConnectionState.NotConnected;
}
try
{
- Listener.SendDataSync(bytes, bytes.Length, RemoteEndPoint);
+ await Listener.SendData(bytes, bytes.Length, RemoteEndPoint);
}
catch { }
- return ValueTask.FromResult(true);
+ return true;
}
protected override void Dispose(bool disposing)
_logger.LogError(ex, "Exception caught in client disconnection.");
}
- _logger.LogInformation("Client {0} disconnecting, reason: {1}.", Id, reason);
+ _logger.LogInformation("Client {0} disconnecting, reason: {1}", Id, reason);
_clientManager.Remove(this);
}
return Connection.SendAsync(message);
}
-
- private async ValueTask DisconnectAsync(DisconnectReason reason, string message = null)
- {
- if (Connection == null)
- {
- return;
- }
-
- using var packet = MessageWriter.Get(MessageType.Reliable);
- Message01JoinGameS2C.SerializeError(packet, false, reason, message);
-
- await Connection.SendAsync(packet);
- await Connection.DisconnectAsync(message ?? reason.ToString());
- }
}
-}
\ No newline at end of file
+}
-using System.Collections.Concurrent;
+using System;
+using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading.Tasks;
+using Impostor.Api.Innersloth;
using Impostor.Api.Net;
using Impostor.Api.Net.Messages;
+using Impostor.Api.Net.Messages.S2C;
+using Impostor.Hazel;
using Impostor.Server.Net.State;
namespace Impostor.Server.Net
public IDictionary<object, object> Items { get; }
- public ClientPlayer Player { get; set; }
+ public ClientPlayer? Player { get; set; }
- IClientPlayer IClient.Player => Player;
+ IClientPlayer? IClient.Player => Player;
public abstract ValueTask HandleMessageAsync(IMessageReader message, MessageType messageType);
public abstract ValueTask HandleDisconnectAsync(string reason);
+
+
+ public async ValueTask DisconnectAsync(DisconnectReason reason, string? message = null)
+ {
+ if (!Connection.IsConnected)
+ {
+ return;
+ }
+
+ using var packet = MessageWriter.Get(MessageType.Reliable);
+ Message01JoinGameS2C.SerializeError(packet, false, reason, message);
+
+ await Connection.SendAsync(packet);
+
+ // Need this to show the correct message, otherwise it shows a generic disconnect message.
+ await Task.Delay(TimeSpan.FromMilliseconds(250));
+
+ await Connection.DisconnectAsync(message ?? reason.ToString());
+ }
}
-}
\ No newline at end of file
+}
break;
}
}
+
+ if (sender.Client.Player == null)
+ {
+ // Disconnect handler was probably invoked, cancel the rest.
+ return false;
+ }
}
return true;
return null;
}
}
-}
\ No newline at end of file
+}