context: using UnityEngine;
  using UnityEngine.UI;
  using UnityEngine.SceneManagement;
  using UnityEngine.Networking;
  using UnityEngine.Networking.Types;
  using UnityEngine.Networking.Match;
  using System.Collections;
  
  
  namespace Prototype.NetworkLobby
  {
      public class LobbyManager : NetworkLobbyManager 
      {
          static short MsgKicked = MsgType.Highest + 1;
  
          static public LobbyManager s_Singleton;
  
  
          [Header("Unity UI Lobby")]
          [Tooltip("Time in second between all players ready & match start")]
          public float prematchCountdown = 5.0f;
  
          [Space]
          [Header("UI Reference")]
          public LobbyTopPanel topPanel;
  
          public RectTransform mainMenuPanel;
          public RectTransform lobbyPanel;
  
          public LobbyInfoPanel infoPanel;
          public LobbyCountdownPanel countdownPanel;
          public GameObject addPlayerButton;
  
          protected RectTransform currentPanel;
  
          public Button backButton;
  
          public Text statusInfo;
          public Text hostInfo;
  
          //Client numPlayers from NetworkManager is always 0, so we count (throught connect/destroy in LobbyPlayer) the number
          //of players, so that even client know how many player there is.
          [HideInInspector]
          public int _playerNumber = 0;
  
          //used to disconnect a client properly when exiting the matchmaker
          [HideInInspector]
          public bool _isMatchmaking = false;
  
          protected bool _disconnectServer = false;
          
          protected ulong _currentMatchID;
  
          protected LobbyHook _lobbyHooks;
  
          void Start()
          {
              s_Singleton = this;
              _lobbyHooks = GetComponent<Prototype.NetworkLobby.LobbyHook>();
              currentPanel = mainMenuPanel;
  
              backButton.gameObject.SetActive(false);
              GetComponent<Canvas>().enabled = true;
  
              DontDestroyOnLoad(gameObject);
  
              SetServerInfo("Offline", "None");
          }
  
          public override void OnLobbyClientSceneChanged(NetworkConnection conn)
          {
              if (SceneManager.GetSceneAt(0).name == lobbyScene)
              {
                  if (topPanel.isInGame)
                  {
                      ChangeTo(lobbyPanel);
                      if (_isMatchmaking)
                      {
                          if (conn.playerControllers[0].unetView.isServer)
                          {
                              backDelegate = StopHostClbk;
                          }
                          else
                          {
                              backDelegate = StopClientClbk;
                          }
                      }
                      else
                      {
                          if (conn.playerControllers[0].unetView.isClient)
                          {
                              backDelegate = StopHostClbk;
                          }
                          else
                          {
                              backDelegate = StopClientClbk;
                          }
                      }
                  }
                  else
                  {
                      ChangeTo(mainMenuPanel);
                  }
  
                  topPanel.ToggleVisibility(true);
                  topPanel.isInGame = false;
              }
              else
              {
                  ChangeTo(null);
  
                  Destroy(GameObject.Find("MainMenuUI(Clone)"));
  
                  //backDelegate = StopGameClbk;
                  topPanel.isInGame = true;
                  topPanel.ToggleVisibility(false);
              }
          }
  
          public void ChangeTo(RectTransform newPanel)
          {
              if (currentPanel != null)
              {
                  currentPanel.gameObject.SetActive(false);
              }
  
              if (newPanel != null)
              {
                  newPanel.gameObject.SetActive(true);
              }
  
              currentPanel = newPanel;
  
              if (currentPanel != mainMenuPanel)
              {
                  backButton.gameObject.SetActive(true);
              }
              else
              {
                  backButton.gameObject.SetActive(false);
                  SetServerInfo("Offline", "None");
                  _isMatchmaking = false;
              }
          }
  
          public void DisplayIsConnecting()
          {
              var _this = this;
              infoPanel.Display("Connecting...", "Cancel", () => { _this.backDelegate(); });
          }
  
          public void SetServerInfo(string status, string host)
          {
              statusInfo.text = status;
              hostInfo.text = host;
          }
  
  
          public delegate void BackButtonDelegate();
          public BackButtonDelegate backDelegate;
          public void GoBackButton()
          {
              backDelegate();
          }
  
          // ----------------- Server management
  
          public void AddLocalPlayer()
          {
              TryToAddPlayer();
          }
  
          public void RemovePlayer(LobbyPlayer player)
          {
              player.RemovePlayer();
          }
  
          public void SimpleBackClbk()
          {
              ChangeTo(mainMenuPanel);
          }
                   
          public void StopHostClbk()
          {
              if (_isMatchmaking)
              {
                  matchMaker.DestroyMatch((NetworkID)_currentMatchID, OnDestroyMatch);
                  _disconnectServer = true;
              }
              else
              {
                  StopHost();
              }
  
              
              ChangeTo(mainMenuPanel);
          }
  
          public void StopClientClbk()
          {
              StopClient();
  
              if (_isMatchmaking)
              {
                  StopMatchMaker();
              }
  
              ChangeTo(mainMenuPanel);
          }
  
          public void StopServerClbk()
          {
              StopServer();
              ChangeTo(mainMenuPanel);
          }
  
          class KickMsg : MessageBase { }
          public void KickPlayer(NetworkConnection conn)
          {
              conn.Send(MsgKicked, new KickMsg());
          }
  
  
  
  
          public void KickedMessageHandler(NetworkMessage netMsg)
          {
              infoPanel.Display("Kicked by Server", "Close", null);
              netMsg.conn.Disconnect();
          }
  
          //===================
  
          public override void OnStartHost()
          {
              base.OnStartHost();
  
              ChangeTo(lobbyPanel);
              backDelegate = StopHostClbk;
              SetServerInfo("Hosting", networkAddress);
  
  			TryToAddPlayer ();
          }
  
          public override void OnMatchCreate(CreateMatchResponse matchInfo)
          {
              base.OnMatchCreate(matchInfo);
              _currentMatchID = (ulong)matchInfo.networkId;
          }
  
          public void OnDestroyMatch(BasicResponse extendedInfo)
          {
              if (_disconnectServer)
              {
                  StopMatchMaker();
                  StopHost();
              }
          }
  
          //allow to handle the (+) button to add/remove player
          public void OnPlayersNumberModified(int count)
          {
              _playerNumber += count;
  
              int localPlayerCount = 0;
              foreach (PlayerController p in ClientScene.localPlayers)
                  localPlayerCount += (p == null || p.playerControllerId == -1) ? 0 : 1;
  
              addPlayerButton.SetActive(localPlayerCount < maxPlayersPerConnection && _playerNumber < maxPlayers);
          }
  
          // ----------------- Server callbacks ------------------
  
          //we want to disable the button JOIN if we don't have enough player
          //But OnLobbyClientConnect isn't called on hosting player. So we override the lobbyPlayer creation
          public override GameObject OnLobbyServerCreateLobbyPlayer(NetworkConnection conn, short playerControllerId)
          {
              GameObject obj = Instantiate(lobbyPlayerPrefab.gameObject) as GameObject;
  
              LobbyPlayer newPlayer = obj.GetComponent<LobbyPlayer>();
              newPlayer.ToggleJoinButton(numPlayers + 1 >= minPlayers);
  
  
              for (int i = 0; i < lobbySlots.Length; ++i)
              {
                  LobbyPlayer p = lobbySlots[i] as LobbyPlayer;
  
                  if (p != null)
                  {
                      p.RpcUpdateRemoveButton();
                      p.ToggleJoinButton(numPlayers + 1 >= minPlayers);
                  }
              }
  
              return obj;
          }
  
          public override void OnLobbyServerPlayerRemoved(NetworkConnection conn, short playerControllerId)
          {
              for (int i = 0; i < lobbySlots.Length; ++i)
              {
                  LobbyPlayer p = lobbySlots[i] as LobbyPlayer;
  
  
gt:                 if (p != null)