Search Unity

Network.CloseConnection Issue - Unity 5

Discussion in 'Multiplayer' started by Stormy102, Mar 12, 2015.

  1. Stormy102

    Stormy102

    Joined:
    Jan 17, 2014
    Posts:
    495
    I am having a problem in Unity 5 where the editor crashes when I "kick" the player. I am looking through my player list on the scoreboard script to find the networkplayer to kick that matches the player name. I the attempt to use Network.CloseConnection. I hope that someone can explain how I am screwing up :D

    Here is the code:

    ServerConsole Interpreter (On a persistent gameObject):

    I only included the consoleInterpreter to interprate the commands.

    Code (CSharp):
    1. void ConsoleInterpet(string obj)
    2.     {
    3.         if (obj.Length == 0) {
    4.             return;
    5.         }
    6.         List<string> result = obj.Split('"')
    7.             .Select((element, index) => index % 2 == 0  // If even index
    8.                     ? element.Split(new[] { ' ' }, System.StringSplitOptions.RemoveEmptyEntries)  // Split the item
    9.                     : new string[] { element })  // Keep the entire item
    10.                 .SelectMany(element => element).ToList();
    11.         if (result[0].ToLower () == "ban")
    12.         {
    13.             Debug.LogError("Banning " + result[1]);
    14.         }
    15.         else if (result[0].ToLower () == "kick")
    16.         {
    17.  
    18.             if (Network.connections.Length == 0)
    19.             {
    20.                 Debug.LogWarning("No players connected!");
    21.                 return;
    22.             }
    23.  
    24.             foreach (ScoreboardEntry entry in GameObject.Find("PlayerSpawner").GetComponent<ScoreboardNonAuth>().playerList)
    25.             {
    26.                 if (entry.playerName.ToLower () == result[1].ToLower())
    27.                 {
    28.                     Debug.LogError("Kicking " + result[1]);
    29.                     NetworkPlayer player = entry.networkPlayer;
    30.                     print (player);
    31.                     Network.CloseConnection(player, true);
    32.                     return;
    33.                 }
    34.             }
    35.             Debug.LogError("Unable to find player " + result[1]);
    36.         }
    37.     }
    Scoreboard Script (Feel free to steal this code :cool:;))

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class ScoreboardNonAuth : MonoBehaviour {
    5.  
    6.     public GUISkin skin;
    7.  
    8.     private string playerName = "";
    9.  
    10.     private string scoreText = "Loading scores";
    11.  
    12.     private bool hidestats  = true;
    13.     private int scoreBoardHeight = 60;
    14.  
    15.     private bool showScoreboard = false;
    16.  
    17.     public ArrayList playerList = new ArrayList();
    18.  
    19.     public NetworkView netView;
    20.  
    21.     public ChatNonAuth chatScript;
    22.  
    23.     // Use this for initialization
    24.     void Start () {
    25.  
    26.         chatScript = GameObject.Find("PlayerSpawner").GetComponent<ChatNonAuth>();
    27.  
    28.         if (SystemInfo.graphicsDeviceID == 0) {//Check if running in batchmode
    29.             enabled = false;
    30.             return;
    31.         }
    32.  
    33.         playerName = PlayerPrefs.GetString("Username", "");
    34.      
    35.         if(Network.isServer){
    36.             netView.RPC ("TellOurName", RPCMode.AllBuffered, playerName);
    37.             chatScript.ShowChatWindow();
    38.          
    39.         }else if(Network.isClient){
    40.          
    41.             netView.RPC ("TellOurName", RPCMode.AllBuffered, playerName);
    42.             chatScript.ShowChatWindow();
    43.         }else{
    44.             enabled = false;
    45.             return;
    46.         }
    47.  
    48.     }
    49.  
    50.     void OnConnectedToServer() {
    51.         //chatScript.ShowChatWindow();
    52.         if (Network.isClient)
    53.         {
    54.             netView.RPC ("TellOurName", RPCMode.AllBuffered, playerName);
    55.         }
    56.     }
    57.  
    58.     //Sent by newly connected clients, recieved by server
    59.     [RPC]
    60.     void TellOurName(string name, NetworkMessageInfo info){  
    61.         NetworkPlayer netPlayer = info.sender;
    62.         if(netPlayer+""=="-1"){
    63.             //This hack is required to fix the local players networkplayer when the RPC is sent to itself.
    64.             netPlayer=Network.player;
    65.         }
    66.      
    67.         ScoreboardEntry newEntry = new ScoreboardEntry();
    68.         newEntry.playerName=name;
    69.         newEntry.networkPlayer=netPlayer;
    70.         playerList.Add(newEntry);
    71.      
    72.         if(Network.isServer){
    73.             Debug.Log(name+" joined the game");
    74.             chatScript.addGameChatMessage(name+" joined the game");
    75.         }
    76.     }
    77.  
    78.     void OnPlayerDisconnected(NetworkPlayer player)
    79.     {
    80.         foreach(ScoreboardEntry entry in  playerList){
    81.             if(entry.networkPlayer==player){
    82.                 chatScript.addGameChatMessage(entry.playerName+" left the game.");
    83.                 Debug.Log(entry.playerName+" left the game.");
    84.                 playerList.Remove(entry);
    85.                 break;
    86.             }
    87.         }
    88.     }
    89.  
    90.     void Update()
    91.     {
    92.         if (SystemInfo.graphicsDeviceID == 0) {
    93.             return;
    94.         }
    95.         if (RebindableInput.GetKey("Scoreboard"))
    96.         {
    97.             showScoreboard = true;
    98.         }
    99.         else
    100.         {
    101.             showScoreboard = false;
    102.         }
    103.     }
    104.  
    105.     void OnGUI()
    106.     {
    107.         if (SystemInfo.graphicsDeviceID == 0) {
    108.             return;
    109.         }
    110.         GUI.skin = skin;
    111.  
    112.         if (showScoreboard)
    113.         {
    114.             GUI.Window(0, new Rect(Screen.width /4, Screen.height/4, Screen.width /2, Screen.height/2), DrawScoreboard, "Scoreboard");
    115.         }
    116.     }
    117.  
    118.     void DrawScoreboard(int window)
    119.     {
    120.         GUI.Label(new Rect(5,20,250,25), "<b>Name</b>");
    121.         GUI.Label(new Rect(260,20,50,25), "<b>Kills</b>");
    122.         GUI.Label(new Rect(315,20,50,25), "<b>Deaths</b>");
    123.         GUI.Label(new Rect(370,20,100,25), "<b>Ping (Avg)</b>");
    124.         int i = 0;
    125.         foreach (ScoreboardEntry entry in playerList)
    126.         {
    127.             i++;
    128.             GUI.Label(new Rect(5, 20 + 20* i, 250,25), entry.playerName);
    129.             GUI.Label(new Rect(260, 20 + 20* i, 250,25), entry.kills.ToString());
    130.             GUI.Label(new Rect(315, 20 + 20* i, 250,25), entry.deaths.ToString());
    131.             GUI.Label(new Rect(370, 20 + 20* i, 250,25), Network.GetAveragePing(entry.networkPlayer).ToString());
    132.             if (Network.GetAveragePing(entry.networkPlayer) != -1 && Network.isServer)
    133.             {
    134.                 if (GUI.Button(new Rect(470, 20 + 20 * i,50,25), "Kick"))
    135.                 {
    136.                     Network.CloseConnection(entry.networkPlayer, true);
    137.                 }
    138.             }
    139.         }
    140.     }
    141.  
    142.     void LocalPlayerHasKilled(){
    143.         int kills = 0;
    144.         int deaths = 0;
    145.         foreach (ScoreboardEntry playerInstance in playerList) {
    146.             if (Network.player == playerInstance.networkPlayer) {
    147.                 kills = playerInstance.kills;
    148.                 deaths = playerInstance.deaths;
    149.                 break;
    150.             }
    151.         }
    152.      
    153.         kills++;
    154.      
    155.         //Overwrite the data of other players with the new correct score
    156.         netView.RPC ("UpdateScore", RPCMode.All, Network.player, kills, deaths);
    157.     }
    158.  
    159.     void LocalPlayerDied(){
    160.         int kills =0;
    161.         int deaths = 0;
    162.         foreach (ScoreboardEntry playerInstance in playerList) {
    163.             if (Network.player == playerInstance.networkPlayer) {
    164.                 kills = playerInstance.kills;
    165.                 deaths = playerInstance.deaths;
    166.                 break;
    167.             }
    168.         }  
    169.         deaths++;
    170.      
    171.         //Overwrite with new correct score
    172.         netView.RPC("UpdateScore",RPCMode.All, Network.player, kills, deaths);
    173.     }
    174.  
    175.     [RPC]
    176.     void UpdateScore(NetworkPlayer player, int kills, int deaths){
    177.         Debug.Log ((Network.player == player) + "=local " + kills + "kills & deaths=" + deaths);
    178.         bool found = false;
    179.         foreach (ScoreboardEntry playerInstance in playerList) {
    180.             if (player == playerInstance.networkPlayer) {
    181.                 playerInstance.kills = kills;
    182.                 playerInstance.deaths = deaths;
    183.                 found = true;
    184.                 break;          
    185.             }
    186.         }  
    187.         if (!found) {
    188.             Debug.LogError ("Could not find network player " + player + " in the gamesetup playerlist!");
    189.         }
    190.     }
    191. }
    192.  
    193. public class ScoreboardEntry {
    194.     public string playerName;
    195.     public NetworkPlayer networkPlayer;
    196.  
    197.     public int kills =0;
    198.     public int deaths =0;
    199. }
    200.  
    And finally the player spawn script:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class PlayerSpawner : MonoBehaviour {
    5.  
    6.     public GameObject player;
    7.     public Transform[] Spawnpoints;
    8.     public NetworkView netView;
    9.  
    10.     // Use this for initialization
    11.     void Start () {
    12.         if (Network.isServer && PlayerPrefs.GetInt("ServerDedicated", 0) == 1 || Network.isClient)
    13.         {
    14.             int RandomSpawn = Random.Range(0, Spawnpoints.Length);
    15.             Network.Instantiate(player, Spawnpoints[RandomSpawn].position, Spawnpoints[RandomSpawn].rotation, 0);
    16.         }
    17.         else if (PlayerPrefs.GetInt("ServerDedicated", 0) != 1 && !Network.isServer)
    18.         {
    19.             Application.LoadLevelAsync(0);
    20.         }
    21.     }
    22.  
    23.     void OnPlayerDisconnected(NetworkPlayer player)
    24.     {
    25.         Network.RemoveRPCs(player);
    26.         Network.DestroyPlayerObjects(player);
    27.     }
    28.  
    29.     void OnDisconnectedFromServer(NetworkDisconnection info)
    30.     {
    31.         if (SystemInfo.graphicsDeviceID == 0) {
    32.             return;
    33.         }
    34.         Debug.Log ("Loading main menu");
    35.         Application.LoadLevel ("MainMenu");
    36.     }
    37. }
    38.  
    I hope this is a Unity 5 bug and not me being stupid.

    Hope someone can get me a quick answer:

    Stormy102

    EDIT:
    I tested it with two machines and neither player could be seen. I am convinced that Unity Networking is broken in Unity 5. Could someone from UT please check this?
     
    Last edited: Mar 12, 2015
  2. Stormy102

    Stormy102

    Joined:
    Jan 17, 2014
    Posts:
    495
  3. Mabenan

    Mabenan

    Joined:
    Feb 7, 2014
    Posts:
    132
    so you running the server from the editor? at wich code line do you have the crash?
     
    Stormy102 likes this.
  4. Mabenan

    Mabenan

    Joined:
    Feb 7, 2014
    Posts:
    132
    have you a second thread running beside the main thread which can result in a dead lock
     
  5. Stormy102

    Stormy102

    Joined:
    Jan 17, 2014
    Posts:
    495
    Sorry about the long reply. The editor is the client. The server is being run from a batchmode console and using command line input to "kick" the player with Network.CloseConnection.
     
  6. Mabenan

    Mabenan

    Joined:
    Feb 7, 2014
    Posts:
    132
    mh so do you get the log "Loading main menu"?
     
  7. demonNo2005

    demonNo2005

    Joined:
    Mar 4, 2015
    Posts:
    2
    I think its a Unity 5 bug, got the same problem here
     
  8. Mabenan

    Mabenan

    Joined:
    Feb 7, 2014
    Posts:
    132
    ok if you think this a unity bug did you already open an issiue
     
  9. demonNo2005

    demonNo2005

    Joined:
    Mar 4, 2015
    Posts:
    2
    no because i am not 100% sure.
     
  10. Stormy102

    Stormy102

    Joined:
    Jan 17, 2014
    Posts:
    495
    I realised that I forgot to re-enabled Network.isMessageQueueRunning. Try this. Unfortunately, Network.CloseConnection still takes 10 seconds to work on the same computer. That is defo a Unity bug.
     
  11. DryTear

    DryTear

    Joined:
    Nov 30, 2012
    Posts:
    312
    you can have rpc that does Network.Disconnect(), and then send that rpc to the networkplayer, thats what i do.
     
  12. Zubba

    Zubba

    Joined:
    Mar 6, 2010
    Posts:
    67
    This is what I've always done.