需要帮助识别解析错误

时间:2017-10-14 16:23:30

标签: c# arrays parsing unity3d

我需要一副新鲜的眼睛来帮助解决我收到的解析错误。在整个网络中更新玩家移动期间会出现此问题。我得到的错误是:

FormatException: Unknown char: % System.Double.Parse (System.String s, NumberStyles style, IFormatProvider provider) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System/Double.cs:209) System.Single.Parse (System.String s) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System/Single.cs:183) Server.Update () (at Assets/Scripts/Server.cs:85)

我认为错误源自Client.cs中的OnAskPosition(),但我没有使用%来解析该字符串。

我正在调试进入服务器的所有邮件,并且当服务器收到MYPOSITION时发生错误:

Player 1 has sent : MYPOSITION|0%-0.003983478 UnityEngine.Debug:Log(Object) Server:Update() (at Assets/Scripts/Server.cs:74)

我的位置不应该包含%符号,它应该只是一个x和y浮点数。我无法弄清楚流氓%来自哪里,真的很感激任何帮助来追踪这个问题。谢谢!

Client.cs

using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;

public class Player
{
    public string playerName;
    public GameObject avatar;
    public int connectionId;

}

public class Client : MonoBehaviour {

    public Dictionary<int, Player> players = new Dictionary<int, Player>();
    public GameObject playerPrefab;

    private const int MAX_CONNECTION = 100;

    private string serverIP = "127.0.0.1";
    private int port = 5701;
    private int hostId;
    private int webHostId;
    private int reliableChannel;
    private int unreliableChannel;

    private int ourClientId;
    private string playerName;
    private int connectionId;

    private float connectionTime;
    private bool isStarted = false;
    private bool isConnected = false;
    private byte error;

    private string GetPlayerName()
    {
        switch (Network.player.ipAddress.ToString())
        {
            case "192.168.1.160":
                playerName = "SMO Server";
                break;

            case "192.168.1.161":
                playerName = "SMO Client 1";
                break;

            case "192.168.1.162":
                playerName = "SMO Client 2";
                break;

            case "192.168.1.163":
                playerName = "SMO Client 3";
                break;

            case "192.168.1.164":
                playerName = "SMO Client 4";
                break;

            default:
                playerName = "SMO UNREG";
                break;
        }
        return playerName;
    }

    public void Connect()
    {
        string pName = GetPlayerName();

        if (pName == "")
            return;

        playerName = pName;

        NetworkTransport.Init();
        ConnectionConfig cc = new ConnectionConfig();

        reliableChannel = cc.AddChannel(QosType.ReliableSequenced);
        unreliableChannel = cc.AddChannel(QosType.UnreliableSequenced);

        HostTopology topo = new HostTopology(cc, MAX_CONNECTION);

        // Run client/server locally for testing
        hostId = NetworkTransport.AddHost(topo, 0);

        // Run client/server on different machines
        //hostID = NetworkTransport.AddHost(topo, port, null);  

        connectionId = NetworkTransport.Connect(hostId, serverIP, port, 0, out error);

        connectionTime = Time.time;
        isConnected = true;
    }

    private void Update()
    {
        if (!isConnected)
            return;

        int recHostId;
        int connectionId;
        int channelId;
        byte[] recBuffer = new byte[1024];
        int bufferSize = 1024;
        int dataSize;
        byte error;

        NetworkEventType recData = NetworkTransport.Receive
            (out recHostId, out connectionId, out channelId, recBuffer, bufferSize, out dataSize, out error);

        switch (recData)
        {
            case NetworkEventType.DataEvent:
                string msg = Encoding.Unicode.GetString(recBuffer, 0, dataSize);
                Debug.Log("Receiving : " + msg);

                string[] splitData = msg.Split('|');

                switch (splitData[0])
                {
                    case "ASKNAME":
                        OnAskName(splitData);
                        break;

                    case "CNN":
                        SpawnPlayer(splitData[1], int.Parse(splitData[2]));
                        break;

                    case "DC":
                        PlayerDisconnected(int.Parse(splitData[1]));
                        break;

                    case "ASKPOSITION":
                        OnAskPosition(splitData);
                        break;

                    default:
                        Debug.Log("Invalid message : " + msg);
                        break;
                }
                break;
        }
    }

