<commit_before>﻿//
// TcpipClient.cs
//
// Copyright (c) 2016 <NAME>
//
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
//

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Threading.Tasks;

namespace AIWolf.Lib
{
    /// <summary>
    /// AIWolf client using TCP/IP connection.
    /// </summary>
    public class TcpipClient
    {
        string host;
        int port;

        TcpClient tcpClient;

        IPlayer player;

        GameInfo lastGameInfo;

        /// <summary>
        /// The requested role.
        /// </summary>
        public Role RequestRole { get; }

        /// <summary>
        /// Whether or not this client is running.
        /// </summary>
        public bool Running { get; private set; }

        /// <summary>
        /// The name of player this client manages.
        /// </summary>
        public string PlayerName { get; set; }

        /// <summary>
        /// The number of milliseconds to wait for the request call.
        /// </summary>
        public int Timeout { get; set; } = -1; // Do not limit by default.

        /// <summary>
        /// Initializes a new instance of this class which connects given port of given host.
        /// </summary>
        /// <param name="host">Hostname this client connects.</param>
        /// <param name="port">Port number this client connects.</param>
        public TcpipClient(string host, int port)
        {
            this.host = host;
            this.port = port;
            Running = false;
        }

        /// <summary>
        /// Initializes a new instance of this class which connects given port of given host, and requests given role.
        /// </summary>
        /// <param name="host">Hostname this client connects.</param>
        /// <param name="port">Port number this client connects.</param>
        /// <param name="requestRole">Role this client requests.</param>
        public TcpipClient(string host, int port, Role requestRole) : this(host, port)
        {
            RequestRole = requestRole;
        }

        /// <summary>
        /// Connects the player to the server.
        /// </summary>
        /// <param name="player">The player to be connected.</param>
        public void Connect(IPlayer player)
        {
            this.player = player;

            tcpClient = new TcpClient();
            tcpClient.ConnectAsync(host, port).Wait();

            try
            {
                StreamReader sr = new StreamReader(tcpClient.GetStream());
                StreamWriter sw = new StreamWriter(tcpClient.GetStream());
                string line;
                while ((line = sr.ReadLine()) != null)
                {
                    Packet packet = ToPacket(line);

                    object obj = Recieve(packet);
                    if (packet.Request.HasReturn())
                    {
                        if (obj == null)
                        {
                            sw.WriteLine();
                        }
                        else if (obj is string)
                        {
                            sw.WriteLine(obj);
                        }
                        else
                        {
                            sw.WriteLine(DataConverter.Serialize(obj));
                        }
                        sw.Flush();
                    }
                }
            }
            catch (IOException e)
            {
                if (Running)
                {
                    throw e;
                }
            }
            finally
            {
                Running = false;
            }
        }

        /// <summary>
        /// Receives a packet from the server and sends it to the player, and returns what returned from the player.
        /// </summary>
        /// <param name="packet">The packet from the server.</param>
        /// <returns>The object returned from the player.</returns>
        public object Recieve(Packet packet)
        {
            GameInfo gameInfo = lastGameInfo;
            GameSetting gameSetting = packet.GameSetting;
<commit_msg>TcpipClient.cs: Change the manner of exception throwing not to lose the original stacktrace.<commit_after>﻿//
// TcpipClient.cs
//
// Copyright (c) 2016 <NAME>
//
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
//

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Threading.Tasks;

namespace AIWolf.Lib
{
    /// <summary>
    /// AIWolf client using TCP/IP connection.
    /// </summary>
    public class TcpipClient
    {
        string host;
        int port;

        TcpClient tcpClient;

        IPlayer player;

        GameInfo lastGameInfo;

        /// <summary>
        /// The requested role.
        /// </summary>
        public Role RequestRole { get; }

        /// <summary>
        /// Whether or not this client is running.
        /// </summary>
        public bool Running { get; private set; }

        /// <summary>
        /// The name of player this client manages.
        /// </summary>
        public string PlayerName { get; set; }

        /// <summary>
        /// The number of milliseconds to wait for the request call.
        /// </summary>
        public int Timeout { get; set; } = -1; // Do not limit by default.

        /// <summary>
        /// Initializes a new instance of this class which connects given port of given host.
        /// </summary>
        /// <param name="host">Hostname this client connects.</param>
        /// <param name="port">Port number this client connects.</param>
        public TcpipClient(string host, int port)
        {
            this.host = host;
            this.port = port;
            Running = false;
        }

        /// <summary>
        /// Initializes a new instance of this class which connects given port of given host, and requests given role.
        /// </summary>
        /// <param name="host">Hostname this client connects.</param>
        /// <param name="port">Port number this client connects.</param>
        /// <param name="requestRole">Role this client requests.</param>
        public TcpipClient(string host, int port, Role requestRole) : this(host, port)
        {
            RequestRole = requestRole;
        }

        /// <summary>
        /// Connects the player to the server.
        /// </summary>
        /// <param name="player">The player to be connected.</param>
        public void Connect(IPlayer player)
        {
            this.player = player;

            tcpClient = new TcpClient();
            tcpClient.ConnectAsync(host, port).Wait();

            try
            {
                StreamReader sr = new StreamReader(tcpClient.GetStream());
                StreamWriter sw = new StreamWriter(tcpClient.GetStream());
                string line;
                while ((line = sr.ReadLine()) != null)
                {
                    Packet packet = ToPacket(line);

                    object obj = Recieve(packet);
                    if (packet.Request.HasReturn())
                    {
                        if (obj == null)
                        {
                            sw.WriteLine();
                        }
                        else if (obj is string)
                        {
                            sw.WriteLine(obj);
                        }
                        else
                        {
                            sw.WriteLine(DataConverter.Serialize(obj));
                        }
                        sw.Flush();
                    }
                }
            }
            catch (IOException)
            {
                if (Running)
                {
                    throw;
                }
            }
            finally
            {
                Running = false;
            }
        }

        /// <summary>
        /// Receives a packet from the server and sends it to the player, and returns what returned from the player.
        /// </summary>
        /// <param name="packet">The packet from the server.</param>
        /// <returns>The object returned from the player.</returns>
        public object Recieve(Packet packet)
        {
            GameInfo gameInfo = lastGameInfo;
            GameSetting gameSetting = packet.GameSetting;

{'fraction_non_alphanumeric': 0.10608736606617214, 'fraction_numerical': 0.0011774402449075709, 'mean_word_length': 1.2620505992010653, 'pattern_counts': {'":': 0, '<': 73, '<?xml version=': 0, '>': 73, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3591192', 'n_tokens_mistral': 2088, 'n_tokens_neox': 1981, 'n_words': 628}