/* * This file is part of the Unity networking tutorial by M2H (http://www.M2H.nl) * The original author of this code is Mike Hergaarden, even though some small parts * are copied from the Unity tutorials/manuals. * Feel free to use this code for your own projects, drop us a line if you made something exciting! */ #pragma strict public var gameName = "Example2"; public var serverPort = 35001; public var hostData : HostData[]; private var natCapable : ConnectionTesterStatus = ConnectionTesterStatus.Undetermined; public var filterNATHosts = false; private var probingPublicIP = false; private var doneTestingNAT = false; private var timer : float = 0.0; private var hideTest = false; private var testMessage = "Undetermined NAT capabilities"; private var tryingToConnectPlayNow : boolean = false; public var tryingToConnectPlayNowNumber : int = 0; private var remotePort : int[] = new int[3]; private var remoteIP : String[] = new String[3]; public var connectionInfo : String = ""; public var lastMSConnectionAttemptForcedNat : boolean= false; private var NAToptionWasSwitchedForTesting : boolean = false; private var officialNATstatus : boolean = Network.useNat; public var errorMessage : String = ""; private var lastPlayNowConnectionTime : float; public var nowConnecting : boolean = false; function Awake () { sortedHostList = new Array (); // Start connection test natCapable = Network.TestConnection(); // What kind of IP does this machine have? TestConnection also indicates this in the // test results if (Network.HavePublicAddress()){ Debug.Log("This machine has a public IP address"); }else{ Debug.Log("This machine has a private IP address"); } /* //If you dont want to use the Unity masterserver.. Network.natFacilitatorIP = myMasterServerIP; Network.natFacilitatorPort = 11111;//Change this MasterServer.ipAddress = myMasterServerIP; MasterServer.port = 22222;//Change this Network.connectionTesterIP = myMasterServerIP; Network.connectionTesterPort = 33333;//Change this */ } function Start(){//must be in start because of coroutine yield WaitForSeconds(0.5); var tries : int=0; while(tries<=10){ if(hostData && hostData.length>0){ //Waiting for hostData }else{ FetchHostList(true); } yield WaitForSeconds(0.5); tries++; } } function OnFailedToConnectToMasterServer(info: NetworkConnectionError) { //Yikes } function OnFailedToConnect(info: NetworkConnectionError) { Debug.Log("FailedToConnect info:"+info); FailedConnRetry(info); } function Connect(ip : String, port : int, usenat : boolean){ // Enable NAT functionality based on what the hosts if configured to do Network.useNat = usenat; lastMSConnectionAttemptForcedNat = usenat; Debug.Log("Connecting to "+ip+":"+port+" NAT:"+usenat); Network.Connect(ip, port); nowConnecting=true; } //This second definition of Connect can handle the ip string[] passed by the masterserver function Connect(ip : String[], port : int, usenat : boolean){ // Enable NAT functionality based on what the hosts if configured to do Network.useNat = usenat; lastMSConnectionAttemptForcedNat = usenat; Debug.Log("Connecting to "+ip[0]+":"+port+" NAT:"+usenat); Network.Connect(ip, port); nowConnecting=true; } function StartHost(players : int, port : int){ if(players<=1){ players=1; } //Network.InitializeSecurity(); Network.InitializeServer(players, port); } function OnConnectedToServer(){ //Stop communication until in the game Network.isMessageQueueRunning = false; //Save these details so we can use it in the next scene PlayerPrefs.SetString("connectIP", Network.connections[0].ipAddress); PlayerPrefs.SetInt("connectPort", Network.connections[0].port); } function FailedConnRetry(info: NetworkConnectionError){ if(info == NetworkConnectionError.InvalidPassword){ mayRetry=false; } nowConnecting=false; //Quickplay if(tryingToConnectPlayNow){ //Try again without NAT if we used NAT if(mayRetry && Network.useNat && lastMSConnectionAttemptForcedNat){ Debug.Log("Failed connect 1A: retry without NAT"); remotePort[0]=serverPort;//Fall back to default server port Connect(remoteIP, remotePort[0], false); lastPlayNowConnectionTime=Time.time; }else{ //We didn't use NAT and failed Debug.Log("Failed connect 1B: Don't retry"); //Reset NAT to org. value Network.useNat=officialNATstatus; //Connect to next playnow/quickplay host tryingToConnectPlayNowNumber++; tryingToConnectPlayNow=false; } }else{ //Direct connect or via host list manually connectionInfo="Failed to connect!"; if(mayRetry && Network.useNat && lastMSConnectionAttemptForcedNat){ //Since the last connect forced NAT usage, // let's try again without NAT. Network.useNat=false; Network.Connect(remoteIP, remotePort[0]); nowConnecting=true; lastPlayNowConnectionTime=Time.time; }else{ Debug.Log("Failed 2b"); if(info == NetworkConnectionError.InvalidPassword){ errorMessage="Failed to connect: Wrong password supplied"; }else if(info == NetworkConnectionError.TooManyConnectedPlayers){ errorMessage="Failed to connect: Server is full"; }else{ errorMessage="Failed to connect"; } //reset to default port remotePort[0]=serverPort; //Reset nat to tested value Network.useNat=officialNATstatus; } } } public var CONNECT_TIMEOUT : float = 0.75; public var CONNECT_NAT_TIMEOUT : float = 5.00; //Our quickplay function: Go trough the gameslist and try to connect to all games function PlayNow(timeStarted : float ){ var i : int=0; for (var myElement in sortedHostList) { var element=hostData[myElement]; // Do not try NAT enabled games if we cannot do NAT punchthrough // Do not try connecting to password protected games if ( !(filterNATHosts && element.useNat) && !element.passwordProtected ) { aHost=1; if(element.connectedPlayers timer) { probingPublicIP = false; // reset Network.useNat = true; doneTestingNAT = true; } break; case ConnectionTesterStatus.PublicIPNoServerStarted: testMessage = "Public IP address but server not initialized, it must be started to check server accessibility. Restart connection test when ready."; break; default: testMessage = "Error in test routine, got " + natCapable; } officialNATstatus=Network.useNat; if(doneTestingNAT){ Debug.Log("TestConn:"+testMessage); Debug.Log("TestConn:"+natCapable + " " + probingPublicIP + " " + doneTestingNAT); } } private var lastHostListRequest : float = 0; //Request the host limit, but we limit these requests //Max once every two minutes automatically, max once every 5 seconds when manually requested function FetchHostList(manual : boolean){ var timeout : int = 120; if(manual){ timeout=5; } if(lastHostListRequest==0 || Time.realtimeSinceStartup > lastHostListRequest + timeout){ lastHostListRequest = Time.realtimeSinceStartup; MasterServer.RequestHostList (gameName); yield WaitForSeconds(1);//We gotta wait :/ hostData = MasterServer.PollHostList(); yield WaitForSeconds(1);//We gotta wait :/ CreateSortedArray(); Debug.Log("Requested new host list, got: "+hostData.length); } } //The code below is all about sorting the game list by playeramount public var sortedHostList : Array; function CreateSortedArray(){ sortedHostList = new Array(); var i : int=0; var data : HostData[] = hostData; for (var element in data) { AddToArray(i); i++; } } function AddToArray(nr : int){ sortedHostList.Add (nr); SortLastItem(); } function SortLastItem(){ if(sortedHostList.length<=1){ return; } for(var i=sortedHostList.length-1;i>0;i--){ var value1 : int= hostData[sortedHostList[i-1]].connectedPlayers; var value2 : int = hostData[sortedHostList[i]].connectedPlayers; if(value1