예제 #1
0
 public Host()
 {
     this._isRunning    = false;
     this._game_name    = string.Empty;
     this._player_count = 0;
     this.gameTunnel    = new UdpProxy();
 }
예제 #2
0
            public UdpClientEx(UdpProxy server, IPEndPoint clientEndpoint, IPEndPoint remoteServer)
            {
                _server = server;

                _isRunning     = true;
                RemoteServer   = remoteServer;
                ClientEndpoint = clientEndpoint;
                if (server.Verbose)
                {
                    Console.WriteLine($"[PROXY] Established {clientEndpoint} => {remoteServer}");
                }
                Run();
            }
예제 #3
0
        private Client(TcpClient tcpClient, bool localonly)
        {
            var gameProxy = new UdpProxy();

            this.taskSrc = new TaskCompletionSource <Client>();
            this._client = tcpClient;
            Task.Factory.StartNew(async(obj) =>
            {
                using (var client = (TcpClient)obj)
                    using (var broadcaster = new UdpClient(new IPEndPoint(localonly ? IPAddress.Loopback : IPAddress.Any, 0)))
                        using (var networkStream = client.GetStream())
                        {
                            networkStream.ReadTimeout  = 5000;
                            networkStream.WriteTimeout = 5000;
                            broadcaster.Connect(IPAddress.Broadcast.ToString(), AmongUs.BroadcastPort);

                            // 4096 bytes should be enough??
                            byte[] buffer           = new byte[4096];
                            byte[] broadcastMessage = null;

                            await networkStream.WriteAsync(Host.BroadcastHandshake, 0, Host.BroadcastHandshake.Length);
                            int readLen = await networkStream.ReadAsync(buffer, 0, buffer.Length);
                            if (readLen == sizeof(int) && (BitConverter.ToInt32(buffer, 0) == (int)MessageID.OK))
                            {
                                var destination = (IPEndPoint)tcpClient.Client.RemoteEndPoint;
                                // this.gameTunnel = new UdpTunnel(new IPEndPoint(localonly ? IPAddress.Loopback : IPAddress.Any, AmongUs.ServerPort), destination);
                                try
                                {
                                    _ = gameProxy.Start(destination.Address.ToString(), (ushort)destination.Port, AmongUs.ServerPort, (localonly ? IPAddress.Loopback : IPAddress.Any).ToString());
                                    // _ = gameTunnel.Start();
                                    while (this._client.Connected)
                                    {
                                        buffer.WriteBytes((int)MessageID.Broadcast, 0);
                                        await networkStream.WriteAsync(buffer, 0, sizeof(int));
                                        readLen         = await networkStream.ReadAsync(buffer, 0, buffer.Length);
                                        var strCount    = readLen - sizeof(ushort);
                                        var playerCount = buffer.ReadUInt16(strCount);

                                        var extendedPart            = $" (Proxy)~Open~{playerCount}~";
                                        var byteCountOfExtendedPart = Encoding.UTF8.GetByteCount(extendedPart);
                                        var byteCountOfMessage      = 2 + strCount + byteCountOfExtendedPart;

                                        // Reuse allocated buffer to avoid unnecessary allocations.
                                        // Only create anew in case it has not been created yet or the buffer's size is not enough
                                        if (broadcastMessage == null || broadcastMessage.Length < byteCountOfMessage)
                                        {
                                            broadcastMessage    = new byte[2 + strCount + byteCountOfExtendedPart];
                                            broadcastMessage[0] = 4;
                                            broadcastMessage[1] = 2;
                                        }

                                        // Copy game name.
                                        Buffer.BlockCopy(buffer, 0, broadcastMessage, 2, strCount);

                                        // Encode the extended part into the buffer
                                        Encoding.UTF8.GetBytes(extendedPart, 0, extendedPart.Length, broadcastMessage, strCount + 2);

                                        broadcaster.Send(broadcastMessage, byteCountOfMessage);

                                        await Task.Delay(100);
                                    }
                                }
                                catch (Exception ex) when(!(ex is ObjectDisposedException))
                                {
                                    this.taskSrc.TrySetException(ex);
                                }
                                finally
                                {
                                    gameProxy.Stop();
                                    // gameTunnel.Stop();
                                }
                                this.taskSrc.TrySetResult(this);
                            }

                            broadcaster.Close();
                            client.Close();
                            this.taskSrc.TrySetCanceled();
                        }
            }, tcpClient, TaskCreationOptions.LongRunning);
        }