protected override async Task ProcessMessage(BaseScertMessage message, IChannel channel) { await base.ProcessMessage(message, channel); switch (message) { } }
public void Send(BaseScertMessage message) { if (AuthenticatedEndPoint == null) { return; } _sendQueue.Enqueue(new ScertDatagramPacket(message, AuthenticatedEndPoint)); }
private void SendTo(BaseScertMessage message, EndPoint target) { if (target == null) { return; } _sendQueue.Enqueue(new ScertDatagramPacket(message, target)); }
public void Queue(BaseScertMessage message, IEnumerable <IChannel> clientChannels) { foreach (var clientChannel in clientChannels) { if (clientChannel != null) { if (_channelDatas.TryGetValue(clientChannel.Id.AsLongText(), out var data)) { data.SendQueue.Enqueue(message); } } } }
/// <summary> /// Create a frame out of the <see cref="IByteBuffer" /> and return it. /// </summary> /// <param name="context"> /// The <see cref="IChannelHandlerContext" /> which this <see cref="ByteToMessageDecoder" /> belongs /// to. /// </param> /// <param name="input">The <see cref="IByteBuffer" /> from which to read data.</param> /// <returns>The <see cref="IByteBuffer" /> which represents the frame or <c>null</c> if no frame could be created.</returns> protected virtual object Decode(IChannelHandlerContext context, DatagramPacket input) { byte id = input.Content.GetByte(input.Content.ReaderIndex); byte[] hash = null; long frameLength = input.Content.GetShortLE(input.Content.ReaderIndex + 1); int headerLength = 3; if (frameLength <= 0) { return(BaseScertMessage.Instantiate((RT_MSG_TYPE)(id & 0x7F), null, new byte[0], _getCipher)); } if (id >= 0x80) { hash = new byte[4]; input.Content.GetBytes(input.Content.ReaderIndex + 3, hash); headerLength += 4; id &= 0x7F; } if (frameLength < 0) { throw new CorruptedFrameException("negative pre-adjustment length field: " + frameLength); } // never overflows because it's less than maxFrameLength int frameLengthInt = (int)frameLength; if (input.Content.ReadableBytes < frameLengthInt) { //input.ResetReaderIndex(); return(null); } // extract frame byte[] messageContents = new byte[frameLengthInt]; input.Content.GetBytes(input.Content.ReaderIndex + headerLength, messageContents); // int totalFrameLength = headerLength + frameLengthInt; input.Content.SetReaderIndex(input.Content.ReaderIndex + totalFrameLength); return(new ScertDatagramPacket(BaseScertMessage.Instantiate((RT_MSG_TYPE)id, hash, messageContents, _getCipher), null, input.Sender)); }
/// <summary> /// Handle all connection messages. /// </summary> protected override async Task ProcessMessage(BaseScertMessage message, IChannel channel) { switch (message) { case RT_MSG_SERVER_HELLO serverHello: { if (State != ClientState.HELLO) { throw new Exception($"Unexpected RT_MSG_SERVER_HELLO from server. {serverHello}"); } // Send public key Queue(new RT_MSG_CLIENT_CRYPTKEY_PUBLIC() { Key = AuthKey.N.ToByteArrayUnsigned().Reverse().ToArray() }); State = ClientState.HANDSHAKE; break; } case RT_MSG_SERVER_CRYPTKEY_PEER serverCryptKeyPeer: { if (State != ClientState.HANDSHAKE) { throw new Exception($"Unexpected RT_MSG_SERVER_CRYPTKEY_PEER from server. {serverCryptKeyPeer}"); } Queue(new RT_MSG_CLIENT_CONNECT_TCP() { AppId = ApplicationId }); State = ClientState.CONNECT_TCP; break; } case RT_MSG_SERVER_CONNECT_ACCEPT_TCP serverConnectAcceptTcp: { if (State != ClientState.CONNECT_TCP) { throw new Exception($"Unexpected RT_MSG_SERVER_CONNECT_ACCEPT_TCP from server. {serverConnectAcceptTcp}"); } // State = ClientState.AUTHENTICATED; break; } case RT_MSG_SERVER_ECHO serverEcho: { Queue(serverEcho); break; } case RT_MSG_SERVER_FORCED_DISCONNECT serverForcedDisconnect: case RT_MSG_CLIENT_DISCONNECT_WITH_REASON clientDisconnectWithReason: { await channel.CloseAsync(); State = ClientState.DISCONNECTED; break; } } }
public void Queue(BaseScertMessage message) { SendMessageQueue.Enqueue(message); }
public void Queue(BaseScertMessage message, params IChannel[] clientChannels) { Queue(message, (IEnumerable <IChannel>)clientChannels); }
protected async Task ProcessMessage(BaseScertMessage message, IChannel clientChannel, ChannelData data) { // switch (message) { case RT_MSG_CLIENT_HELLO clientHello: { Queue(new RT_MSG_SERVER_HELLO() { ARG2 = 0 }, clientChannel); break; } case RT_MSG_CLIENT_CRYPTKEY_PUBLIC clientCryptKeyPublic: { Queue(new RT_MSG_SERVER_CRYPTKEY_PEER() { Key = Utils.FromString(Program.KEY) }, clientChannel); break; } case RT_MSG_CLIENT_CONNECT_TCP_AUX_UDP clientConnectTcpAuxUdp: { data.ApplicationId = clientConnectTcpAuxUdp.AppId; data.ClientObject = Program.Manager.GetClientByAccessToken(clientConnectTcpAuxUdp.AccessToken); if (data.ClientObject.DmeWorld == null || data.ClientObject.DmeWorld.WorldId != clientConnectTcpAuxUdp.ARG1) { throw new Exception($"Client connected with invalid world id!"); } data.ClientObject.ApplicationId = clientConnectTcpAuxUdp.AppId; data.ClientObject.OnTcpConnected(clientChannel); data.ClientObject.ScertId = GenerateNewScertClientId(); if (!_scertIdToClient.TryAdd(data.ClientObject.ScertId, data.ClientObject)) { throw new Exception($"Duplicate scert client id"); } Queue(new RT_MSG_SERVER_CONNECT_REQUIRE() { Contents = Utils.FromString("0648024802") }, clientChannel); break; } case RT_MSG_CLIENT_CONNECT_TCP clientConnectTcp: { data.ApplicationId = clientConnectTcp.AppId; break; } case RT_MSG_CLIENT_CONNECT_READY_REQUIRE clientConnectReadyRequire: { // Queue(new RT_MSG_SERVER_CRYPTKEY_GAME() { Key = Utils.FromString(Program.KEY) }, clientChannel); Queue(new RT_MSG_SERVER_CONNECT_ACCEPT_TCP() { UNK_00 = (ushort)data.ClientObject.DmeId, UNK_02 = data.ClientObject.ScertId, UNK_04 = 0, UNK_06 = (ushort)data.ClientObject.DmeWorld.Clients.Count, IP = (clientChannel.RemoteAddress as IPEndPoint)?.Address }, clientChannel); break; } case RT_MSG_CLIENT_CONNECT_READY_TCP clientConnectReadyTcp: { Queue(new RT_MSG_SERVER_STARTUP_INFO_NOTIFY() { GameHostType = (byte)MGCL_GAME_HOST_TYPE.MGCLGameHostClientServerAuxUDP, Timestamp = (uint)(DateTime.UtcNow - data.ClientObject.DmeWorld.WorldCreatedTimeUtc).TotalMilliseconds }, clientChannel); Queue(new RT_MSG_SERVER_INFO_AUX_UDP() { Ip = Program.SERVER_IP, Port = (ushort)data.ClientObject.UdpPort }, clientChannel); break; } case RT_MSG_CLIENT_CONNECT_READY_AUX_UDP connectReadyAuxUdp: { Queue(new RT_MSG_SERVER_CONNECT_COMPLETE() { ARG1 = (ushort)data.ClientObject.DmeWorld.Clients.Count }, clientChannel); Queue(new RT_MSG_SERVER_APP() { Message = new DMEServerVersion() { Version = "2.10.0009" } }, clientChannel); data.ClientObject.DmeWorld.OnPlayerJoined(data.ClientObject); break; } case RT_MSG_SERVER_ECHO serverEchoReply: { break; } case RT_MSG_CLIENT_ECHO clientEcho: { Queue(new RT_MSG_CLIENT_ECHO() { Value = clientEcho.Value }, clientChannel); break; } case RT_MSG_CLIENT_SET_RECV_FLAG setRecvFlag: { break; } case RT_MSG_CLIENT_SET_AGG_TIME setAggTime: { break; } case RT_MSG_CLIENT_TIMEBASE_QUERY timebaseQuery: { Queue(new RT_MSG_SERVER_TIMEBASE_QUERY_NOTIFY() { ClientTime = timebaseQuery.Timestamp, ServerTime = (uint)(DateTime.UtcNow - data.ClientObject.DmeWorld.WorldCreatedTimeUtc).TotalMilliseconds }, clientChannel); break; } case RT_MSG_CLIENT_TOKEN_MESSAGE tokenMessage: { byte[] test = { 08, 00, 00 }; Queue(new RT_MSG_SERVER_TOKEN_MESSAGE() { Contents = test }, clientChannel); break; } case RT_MSG_CLIENT_APP_BROADCAST clientAppBroadcast: { data.ClientObject.DmeWorld?.BroadcastTcp(data.ClientObject, clientAppBroadcast.Payload); break; } case RT_MSG_CLIENT_APP_LIST clientAppList: { var world = data.ClientObject.DmeWorld; if (world != null && clientAppList.Targets != null) { foreach (var target in clientAppList.Targets) { world.SendTcpAppSingle(data.ClientObject, (short)target, clientAppList.Payload); } } break; } case RT_MSG_CLIENT_APP_SINGLE clientAppSingle: { data.ClientObject.DmeWorld?.SendTcpAppSingle(data.ClientObject, clientAppSingle.TargetOrSource, clientAppSingle.Payload); break; } case RT_MSG_CLIENT_APP_TOSERVER clientAppToServer: { ProcessMediusMessage(clientAppToServer.Message, clientChannel, data); break; } case RT_MSG_CLIENT_DISCONNECT_WITH_REASON clientDisconnectWithReason: { await DisconnectClient(clientChannel); break; } default: { Logger.Warn($"UNHANDLED MESSAGE: {message}"); break; } } return; }
private async Task ProcessMessage(BaseScertMessage message, IChannel serverChannel) { // switch (message) { // Authentication case RT_MSG_SERVER_HELLO serverHello: { if (_mpsState != MPSConnectionState.HELLO) { throw new Exception($"Unexpected RT_MSG_SERVER_HELLO from server. {serverHello}"); } // Send public key Enqueue(new RT_MSG_CLIENT_CRYPTKEY_PUBLIC() { Key = _clientKey.N.ToByteArrayUnsigned().Reverse().ToArray() }); _mpsState = MPSConnectionState.HANDSHAKE; break; } case RT_MSG_SERVER_CRYPTKEY_PEER serverCryptKeyPeer: { if (_mpsState != MPSConnectionState.HANDSHAKE) { throw new Exception($"Unexpected RT_MSG_SERVER_CRYPTKEY_PEER from server. {serverCryptKeyPeer}"); } await _mpsChannel.WriteAndFlushAsync(new RT_MSG_CLIENT_CONNECT_TCP() { AppId = Program.Settings.ApplicationId }); _mpsState = MPSConnectionState.CONNECT_TCP; break; } case RT_MSG_SERVER_CONNECT_ACCEPT_TCP serverConnectAcceptTcp: { if (_mpsState != MPSConnectionState.CONNECT_TCP) { throw new Exception($"Unexpected RT_MSG_SERVER_CONNECT_ACCEPT_TCP from server. {serverConnectAcceptTcp}"); } // Send attributes await _mpsChannel.WriteAndFlushAsync(new RT_MSG_CLIENT_APP_TOSERVER() { Message = new MediusServerSetAttributesRequest() { MessageID = new MessageId(), ListenServerAddress = new NetAddress() { Address = Program.SERVER_IP.ToString(), Port = (uint)Program.TcpServer.Port } } }); _mpsState = MPSConnectionState.SET_ATTRIBUTES; break; } // case RT_MSG_SERVER_ECHO serverEcho: { Enqueue(serverEcho); break; } case RT_MSG_CLIENT_ECHO clientEcho: { Enqueue(new RT_MSG_CLIENT_ECHO() { Value = clientEcho.Value }); break; } case RT_MSG_SERVER_APP serverApp: { ProcessMediusMessage(serverApp.Message, serverChannel); break; } case RT_MSG_SERVER_FORCED_DISCONNECT serverForcedDisconnect: case RT_MSG_CLIENT_DISCONNECT_WITH_REASON clientDisconnectWithReason: { await serverChannel.CloseAsync(); _mpsState = MPSConnectionState.NO_CONNECTION; break; } default: { Logger.Warn($"UNHANDLED MESSAGE: {message}"); break; } } return; }
public ScertDatagramPacket(BaseScertMessage message, EndPoint destination) { this.Destination = destination; this.Source = null; this.Message = message; }
protected abstract Task ProcessMessage(BaseScertMessage message, IChannel channel);
protected abstract Task ProcessMessage(BaseScertMessage message, IChannel clientChannel, ChannelData data);
public void EnqueueUdp(BaseScertMessage message) { Udp?.Send(message); }
public void EnqueueTcp(BaseScertMessage message) { TcpSendMessageQueue.Enqueue(message); }
public void Enqueue(BaseScertMessage message) { _mpsSendQueue.Enqueue(message); }
protected override async Task ProcessMessage(BaseScertMessage message, IChannel clientChannel, ChannelData data) { // switch (message) { case RT_MSG_CLIENT_HELLO clientHello: { Queue(new RT_MSG_SERVER_HELLO(), clientChannel); break; } case RT_MSG_CLIENT_CRYPTKEY_PUBLIC clientCryptKeyPublic: { Queue(new RT_MSG_SERVER_CRYPTKEY_PEER() { Key = Utils.FromString(Program.KEY) }, clientChannel); break; } case RT_MSG_CLIENT_CONNECT_TCP clientConnectTcp: { if (!Program.Settings.IsCompatAppId(clientConnectTcp.AppId)) { Logger.Error($"Client {clientChannel.RemoteAddress} attempting to authenticate with incompatible app id {clientConnectTcp.AppId}"); await clientChannel.CloseAsync(); return; } data.ApplicationId = clientConnectTcp.AppId; Queue(new RT_MSG_SERVER_CONNECT_REQUIRE() { Contents = Utils.FromString("024802") }, clientChannel); break; } case RT_MSG_CLIENT_CONNECT_READY_REQUIRE clientConnectReadyRequire: { Queue(new RT_MSG_SERVER_CRYPTKEY_GAME() { Key = Utils.FromString(Program.KEY) }, clientChannel); Queue(new RT_MSG_SERVER_CONNECT_ACCEPT_TCP() { UNK_00 = 0, UNK_02 = GenerateNewScertClientId(), UNK_06 = 0x0001, IP = (clientChannel.RemoteAddress as IPEndPoint)?.Address }, clientChannel); break; } case RT_MSG_CLIENT_CONNECT_READY_TCP clientConnectReadyTcp: { Queue(new RT_MSG_SERVER_CONNECT_COMPLETE() { ARG1 = 0x0001 }, clientChannel); Queue(new RT_MSG_SERVER_ECHO(), clientChannel); break; } case RT_MSG_SERVER_ECHO serverEchoReply: { break; } case RT_MSG_CLIENT_ECHO clientEcho: { Queue(new RT_MSG_CLIENT_ECHO() { Value = clientEcho.Value }, clientChannel); break; } case RT_MSG_CLIENT_APP_TOSERVER clientAppToServer: { ProcessMediusMessage(clientAppToServer.Message, clientChannel, data); break; } case RT_MSG_CLIENT_DISCONNECT_WITH_REASON clientDisconnectWithReason: { data.State = ClientState.DISCONNECTED; _ = clientChannel.CloseAsync(); break; } default: { Logger.Warn($"UNHANDLED MESSAGE: {message}"); break; } } return; }
protected override async Task ProcessMessage(BaseScertMessage message, IChannel clientChannel, ChannelData data) { // switch (message) { case RT_MSG_CLIENT_HELLO clientHello: { if (data.State > ClientState.HELLO) { throw new Exception($"Unexpected RT_MSG_CLIENT_HELLO from {clientChannel.RemoteAddress}: {clientHello}"); } data.State = ClientState.HELLO; Queue(new RT_MSG_SERVER_HELLO(), clientChannel); break; } case RT_MSG_CLIENT_CRYPTKEY_PUBLIC clientCryptKeyPublic: { if (data.State > ClientState.HANDSHAKE) { throw new Exception($"Unexpected RT_MSG_CLIENT_CRYPTKEY_PUBLIC from {clientChannel.RemoteAddress}: {clientCryptKeyPublic}"); } // Ensure key is correct if (!clientCryptKeyPublic.Key.Reverse().SequenceEqual(Program.Settings.MPSKey.N.ToByteArrayUnsigned())) { Logger.Error($"Client {clientChannel.RemoteAddress} attempting to authenticate with invalid key {clientCryptKeyPublic}"); data.State = ClientState.DISCONNECTED; await clientChannel.CloseAsync(); break; } data.State = ClientState.CONNECT_1; Queue(new RT_MSG_SERVER_CRYPTKEY_PEER() { Key = Utils.FromString(Program.KEY) }, clientChannel); break; } case RT_MSG_CLIENT_CONNECT_TCP clientConnectTcp: { if (data.State > ClientState.CONNECT_1) { throw new Exception($"Unexpected RT_MSG_CLIENT_CONNECT_TCP from {clientChannel.RemoteAddress}: {clientConnectTcp}"); } data.ApplicationId = clientConnectTcp.AppId; data.State = ClientState.AUTHENTICATED; Queue(new RT_MSG_SERVER_CONNECT_ACCEPT_TCP() { UNK_00 = 0, UNK_02 = GenerateNewScertClientId(), UNK_04 = 0, UNK_06 = 0x0001, IP = (clientChannel.RemoteAddress as IPEndPoint)?.Address }, clientChannel); break; } case RT_MSG_SERVER_ECHO serverEchoReply: { break; } case RT_MSG_CLIENT_ECHO clientEcho: { Queue(new RT_MSG_CLIENT_ECHO() { Value = clientEcho.Value }, clientChannel); break; } case RT_MSG_CLIENT_APP_TOSERVER clientAppToServer: { if (data.State != ClientState.AUTHENTICATED) { throw new Exception($"Unexpected RT_MSG_CLIENT_APP_TOSERVER from {clientChannel.RemoteAddress}: {clientAppToServer}"); } ProcessMediusMessage(clientAppToServer.Message, clientChannel, data); break; } case RT_MSG_CLIENT_DISCONNECT_WITH_REASON clientDisconnectWithReason: { data.State = ClientState.DISCONNECTED; await clientChannel.CloseAsync(); break; } default: { Logger.Warn($"UNHANDLED MESSAGE: {message}"); break; } } return; }
protected async Task ProcessMessage(BaseScertMessage message, IChannel clientChannel, ChannelData data) { // switch (message) { case RT_MSG_CLIENT_HELLO clientHello: { Queue(new RT_MSG_SERVER_HELLO(), clientChannel); break; } case RT_MSG_CLIENT_CRYPTKEY_PUBLIC clientCryptKeyPublic: { Queue(new RT_MSG_SERVER_CRYPTKEY_PEER() { Key = _clientSessionKey }, clientChannel); break; } case RT_MSG_CLIENT_CONNECT_TCP clientConnectTcp: { data.ApplicationId = clientConnectTcp.AppId; Queue(new RT_MSG_SERVER_CONNECT_REQUIRE() { Contents = Utils.FromString("024802") }, clientChannel); break; } case RT_MSG_CLIENT_CONNECT_READY_REQUIRE clientConnectReadyRequire: { Queue(new RT_MSG_SERVER_CRYPTKEY_GAME() { Key = _clientSessionKey }, clientChannel); Queue(new RT_MSG_SERVER_CONNECT_ACCEPT_TCP() { UNK_00 = 0, UNK_02 = GenerateNewScertClientId(), UNK_04 = 0, UNK_06 = 0x0001, IP = (clientChannel.RemoteAddress as IPEndPoint)?.Address }, clientChannel); break; } case RT_MSG_CLIENT_CONNECT_READY_TCP clientConnectReadyTcp: { Queue(new RT_MSG_SERVER_CONNECT_COMPLETE() { ARG1 = 0x0001 }, clientChannel); break; } case RT_MSG_SERVER_ECHO serverEchoReply: { break; } case RT_MSG_CLIENT_ECHO clientEcho: { Queue(new RT_MSG_CLIENT_ECHO() { Value = clientEcho.Value }, clientChannel); break; } case RT_MSG_CLIENT_APP_TOSERVER clientAppToServer: { ProcessMediusMessage(clientAppToServer.Message, clientChannel, data); break; } case RT_MSG_CLIENT_DISCONNECT_WITH_REASON clientDisconnectWithReason: { await clientChannel.DisconnectAsync(); break; } default: { Logger.Warn($"UNHANDLED MESSAGE: {message}"); break; } } return; }
public ScertDatagramPacket(BaseScertMessage message, EndPoint target, EndPoint source) { this.Source = source; this.Destination = target; this.Message = message; }