// Figure out what IP Address to listen on internal void SetHostIPInformation() { _networkStatusMessage = ""; if (GameConfig.LocalIPAddress.Length != 0) { _hostIP = IPAddress.Parse(GameConfig.LocalIPAddress.Trim()); if (_hostIP.ToString() == "0.0.0.0") { Debug.Assert(_networkStatusMessage.Length == 0); _networkStatusMessage = "You have not entered a valid ipAddress in the localIPAddress tag of the Userconfig.xml file.\nUse the format: <localIPAddress>X.X.X.X</localIPAddress>."; } return; } var peerService = new PeerDiscoveryService { Url = (GameConfig.WebRoot + "/discovery/discoverydb.asmx"), Timeout = NetworkTimeoutMsec }; string address; var isVisibleNetworkAddress = false; var contactedDiscoveryServer = false; try { address = peerService.ValidatePeer(); contactedDiscoveryServer = true; } catch (Exception e) { Trace.WriteLine("HANDLED EXCEPTION: There was a problem accessing the Peer Discovery Web Service. " + e); Debug.Assert(_networkStatusMessage.Length == 0); _networkStatusMessage = "The .NET Terrarium is unable to connect to the Terrarium server. \nThis means you won't receive any creatures from other peers.\nYou'll need to restart the Terrarium when it is accessible again to receive creatures."; address = "127.0.0.1"; } if (contactedDiscoveryServer) { isVisibleNetworkAddress = ValidatePeer(address); } if (isVisibleNetworkAddress) { _hostIP = IPAddress.Parse(address); } else { if (contactedDiscoveryServer) { Debug.Assert(_networkStatusMessage.Length == 0); _networkStatusMessage = NetworkBehindNatMessage; IPHostEntry he = null; try { he = Dns.GetHostEntry(Dns.GetHostName()); } catch (Exception ex) { Trace.WriteLine("There was a problem resolving the hostname for this peer: " + address + " : " + ex); } _hostIP = he != null ? he.AddressList[0] : IPAddress.Parse("127.0.0.1"); } } Trace.WriteLine("The IP address used for listening is " + _hostIP); }
/// <summary> /// Tries to validate a new server whenever the server changes. /// </summary> /// <returns>True if the server is a valid Terrarium server, false otherwise.</returns> private bool RegisterServer() { txtServerURI.Text = txtServerURI.Text.Trim(); try { Uri uri = new Uri(txtServerURI.Text); } catch (Exception exception) { MessageBox.Show(exception.Message); return false; } this.Cursor = Cursors.WaitCursor; try { PeerDiscoveryService peerService = new PeerDiscoveryService(); peerService.Url = txtServerURI.Text + "/discovery/discoverydb.asmx"; peerService.Timeout = 15000; // 15 seconds peerService.ValidatePeer(); GameConfig.WebRoot = txtServerURI.Text; } catch (Exception exception) { ErrorLog.LogHandledException(exception); DialogResult result = MessageBox.Show("Error accessing '" + txtServerURI.Text + "':\nThe remote server is either unavailable or is not a valid Terrarium Server.\n\nWould you still like to set this address as your Terrarium server?", "Verify Terrarium Server", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (result == DialogResult.Yes) { GameConfig.WebRoot = txtServerURI.Text; return true; } else { return false; } } finally { this.Cursor = Cursors.Default; } return true; }
// Used to find other peers on the network // This routine is run on its own thread and just goes through the // while loop forever internal void AnnounceAndRegisterPeer() { try { var peerService = new PeerDiscoveryService { Url = (GameConfig.WebRoot + "/discovery/discoverydb.asmx"), Timeout = NetworkTimeoutMsec }; while (true) { // Make sure our bad peer list remains manageable _peerManager.TruncateBadPeerList(); // Register with the central server and get peers try { if (GameConfig.UseConfigForDiscovery || ValidatePeer(peerService.ValidatePeer())) { _networkStatusMessage = ""; if (_discoveryLed != null) _discoveryLed.LedState = LedStates.Waiting; DataSet data; if (GameConfig.UseConfigForDiscovery) { // Get it from the config file _totalPeersOnChannel = GetNumPeersFromConfig(_peerChannel); if (_discoveryLed != null) _discoveryLed.LedState = LedStates.Idle; if (_discoveryLed != null) _discoveryLed.LedState = LedStates.Waiting; data = GetAllPeersFromConfig(_peerChannel); if (_discoveryLed != null) _discoveryLed.LedState = LedStates.Idle; } else { peerService.RegisterMyPeerGetCountAndPeerList( Assembly.GetExecutingAssembly().GetName().Version.ToString(), _peerChannel, GameEngine.Current.CurrentVector.State.StateGuid, out data, out _totalPeersOnChannel); } if (_discoveryLed != null) _discoveryLed.LedState = LedStates.Idle; if (data != null) { var peerTable = data.Tables["Peers"]; var newPeersHash = Hashtable.Synchronized(new Hashtable()); foreach (DataRow row in peerTable.Rows) { var ipAddress = (string) row["IPAddress"]; var peerLease = (DateTime) row["Lease"]; if (ipAddress == _hostIP.ToString()) { continue; } // If the bad peer has updated their lease, then they // are online again, count them as good if (!_peerManager.ClearBadPeer(ipAddress, peerLease)) continue; newPeersHash.Add(ipAddress, new Peer(ipAddress, peerLease)); } _peerManager.KnownPeers = newPeersHash; } } else { _networkStatusMessage = NetworkBehindNatMessage; } } catch (Exception ex) { if (_discoveryLed != null) _discoveryLed.LedState = LedStates.Failed; ErrorLog.LogHandledException(ex); } // Sleep for a while so we don't flood the network Thread.Sleep(AnnounceAndRegisterPeerWaitMsec); } } catch (ThreadAbortException) { // percolate out and exit Thread.ResetAbort(); } catch (Exception e) { if (!(e.InnerException is ThreadAbortException)) { ErrorLog.LogHandledException(e); } } }