protected virtual void GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) { List <MapBlockData> mapBlocks = new List <MapBlockData>(); List <GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, (minX - 4) * (int)Constants.RegionSize, (maxX + 4) * (int)Constants.RegionSize, (minY - 4) * (int)Constants.RegionSize, (maxY + 4) * (int)Constants.RegionSize); foreach (GridRegion r in regions) { MapBlockData block = new MapBlockData(); MapBlockFromGridRegion(block, r); mapBlocks.Add(block); } remoteClient.SendMapBlock(mapBlocks, flag); }
protected MapBlockData TerrainBlockFromGridRegion(GridRegion r) { MapBlockData block = new MapBlockData(); if (r == null) { block.Access = (byte)SimAccess.Down; block.MapImageID = UUID.Zero; return(block); } block.Access = r.Access; block.MapImageID = r.TerrainMapImage; block.Name = r.RegionName; block.X = (ushort)(r.RegionLocX / Constants.RegionSize); block.Y = (ushort)(r.RegionLocY / Constants.RegionSize); return(block); }
private void AddFinalBlock(List <MapBlockData> blocks, string name) { // final block, closing the search result MapBlockData data = new MapBlockData() { Agents = 0, Access = (byte)SimAccess.NonExistent, MapImageId = UUID.Zero, Name = name, RegionFlags = 0, WaterHeight = 0, // not used X = 0, Y = 0 }; blocks.Add(data); }
protected MapBlockData SearchMapBlockFromGridRegion(GridRegion r) { MapBlockData block = new MapBlockData(); block.Access = r.Access; if ((r.Access & (byte)SimAccess.Down) == (byte)SimAccess.Down) { block.Name = r.RegionName + " (offline)"; } else { block.Name = r.RegionName; } block.MapImageID = r.TerrainImage; block.Name = r.RegionName; block.X = (ushort)(r.RegionLocX / Constants.RegionSize); block.Y = (ushort)(r.RegionLocY / Constants.RegionSize); return(block); }
//根据状态刷新(位置) public void UpdateMoveState() { if (BattleState == BATTLE_STATE.MOVE && MoveDir != MOVE_DIR.NONE) { this.ChangeRotate(CharaDefine.GetDirVec(MoveDir)); List <Vector3> list = CharaDefine.GetDirMoveVecs(MoveDir); for (int i = 0; i < list.Count; i++) { bool isMove = false; _hitPos = MovePos + list[i] * Speed; _mapBlockData = MapManager.GetInstance().GetCurMapBlock(_hitPos); if (null != _mapBlockData) { //草丛判断 if (_mapBlockData.type == eMapBlockType.Hide) { // GrassId = int.Parse(_mapBlockData.param); } else { GrassId = -1; } //碰撞判断 if (_mapBlockData.type != eMapBlockType.Collect) { MovePos = _hitPos; isMove = true; } } else { MovePos = _hitPos; GrassId = -1; isMove = true; } if (isMove) { return; } } } }
/// <summary> /// /// </summary> /// <param name="minX"></param> /// <param name="minY"></param> /// <param name="maxX"></param> /// <param name="maxY"></param> /// <returns></returns> public List <MapBlockData> RequestNeighbourMapBlocks(int minX, int minY, int maxX, int maxY) { int temp = 0; if (minX > maxX) { temp = minX; minX = maxX; maxX = temp; } if (minY > maxY) { temp = minY; minY = maxY; maxY = temp; } Hashtable respData = MapBlockQuery(minX, minY, maxX, maxY); List <MapBlockData> neighbours = new List <MapBlockData>(); foreach (ArrayList a in respData.Values) { foreach (Hashtable n in a) { MapBlockData neighbour = new MapBlockData(); neighbour.X = Convert.ToUInt16(n["x"]); neighbour.Y = Convert.ToUInt16(n["y"]); neighbour.Name = (string)n["name"]; neighbour.Access = Convert.ToByte(n["access"]); neighbour.RegionFlags = Convert.ToUInt32(n["region-flags"]); neighbour.WaterHeight = Convert.ToByte(n["water-height"]); neighbour.MapImageId = new UUID((string)n["map-image-id"]); neighbours.Add(neighbour); } } return(neighbours); }
private void FillInMap(List <MapBlockData> mapBlocks, int minX, int minY, int maxX, int maxY) { for (int x = minX; x <= maxX; x++) { for (int y = minY; y <= maxY; y++) { MapBlockData mblock = mapBlocks.Find(delegate(MapBlockData mb) { return((mb.X == x) && (mb.Y == y)); }); if (mblock == null) { mblock = new MapBlockData(); mblock.X = (ushort)x; mblock.Y = (ushort)y; mblock.Name = ""; mblock.Access = 254; // means 'simulator is offline'. We need this because the viewer ignores 255's mblock.MapImageId = UUID.Zero; mapBlocks.Add(mblock); } } } }
private void FillInMap(List <MapBlockData> mapBlocks, int minX, int minY, int maxX, int maxY) { for (int x = minX; x <= maxX; x++) { for (int y = minY; y <= maxY; y++) { MapBlockData mblock = mapBlocks.Find(delegate(MapBlockData mb) { return((mb.X == x) && (mb.Y == y)); }); if (mblock == null) { mblock = new MapBlockData(); mblock.X = (ushort)x; mblock.Y = (ushort)y; mblock.Name = ""; mblock.Access = 254; // not here??? mblock.MapImageId = UUID.Zero; mapBlocks.Add(mblock); } } } }
private void Test() { if (CurViewType == eMapViewType.Port || CurViewType == eMapViewType.Edit) { int row = (int)((int)_selectGridPos_Main.x * _gridCnt_Port * _gridCnt_Edit + (int)_selectGridPos_Port.x * _gridCnt_Edit); // + (int)_selectGridPos_Edit.x); int col = (int)((int)_selectGridPos_Main.y * _gridCnt_Port * _gridCnt_Edit + (int)_selectGridPos_Port.y * _gridCnt_Edit); //+ (int)_selectGridPos_Edit.y); for (int index = row; index < row + _gridCnt_Edit; index++) { for (int i = col; i < col + _gridCnt_Edit; i++) { AddCollider(index, i, MapBlockType); MapBlockData tempBlock = GetCollider(index, i); if (tempBlock != null && (MapBlockType == eMapBlockType.Hide || MapBlockType == eMapBlockType.Event)) { // tempBlock.param = "1"; } } } } }
void InstantiateMap(MapBlockData mapData, int Worldx, int Worldy, int x, int y, YieldDirection yieldDirection) { GameObject world = GameObject.Find(getWorldName(Worldx, Worldy)); if (world == null) { world = (GameObject)Instantiate(prefabMapBlockView, new Vector3(0, 0, 0), Quaternion.identity, prefabParent.transform); world.name = getWorldName(Worldx, Worldy); world.transform.position = calculateTransformPosition(Worldx, Worldy); MapBlockView mapBlockView = world.GetComponent <MapBlockView> (); if (mapBlockView == null) { throw new MissingComponentException("Expected to find the MapBlockView Component"); } mapBlockView.AutoSave = AutoSave; worlds [x, y] = world; this.mapBlocks [x, y] = mapBlockView; StartCoroutine(mapBlockView.Initialize(Worldx, Worldy, mapData, getMapPath(Worldx, Worldy, saveMapDataPath), yieldDirection, resourceManager, this)); } }
protected override List <MapBlockData> GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) { List <MapBlockData> mapBlocks = new List <MapBlockData>(); List <GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, minX * (int)Constants.RegionSize, maxX * (int)Constants.RegionSize, minY * (int)Constants.RegionSize, maxY * (int)Constants.RegionSize); foreach (GridRegion r in regions) { uint x = 0, y = 0; long handle = 0; if (r.RegionSecret != null && r.RegionSecret != string.Empty) { if (long.TryParse(r.RegionSecret, out handle)) { Utils.LongToUInts((ulong)handle, out x, out y); x = x / Constants.RegionSize; y = y / Constants.RegionSize; } } if (handle == 0 || // Check the distance from the current region (handle != 0 && Math.Abs((int)(x - m_scene.RegionInfo.RegionLocX)) < 4096 && Math.Abs((int)(y - m_scene.RegionInfo.RegionLocY)) < 4096)) { MapBlockData block = new MapBlockData(); MapBlockFromGridRegion(block, r); mapBlocks.Add(block); } } // Different from super FillInMap(mapBlocks, minX, minY, maxX, maxY); // remoteClient.SendMapBlock(mapBlocks, 0); return(mapBlocks); }
/// <summary> /// Requests map blocks in area of minX, maxX, minY, MaxY in world cordinates /// </summary> /// <param name="minX"></param> /// <param name="minY"></param> /// <param name="maxX"></param> /// <param name="maxY"></param> public virtual void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag) { if ((flag & 0x10000) != 0) // user clicked on the map a tile that isn't visible { List <MapBlockData> response = new List <MapBlockData>(); // this should return one mapblock at most. But make sure: Look whether the one we requested is in there List <MapBlockData> mapBlocks = m_scene.SceneGridService.RequestNeighbourMapBlocks(minX, minY, maxX, maxY); if (mapBlocks != null) { foreach (MapBlockData block in mapBlocks) { if (block.X == minX && block.Y == minY) { // found it => add it to response response.Add(block); break; } } } if (response.Count == 0) { // response still empty => couldn't find the map-tile the user clicked on => tell the client MapBlockData block = new MapBlockData(); block.X = (ushort)minX; block.Y = (ushort)minY; block.Access = 254; // == not there response.Add(block); } remoteClient.SendMapBlock(response, 0); } else { // normal mapblock request. Use the provided values GetAndSendBlocks(remoteClient, minX, minY, maxX, maxY, flag); } }
/// <summary> /// /// </summary> /// <param name="minX"></param> /// <param name="minY"></param> /// <param name="maxX"></param> /// <param name="maxY"></param> /// <returns></returns> public List <MapBlockData> RequestNeighbourMapBlocks(int minX, int minY, int maxX, int maxY) { List <MapBlockData> mapBlocks = new List <MapBlockData>(); foreach (RegionInfo regInfo in m_regions.Values) { if (((regInfo.RegionLocX >= minX) && (regInfo.RegionLocX <= maxX)) && ((regInfo.RegionLocY >= minY) && (regInfo.RegionLocY <= maxY))) { MapBlockData map = new MapBlockData(); map.Name = regInfo.RegionName; map.X = (ushort)regInfo.RegionLocX; map.Y = (ushort)regInfo.RegionLocY; map.WaterHeight = (byte)regInfo.RegionSettings.WaterHeight; map.MapImageId = regInfo.RegionSettings.TerrainImageID; map.Agents = 1; map.RegionFlags = 72458694; map.Access = regInfo.AccessLevel; mapBlocks.Add(map); } } return(mapBlocks); }
//获取草丛或者碰撞数据 public MapBlockData GetCurMapBlock(Vector3 pos) { int row = Mathf.RoundToInt(pos.x / MapDefine.MapMinGridSize); int col = Mathf.RoundToInt(pos.z / MapDefine.MapMinGridSize); MapBlockData tempData = null; int index = row + col * 10240; int byteRow = index / 8; int byteCol = index % 8; if (byteRow < ColliderDatas.Length)//取碰撞 { byte curByte = ColliderDatas[byteRow]; byte temp = (byte)Mathf.Pow(2, byteCol); int value = curByte & temp; if (value >= 1) { tempData = new MapBlockData(); tempData.row = row; tempData.col = col; tempData.type = eMapBlockType.Collect; } } if (tempData == null)//取草丛 { // Debug.LogError(col + " " + row + " asdfasd"); if (mapBlockDataDic.TryGetValue(row + "_" + col, out tempData)) { // Debug.LogError(tempData.col+" "+tempData.row+" >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); return(tempData); } } return(tempData); }
private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags) { Util.FireAndForget(x => { try { List <MapBlockData> blocks = new List <MapBlockData>(); if (mapName.Length < 3 || (mapName.EndsWith("#") && mapName.Length < 4)) { // final block, closing the search result AddFinalBlock(blocks, mapName); // flags are agent flags sent from the viewer. // they have different values depending on different viewers, apparently remoteClient.SendMapBlock(blocks, flags); remoteClient.SendAlertMessage("Use a search string with at least 3 characters"); return; } //m_log.DebugFormat("MAP NAME=({0})", mapName); // Hack to get around the fact that ll V3 now drops the port from the // map name. See https://jira.secondlife.com/browse/VWR-28570 // // Caller, use this magic form instead: // secondlife://http|!!mygrid.com|8002|Region+Name/128/128 // or url encode if possible. // the hacks we do with this viewer... // bool needOriginalName = false; string mapNameOrig = mapName; if (mapName.Contains("|")) { mapName = mapName.Replace('|', ':'); needOriginalName = true; } if (mapName.Contains("+")) { mapName = mapName.Replace('+', ' '); needOriginalName = true; } if (mapName.Contains("!")) { mapName = mapName.Replace('!', '/'); needOriginalName = true; } if (mapName.Contains(".")) { needOriginalName = true; } // try to fetch from GridServer List <GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20); // if (regionInfos.Count == 0) // remoteClient.SendAlertMessage("Hyperlink could not be established."); //m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions", mapName, regionInfos.Count); MapBlockData data; if (regionInfos != null && regionInfos.Count > 0) { foreach (GridRegion info in regionInfos) { data = new MapBlockData(); data.Agents = 0; data.Access = info.Access; MapBlockData block = new MapBlockData(); WorldMap.MapBlockFromGridRegion(block, info, flags); if (flags == 2 && regionInfos.Count == 1 && needOriginalName) { block.Name = mapNameOrig; } blocks.Add(block); } } // final block, closing the search result AddFinalBlock(blocks, mapNameOrig); // flags are agent flags sent from the viewer. // they have different values depending on different viewers, apparently remoteClient.SendMapBlock(blocks, flags); // send extra user messages for V3 // because the UI is very confusing // while we don't fix the hard-coded urls if (flags == 2) { if (regionInfos == null || regionInfos.Count == 0) { remoteClient.SendAgentAlertMessage("No regions found with that name.", true); } // else if (regionInfos.Count == 1) // remoteClient.SendAgentAlertMessage("Region found!", false); } } finally { lock (m_Clients) m_Clients.Remove(remoteClient.AgentId); } }); }
private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags) { List <MapBlockData> blocks = new List <MapBlockData>(); MapBlockData data; if (mapName.Length < 3 || (mapName.EndsWith("#") && mapName.Length < 4)) { // final block, closing the search result AddFinalBlock(blocks); // flags are agent flags sent from the viewer. // they have different values depending on different viewers, apparently remoteClient.SendMapBlock(blocks, flags); remoteClient.SendAlertMessage("Use a search string with at least 3 characters"); return; } //m_log.DebugFormat("MAP NAME=({0})", mapName); // Hack to get around the fact that ll V3 now drops the port from the // map name. See https://jira.secondlife.com/browse/VWR-28570 // // Caller, use this magic form instead: // secondlife://http|!!mygrid.com|8002|Region+Name/128/128 // or url encode if possible. // the hacks we do with this viewer... // string mapNameOrig = mapName; if (mapName.Contains("|")) { mapName = mapName.Replace('|', ':'); } if (mapName.Contains("+")) { mapName = mapName.Replace('+', ' '); } if (mapName.Contains("!")) { mapName = mapName.Replace('!', '/'); } // try to fetch from GridServer List <GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20); m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions. Flags={2}", mapName, regionInfos.Count, flags); if (regionInfos.Count > 0) { foreach (GridRegion info in regionInfos) { data = new MapBlockData(); data.Agents = 0; data.Access = info.Access; if (flags == 2) // V2 sends this { data.MapImageId = UUID.Zero; } else { data.MapImageId = info.TerrainImage; } // ugh! V2-3 is very sensitive about the result being // exactly the same as the requested name if (regionInfos.Count == 1 && mapNameOrig.Contains("|") || mapNameOrig.Contains("+")) { data.Name = mapNameOrig; } else { data.Name = info.RegionName; } data.RegionFlags = 0; // TODO not used? data.WaterHeight = 0; // not used data.X = (ushort)Util.WorldToRegionLoc((uint)info.RegionLocX); data.Y = (ushort)Util.WorldToRegionLoc((uint)info.RegionLocY); blocks.Add(data); } } // final block, closing the search result AddFinalBlock(blocks); // flags are agent flags sent from the viewer. // they have different values depending on different viewers, apparently remoteClient.SendMapBlock(blocks, flags); // send extra user messages for V3 // because the UI is very confusing // while we don't fix the hard-coded urls if (flags == 2) { if (regionInfos.Count == 0) { remoteClient.SendAlertMessage("No regions found with that name."); } else if (regionInfos.Count == 1) { remoteClient.SendAlertMessage("Region found!"); } } }
public void SaveFile(MapBlockData mapData, BinaryWriter writer) { if (mapData == null) { throw new NullReferenceException("Parameter mapData cannot be null"); } if (writer == null) { throw new NullReferenceException("Parameter writer cannot be null"); } Int32 rows = mapData.getRows(); Int32 cols = mapData.getCols(); ArrayList floorResources = new ArrayList(); ArrayList mainResources = new ArrayList(); Int32[,] floorarray = new Int32[rows, cols]; Int32[,] array = new Int32[rows, cols]; for (int x = 0; x < rows; x++) { for (int y = 0; y < cols; y++) { String floorResource = mapData.getFloorResource(x, y); if (!floorResources.Contains(floorResource)) { floorResources.Add(floorResource); floorarray [x, y] = floorResources.Count - 1; } else { floorarray [x, y] = floorResources.IndexOf(floorResource); } String mainResource = mapData.getMainResource(x, y); if (!mainResources.Contains(mainResource)) { mainResources.Add(mainResource); array [x, y] = mainResources.Count - 1; } else { array [x, y] = mainResources.IndexOf(mainResource); } } } writer.Write((Int32)floorResources.Count); for (int i = 0; i < floorResources.Count; i++) { String floorResource = (String)floorResources [i]; if (floorResource == null) { floorResource = ""; } writer.Write(floorResource); } writer.Write((Int32)mainResources.Count); for (int i = 0; i < mainResources.Count; i++) { String mainResource = (String)mainResources [i]; if (mainResource == null) { mainResource = ""; } writer.Write(mainResource); } writer.Write((Int32)rows); writer.Write((Int32)cols); for (int x = 0; x < rows; x++) { for (int y = 0; y < cols; y++) { writer.Write((Int32)floorarray [x, y]); } } for (int x = 0; x < rows; x++) { for (int y = 0; y < cols; y++) { writer.Write((Int32)array [x, y]); } } }
private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags) { if (mapName.Length < 3) { remoteClient.SendAlertMessage("Use a search string with at least 3 characters"); return; } // try to fetch from GridServer List <GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20); if (regionInfos == null) { m_log.Warn("[MAPSEARCHMODULE]: RequestNamedRegions returned null. Old gridserver?"); // service wasn't available; maybe still an old GridServer. Try the old API, though it will return only one region regionInfos = new List <GridRegion>(); GridRegion info = m_scene.GridService.GetRegionByName(m_scene.RegionInfo.ScopeID, mapName); if (info != null) { regionInfos.Add(info); } } else if (regionInfos.Count == 0 && mapName.StartsWith("http://")) { remoteClient.SendAlertMessage("Hyperlink could not be established."); } m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions. Flags={2}", mapName, regionInfos.Count, flags); List <MapBlockData> blocks = new List <MapBlockData>(); MapBlockData data; if (regionInfos.Count > 0) { foreach (GridRegion info in regionInfos) { data = new MapBlockData(); data.Agents = 0; data.Access = info.Access; if (flags == 2) // V2 sends this { data.MapImageId = UUID.Zero; } else { data.MapImageId = info.TerrainImage; } data.Name = info.RegionName; data.RegionFlags = 0; // TODO not used? data.WaterHeight = 0; // not used data.X = (ushort)(info.RegionLocX / Constants.RegionSize); data.Y = (ushort)(info.RegionLocY / Constants.RegionSize); blocks.Add(data); } } // final block, closing the search result data = new MapBlockData(); data.Agents = 0; data.Access = 255; data.MapImageId = UUID.Zero; data.Name = ""; // mapName; data.RegionFlags = 0; data.WaterHeight = 0; // not used data.X = 0; data.Y = 0; blocks.Add(data); // flags are agent flags sent from the viewer. // they have different values depending on different viewers, apparently remoteClient.SendMapBlock(blocks, flags); }
public virtual void Teleport(IScenePresence sp, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags) { int x = 0, y = 0; Util.UlongToInts(regionHandle, out x, out y); GridRegion reg = sp.Scene.GridService.GetRegionByPosition (sp.ControllingClient.AllScopeIDs, x, y); if (reg == null) { List<GridRegion> regions = sp.Scene.GridService.GetRegionRange(sp.ControllingClient.AllScopeIDs, x - (sp.Scene.GridService.GetRegionViewSize() * sp.Scene.RegionInfo.RegionSizeX), x + (sp.Scene.GridService.GetRegionViewSize() * sp.Scene.RegionInfo.RegionSizeX), y - (sp.Scene.GridService.GetRegionViewSize() * sp.Scene.RegionInfo.RegionSizeY), y + (sp.Scene.GridService.GetRegionViewSize() * sp.Scene.RegionInfo.RegionSizeY)); foreach (GridRegion r in regions) { if (r.RegionLocX <= x && r.RegionLocX + r.RegionSizeX > x && r.RegionLocY <= y && r.RegionLocY + r.RegionSizeY > y) { reg = r; position.X += x - reg.RegionLocX; position.Y += y - reg.RegionLocY; break; } } if (reg == null) { // TP to a place that doesn't exist (anymore) // Inform the viewer about that sp.ControllingClient.SendTeleportFailed ("The region you tried to teleport to doesn't exist anymore"); // and set the map-tile to '(Offline)' int regX, regY; Util.UlongToInts (regionHandle, out regX, out regY); MapBlockData block = new MapBlockData { X = (ushort) (regX/Constants.RegionSize), Y = (ushort) (regY/Constants.RegionSize), Access = 254 }; // == not there List<MapBlockData> blocks = new List<MapBlockData> {block}; sp.ControllingClient.SendMapBlock (blocks, 0); return; } } Teleport(sp, reg, position, lookAt, teleportFlags); }
protected MapBlockData TerrainBlockFromGridRegion(GridRegion r) { MapBlockData block = new MapBlockData(); if (r == null) { block.Access = (byte)SimAccess.Down; block.MapImageID = UUID.Zero; return block; } block.Access = r.Access; block.MapImageID = r.TerrainMapImage; if ((r.Access & (byte)SimAccess.Down) == (byte)SimAccess.Down) block.Name = r.RegionName + " (offline)"; else block.Name = r.RegionName; block.X = (ushort)(r.RegionLocX / Constants.RegionSize); block.Y = (ushort)(r.RegionLocY / Constants.RegionSize); block.SizeX = (ushort)r.RegionSizeX; block.SizeY = (ushort)r.RegionSizeY; return block; }
protected List<MapBlockData> Map2BlockFromGridRegion (GridRegion r) { List<MapBlockData> blocks = new List<MapBlockData> (); MapBlockData block = new MapBlockData (); if (r == null) { block.Access = (byte)SimAccess.Down; block.MapImageID = UUID.Zero; blocks.Add (block); return blocks; } block.Access = r.Access; block.MapImageID = r.TerrainImage; if ((r.Access & (byte)SimAccess.Down) == (byte)SimAccess.Down) block.Name = r.RegionName + " (offline)"; else block.Name = r.RegionName; block.X = (ushort)(r.RegionLocX / Constants.RegionSize); block.Y = (ushort)(r.RegionLocY / Constants.RegionSize); block.SizeX = (ushort)r.RegionSizeX; block.SizeY = (ushort)r.RegionSizeY; blocks.Add(block); if (r.RegionSizeX > Constants.RegionSize || r.RegionSizeY > Constants.RegionSize) { for (int x = 0; x < r.RegionSizeX / Constants.RegionSize; x++) { for (int y = 0; y < r.RegionSizeY / Constants.RegionSize; y++) { if (x == 0 && y == 0) continue; block = new MapBlockData { Access = r.Access, MapImageID = r.TerrainImage, Name = r.RegionName, X = (ushort) ((r.RegionLocX/Constants.RegionSize) + x), Y = (ushort) ((r.RegionLocY/Constants.RegionSize) + y), SizeX = (ushort) r.RegionSizeX, SizeY = (ushort) r.RegionSizeY }; //Child piece, so ignore it blocks.Add (block); } } } return blocks; }
public MapBlock(MapTile tile, int id, MapBlockData data) { parentTile = tile; block_id = id; this.data = data; }
//------------ Map 控制相關 ------------------- // player click a tile in Map, Top Left is 0, 0 public void MapTileClick(MapBlockData data) { switch (_currentPlayStatus) { // 開始選擇要控制哪個 UNIT case PlayStatus.RoundHumanTurn: case PlayStatus.RoundScarabTurn: if (NowHitter == Creature.None) { DebugLog(" Status error : not round turn status. " + _currentPlayStatus.ToString()); return; } UIManager.Instance.ScarabCount = _logic.ScarabCount; UIManager.Instance.HumanCount = _logic.PeopleCount; IVector2 vec = new IVector2(); vec.x = data.Column; vec.y = data.Row; ControlMessage controlMsg = _logic.CanControl(vec, NowHitter); if (controlMsg != ControlMessage.OK) { UIManager.Instance.ShowCenterMsg("you can't do it !"); return; } // todo: some click effect if (_currentSelection != null) { _currentSelection.Block.CreatureComponent.UnHighLight(); } // ready click 2 if (NowHitter == Creature.People) { _currentPlayStatus = PlayStatus.RoundHumanReadyMove; } else if (NowHitter == Creature.Scarab) { _currentPlayStatus = PlayStatus.RoundScarabReadyMove; } _currentChoosedBlock = data; _currentSelection = _currentChoosedBlock; _currentSelection.Block.CreatureComponent.HighLight(); DebugLog("PlayStatus: " + _currentPlayStatus.ToString()); break; // 開始選擇要移動到哪裡 case PlayStatus.RoundHumanReadyMove: case PlayStatus.RoundScarabReadyMove: //debug //StartCoroutine(WaitReturnToMain()); //準備回到主畫面 if (_currentSelection != null) { _currentSelection.Block.CreatureComponent.UnHighLight(); } //檢查是否為重新選取 unit if ((data.Block.LivingObject == Creature.People) && (_currentPlayStatus == PlayStatus.RoundHumanReadyMove)) { _currentPlayStatus = PlayStatus.RoundHumanTurn; // 回到選取狀態 MapTileClick(data); return; } else if ((data.Block.LivingObject == Creature.Scarab) && (_currentPlayStatus == PlayStatus.RoundScarabReadyMove)) { _currentPlayStatus = PlayStatus.RoundScarabTurn; // 回到選取狀態 MapTileClick(data); return; } bool legal = _logic.IsLegalMove(_currentChoosedBlock.Block.Pos, data.Block.Pos); if (legal == false) { UIManager.Instance.ShowCenterMsg("wrong move position !"); return; } List <IVector2> infectPositions = new List <IVector2>(); IVector2 realEnd; MoveType moveType = _logic.Move(_currentChoosedBlock.Block.Pos, data.Block.Pos, out realEnd, out infectPositions); bool isHoleTeleport = ((data.Block.Pos.x != realEnd.x) && (data.Block.Pos.y != realEnd.y)); DebugLog(" Move Start : " + _currentChoosedBlock.Block.Pos.x.ToString() + "," + _currentChoosedBlock.Block.Pos.y.ToString() + " End: " + data.Block.Pos.x.ToString() + "," + data.Block.Pos.y.ToString() + " Real End " + realEnd.x.ToString() + "," + realEnd.y.ToString() + " MoveType : " + moveType.ToString()); if (moveType == MoveType.Move) { //移動場景物件 MapBlock destBlockMove = _logic.GetMapBlock(realEnd); MapGenerator.CopyMoveUnit(_currentChoosedBlock.Block, destBlockMove); for (int i = 0; i < infectPositions.Count; i++) { MapBlock block = _logic.GetMapBlock(infectPositions[i]); //人類 if (_lastPlayStatus == PlayStatus.RoundHumanReadyMove) { MapGenerator.HumanInfectBlock(block); } //蟲類 else { MapGenerator.ScarabInfectBlock(block); } } if (infectPositions.Count > 0) { UIManager.Instance.ShowCenterMsg((isHoleTeleport? "[Teleport]":"") + " Infect !!! "); } else { UIManager.Instance.ShowCenterMsg((isHoleTeleport ? "[Teleport]" : "") + " Move !"); } DebugLog(" 淫內感染 infect nums. " + infectPositions.Count.ToString()); } else if (moveType == MoveType.Clone) { MapBlock destBlock = _logic.GetMapBlock(realEnd); //人類 if (_lastPlayStatus == PlayStatus.RoundHumanReadyMove) { MapGenerator.HumanInfectBlock(destBlock); } //蟲類 else { MapGenerator.ScarabInfectBlock(destBlock); } for (int i = 0; i < infectPositions.Count; i++) { MapBlock blockClone = _logic.GetMapBlock(infectPositions[i]); //人類 if (_lastPlayStatus == PlayStatus.RoundHumanReadyMove) { MapGenerator.HumanInfectBlock(blockClone); } //蟲類 else { MapGenerator.ScarabInfectBlock(blockClone); } } if (infectPositions.Count > 0) { UIManager.Instance.ShowCenterMsg((isHoleTeleport ? "[Teleport]" : "") + " Clone and Infect !!! "); } else { UIManager.Instance.ShowCenterMsg((isHoleTeleport ? "[Teleport]" : "") + " Clone ! "); } DebugLog("MoveType.Clone " + realEnd.DataToString()); } else { DebugLog("MoveType.None"); } BattleResult res = BattleResult.None; if (_currentPlayStatus == PlayStatus.RoundHumanReadyMove) { _currentPlayStatus = PlayStatus.RoundScarabTurn; // 換蟲方 res = _logic.DecideResult(Creature.Scarab); } else if (_currentPlayStatus == PlayStatus.RoundScarabReadyMove) { _currentPlayStatus = PlayStatus.RoundHumanTurn; // 換人方 res = _logic.DecideResult(Creature.People); } if (res != BattleResult.None) { UIManager.Instance.ShowResult(res); _currentPlayStatus = PlayStatus.BattleResult; //本局結束 StartCoroutine(WaitReturnToMain()); //準備回到主畫面 if (res == BattleResult.Draw) { UIManager.Instance.ShowCenterMsg("Draw !"); } else if (res == BattleResult.PeopleWin) { UIManager.Instance.ShowCenterMsg("Human Win !"); } else if (res == BattleResult.ScarabWin) { UIManager.Instance.ShowCenterMsg("Scarab Win !\n\n Colonization Success !!!"); } } _currentChoosedBlock = null; break; default: DebugLog("Click Tile valid. " + _currentPlayStatus.ToString()); break; } }
protected MapBlockData MapBlockFromGridRegion(GridRegion r, int x, int y) { MapBlockData block = new MapBlockData(); if (r == null) { block.Access = (byte)SimAccess.NonExistent; block.X = (ushort)x; block.Y = (ushort)y; block.MapImageID = UUID.Zero; return block; } if ((r.Flags & (int)Aurora.Framework.RegionFlags.RegionOnline) == (int)Aurora.Framework.RegionFlags.RegionOnline) block.Access = r.Access; else block.Access = (byte)OpenMetaverse.SimAccess.Down; block.MapImageID = r.TerrainImage; block.Name = r.RegionName; block.X = (ushort)(r.RegionLocX / Constants.RegionSize); block.Y = (ushort)(r.RegionLocY / Constants.RegionSize); block.SizeX = (ushort)r.RegionSizeX; block.SizeY = (ushort)r.RegionSizeY; return block; }
protected MapBlockData MapBlockFromGridRegion(GridRegion r) { MapBlockData block = new MapBlockData(); if (r == null) { block.Access = (byte) SimAccess.Down; block.MapImageID = UUID.Zero; return block; } block.Access = r.Access; block.MapImageID = r.TerrainImage; block.Name = r.RegionName; block.X = (ushort) (r.RegionLocX/Constants.RegionSize); block.Y = (ushort) (r.RegionLocY/Constants.RegionSize); block.SizeX = (ushort) (r.RegionSizeX); block.SizeY = (ushort) (r.RegionSizeY); return block; }
/// <summary> /// Export the world map /// </summary> /// <param name="fileName"></param> public void HandleExportWorldMapConsoleCommand(string module, string[] cmdparams) { if (m_scene.ConsoleScene() == null) { // FIXME: If console region is root then this will be printed by every module. Currently, there is no // way to prevent this, short of making the entire module shared (which is complete overkill). // One possibility is to return a bool to signal whether the module has completely handled the command m_log.InfoFormat("[WORLD MAP]: Please change to a specific region in order to export its world map"); return; } if (m_scene.ConsoleScene() != m_scene) { return; } string exportPath; if (cmdparams.Length > 1) { exportPath = cmdparams[1]; } else { exportPath = DEFAULT_WORLD_MAP_EXPORT_PATH; } m_log.InfoFormat( "[WORLD MAP]: Exporting world map for {0} to {1}", m_scene.RegionInfo.RegionName, exportPath); List <MapBlockData> mapBlocks = new List <MapBlockData>(); List <GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, (int)(m_scene.RegionInfo.RegionLocX - 9) * (int)Constants.RegionSize, (int)(m_scene.RegionInfo.RegionLocX + 9) * (int)Constants.RegionSize, (int)(m_scene.RegionInfo.RegionLocY - 9) * (int)Constants.RegionSize, (int)(m_scene.RegionInfo.RegionLocY + 9) * (int)Constants.RegionSize); List <AssetBase> textures = new List <AssetBase>(); List <Image> bitImages = new List <Image>(); foreach (GridRegion r in regions) { MapBlockData mapBlock = new MapBlockData(); MapBlockFromGridRegion(mapBlock, r); AssetBase texAsset = m_scene.AssetService.Get(mapBlock.MapImageId.ToString()); if (texAsset != null) { textures.Add(texAsset); } //else //{ // // WHAT?!? This doesn't seem right. Commenting (diva) // texAsset = m_scene.AssetService.Get(mapBlock.MapImageId.ToString()); // if (texAsset != null) // { // textures.Add(texAsset); // } //} } foreach (AssetBase asset in textures) { ManagedImage managedImage; Image image; if (OpenJPEG.DecodeToImage(asset.Data, out managedImage, out image)) { bitImages.Add(image); } } Bitmap mapTexture = new Bitmap(2560, 2560); Graphics g = Graphics.FromImage(mapTexture); SolidBrush sea = new SolidBrush(Color.DarkBlue); g.FillRectangle(sea, 0, 0, 2560, 2560); for (int i = 0; i < mapBlocks.Count; i++) { ushort x = (ushort)((mapBlocks[i].X - m_scene.RegionInfo.RegionLocX) + 10); ushort y = (ushort)((mapBlocks[i].Y - m_scene.RegionInfo.RegionLocY) + 10); g.DrawImage(bitImages[i], (x * 128), 2560 - (y * 128), 128, 128); // y origin is top } mapTexture.Save(exportPath, ImageFormat.Jpeg); m_log.InfoFormat( "[WORLD MAP]: Successfully exported world map for {0} to {1}", m_scene.RegionInfo.RegionName, exportPath); }
private void OnMapNameRequestHandler(IClientAPI remoteClient, string mapName, uint flags) { if (m_gridservice == null) { return; } try { List <MapBlockData> blocks = new List <MapBlockData>(); if (mapName.Length < 3 || (mapName.EndsWith("#") && mapName.Length < 4)) { // final block, closing the search result AddFinalBlock(blocks, mapName); // flags are agent flags sent from the viewer. // they have different values depending on different viewers, apparently remoteClient.SendMapBlock(blocks, flags); remoteClient.SendAlertMessage("Use a search string with at least 3 characters"); return; } //m_log.DebugFormat("MAP NAME=({0})", mapName); string mapNameOrig = mapName; int indx = mapName.IndexOfAny(new char[] { '.', '!', '+', '|', ':', '%' }); bool needOriginalName = indx >= 0; // try to fetch from GridServer List <GridRegion> regionInfos = m_gridservice.GetRegionsByName(m_stupidScope, mapName, 20); if (!remoteClient.IsActive) { return; } //m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions", mapName, regionInfos.Count); MapBlockData data; if (regionInfos != null && regionInfos.Count > 0) { foreach (GridRegion info in regionInfos) { data = new MapBlockData(); data.Agents = 0; data.Access = info.Access; MapBlockData block = new MapBlockData(); MapBlockFromGridRegion(block, info, flags); if (needOriginalName && flags == 2 && regionInfos.Count == 1) { block.Name = mapNameOrig; } blocks.Add(block); } } // final block, closing the search result AddFinalBlock(blocks, mapNameOrig); // flags are agent flags sent from the viewer. // they have different values depending on different viewers, apparently remoteClient.SendMapBlock(blocks, flags); // send extra user messages for V3 // because the UI is very confusing // while we don't fix the hard-coded urls if (flags == 2) { if (regionInfos == null || regionInfos.Count == 0) { remoteClient.SendAgentAlertMessage("No regions found with that name.", true); } } } catch { } }
private void OnMapNameRequest(IClientAPI remoteClient, string mapName) { if (mapName.Length < 3) { remoteClient.SendAlertMessage("Use a search string with at least 3 characters"); return; } // try to fetch from GridServer List <RegionInfo> regionInfos = m_scene.SceneGridService.RequestNamedRegions(mapName, 20); if (regionInfos == null) { m_log.Warn("[MAPSEARCHMODULE]: RequestNamedRegions returned null. Old gridserver?"); // service wasn't available; maybe still an old GridServer. Try the old API, though it will return only one region regionInfos = new List <RegionInfo>(); RegionInfo info = m_scene.SceneGridService.RequestClosestRegion(mapName); if (info != null) { regionInfos.Add(info); } } if ((regionInfos.Count == 0) && IsHypergridOn()) { // OK, we tried but there are no regions matching that name. // Let's check quickly if this is a domain name, and if so link to it if (mapName.Contains(".") && mapName.Contains(":")) { // It probably is a domain name. Try to link to it. RegionInfo regInfo; Scene cScene = GetClientScene(remoteClient); regInfo = HGHyperlink.TryLinkRegion(cScene, remoteClient, mapName); if (regInfo != null) { regionInfos.Add(regInfo); } } } List <MapBlockData> blocks = new List <MapBlockData>(); MapBlockData data; if (regionInfos.Count > 0) { foreach (RegionInfo info in regionInfos) { data = new MapBlockData(); data.Agents = 0; data.Access = info.AccessLevel; data.MapImageId = info.RegionSettings.TerrainImageID; data.Name = info.RegionName; data.RegionFlags = 0; // TODO not used? data.WaterHeight = 0; // not used data.X = (ushort)info.RegionLocX; data.Y = (ushort)info.RegionLocY; blocks.Add(data); } } // final block, closing the search result data = new MapBlockData(); data.Agents = 0; data.Access = 255; data.MapImageId = UUID.Zero; data.Name = mapName; data.RegionFlags = 0; data.WaterHeight = 0; // not used data.X = 0; data.Y = 0; blocks.Add(data); remoteClient.SendMapBlock(blocks, 0); }
void InstantiateMap(MapBlockData mapData, int Worldx, int Worldy, int x, int y) { InstantiateMap(mapData, Worldx, Worldy, x, y, YieldDirection.NoYield); }
private void OnMapNameRequest (IClientAPI remoteClient, string mapName, uint flags) { if (mapName.Length < 1) { remoteClient.SendAlertMessage("Use a search string with at least 1 character"); return; } bool TryCoordsSearch = false; int XCoord = 0; int YCoord = 0; string[] splitSearch = mapName.Split(','); if (splitSearch.Length != 1) { if (splitSearch[1].StartsWith (" ")) splitSearch[1] = splitSearch[1].Remove (0, 1); if (int.TryParse(splitSearch[0], out XCoord) && int.TryParse(splitSearch[1], out YCoord)) TryCoordsSearch = true; } List<MapBlockData> blocks = new List<MapBlockData>(); List<GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(UUID.Zero, mapName, 20); if (TryCoordsSearch) { GridRegion region = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, XCoord * Constants.RegionSize, YCoord * Constants.RegionSize); if (region != null) { region.RegionName = mapName + " - " + region.RegionName; regionInfos.Add (region); } } List<GridRegion> allRegions = new List<GridRegion> (); foreach (GridRegion region in regionInfos) { //Add the found in search region first if (!allRegions.Contains (region)) { allRegions.Add (region); blocks.Add (SearchMapBlockFromGridRegion (region)); } //Then send surrounding regions List<GridRegion> regions = m_scene.GridService.GetRegionRange (m_scene.RegionInfo.ScopeID, (region.RegionLocX - (4 * Constants.RegionSize)), (region.RegionLocX + (4 * Constants.RegionSize)), (region.RegionLocY - (4 * Constants.RegionSize)), (region.RegionLocY + (4 * Constants.RegionSize))); if (regions != null) { foreach (GridRegion r in regions) { if (!allRegions.Contains (region)) { allRegions.Add (region); blocks.Add (SearchMapBlockFromGridRegion (r)); } } } } // final block, closing the search result MapBlockData data = new MapBlockData { Agents = 0, Access = 255, MapImageID = UUID.Zero, Name = mapName, RegionFlags = 0, WaterHeight = 0, X = 0, Y = 0, SizeX = 256, SizeY = 256 }; // not used blocks.Add(data); remoteClient.SendMapBlock (blocks, flags); }
private void OnMapNameRequest(IClientAPI remoteClient, string mapName) { if (mapName.Length < 1) { remoteClient.SendAlertMessage("Use a search string with at least 1 character"); return; } bool TryCoordsSearch = false; int XCoord = 0; int YCoord = 0; string[] splitSearch = mapName.Split(','); if (splitSearch.Length != 1) { if (int.TryParse(splitSearch[0], out XCoord) && int.TryParse(splitSearch[1], out YCoord)) { TryCoordsSearch = true; } } List <MapBlockData> blocks = new List <MapBlockData>(); List <GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(UUID.Zero, mapName, 20); if (TryCoordsSearch) { GridRegion region = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, (int)(XCoord * Constants.RegionSize), (int)(YCoord * Constants.RegionSize)); if (region != null) { regionInfos.Add(region); } } foreach (GridRegion region in regionInfos) { //Add the found in search region first blocks.Add(SearchMapBlockFromGridRegion(region)); //Then send surrounding regions List <GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, (region.RegionLocX - (4 * (int)Constants.RegionSize)), (region.RegionLocX + (4 * (int)Constants.RegionSize)), (region.RegionLocY - (4 * (int)Constants.RegionSize)), (region.RegionLocY + (4 * (int)Constants.RegionSize))); foreach (GridRegion r in regions) { blocks.Add(SearchMapBlockFromGridRegion(r)); } } // final block, closing the search result MapBlockData data = new MapBlockData(); data.Agents = 0; data.Access = 255; data.MapImageID = UUID.Zero; data.Name = mapName; data.RegionFlags = 0; data.WaterHeight = 0; // not used data.X = 0; data.Y = 0; blocks.Add(data); remoteClient.SendMapBlock(blocks, 0); }
private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags) { List <MapBlockData> blocks = new List <MapBlockData>(); if (mapName.Length < 3 || (mapName.EndsWith("#") && mapName.Length < 4)) { // final block, closing the search result AddFinalBlock(blocks); // flags are agent flags sent from the viewer. // they have different values depending on different viewers, apparently remoteClient.SendMapBlock(blocks, flags); remoteClient.SendAlertMessage("Use a search string with at least 3 characters"); return; } List <GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20); string mapNameOrig = mapName; if (regionInfos.Count == 0) { // Hack to get around the fact that ll V3 now drops the port from the // map name. See https://jira.secondlife.com/browse/VWR-28570 // // Caller, use this magic form instead: // secondlife://http|!!mygrid.com|8002|Region+Name/128/128 // or url encode if possible. // the hacks we do with this viewer... // if (mapName.Contains("|")) { mapName = mapName.Replace('|', ':'); } if (mapName.Contains("+")) { mapName = mapName.Replace('+', ' '); } if (mapName.Contains("!")) { mapName = mapName.Replace('!', '/'); } if (mapName != mapNameOrig) { regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20); } } m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions. Flags={2}", mapName, regionInfos.Count, flags); if (regionInfos.Count > 0) { foreach (GridRegion info in regionInfos) { if ((flags & 2) == 2) // V2 sends this { List <MapBlockData> datas = WorldMap.Map2BlockFromGridRegion(info, flags); // ugh! V2-3 is very sensitive about the result being // exactly the same as the requested name if (regionInfos.Count == 1 && (mapName != mapNameOrig)) { datas.ForEach(d => d.Name = mapNameOrig); } blocks.AddRange(datas); } else { MapBlockData data = WorldMap.MapBlockFromGridRegion(info, flags); blocks.Add(data); } } } // final block, closing the search result AddFinalBlock(blocks); // flags are agent flags sent from the viewer. // they have different values depending on different viewers, apparently remoteClient.SendMapBlock(blocks, flags); // send extra user messages for V3 // because the UI is very confusing // while we don't fix the hard-coded urls if (flags == 2) { if (regionInfos.Count == 0) { remoteClient.SendAlertMessage("No regions found with that name."); } else if (regionInfos.Count == 1) { remoteClient.SendAlertMessage("Region found!"); } } }
public virtual void Teleport(IScenePresence sp, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags) { int x = 0, y = 0; Util.UlongToInts(regionHandle, out x, out y); GridRegion reg = sp.Scene.GridService.GetRegionByPosition(sp.ControllingClient.AllScopeIDs, x, y); if (reg == null) { List <GridRegion> regions = sp.Scene.GridService.GetRegionRange(sp.ControllingClient.AllScopeIDs, x - (sp.Scene.GridService.GetRegionViewSize() * sp.Scene.RegionInfo.RegionSizeX), x + (sp.Scene.GridService.GetRegionViewSize() * sp.Scene.RegionInfo.RegionSizeX), y - (sp.Scene.GridService.GetRegionViewSize() * sp.Scene.RegionInfo.RegionSizeY), y + (sp.Scene.GridService.GetRegionViewSize() * sp.Scene.RegionInfo.RegionSizeY)); foreach (GridRegion r in regions) { if (r.RegionLocX <= x && r.RegionLocX + r.RegionSizeX > x && r.RegionLocY <= y && r.RegionLocY + r.RegionSizeY > y) { reg = r; position.X += x - reg.RegionLocX; position.Y += y - reg.RegionLocY; break; } } if (reg == null) { // TP to a place that doesn't exist (anymore) // Inform the viewer about that sp.ControllingClient.SendTeleportFailed("The region you tried to teleport to doesn't exist anymore"); // and set the map-tile to '(Offline)' int regX, regY; Util.UlongToInts(regionHandle, out regX, out regY); MapBlockData block = new MapBlockData { X = (ushort)(regX / Constants.RegionSize), Y = (ushort)(regY / Constants.RegionSize), Access = 254 }; // == not there List <MapBlockData> blocks = new List <MapBlockData> { block }; sp.ControllingClient.SendMapBlock(blocks, 0); return; } } Teleport(sp, reg, position, lookAt, teleportFlags); }
private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags) { if (mapName.Length < 1) { remoteClient.SendAlertMessage("Use a search string with at least 1 character"); return; } bool TryCoordsSearch = false; int XCoord = 0; int YCoord = 0; string[] splitSearch = mapName.Split(','); if (splitSearch.Length != 1) { if (splitSearch[1].StartsWith(" ")) { splitSearch[1] = splitSearch[1].Remove(0, 1); } if (int.TryParse(splitSearch[0], out XCoord) && int.TryParse(splitSearch[1], out YCoord)) { TryCoordsSearch = true; } } List <MapBlockData> blocks = new List <MapBlockData>(); List <GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(remoteClient.AllScopeIDs, mapName, 0, 20); if (TryCoordsSearch) { GridRegion region = m_scene.GridService.GetRegionByPosition(remoteClient.AllScopeIDs, XCoord * Constants.RegionSize, YCoord * Constants.RegionSize); if (region != null) { region.RegionName = mapName + " - " + region.RegionName; regionInfos.Add(region); } } List <GridRegion> allRegions = new List <GridRegion>(); if (regionInfos != null) { foreach (GridRegion region in regionInfos) { //Add the found in search region first if (!allRegions.Contains(region)) { allRegions.Add(region); blocks.Add(SearchMapBlockFromGridRegion(region)); } //Then send surrounding regions List <GridRegion> regions = m_scene.GridService.GetRegionRange(remoteClient.AllScopeIDs, (region.RegionLocX - (4 * Constants.RegionSize)), (region.RegionLocX + (4 * Constants.RegionSize)), (region.RegionLocY - (4 * Constants.RegionSize)), (region.RegionLocY + (4 * Constants.RegionSize))); if (regions != null) { foreach (GridRegion r in regions) { if (!allRegions.Contains(region)) { allRegions.Add(region); blocks.Add(SearchMapBlockFromGridRegion(r)); } } } } } // final block, closing the search result MapBlockData data = new MapBlockData { Agents = 0, Access = 255, MapImageID = UUID.Zero, Name = mapName, RegionFlags = 0, WaterHeight = 0, X = 0, Y = 0, SizeX = 256, SizeY = 256 }; // not used blocks.Add(data); remoteClient.SendMapBlock(blocks, flags); }
/// <summary> /// Try to teleport an agent to a new region. /// </summary> /// <param name="remoteClient"></param> /// <param name="RegionHandle"></param> /// <param name="position"></param> /// <param name="lookAt"></param> /// <param name="flags"></param> public override void RequestTeleportToLocation(ScenePresence avatar, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags) { if (!avatar.Scene.Permissions.CanTeleport(avatar.UUID)) { return; } bool destRegionUp = true; IEventQueue eq = avatar.Scene.RequestModuleInterface <IEventQueue>(); // Reset animations; the viewer does that in teleports. avatar.ResetAnimations(); if (regionHandle == m_regionInfo.RegionHandle) { // Teleport within the same region if (position.X < 0 || position.X > Constants.RegionSize || position.Y < 0 || position.Y > Constants.RegionSize || position.Z < 0) { Vector3 emergencyPos = new Vector3(128, 128, 128); m_log.WarnFormat( "[HGSceneCommService]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", position, avatar.Name, avatar.UUID, emergencyPos); position = emergencyPos; } // TODO: Get proper AVG Height float localAVHeight = 1.56f; float posZLimit = (float)avatar.Scene.Heightmap[(int)position.X, (int)position.Y]; float newPosZ = posZLimit + localAVHeight; if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) { position.Z = newPosZ; } // Only send this if the event queue is null if (eq == null) { avatar.ControllingClient.SendTeleportLocationStart(); } avatar.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); avatar.Teleport(position); } else { RegionInfo reg = RequestNeighbouringRegionInfo(regionHandle); if (reg != null) { uint newRegionX = (uint)(reg.RegionHandle >> 40); uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); uint oldRegionX = (uint)(m_regionInfo.RegionHandle >> 40); uint oldRegionY = (((uint)(m_regionInfo.RegionHandle)) >> 8); /// /// Hypergrid mod start /// /// bool isHyperLink = m_hg.IsHyperlinkRegion(reg.RegionHandle); bool isHomeUser = true; ulong realHandle = regionHandle; CachedUserInfo uinfo = m_commsProvider.UserProfileCacheService.GetUserDetails(avatar.UUID); if (uinfo != null) { isHomeUser = HGNetworkServersInfo.Singleton.IsLocalUser(uinfo.UserProfile); realHandle = m_hg.FindRegionHandle(regionHandle); m_log.Debug("XXX ---- home user? " + isHomeUser + " --- hyperlink? " + isHyperLink + " --- real handle: " + realHandle.ToString()); } /// /// Hypergrid mod stop /// /// if (eq == null) { avatar.ControllingClient.SendTeleportLocationStart(); } // Let's do DNS resolution only once in this process, please! // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, // it's actually doing a lot of work. IPEndPoint endPoint = reg.ExternalEndPoint; if (endPoint.Address == null) { // Couldn't resolve the name. Can't TP, because the viewer wants IP addresses. destRegionUp = false; } if (destRegionUp) { // Fixing a bug where teleporting while sitting results in the avatar ending up removed from // both regions if (avatar.ParentID != (uint)0) { avatar.StandUp(); } if (!avatar.ValidateAttachments()) { avatar.ControllingClient.SendTeleportFailed("Inconsistent attachment state"); return; } // the avatar.Close below will clear the child region list. We need this below for (possibly) // closing the child agents, so save it here (we need a copy as it is Clear()-ed). //List<ulong> childRegions = new List<ulong>(avatar.GetKnownRegionList()); // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport // failure at this point (unlike a border crossing failure). So perhaps this can never fail // once we reach here... //avatar.Scene.RemoveCapsHandler(avatar.UUID); string capsPath = String.Empty; AgentCircuitData agentCircuit = avatar.ControllingClient.RequestClientInfo(); agentCircuit.BaseFolder = UUID.Zero; agentCircuit.InventoryFolder = UUID.Zero; agentCircuit.startpos = position; agentCircuit.child = true; if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY)) { // brand new agent, let's create a new caps seed agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); } string reason = String.Empty; //if (!m_commsProvider.InterRegion.InformRegionOfChildAgent(reg.RegionHandle, agentCircuit)) if (!m_interregionCommsOut.SendCreateChildAgent(reg.RegionHandle, agentCircuit, out reason)) { avatar.ControllingClient.SendTeleportFailed(String.Format("Destination is not accepting teleports: {0}", reason)); return; } // Let's close some agents if (isHyperLink) // close them all except this one { List <ulong> regions = new List <ulong>(avatar.KnownChildRegionHandles); regions.Remove(avatar.Scene.RegionInfo.RegionHandle); SendCloseChildAgentConnections(avatar.UUID, regions); } else // close just a few { avatar.CloseChildAgents(newRegionX, newRegionY); } if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY) || isHyperLink) { capsPath = "http://" + reg.ExternalHostName + ":" + reg.HttpPort + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); if (eq != null) { eq.EnableSimulator(realHandle, endPoint, avatar.UUID); // ES makes the client send a UseCircuitCode message to the destination, // which triggers a bunch of things there. // So let's wait Thread.Sleep(2000); eq.EstablishAgentCommunication(avatar.UUID, endPoint, capsPath); } else { avatar.ControllingClient.InformClientOfNeighbour(realHandle, endPoint); // TODO: make Event Queue disablable! } } else { // child agent already there agentCircuit.CapsPath = avatar.Scene.CapsModule.GetChildSeed(avatar.UUID, reg.RegionHandle); capsPath = "http://" + reg.ExternalHostName + ":" + reg.HttpPort + "/CAPS/" + agentCircuit.CapsPath + "0000/"; } //m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId, // position, false); //if (!m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId, // position, false)) //{ // avatar.ControllingClient.SendTeleportFailed("Problem with destination."); // // We should close that agent we just created over at destination... // List<ulong> lst = new List<ulong>(); // lst.Add(realHandle); // SendCloseChildAgentAsync(avatar.UUID, lst); // return; //} SetInTransit(avatar.UUID); // Let's send a full update of the agent. This is a synchronous call. AgentData agent = new AgentData(); avatar.CopyTo(agent); agent.Position = position; agent.CallbackURI = "http://" + m_regionInfo.ExternalHostName + ":" + m_regionInfo.HttpPort + "/agent/" + avatar.UUID.ToString() + "/" + avatar.Scene.RegionInfo.RegionHandle.ToString() + "/release/"; m_interregionCommsOut.SendChildAgentUpdate(reg.RegionHandle, agent); m_log.DebugFormat( "[CAPS]: Sending new CAPS seed url {0} to client {1}", agentCircuit.CapsPath, avatar.UUID); /// /// Hypergrid mod: realHandle instead of reg.RegionHandle /// /// if (eq != null) { eq.TeleportFinishEvent(realHandle, 13, endPoint, 4, teleportFlags, capsPath, avatar.UUID); } else { avatar.ControllingClient.SendRegionTeleport(realHandle, 13, endPoint, 4, teleportFlags, capsPath); } /// /// Hypergrid mod stop /// // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation // that the client contacted the destination before we send the attachments and close things here. if (!WaitForCallback(avatar.UUID)) { // Client never contacted destination. Let's restore everything back avatar.ControllingClient.SendTeleportFailed("Problems connecting to destination."); ResetFromTransit(avatar.UUID); // Yikes! We should just have a ref to scene here. avatar.Scene.InformClientOfNeighbours(avatar); // Finally, kill the agent we just created at the destination. m_interregionCommsOut.SendCloseAgent(reg.RegionHandle, avatar.UUID); return; } // Can't go back from here if (KiPrimitive != null) { KiPrimitive(avatar.LocalId); } avatar.MakeChildAgent(); // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true); // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone /// /// Hypergrid mod: extra check for isHyperLink /// if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY) || isHyperLink) { Thread.Sleep(5000); avatar.Close(); CloseConnection(avatar.UUID); } // if (teleport success) // seems to be always success here // the user may change their profile information in other region, // so the userinfo in UserProfileCache is not reliable any more, delete it if (avatar.Scene.NeedSceneCacheClear(avatar.UUID) || isHyperLink) { m_commsProvider.UserProfileCacheService.RemoveUser(avatar.UUID); m_log.DebugFormat( "[HGSceneCommService]: User {0} is going to another region, profile cache removed", avatar.UUID); } } else { avatar.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); } } else { // TP to a place that doesn't exist (anymore) // Inform the viewer about that avatar.ControllingClient.SendTeleportFailed("The region you tried to teleport to doesn't exist anymore"); // and set the map-tile to '(Offline)' uint regX, regY; Utils.LongToUInts(regionHandle, out regX, out regY); MapBlockData block = new MapBlockData(); block.X = (ushort)(regX / Constants.RegionSize); block.Y = (ushort)(regY / Constants.RegionSize); block.Access = 254; // == not there List <MapBlockData> blocks = new List <MapBlockData>(); blocks.Add(block); avatar.ControllingClient.SendMapBlock(blocks, 0); } } }