// Called by the worker thread to do the actual work of the Teleport
// returns the teleported object if it couldn't teleport or null if successful
internal object DoTeleport()
{
// Check to see if the versions match
Version remoteVersion;
string remoteChannel;
try
{
if (_peerConnectionLed != null)
{
_peerConnectionLed.LedState = LedStates.Waiting;
}
var peerInfo = getPeerTerrariumInfo(_address);
remoteVersion = new Version(Convert.ToInt32(peerInfo["major"]), Convert.ToInt32(peerInfo["minor"]),
Convert.ToInt32(peerInfo["build"]));
remoteChannel = peerInfo["channel"];
// Check to see if there is a channel and if they don't match
if (remoteChannel.ToLower(CultureInfo.InvariantCulture) !=
GameEngine.Current.PeerChannel.ToLower(CultureInfo.InvariantCulture))
{
throw new Exception(
"An attempt was made to teleport an organism to another peer using a different channel.");
}
}
catch (Exception e)
{
if (_peerConnectionLed != null)
{
_peerConnectionLed.LedState = LedStates.Failed;
}
ErrorLog.LogHandledException(e);
GameEngine.Current.NetworkEngine.LastTeleportationException = e.ToString();
// Remove the bad IP from the list
_engine.PeerManager.RemovePeer(_address);
GameEngine.Current.NetworkEngine.CountFailedTeleportationSends();
return(_state);
}
if (_peerConnectionLed != null)
{
_peerConnectionLed.LedState = LedStates.Idle;
}
var versionsMatch = false;
if (remoteVersion.Build == _peerVersion.Build && remoteVersion.Major == _peerVersion.Major &&
remoteVersion.Minor == _peerVersion.Minor)
{
versionsMatch = true;
}
if (versionsMatch)
{
// Send the peer assembly - Assuming this succeeds
_engine.WriteProtocolInfo("DoTeleport: Versions Match: Send the peer assembly");
try
{
if (_peerConnectionLed != null)
{
_peerConnectionLed.LedState = LedStates.Waiting;
}
sendAssemblyToPeer(_address, _state);
}
catch (Exception exception)
{
GameEngine.Current.NetworkEngine.LastTeleportationException = exception.ToString();
GameEngine.Current.NetworkEngine.CountFailedTeleportationSends();
if (exception is AbortPeerDiscussionException)
{
// Don't remove them from the peer list, just teleport locally until they get up to date
if (_peerConnectionLed != null)
{
_peerConnectionLed.LedState = LedStates.Idle;
}
return(_state);
}
ErrorLog.LogHandledException(exception);
if (_peerConnectionLed != null)
{
_peerConnectionLed.LedState = LedStates.Failed;
}
// Remove the bad IP from the list
_engine.PeerManager.RemovePeer(_address);
return(_state);
}
if (_peerConnectionLed != null)
{
_peerConnectionLed.LedState = LedStates.Idle;
}
}
else
{
// Versions don't match so return the object and remove peer from list
// Remove the bad IP from the list
_engine.WriteProtocolInfo("DoTeleport: Versions don't match: remove peer from list.");
_engine.PeerManager.RemovePeer(_address);
GameEngine.Current.NetworkEngine.CountFailedTeleportationSends();
return(_state);
}
return(null);
}