    private void OnAskName(string[] data)
    {
        // Set client ID
        ourClientId = int.Parse(data[1]);

        // Send our name to the server
        Send("NAMEIS|" + playerName, reliableChannel);

        Debug.Log("The player name sent to server is : " + playerName);

        // Create all the other players
        for (int i = 2; i < data.Length - 1; i++)
        {
            string[] d = data[i].Split('%');
            SpawnPlayer(d[0], int.Parse(d[1]));
        }
    }

    private void OnAskPosition(string[] data)
    {
        if (!isStarted)
            return;

        // Update all other players
        for (int i = 1; i < data.Length - 1; i++)
        {
            string[] d = data[i].Split('%');

            // Prevent the server from updating us

            if (ourClientId != int.Parse(d[0]))
            {
                Vector3 position = Vector3.zero;
                position.x = float.Parse(d[1]);
                position.y = float.Parse(d[2]);
                players[int.Parse(d[0])].avatar.transform.position = position;
            }
        }

        // Send our own position
        Vector3 myPosition = players[ourClientId].avatar.transform.position;
        string moveMsg = "MYPOSIION|" + myPosition.x.ToString() + '|' + myPosition.y.ToString();
        Send(moveMsg, unreliableChannel);
    }

    private void SpawnPlayer(string pName, int cnnId)
    {
        GameObject go = Instantiate(playerPrefab) as GameObject;

        // Is this our player?
        if (cnnId == ourClientId)
        {
            // Add mobility
            go.AddComponent<Movement>();

            // Remove Canvas
            if(GameObject.Find("Canvas").activeInHierarchy == true)
                GameObject.Find("Canvas").SetActive(false);

            isStarted = true;
        }

        Player p = new Player();
        p.avatar = go;
        p.playerName = playerName;
        p.connectionId = cnnId;
        p.avatar.GetComponentInChildren<TextMesh>().text = pName;
        players.Add(cnnId, p);
    }

    private void PlayerDisconnected(int cnnId)
    {
        Destroy(players[cnnId].avatar);
        players.Remove(cnnId);
    }

    private void Send(string message, int channelId)
    {
        Debug.Log("Sending : " + message);
        byte[] msg = Encoding.Unicode.GetBytes(message);
        NetworkTransport.Send(hostId, connectionId, channelId, msg, msg.Length * sizeof(char), out error);
    }
}

Server.cs

using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;

// Define the definition of a client on the server
public class ServerClient
{
    public int connectionId;
    public string playerName;
    public Vector3 playerPosition;
}

public class Server : MonoBehaviour {

    private const int MAX_CONNECTION = 100;

    private int port = 5701;
    private int hostId;
    private int webHostId;
    private int reliableChannel;
    private int unreliableChannel;

    private bool isStarted = false;
    private byte error;

    private List<ServerClient> clients = new List<ServerClient>();

    private float lastMovementUpdate;
    private float movementUpdateRate = 0.1f;

    private void Start()
    {
        NetworkTransport.Init();
        ConnectionConfig cc = new ConnectionConfig();

        reliableChannel = cc.AddChannel(QosType.ReliableSequenced);
        unreliableChannel = cc.AddChannel(QosType.UnreliableSequenced);

        HostTopology topo = new HostTopology(cc, MAX_CONNECTION);

        hostId = NetworkTransport.AddHost(topo, port, null);
        webHostId = NetworkTransport.AddWebsocketHost(topo, port, null);

        isStarted = true;
    }

