/// <summary> /// Request sim data based on arbitrary key/value /// </summary> private RegionProfileData RequestSimData(Uri gridserverUrl, string gridserverSendkey, string keyField, string keyValue) { Hashtable requestData = new Hashtable(); requestData[keyField] = keyValue; requestData["authkey"] = gridserverSendkey; ArrayList SendParams = new ArrayList(); SendParams.Add(requestData); XmlRpcRequest GridReq = new XmlRpcRequest("simulator_data_request", SendParams); XmlRpcResponse GridResp = GridReq.Send(gridserverUrl.ToString(), 3000); Hashtable responseData = (Hashtable)GridResp.Value; RegionProfileData simData = null; if (!responseData.ContainsKey("error")) { uint locX = Convert.ToUInt32((string)responseData["region_locx"]); uint locY = Convert.ToUInt32((string)responseData["region_locy"]); string externalHostName = (string)responseData["sim_ip"]; uint simPort = Convert.ToUInt32((string)responseData["sim_port"]); uint httpPort = Convert.ToUInt32((string)responseData["http_port"]); uint remotingPort = Convert.ToUInt32((string)responseData["remoting_port"]); string serverUri = (string)responseData["server_uri"]; UUID regionID = new UUID((string)responseData["region_UUID"]); string regionName = (string)responseData["region_name"]; byte access = Convert.ToByte((string)responseData["access"]); simData = RegionProfileData.Create(regionID, regionName, locX, locY, externalHostName, simPort, httpPort, remotingPort, serverUri, access); } return(simData); }
/// <summary> /// Informs a region about an Agent /// </summary> /// <param name="TalkingAbout">User to talk about</param> /// <param name="UserToUpdate">User we're sending this too (contains the region)</param> public void SendRegionPresenceUpdate(UserPresenceData TalkingAbout, UserPresenceData UserToUpdate) { // TODO: Fill in pertenant Presence Data from 'TalkingAbout' RegionProfileData whichRegion = new RegionProfileData(); if (lookupRegion) { handlerGetRegionData = OnGetRegionData; if (handlerGetRegionData != null) { whichRegion = handlerGetRegionData(UserToUpdate.regionData.regionHandle); } //RegionProfileData rp = RegionProfileData.RequestSimProfileData(UserToUpdate.regionData.regionHandle, gridserverurl, gridserversendkey, gridserverrecvkey); //whichRegion = rp; } else { whichRegion = UserToUpdate.regionData; } //whichRegion.httpServerURI if (whichRegion != null) { Hashtable PresenceParams = new Hashtable(); PresenceParams.Add("agent_id",TalkingAbout.agentData.AgentID.ToString()); PresenceParams.Add("notify_id",UserToUpdate.agentData.AgentID.ToString()); if (TalkingAbout.OnlineYN) PresenceParams.Add("status","TRUE"); else PresenceParams.Add("status","FALSE"); ArrayList SendParams = new ArrayList(); SendParams.Add(PresenceParams); m_log.InfoFormat("[PRESENCE]: Informing {0}@{1} at {2} about {3}", TalkingAbout.agentData.firstname + " " + TalkingAbout.agentData.lastname, whichRegion.regionName, whichRegion.httpServerURI, UserToUpdate.agentData.firstname + " " + UserToUpdate.agentData.lastname); // Send XmlRpcRequest RegionReq = new XmlRpcRequest("presence_update", SendParams); try { // XmlRpcResponse RegionResp = RegionReq.Send(whichRegion.httpServerURI, 6000); RegionReq.Send(whichRegion.httpServerURI, 6000); } catch (WebException) { m_log.WarnFormat("[INFORM]: failed notifying region {0} containing user {1} about {2}", whichRegion.regionName, UserToUpdate.agentData.firstname + " " + UserToUpdate.agentData.lastname, TalkingAbout.agentData.firstname + " " + TalkingAbout.agentData.lastname); } } else { m_log.Info("[PRESENCEUPDATER]: Region data was null skipping"); } handlerDone = OnDone; if (handlerDone != null) { handlerDone(this); } }
/// <summary> /// Request sim data based on arbitrary key/value /// </summary> private RegionProfileData RequestSimData(Uri gridserverUrl, string gridserverSendkey, string keyField, string keyValue) { Hashtable requestData = new Hashtable(); requestData[keyField] = keyValue; requestData["authkey"] = gridserverSendkey; ArrayList SendParams = new ArrayList(); SendParams.Add(requestData); string methodName = "simulator_data_request"; XmlRpcRequest GridReq = new XmlRpcRequest(methodName, SendParams); XmlRpcResponse GridResp = GridReq.Send(Util.XmlRpcRequestURI(gridserverUrl.ToString(), methodName), 5000); Hashtable responseData = (Hashtable)GridResp.Value; RegionProfileData simData = null; if (!responseData.ContainsKey("error")) { uint locX = Convert.ToUInt32((string)responseData["region_locx"]); uint locY = Convert.ToUInt32((string)responseData["region_locy"]); string externalHostName = (string)responseData["sim_ip"]; uint simPort = Convert.ToUInt32((string)responseData["sim_port"]); uint httpPort = Convert.ToUInt32((string)responseData["http_port"]); uint remotingPort = Convert.ToUInt32((string)responseData["remoting_port"]); UUID regionID = new UUID((string)responseData["region_UUID"]); string regionName = (string)responseData["region_name"]; byte access = Convert.ToByte((string)responseData["access"]); ProductRulesUse product = (ProductRulesUse)Convert.ToInt32(responseData["product"]); string outsideIp = null; if (responseData.ContainsKey("outside_ip")) { outsideIp = (string)responseData["outside_ip"]; } simData = RegionProfileData.Create(regionID, regionName, locX, locY, externalHostName, simPort, httpPort, remotingPort, access, product, outsideIp); } return(simData); }
public static RegionProfileData Create(UUID regionID, string regionName, uint locX, uint locY, string externalHostName, uint regionPort, uint httpPort, uint remotingPort, string serverUri, byte access) { RegionProfileData regionProfile; regionProfile = new RegionProfileData(); regionProfile.regionLocX = locX; regionProfile.regionLocY = locY; regionProfile.regionHandle = Utils.UIntsToLong((regionProfile.regionLocX * Constants.RegionSize), (regionProfile.regionLocY*Constants.RegionSize)); regionProfile.serverIP = externalHostName; regionProfile.serverPort = regionPort; regionProfile.httpPort = httpPort; regionProfile.remotingPort = remotingPort; regionProfile.serverURI = serverUri; regionProfile.httpServerURI = "http://" + externalHostName + ":" + httpPort + "/"; regionProfile.UUID = regionID; regionProfile.regionName = regionName; regionProfile.maturity = access; return regionProfile; }
public static RegionProfileData Create(UUID regionID, string regionName, uint locX, uint locY, string externalHostName, uint regionPort, uint httpPort, uint remotingPort, byte access, ProductRulesUse product, string outsideIP) { RegionProfileData regionProfile; regionProfile = new RegionProfileData(); regionProfile.regionLocX = locX; regionProfile.regionLocY = locY; regionProfile.regionHandle = Utils.UIntsToLong((regionProfile.regionLocX * Constants.RegionSize), (regionProfile.regionLocY * Constants.RegionSize)); regionProfile.serverHostName = externalHostName; regionProfile.serverPort = regionPort; regionProfile.httpPort = httpPort; regionProfile.remotingPort = remotingPort; regionProfile.UUID = regionID; regionProfile.regionName = regionName; regionProfile.maturity = access; regionProfile.product = product; regionProfile._outsideIp = outsideIP; return(regionProfile); }
public abstract DataResponse AddProfile(RegionProfileData profile);
/// <summary> /// Loads the grid's own RegionProfileData object with data from the XMLRPC simulator_login request from a region /// </summary> /// <param name="requestData"></param> /// <returns></returns> private RegionProfileData RegionFromRequest(Hashtable requestData) { RegionProfileData sim; sim = new RegionProfileData(); sim.UUID = new UUID((string)requestData["UUID"]); sim.originUUID = new UUID((string)requestData["originUUID"]); sim.regionRecvKey = String.Empty; sim.regionSendKey = String.Empty; if (requestData.ContainsKey("region_secret")) { string regionsecret = (string)requestData["region_secret"]; if (regionsecret.Length > 0) sim.regionSecret = regionsecret; else sim.regionSecret = m_config.SimRecvKey; } else { sim.regionSecret = m_config.SimRecvKey; } sim.regionDataURI = String.Empty; sim.regionAssetURI = m_config.DefaultAssetServer; sim.regionAssetRecvKey = m_config.AssetRecvKey; sim.regionAssetSendKey = m_config.AssetSendKey; sim.regionUserURI = m_config.DefaultUserServer; sim.regionUserSendKey = m_config.UserSendKey; sim.regionUserRecvKey = m_config.UserRecvKey; sim.serverHostName = (string)requestData["sim_ip"]; sim.serverPort = Convert.ToUInt32((string)requestData["sim_port"]); sim.httpPort = Convert.ToUInt32((string)requestData["http_port"]); sim.remotingPort = Convert.ToUInt32((string)requestData["remoting_port"]); sim.regionLocX = Convert.ToUInt32((string)requestData["region_locx"]); sim.regionLocY = Convert.ToUInt32((string)requestData["region_locy"]); sim.regionLocZ = 0; UUID textureID; if (UUID.TryParse((string)requestData["map-image-id"], out textureID)) { sim.regionMapTextureID = textureID; } // part of an initial brutish effort to provide accurate information (as per the xml region spec) // wrt the ownership of a given region // the (very bad) assumption is that this value is being read and handled inconsistently or // not at all. Current strategy is to put the code in place to support the validity of this information // and to roll forward debugging any issues from that point // // this particular section of the mod attempts to receive a value from the region's xml file by way of // OSG1GridServices for the region's owner sim.owner_uuid = (UUID)(string)requestData["master_avatar_uuid"]; try { sim.regionRecvKey = (string)requestData["recvkey"]; sim.regionSendKey = (string)requestData["authkey"]; } catch (KeyNotFoundException) { } sim.regionHandle = Utils.UIntsToLong((sim.regionLocX * Constants.RegionSize), (sim.regionLocY * Constants.RegionSize)); sim.regionName = (string)requestData["sim_name"]; if (requestData.ContainsKey("product")) sim.product = (ProductRulesUse)Convert.ToInt32(requestData["product"]); else sim.product = ProductRulesUse.UnknownUse; if (requestData.ContainsKey("outside_ip")) sim.OutsideIP = (string)requestData["outside_ip"]; try { sim.maturity = Convert.ToUInt32((string)requestData["maturity"]); } catch (KeyNotFoundException) { //older region not providing this key - so default to Mature sim.maturity = 1; } return sim; }
/// <summary> /// Construct a successful response to a simulator's login attempt. /// </summary> /// <param name="sim"></param> /// <returns></returns> private XmlRpcResponse CreateLoginResponse(RegionProfileData sim) { XmlRpcResponse response = new XmlRpcResponse(); Hashtable responseData = new Hashtable(); response.Value = responseData; ArrayList SimNeighboursData = GetSimNeighboursData(sim); responseData["UUID"] = sim.UUID.ToString(); responseData["region_locx"] = sim.regionLocX.ToString(); responseData["region_locy"] = sim.regionLocY.ToString(); responseData["regionname"] = sim.regionName; responseData["estate_id"] = "1"; responseData["neighbours"] = SimNeighboursData; responseData["sim_ip"] = sim.serverHostName; responseData["sim_port"] = sim.serverPort.ToString(); responseData["asset_url"] = sim.regionAssetURI; responseData["asset_sendkey"] = sim.regionAssetSendKey; responseData["asset_recvkey"] = sim.regionAssetRecvKey; responseData["user_url"] = sim.regionUserURI; responseData["user_sendkey"] = sim.regionUserSendKey; responseData["user_recvkey"] = sim.regionUserRecvKey; responseData["authkey"] = sim.regionSecret; responseData["product"] = Convert.ToInt32(sim.product).ToString(); if (sim.OutsideIP != null) responseData["outside_ip"] = sim.OutsideIP; // New! If set, use as URL to local sim storage (ie http://remotehost/region.Yap) responseData["data_uri"] = sim.regionDataURI; responseData["allow_forceful_banlines"] = m_config.AllowForcefulBanlines; // Instead of sending a multitude of message servers to the registering sim // we should probably be sending a single one and parhaps it's backup // that has responsibility over routing it's messages. // The Sim won't be contacting us again about any of the message server stuff during it's time up. responseData["messageserver_count"] = 0; // IGridMessagingModule messagingModule; // if (m_gridCore.TryGet<IGridMessagingModule>(out messagingModule)) //{ if (m_messagingServerMapper != null) { List<MessageServerInfo> messageServers = m_messagingServerMapper.GetMessageServersList(); responseData["messageserver_count"] = messageServers.Count; for (int i = 0; i < messageServers.Count; i++) { responseData["messageserver_uri" + i] = messageServers[i].URI; responseData["messageserver_sendkey" + i] = messageServers[i].sendkey; responseData["messageserver_recvkey" + i] = messageServers[i].recvkey; } } return response; }
/// <summary> /// Checks that the new region data is valid. /// /// Currently, this means checking that the keys passed in by the new region /// match those in the grid server's configuration. /// </summary> /// /// <param name="sim"></param> /// <exception cref="LoginException">Thrown if region login failed</exception> protected virtual void ValidateNewRegionKeys(RegionProfileData sim) { if (!(sim.regionRecvKey == m_config.SimSendKey && sim.regionSendKey == m_config.SimRecvKey)) { throw new LoginException( String.Format( "Authentication failed when trying to login new region {0} at location {1} {2}" + " with the region's send key {3} (expected {4}) and the region's receive key {5} (expected {6})", sim.regionName, sim.regionLocX, sim.regionLocY, sim.regionSendKey, m_config.SimRecvKey, sim.regionRecvKey, m_config.SimSendKey), "The keys required to login your region did not match your existing region keys. Please check your grid send and receive keys."); } }
public static RegionProfileData Create(UUID regionID, string regionName, uint locX, uint locY, string externalHostName, uint regionPort, uint httpPort, uint remotingPort, byte access, ProductRulesUse product, string outsideIP) { RegionProfileData regionProfile; regionProfile = new RegionProfileData(); regionProfile.regionLocX = locX; regionProfile.regionLocY = locY; regionProfile.regionHandle = Utils.UIntsToLong((regionProfile.regionLocX * Constants.RegionSize), (regionProfile.regionLocY*Constants.RegionSize)); regionProfile.serverHostName = externalHostName; regionProfile.serverPort = regionPort; regionProfile.httpPort = httpPort; regionProfile.remotingPort = remotingPort; regionProfile.UUID = regionID; regionProfile.regionName = regionName; regionProfile.maturity = access; regionProfile.product = product; regionProfile._outsideIp = outsideIP; return regionProfile; }
public abstract DataResponse UpdateProfile(RegionProfileData profile);
private RegionProfileData GridRegionToRegionProfile(GridRegion region) { RegionProfileData rprofile = new RegionProfileData(); rprofile.httpPort = region.HttpPort; rprofile.httpServerURI = region.ServerURI; rprofile.regionLocX = (uint)(region.RegionLocX / Constants.RegionSize); rprofile.regionLocY = (uint)(region.RegionLocY / Constants.RegionSize); rprofile.RegionName = region.RegionName; rprofile.ServerHttpPort = region.HttpPort; rprofile.ServerIP = region.ExternalHostName; rprofile.ServerPort = (uint)region.ExternalEndPoint.Port; rprofile.Uuid = region.RegionID; return rprofile; }
/// <summary> /// Creates or updates a sim via a REST Method Request /// BROKEN with SQL Update /// </summary> /// <param name="request"></param> /// <param name="path"></param> /// <param name="param"></param> /// <param name="httpRequest">HTTP request header object</param> /// <param name="httpResponse">HTTP response header object</param> /// <returns>"OK" or an error</returns> public string RestSetSimMethod(string request, string path, string param, OSHttpRequest httpRequest, OSHttpResponse httpResponse) { m_log.Info("Processing region update via REST method"); RegionProfileData theSim; theSim = m_gridDBService.GetRegion(new UUID(param)); if (theSim == null) { theSim = new RegionProfileData(); UUID UUID = new UUID(param); theSim.UUID = UUID; theSim.regionRecvKey = m_config.SimRecvKey; } XmlDocument doc = new XmlDocument(); doc.LoadXml(request); XmlNode rootnode = doc.FirstChild; XmlNode authkeynode = rootnode.ChildNodes[0]; if (authkeynode.Name != "authkey") { return "ERROR! bad XML - expected authkey tag"; } XmlNode simnode = rootnode.ChildNodes[1]; if (simnode.Name != "sim") { return "ERROR! bad XML - expected sim tag"; } //theSim.regionSendKey = Cfg; theSim.regionRecvKey = m_config.SimRecvKey; theSim.regionSendKey = m_config.SimSendKey; theSim.regionSecret = m_config.SimRecvKey; theSim.regionDataURI = String.Empty; theSim.regionAssetURI = m_config.DefaultAssetServer; theSim.regionAssetRecvKey = m_config.AssetRecvKey; theSim.regionAssetSendKey = m_config.AssetSendKey; theSim.regionUserURI = m_config.DefaultUserServer; theSim.regionUserSendKey = m_config.UserSendKey; theSim.regionUserRecvKey = m_config.UserRecvKey; for (int i = 0; i < simnode.ChildNodes.Count; i++) { switch (simnode.ChildNodes[i].Name) { case "regionname": theSim.regionName = simnode.ChildNodes[i].InnerText; break; case "sim_ip": theSim.serverHostName = simnode.ChildNodes[i].InnerText; break; case "sim_port": theSim.serverPort = Convert.ToUInt32(simnode.ChildNodes[i].InnerText); break; case "region_locx": theSim.regionLocX = Convert.ToUInt32((string)simnode.ChildNodes[i].InnerText); theSim.regionHandle = Utils.UIntsToLong((theSim.regionLocX * Constants.RegionSize), (theSim.regionLocY * Constants.RegionSize)); break; case "region_locy": theSim.regionLocY = Convert.ToUInt32((string)simnode.ChildNodes[i].InnerText); theSim.regionHandle = Utils.UIntsToLong((theSim.regionLocX * Constants.RegionSize), (theSim.regionLocY * Constants.RegionSize)); break; } } bool requirePublic = false; bool requireValid = true; if (requirePublic && (theSim.serverHostName.StartsWith("172.16") || theSim.serverHostName.StartsWith("192.168") || theSim.serverHostName.StartsWith("10.") || theSim.serverHostName.StartsWith("0.") || theSim.serverHostName.StartsWith("255."))) { return "ERROR! Servers must register with public addresses."; } if (requireValid && (theSim.serverHostName.StartsWith("0.") || theSim.serverHostName.StartsWith("255."))) { return "ERROR! 0.*.*.* / 255.*.*.* Addresses are invalid, please check your server config and try again"; } try { m_log.Info("[DATA]: " + "Updating / adding via " + m_gridDBService.GetNumberOfPlugins() + " storage provider(s) registered."); return m_gridDBService.CheckReservations(theSim, authkeynode); } catch (Exception e) { return "ERROR! Could not save to database! (" + e.ToString() + ")"; } }
/// <summary> /// Prepare a login to the given region. This involves both telling the region to expect a connection /// and appropriately customising the response to the user. /// </summary> /// <param name="regionInfo"></param> /// <param name="user"></param> /// <param name="response"></param> /// <returns>true if the region was successfully contacted, false otherwise</returns> private bool PrepareLoginToRegion(RegionProfileData regionInfo, UserProfileData user, LoginResponse response, IPEndPoint remoteClient) { try { response.SimAddress = Util.GetHostFromURL(regionInfo.serverURI).ToString(); response.SimPort = uint.Parse(regionInfo.serverURI.Split(new char[] { '/', ':' })[4]); response.RegionX = regionInfo.regionLocX; response.RegionY = regionInfo.regionLocY; string capsPath = CapsUtil.GetRandomCapsObjectPath(); // Adam's working code commented for now -- Diva 5/25/2009 //// For NAT ////string host = NetworkUtil.GetHostFor(remoteClient.Address, regionInfo.ServerIP); //string host = response.SimAddress; //// TODO: This doesnt support SSL. -Adam //string serverURI = "http://" + host + ":" + regionInfo.ServerPort; //response.SeedCapability = serverURI + CapsUtil.GetCapsSeedPath(capsPath); // Take off trailing / so that the caps path isn't //CAPS/someUUID string uri = regionInfo.httpServerURI.Trim(new char[] { '/' }); response.SeedCapability = uri + CapsUtil.GetCapsSeedPath(capsPath); // Notify the target of an incoming user m_log.InfoFormat( "[LOGIN]: Telling {0} @ {1},{2} ({3}) to prepare for client connection", regionInfo.regionName, response.RegionX, response.RegionY, regionInfo.httpServerURI); // Update agent with target sim user.CurrentAgent.Region = regionInfo.UUID; user.CurrentAgent.Handle = regionInfo.regionHandle; // Prepare notification Hashtable loginParams = new Hashtable(); loginParams["session_id"] = user.CurrentAgent.SessionID.ToString(); loginParams["secure_session_id"] = user.CurrentAgent.SecureSessionID.ToString(); loginParams["firstname"] = user.FirstName; loginParams["lastname"] = user.SurName; loginParams["agent_id"] = user.ID.ToString(); loginParams["circuit_code"] = (Int32)Convert.ToUInt32(response.CircuitCode); loginParams["startpos_x"] = user.CurrentAgent.Position.X.ToString(); loginParams["startpos_y"] = user.CurrentAgent.Position.Y.ToString(); loginParams["startpos_z"] = user.CurrentAgent.Position.Z.ToString(); loginParams["regionhandle"] = user.CurrentAgent.Handle.ToString(); loginParams["caps_path"] = capsPath; // Get appearance AvatarAppearance appearance = m_userManager.GetUserAppearance(user.ID); if (appearance != null) { loginParams["appearance"] = appearance.ToHashTable(); m_log.DebugFormat("[LOGIN]: Found appearance for {0} {1}", user.FirstName, user.SurName); } else { m_log.DebugFormat("[LOGIN]: Appearance not for {0} {1}. Creating default.", user.FirstName, user.SurName); appearance = new AvatarAppearance(user.ID); loginParams["appearance"] = appearance.ToHashTable(); } ArrayList SendParams = new ArrayList(); SendParams.Add(loginParams); // Send XmlRpcRequest GridReq = new XmlRpcRequest("expect_user", SendParams); XmlRpcResponse GridResp = GridReq.Send(regionInfo.httpServerURI, 6000); if (!GridResp.IsFault) { bool responseSuccess = true; if (GridResp.Value != null) { Hashtable resp = (Hashtable)GridResp.Value; if (resp.ContainsKey("success")) { if ((string)resp["success"] == "FALSE") { responseSuccess = false; } } } if (responseSuccess) { handlerUserLoggedInAtLocation = OnUserLoggedInAtLocation; if (handlerUserLoggedInAtLocation != null) { handlerUserLoggedInAtLocation(user.ID, user.CurrentAgent.SessionID, user.CurrentAgent.Region, user.CurrentAgent.Handle, user.CurrentAgent.Position.X, user.CurrentAgent.Position.Y, user.CurrentAgent.Position.Z, user.FirstName, user.SurName); } } else { m_log.ErrorFormat("[LOGIN]: Region responded that it is not available to receive clients"); return false; } } else { m_log.ErrorFormat("[LOGIN]: XmlRpc request to region failed with message {0}, code {1} ", GridResp.FaultString, GridResp.FaultCode); return false; } } catch (Exception e) { m_log.ErrorFormat("[LOGIN]: Region not available for login, {0}", e); return false; } return true; }
/// <summary> /// Get RegionProfileData from the GridServer. /// We'll cache this information in GetRegionInfo and use it for presence updates /// </summary> /// <param name="regionHandle"></param> /// <returns></returns> public RegionProfileData RequestRegionInfo(ulong regionHandle) { RegionProfileData regionProfile = null; try { Hashtable requestData = new Hashtable(); requestData["region_handle"] = regionHandle.ToString(); requestData["authkey"] = m_cfg.GridSendKey; ArrayList SendParams = new ArrayList(); SendParams.Add(requestData); string methodName = "simulator_data_request"; XmlRpcRequest GridReq = new XmlRpcRequest(methodName, SendParams); XmlRpcResponse GridResp = GridReq.Send(Util.XmlRpcRequestURI(m_cfg.GridServerURL, methodName), 3000); Hashtable responseData = (Hashtable)GridResp.Value; if (responseData.ContainsKey("error")) { m_log.Error("[GRID]: error received from grid server" + responseData["error"]); return null; } uint regX = Convert.ToUInt32((string)responseData["region_locx"]); uint regY = Convert.ToUInt32((string)responseData["region_locy"]); regionProfile = new RegionProfileData(); regionProfile.serverHostName = (string)responseData["sim_ip"]; regionProfile.serverPort = Convert.ToUInt16((string)responseData["sim_port"]); regionProfile.httpPort = (uint)Convert.ToInt32((string)responseData["http_port"]); regionProfile.regionHandle = Utils.UIntsToLong((regX * Constants.RegionSize), (regY * Constants.RegionSize)); regionProfile.regionLocX = regX; regionProfile.regionLocY = regY; regionProfile.remotingPort = Convert.ToUInt32((string)responseData["remoting_port"]); regionProfile.UUID = new UUID((string)responseData["region_UUID"]); regionProfile.regionName = (string)responseData["region_name"]; if (requestData.ContainsKey("product")) regionProfile.product = (ProductRulesUse)Convert.ToInt32(requestData["product"]); else regionProfile.product = ProductRulesUse.UnknownUse; if (requestData.ContainsKey("outside_ip")) regionProfile.OutsideIP = (string)responseData["outside_ip"]; } catch (WebException e) { m_log.ErrorFormat("[GRID]: Region lookup failed for {0}: {1} ", regionHandle.ToString(), e.Message); } return regionProfile; }
/// <summary> /// Checks that it's valid to replace the existing region data with new data /// /// Currently, this means ensure that the keys passed in by the new region /// match those in the original region. (XXX Is this correct? Shouldn't we simply check /// against the keys in the current configuration?) /// </summary> /// <param name="sim"></param> /// <returns></returns> protected virtual void ValidateOverwriteKeys(RegionProfileData sim, RegionProfileData existingSim) { if (!(existingSim.regionRecvKey == sim.regionRecvKey && existingSim.regionSendKey == sim.regionSendKey)) { throw new LoginException( String.Format( "Authentication failed when trying to login existing region {0} at location {1} {2} currently occupied by {3}" + " with the region's send key {4} (expected {5}) and the region's receive key {6} (expected {7})", sim.regionName, sim.regionLocX, sim.regionLocY, existingSim.regionName, sim.regionSendKey, existingSim.regionSendKey, sim.regionRecvKey, existingSim.regionRecvKey), "The keys required to login your region did not match the grid server keys. Please check your grid send and receive keys."); } }
public DataResponse AddUpdateRegion(RegionProfileData sim, RegionProfileData existingSim) { DataResponse insertResponse = DataResponse.RESPONSE_ERROR; foreach (IGridDataPlugin plugin in _plugins) { try { if (existingSim == null) { insertResponse = plugin.AddProfile(sim); } else { insertResponse = plugin.UpdateProfile(sim); } } catch (Exception e) { m_log.Warn("[LOGIN END]: " + "Unable to login region " + sim.ToString() + " via " + plugin.Name); m_log.Warn("[LOGIN END]: " + e.ToString()); } } return insertResponse; }
/// <summary> /// Check that a region's http uri is externally contactable. /// </summary> /// <param name="sim"></param> /// <exception cref="LoginException">Thrown if the region is not contactable</exception> protected virtual void ValidateRegionContactable(RegionProfileData sim) { string regionStatusUrl = String.Format("{0}{1}", sim.httpServerURI, "simstatus/"); string regionStatusResponse; using (RestClient rc = new RestClient(regionStatusUrl)) { rc.RequestMethod = "GET"; m_log.DebugFormat("[LOGIN]: Contacting {0} for status of region {1}", regionStatusUrl, sim.regionName); try { Stream rs = rc.Request(); StreamReader sr = new StreamReader(rs); regionStatusResponse = sr.ReadToEnd(); sr.Close(); } catch (Exception e) { throw new LoginException( String.Format("Region status request to {0} failed", regionStatusUrl), String.Format( "The grid service could not contact the http url {0} at your region. Please make sure this url is reachable by the grid service", regionStatusUrl), e); } if (!regionStatusResponse.Equals("OK")) { throw new LoginException( String.Format( "Region {0} at {1} returned status response {2} rather than {3}", sim.regionName, regionStatusUrl, regionStatusResponse, "OK"), String.Format( "When the grid service asked for the status of your region, it received the response {0} rather than {1}. Please check your status", regionStatusResponse, "OK")); } } }
public string CheckReservations(RegionProfileData theSim, XmlNode authkeynode) { foreach (IGridDataPlugin plugin in _plugins) { try { //Check reservations ReservationData reserveData = plugin.GetReservationAtPoint(theSim.regionLocX, theSim.regionLocY); if ((reserveData != null && reserveData.gridRecvKey == theSim.regionRecvKey) || (reserveData == null && authkeynode.InnerText != theSim.regionRecvKey)) { plugin.AddProfile(theSim); m_log.Info("[grid]: New sim added to grid (" + theSim.regionName + ")"); logToDB(theSim.ToString(), "RestSetSimMethod", String.Empty, 5, "Region successfully updated and connected to grid."); } else { m_log.Warn("[grid]: " + "Unable to update region (RestSetSimMethod): Incorrect reservation auth key."); // Wanted: " + reserveData.gridRecvKey + ", Got: " + theSim.regionRecvKey + "."); return "Unable to update region (RestSetSimMethod): Incorrect auth key."; } } catch (Exception e) { m_log.Warn("[GRID]: GetRegionPlugin Handle " + plugin.Name + " unable to add new sim: " + e.ToString()); } } return "OK"; }
private ArrayList GetSimNeighboursData(RegionProfileData sim) { ArrayList SimNeighboursData = new ArrayList(); RegionProfileData neighbour; Hashtable NeighbourBlock; //First use the fast method. (not implemented in SQLLite) List<RegionProfileData> neighbours = m_gridDBService.GetRegions(sim.regionLocX - 1, sim.regionLocY - 1, sim.regionLocX + 1, sim.regionLocY + 1); if (neighbours.Count > 0) { foreach (RegionProfileData aSim in neighbours) { NeighbourBlock = new Hashtable(); NeighbourBlock["sim_ip"] = aSim.serverHostName; NeighbourBlock["sim_port"] = aSim.serverPort.ToString(); NeighbourBlock["region_locx"] = aSim.regionLocX.ToString(); NeighbourBlock["region_locy"] = aSim.regionLocY.ToString(); NeighbourBlock["UUID"] = aSim.ToString(); NeighbourBlock["regionHandle"] = aSim.regionHandle.ToString(); if (aSim.UUID != sim.UUID) { SimNeighboursData.Add(NeighbourBlock); } } } else { for (int x = -1; x < 2; x++) { for (int y = -1; y < 2; y++) { if ( m_gridDBService.GetRegion( Utils.UIntsToLong((uint)((sim.regionLocX + x) * Constants.RegionSize), (uint)(sim.regionLocY + y) * Constants.RegionSize)) != null) { neighbour = m_gridDBService.GetRegion( Utils.UIntsToLong((uint)((sim.regionLocX + x) * Constants.RegionSize), (uint)(sim.regionLocY + y) * Constants.RegionSize)); NeighbourBlock = new Hashtable(); NeighbourBlock["sim_ip"] = neighbour.serverHostName; NeighbourBlock["sim_port"] = neighbour.serverPort.ToString(); NeighbourBlock["region_locx"] = neighbour.regionLocX.ToString(); NeighbourBlock["region_locy"] = neighbour.regionLocY.ToString(); NeighbourBlock["UUID"] = neighbour.UUID.ToString(); NeighbourBlock["regionHandle"] = neighbour.regionHandle.ToString(); if (neighbour.UUID != sim.UUID) SimNeighboursData.Add(NeighbourBlock); } } } } return SimNeighboursData; }
public abstract DataResponse StoreProfile(RegionProfileData profile);
/// <summary> /// Prepare a login to the given region. This involves both telling the region to expect a connection /// and appropriately customising the response to the user. /// </summary> /// <param name="regionInfo"></param> /// <param name="user"></param> /// <param name="response"></param> /// <returns>true if the region was successfully contacted, false otherwise</returns> private bool PrepareLoginToRegion(RegionProfileData regionInfo, UserProfileData user, LoginResponse response, string clientVersion) { string regionName = regionInfo.regionName; bool success = false; try { lock (_LastRegionFailure) { if (_LastRegionFailure.ContainsKey(regionName)) { // region failed previously RegionLoginFailure failure = _LastRegionFailure[regionName]; if (failure.IsExpired()) { // failure has expired, retry this region again _LastRegionFailure.Remove(regionName); // m_log.WarnFormat("[LOGIN]: Region '{0}' was previously down, retrying.", regionName); } else { if (failure.IsFailed()) { // m_log.WarnFormat("[LOGIN]: Region '{0}' was recently down, skipping.", regionName); return false; // within 5 minutes, don't repeat attempt } // m_log.WarnFormat("[LOGIN]: Region '{0}' was recently down but under threshold, retrying.", regionName); } } } response.SimAddress = regionInfo.OutsideIpOrResolvedHostname; response.SimPort = regionInfo.serverPort; response.RegionX = regionInfo.regionLocX; response.RegionY = regionInfo.regionLocY; string capsPath = CapsUtil.GetRandomCapsObjectPath(); response.SeedCapability = CapsUtil.GetFullCapsSeedURL(regionInfo.httpServerURI, capsPath); // Notify the target of an incoming user m_log.InfoFormat( "[LOGIN]: Telling {0} @ {1},{2} ({3}) to prepare for client connection", regionInfo.regionName, response.RegionX, response.RegionY, response.SeedCapability); // Update agent with target sim user.CurrentAgent.Region = regionInfo.UUID; user.CurrentAgent.Handle = regionInfo.regionHandle; // Prepare notification Hashtable loginParams = new Hashtable(); loginParams["session_id"] = user.CurrentAgent.SessionID.ToString(); loginParams["secure_session_id"] = user.CurrentAgent.SecureSessionID.ToString(); loginParams["firstname"] = user.FirstName; loginParams["lastname"] = user.SurName; loginParams["agent_id"] = user.ID.ToString(); loginParams["circuit_code"] = (Int32)Convert.ToUInt32(response.CircuitCode); loginParams["startpos_x"] = user.CurrentAgent.Position.X.ToString(); loginParams["startpos_y"] = user.CurrentAgent.Position.Y.ToString(); loginParams["startpos_z"] = user.CurrentAgent.Position.Z.ToString(); loginParams["regionhandle"] = user.CurrentAgent.Handle.ToString(); loginParams["caps_path"] = capsPath; loginParams["client_version"] = clientVersion; // Get appearance AvatarAppearance appearance = m_userManager.GetUserAppearance(user.ID); if (appearance != null) { loginParams["appearance"] = appearance.ToHashTable(); m_log.DebugFormat("[LOGIN]: Found appearance version {0} for {1} {2}", appearance.Serial, user.FirstName, user.SurName); } else { m_log.DebugFormat("[LOGIN]: Appearance not for {0} {1}. Creating default.", user.FirstName, user.SurName); appearance = new AvatarAppearance(user.ID); } // Tell the client the COF version so it can use cached appearance if it matches. response.CofVersion = appearance.Serial.ToString(); loginParams["cof_version"] = response.CofVersion; ArrayList SendParams = new ArrayList(); SendParams.Add(loginParams); SendParams.Add(m_config.GridSendKey); // Send const string METHOD_NAME = "expect_user"; XmlRpcRequest GridReq = new XmlRpcRequest(METHOD_NAME, SendParams); XmlRpcResponse GridResp = GridReq.Send(Util.XmlRpcRequestURI(regionInfo.httpServerURI, METHOD_NAME), 6000); if (!GridResp.IsFault) { bool responseSuccess = true; if (GridResp.Value != null) { Hashtable resp = (Hashtable)GridResp.Value; if (resp.ContainsKey("success")) { if ((string)resp["success"] == "FALSE") { responseSuccess = false; } } if (!responseSuccess) { if (resp.ContainsKey("reason")) { response.ErrorMessage = resp["reason"].ToString(); } } } if (responseSuccess) { handlerUserLoggedInAtLocation = OnUserLoggedInAtLocation; if (handlerUserLoggedInAtLocation != null) { handlerUserLoggedInAtLocation(user.ID, user.CurrentAgent.SessionID, user.CurrentAgent.Region, user.CurrentAgent.Handle, user.CurrentAgent.Position.X, user.CurrentAgent.Position.Y, user.CurrentAgent.Position.Z, user.FirstName, user.SurName); } success = true; } else { m_log.ErrorFormat("[LOGIN]: Region responded that it is not available to receive clients"); } } else { m_log.ErrorFormat("[LOGIN]: XmlRpc request to region failed with message {0}, code {1} ", GridResp.FaultString, GridResp.FaultCode); } } catch (Exception e) { m_log.ErrorFormat("[LOGIN]: Region not available for login, {0}", e); } lock (_LastRegionFailure) { if (_LastRegionFailure.ContainsKey(regionName)) { RegionLoginFailure failure = _LastRegionFailure[regionName]; if (success) { // Success, so if we've been storing this as a failed region, remove that from the failed list. m_log.WarnFormat("[LOGIN]: Region '{0}' recently down, is available again.", regionName); _LastRegionFailure.Remove(regionName); } else { // Region not available, update cache with incremented count. failure.AddFailure(); // m_log.WarnFormat("[LOGIN]: Region '{0}' is still down ({1}).", regionName, failure.Count); } } else { if (!success) { // Region not available, cache that temporarily. m_log.WarnFormat("[LOGIN]: Region '{0}' is down, marking.", regionName); _LastRegionFailure[regionName] = new RegionLoginFailure(); } } } return success; }
/// <summary> /// Get RegionProfileData from the GridServer. /// We'll cache this information in GetRegionInfo and use it for presence updates /// </summary> /// <param name="regionHandle"></param> /// <returns></returns> public RegionProfileData RequestRegionInfo(ulong regionHandle) { RegionProfileData regionProfile = null; try { Hashtable requestData = new Hashtable(); requestData["region_handle"] = regionHandle.ToString(); requestData["authkey"] = m_cfg.GridSendKey; ArrayList SendParams = new ArrayList(); SendParams.Add(requestData); XmlRpcRequest GridReq = new XmlRpcRequest("simulator_data_request", SendParams); XmlRpcResponse GridResp = GridReq.Send(m_cfg.GridServerURL, 3000); Hashtable responseData = (Hashtable)GridResp.Value; if (responseData.ContainsKey("error")) { m_log.Error("[GRID]: error received from grid server" + responseData["error"]); return null; } uint regX = Convert.ToUInt32((string)responseData["region_locx"]); uint regY = Convert.ToUInt32((string)responseData["region_locy"]); string internalIpStr = (string)responseData["sim_ip"]; regionProfile = new RegionProfileData(); regionProfile.httpPort = (uint)Convert.ToInt32((string)responseData["http_port"]); regionProfile.httpServerURI = "http://" + internalIpStr + ":" + regionProfile.httpPort + "/"; regionProfile.regionHandle = Utils.UIntsToLong((regX * Constants.RegionSize), (regY * Constants.RegionSize)); regionProfile.regionLocX = regX; regionProfile.regionLocY = regY; regionProfile.remotingPort = Convert.ToUInt32((string)responseData["remoting_port"]); regionProfile.UUID = new UUID((string)responseData["region_UUID"]); regionProfile.regionName = (string)responseData["region_name"]; } catch (WebException) { m_log.Error("[GRID]: " + "Region lookup failed for: " + regionHandle.ToString() + " - Is the GridServer down?"); } return regionProfile; }