    private void Update()
    {
        if (!isStarted)
            return;

        int recHostId;
        int connectionId;
        int channelId;
        byte[] recBuffer = new byte[1024];
        int bufferSize = 1024;
        int dataSize;
        byte error;

        NetworkEventType recData = NetworkTransport.Receive
            (out recHostId, out connectionId, out channelId, recBuffer, bufferSize, out dataSize, out error);

        switch (recData)
        {
            case NetworkEventType.ConnectEvent:
                Debug.Log("Player " + connectionId + " has connected");
                OnConnection(connectionId);
                break;

            case NetworkEventType.DataEvent:
                string msg = Encoding.Unicode.GetString(recBuffer, 0, dataSize);
                Debug.Log("Player " + connectionId + " has sent : " + msg);

                string[] splitData = msg.Split('|');

                switch (splitData[0])
                {
                    case "NAMEIS":
                        OnNameIs(connectionId, splitData[1]);
                        break;

                    case "MYPOSITION":
                        OnMyPosition(connectionId, float.Parse(splitData[1]), float.Parse(splitData[2]));
                        break;

                    default:
                        Debug.Log("Invalid message : " + msg);
                        break;
                }
                break;

            case NetworkEventType.DisconnectEvent:
                Debug.Log("Player " + connectionId + " has disconnected");
                OnDisconnection(connectionId);
                break;
        }

        // Ask player for their position
        if (Time.time - lastMovementUpdate > movementUpdateRate)
        {
            lastMovementUpdate = Time.time;
            string moveMsg = "ASKPOSITION|";
            foreach (ServerClient sc in clients)
                moveMsg += sc.connectionId.ToString() + '%' + sc.playerPosition.x.ToString() + '%' + sc.playerPosition.y.ToString() + '|';
            moveMsg = moveMsg.Trim('|');
            Send(moveMsg, unreliableChannel, clients);
        }
    }

    private void OnConnection(int cnnId)
    {
        // Add him to a list
        ServerClient c = new ServerClient();
        c.connectionId = cnnId;
        c.playerName = "TEMP";
        clients.Add(c);

        // When player joins server, tell player id, request name and send name to other players
        string msg = "ASKNAME|" + cnnId + "|";

        foreach (ServerClient sc in clients)
        {
            msg += sc.playerName + '%' + sc.connectionId + '|';

        }

        msg = msg.Trim('|');
        Send(msg, reliableChannel, cnnId);
    }

    private void OnDisconnection(int cnnId)
    {
        // Remove this player from client list
        clients.Remove(clients.Find(x => x.connectionId == cnnId));

        // Tell all clients that a player has disconnected
        Send("DC|" + cnnId, reliableChannel, clients);
    }

    private void OnNameIs(int cnnId, string pName)
    {
        // Link the name to the connection ID
        clients.Find(x => x.connectionId == cnnId).playerName = pName;

        // Tell everybody that a new player has connected
        Send("CNN|" + pName + '|' + cnnId, reliableChannel, clients);
    }

    private void OnMyPosition(int cnnId, float x, float y)
    {
        clients.Find(c => c.connectionId == cnnId).playerPosition = new Vector3(x, y, 0);
    }

    private void Send(string message, int channelId, int cnnId)     // send to one player
    {
        List<ServerClient> c = new List<ServerClient>();
        c.Add(clients.Find(x => x.connectionId == cnnId));          // target only one user based on connectionID
        Send(message, channelId, c);
    }
    private void Send(string message, int channelId, List<ServerClient> c)  // send to all players
    {
        Debug.Log("Sending : " + message);
        byte[] msg = Encoding.Unicode.GetBytes(message);

        foreach (ServerClient sc in c)
        {
            NetworkTransport.Send(hostId, sc.connectionId, channelId, msg, msg.Length * sizeof(char), out error);
        }
    }
}

1 个答案:

答案 0 :(得分:1)

它在float.parse

上崩溃了
OnMyPosition(connectionId, float.Parse(splitData[1]), float.Parse(splitData[2]));

你可以:

1)打印出splitData的所有内容,看看为什么没有解析。

2)将它包装在try / catch

3)使用TryParse