diff options
author | Tom Grimshaw | 2010-07-04 06:51:01 -0700 |
---|---|---|
committer | Tom Grimshaw | 2010-07-04 06:51:01 -0700 |
commit | 14ab22dcd43740e1ece2840a1b10dea155b55ebe (patch) | |
tree | 7a58bca4a2e584b383d1d95942267f2393f1f06c /OpenSim | |
parent | Check cached asset to make sure it contains data, and if not, re-request (diff) | |
parent | Merge branch 'master' into careminster-presence-refactor (diff) | |
download | opensim-SC-14ab22dcd43740e1ece2840a1b10dea155b55ebe.zip opensim-SC-14ab22dcd43740e1ece2840a1b10dea155b55ebe.tar.gz opensim-SC-14ab22dcd43740e1ece2840a1b10dea155b55ebe.tar.bz2 opensim-SC-14ab22dcd43740e1ece2840a1b10dea155b55ebe.tar.xz |
Merge branch 'careminster-presence-refactor' of ssh://3dhosting.de/var/git/careminster into careminster-presence-refactor
Diffstat (limited to '')
8 files changed, 111 insertions, 40 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs index a7aa4ea..ffdac58 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs | |||
@@ -156,16 +156,31 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
156 | return; | 156 | return; |
157 | } | 157 | } |
158 | 158 | ||
159 | // Force timestamp to server time to avoid "Saved on" headers | 159 | DateTime dt = DateTime.UtcNow; |
160 | // being generated for online users | ||
161 | im.timestamp = (uint)Util.UnixTimeSinceEpoch(); | ||
162 | 160 | ||
163 | if (dialog == (byte)InstantMessageDialog.MessageFromAgent || | 161 | // Ticks from UtcNow, but make it look like local. Evil, huh? |
164 | dialog == (byte)InstantMessageDialog.MessageFromObject) | 162 | dt = DateTime.SpecifyKind(dt, DateTimeKind.Local); |
163 | |||
164 | try | ||
165 | { | ||
166 | // Convert that to the PST timezone | ||
167 | TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles"); | ||
168 | dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo); | ||
169 | } | ||
170 | catch | ||
165 | { | 171 | { |
166 | im.offline = 1; | 172 | m_log.Info("[OFFLINE MESSAGING]: No PST timezone found on this machine. Saving with local timestamp."); |
167 | } | 173 | } |
168 | 174 | ||
175 | // And make it look local again to fool the unix time util | ||
176 | dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc); | ||
177 | |||
178 | im.timestamp = (uint)Util.ToUnixTime(dt); | ||
179 | |||
180 | // If client is null, this message comes from storage and IS offline | ||
181 | if (client != null) | ||
182 | im.offline = 0; | ||
183 | |||
169 | if (m_TransferModule != null) | 184 | if (m_TransferModule != null) |
170 | { | 185 | { |
171 | m_TransferModule.SendInstantMessage(im, | 186 | m_TransferModule.SendInstantMessage(im, |
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs index a2dc91f..feeb9e6 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs | |||
@@ -192,6 +192,17 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
192 | // Needed for proper state management for stored group | 192 | // Needed for proper state management for stored group |
193 | // invitations | 193 | // invitations |
194 | // | 194 | // |
195 | |||
196 | im.offline = 1; | ||
197 | |||
198 | // Reconstruct imSessionID | ||
199 | if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent) | ||
200 | { | ||
201 | UUID fromAgentID = new UUID(im.fromAgentID); | ||
202 | UUID sessionID = fromAgentID ^ client.AgentId; | ||
203 | im.imSessionID = new Guid(sessionID.ToString()); | ||
204 | } | ||
205 | |||
195 | Scene s = FindScene(client.AgentId); | 206 | Scene s = FindScene(client.AgentId); |
196 | if (s != null) | 207 | if (s != null) |
197 | s.EventManager.TriggerIncomingInstantMessage(im); | 208 | s.EventManager.TriggerIncomingInstantMessage(im); |
@@ -201,35 +212,37 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
201 | 212 | ||
202 | private void UndeliveredMessage(GridInstantMessage im) | 213 | private void UndeliveredMessage(GridInstantMessage im) |
203 | { | 214 | { |
204 | if (im.dialog == 19) | 215 | if (im.dialog != (byte)InstantMessageDialog.MessageFromObject && |
205 | im.offline = 1; // We want them pushed out to the server | 216 | im.dialog != (byte)InstantMessageDialog.MessageFromAgent && |
206 | if ((im.offline != 0) | 217 | im.dialog != (byte)InstantMessageDialog.GroupNotice && |
207 | && (!im.fromGroup || (im.fromGroup && m_ForwardOfflineGroupMessages))) | 218 | im.dialog != (byte)InstantMessageDialog.InventoryOffered) |
208 | { | 219 | { |
209 | // It's not delivered. Make sure the scope id is saved | 220 | return; |
210 | // We don't need the imSessionID here anymore, overwrite it | 221 | } |
211 | Scene scene = FindScene(new UUID(im.fromAgentID)); | ||
212 | if (scene == null) | ||
213 | scene = m_SceneList[0]; | ||
214 | im.imSessionID = new Guid(scene.RegionInfo.ScopeID.ToString()); | ||
215 | 222 | ||
216 | bool success = SynchronousRestObjectPoster.BeginPostObject<GridInstantMessage, bool>( | 223 | // It's not delivered. Make sure the scope id is saved |
217 | "POST", m_RestURL+"/SaveMessage/", im); | 224 | // We don't need the imSessionID here anymore, overwrite it |
225 | Scene scene = FindScene(new UUID(im.fromAgentID)); | ||
226 | if (scene == null) | ||
227 | scene = m_SceneList[0]; | ||
228 | im.imSessionID = new Guid(scene.RegionInfo.ScopeID.ToString()); | ||
218 | 229 | ||
219 | if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent) | 230 | bool success = SynchronousRestObjectPoster.BeginPostObject<GridInstantMessage, bool>( |
220 | { | 231 | "POST", m_RestURL+"/SaveMessage/", im); |
221 | IClientAPI client = FindClient(new UUID(im.fromAgentID)); | 232 | |
222 | if (client == null) | 233 | if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent) |
223 | return; | 234 | { |
224 | 235 | IClientAPI client = FindClient(new UUID(im.fromAgentID)); | |
225 | client.SendInstantMessage(new GridInstantMessage( | 236 | if (client == null) |
226 | null, new UUID(im.toAgentID), | 237 | return; |
227 | "System", new UUID(im.fromAgentID), | 238 | |
228 | (byte)InstantMessageDialog.MessageFromAgent, | 239 | client.SendInstantMessage(new GridInstantMessage( |
229 | "User is not logged in. "+ | 240 | null, new UUID(im.toAgentID), |
230 | (success ? "Message saved." : "Message not saved"), | 241 | "System", new UUID(im.fromAgentID), |
231 | false, new Vector3())); | 242 | (byte)InstantMessageDialog.MessageFromAgent, |
232 | } | 243 | "User is not logged in. "+ |
244 | (success ? "Message saved." : "Message not saved"), | ||
245 | false, new Vector3())); | ||
233 | } | 246 | } |
234 | } | 247 | } |
235 | } | 248 | } |
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index 0e849e5..9d9967a 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs | |||
@@ -805,7 +805,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
805 | imgstream = new MemoryStream(); | 805 | imgstream = new MemoryStream(); |
806 | 806 | ||
807 | // non-async because we know we have the asset immediately. | 807 | // non-async because we know we have the asset immediately. |
808 | AssetBase mapasset = m_scene.AssetService.Get(m_scene.RegionInfo.lastMapUUID.ToString()); | 808 | AssetBase mapasset = m_scene.AssetService.Get(m_scene.RegionInfo.RegionSettings.TerrainImageID.ToString()); |
809 | 809 | ||
810 | // Decode image to System.Drawing.Image | 810 | // Decode image to System.Drawing.Image |
811 | if (OpenJPEG.DecodeToImage(mapasset.Data, out managedImage, out image)) | 811 | if (OpenJPEG.DecodeToImage(mapasset.Data, out managedImage, out image)) |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 489b8ca..b859042 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | |||
@@ -1633,7 +1633,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1633 | if (action == DeRezAction.SaveToExistingUserInventoryItem) | 1633 | if (action == DeRezAction.SaveToExistingUserInventoryItem) |
1634 | permissionToDelete = false; | 1634 | permissionToDelete = false; |
1635 | 1635 | ||
1636 | // if we want to take a copy,, we also don't want to delete | 1636 | // if we want to take a copy, we also don't want to delete |
1637 | // Note: after this point, the permissionToTakeCopy flag | 1637 | // Note: after this point, the permissionToTakeCopy flag |
1638 | // becomes irrelevant. It already includes the permissionToTake | 1638 | // becomes irrelevant. It already includes the permissionToTake |
1639 | // permission and after excluding no copy items here, we can | 1639 | // permission and after excluding no copy items here, we can |
@@ -1644,6 +1644,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1644 | if (!permissionToTakeCopy) | 1644 | if (!permissionToTakeCopy) |
1645 | return; | 1645 | return; |
1646 | 1646 | ||
1647 | permissionToTake = true; | ||
1647 | // Don't delete | 1648 | // Don't delete |
1648 | permissionToDelete = false; | 1649 | permissionToDelete = false; |
1649 | } | 1650 | } |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 4a4cac9..e51d9ee 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -3730,8 +3730,11 @@ Console.WriteLine("Scripted Sit ofset {0}", m_pos); | |||
3730 | { | 3730 | { |
3731 | CollidingMessage.Colliders = colliding; | 3731 | CollidingMessage.Colliders = colliding; |
3732 | 3732 | ||
3733 | foreach (SceneObjectGroup att in Attachments) | 3733 | lock (m_attachments) |
3734 | Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage); | 3734 | { |
3735 | foreach (SceneObjectGroup att in m_attachments) | ||
3736 | Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage); | ||
3737 | } | ||
3735 | } | 3738 | } |
3736 | } | 3739 | } |
3737 | 3740 | ||
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 11d7c2b..f153504 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -3252,7 +3252,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
3252 | msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here | 3252 | msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here |
3253 | // m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); | 3253 | // m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); |
3254 | // m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); | 3254 | // m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); |
3255 | msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; | 3255 | DateTime dt = DateTime.UtcNow; |
3256 | |||
3257 | // Ticks from UtcNow, but make it look like local. Evil, huh? | ||
3258 | dt = DateTime.SpecifyKind(dt, DateTimeKind.Local); | ||
3259 | |||
3260 | try | ||
3261 | { | ||
3262 | // Convert that to the PST timezone | ||
3263 | TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles"); | ||
3264 | dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo); | ||
3265 | } | ||
3266 | catch | ||
3267 | { | ||
3268 | // No logging here, as it could be VERY spammy | ||
3269 | } | ||
3270 | |||
3271 | // And make it look local again to fool the unix time util | ||
3272 | dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc); | ||
3273 | |||
3274 | msg.timestamp = (uint)Util.ToUnixTime(dt); | ||
3275 | |||
3256 | //if (client != null) | 3276 | //if (client != null) |
3257 | //{ | 3277 | //{ |
3258 | msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; | 3278 | msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; |
diff --git a/OpenSim/Services/LLLoginService/LLLoginResponse.cs b/OpenSim/Services/LLLoginService/LLLoginResponse.cs index 6a2cbeb..240f5b1 100644 --- a/OpenSim/Services/LLLoginService/LLLoginResponse.cs +++ b/OpenSim/Services/LLLoginService/LLLoginResponse.cs | |||
@@ -175,6 +175,9 @@ namespace OpenSim.Services.LLLoginService | |||
175 | private string firstname; | 175 | private string firstname; |
176 | private string lastname; | 176 | private string lastname; |
177 | 177 | ||
178 | // Web map | ||
179 | private string mapTileURL; | ||
180 | |||
178 | // Error Flags | 181 | // Error Flags |
179 | private string errorReason; | 182 | private string errorReason; |
180 | private string errorMessage; | 183 | private string errorMessage; |
@@ -223,7 +226,7 @@ namespace OpenSim.Services.LLLoginService | |||
223 | public LLLoginResponse(UserAccount account, AgentCircuitData aCircuit, GridUserInfo pinfo, | 226 | public LLLoginResponse(UserAccount account, AgentCircuitData aCircuit, GridUserInfo pinfo, |
224 | GridRegion destination, List<InventoryFolderBase> invSkel, FriendInfo[] friendsList, ILibraryService libService, | 227 | GridRegion destination, List<InventoryFolderBase> invSkel, FriendInfo[] friendsList, ILibraryService libService, |
225 | string where, string startlocation, Vector3 position, Vector3 lookAt, List<InventoryItemBase> gestures, string message, | 228 | string where, string startlocation, Vector3 position, Vector3 lookAt, List<InventoryItemBase> gestures, string message, |
226 | GridRegion home, IPEndPoint clientIP) | 229 | GridRegion home, IPEndPoint clientIP, string mapTileURL) |
227 | : this() | 230 | : this() |
228 | { | 231 | { |
229 | FillOutInventoryData(invSkel, libService); | 232 | FillOutInventoryData(invSkel, libService); |
@@ -239,6 +242,7 @@ namespace OpenSim.Services.LLLoginService | |||
239 | Message = message; | 242 | Message = message; |
240 | BuddList = ConvertFriendListItem(friendsList); | 243 | BuddList = ConvertFriendListItem(friendsList); |
241 | StartLocation = where; | 244 | StartLocation = where; |
245 | MapTileURL = mapTileURL; | ||
242 | 246 | ||
243 | FillOutHomeData(pinfo, home); | 247 | FillOutHomeData(pinfo, home); |
244 | LookAt = String.Format("[r{0},r{1},r{2}]", lookAt.X, lookAt.Y, lookAt.Z); | 248 | LookAt = String.Format("[r{0},r{1},r{2}]", lookAt.X, lookAt.Y, lookAt.Z); |
@@ -411,6 +415,7 @@ namespace OpenSim.Services.LLLoginService | |||
411 | InitialOutfitHash["folder_name"] = "Nightclub Female"; | 415 | InitialOutfitHash["folder_name"] = "Nightclub Female"; |
412 | InitialOutfitHash["gender"] = "female"; | 416 | InitialOutfitHash["gender"] = "female"; |
413 | initialOutfit.Add(InitialOutfitHash); | 417 | initialOutfit.Add(InitialOutfitHash); |
418 | mapTileURL = String.Empty; | ||
414 | } | 419 | } |
415 | 420 | ||
416 | 421 | ||
@@ -474,6 +479,9 @@ namespace OpenSim.Services.LLLoginService | |||
474 | responseData["region_x"] = (Int32)(RegionX); | 479 | responseData["region_x"] = (Int32)(RegionX); |
475 | responseData["region_y"] = (Int32)(RegionY); | 480 | responseData["region_y"] = (Int32)(RegionY); |
476 | 481 | ||
482 | if (mapTileURL != String.Empty) | ||
483 | responseData["map-server-url"] = mapTileURL; | ||
484 | |||
477 | if (m_buddyList != null) | 485 | if (m_buddyList != null) |
478 | { | 486 | { |
479 | responseData["buddy-list"] = m_buddyList.ToArray(); | 487 | responseData["buddy-list"] = m_buddyList.ToArray(); |
@@ -570,6 +578,9 @@ namespace OpenSim.Services.LLLoginService | |||
570 | map["region_x"] = OSD.FromInteger(RegionX); | 578 | map["region_x"] = OSD.FromInteger(RegionX); |
571 | map["region_y"] = OSD.FromInteger(RegionY); | 579 | map["region_y"] = OSD.FromInteger(RegionY); |
572 | 580 | ||
581 | if (mapTileURL != String.Empty) | ||
582 | map["map-server-url"] = OSD.FromString(mapTileURL); | ||
583 | |||
573 | if (m_buddyList != null) | 584 | if (m_buddyList != null) |
574 | { | 585 | { |
575 | map["buddy-list"] = ArrayListToOSDArray(m_buddyList.ToArray()); | 586 | map["buddy-list"] = ArrayListToOSDArray(m_buddyList.ToArray()); |
@@ -653,7 +664,7 @@ namespace OpenSim.Services.LLLoginService | |||
653 | Hashtable TempHash; | 664 | Hashtable TempHash; |
654 | foreach (InventoryFolderBase InvFolder in folders) | 665 | foreach (InventoryFolderBase InvFolder in folders) |
655 | { | 666 | { |
656 | if (InvFolder.ParentID == UUID.Zero) | 667 | if (InvFolder.ParentID == UUID.Zero && InvFolder.Name == "My Inventory") |
657 | { | 668 | { |
658 | rootID = InvFolder.ID; | 669 | rootID = InvFolder.ID; |
659 | } | 670 | } |
@@ -921,6 +932,12 @@ namespace OpenSim.Services.LLLoginService | |||
921 | set { home = value; } | 932 | set { home = value; } |
922 | } | 933 | } |
923 | 934 | ||
935 | public string MapTileURL | ||
936 | { | ||
937 | get { return mapTileURL; } | ||
938 | set { mapTileURL = value; } | ||
939 | } | ||
940 | |||
924 | public string Message | 941 | public string Message |
925 | { | 942 | { |
926 | get { return welcomeMessage; } | 943 | get { return welcomeMessage; } |
diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs index 5c12a54..d27c26d 100644 --- a/OpenSim/Services/LLLoginService/LLLoginService.cs +++ b/OpenSim/Services/LLLoginService/LLLoginService.cs | |||
@@ -73,6 +73,7 @@ namespace OpenSim.Services.LLLoginService | |||
73 | protected int m_MinLoginLevel; | 73 | protected int m_MinLoginLevel; |
74 | protected string m_GatekeeperURL; | 74 | protected string m_GatekeeperURL; |
75 | protected bool m_AllowRemoteSetLoginLevel; | 75 | protected bool m_AllowRemoteSetLoginLevel; |
76 | protected string m_MapTileURL; | ||
76 | 77 | ||
77 | IConfig m_LoginServerConfig; | 78 | IConfig m_LoginServerConfig; |
78 | 79 | ||
@@ -100,6 +101,7 @@ namespace OpenSim.Services.LLLoginService | |||
100 | m_AllowRemoteSetLoginLevel = m_LoginServerConfig.GetBoolean("AllowRemoteSetLoginLevel", false); | 101 | m_AllowRemoteSetLoginLevel = m_LoginServerConfig.GetBoolean("AllowRemoteSetLoginLevel", false); |
101 | m_MinLoginLevel = m_LoginServerConfig.GetInt("MinLoginLevel", 0); | 102 | m_MinLoginLevel = m_LoginServerConfig.GetInt("MinLoginLevel", 0); |
102 | m_GatekeeperURL = m_LoginServerConfig.GetString("GatekeeperURI", string.Empty); | 103 | m_GatekeeperURL = m_LoginServerConfig.GetString("GatekeeperURI", string.Empty); |
104 | m_MapTileURL = m_LoginServerConfig.GetString("MapTileURL", string.Empty); | ||
103 | 105 | ||
104 | // These are required; the others aren't | 106 | // These are required; the others aren't |
105 | if (accountService == string.Empty || authService == string.Empty) | 107 | if (accountService == string.Empty || authService == string.Empty) |
@@ -362,7 +364,7 @@ namespace OpenSim.Services.LLLoginService | |||
362 | // Finally, fill out the response and return it | 364 | // Finally, fill out the response and return it |
363 | // | 365 | // |
364 | LLLoginResponse response = new LLLoginResponse(account, aCircuit, guinfo, destination, inventorySkel, friendsList, m_LibraryService, | 366 | LLLoginResponse response = new LLLoginResponse(account, aCircuit, guinfo, destination, inventorySkel, friendsList, m_LibraryService, |
365 | where, startLocation, position, lookAt, gestures, m_WelcomeMessage, home, clientIP); | 367 | where, startLocation, position, lookAt, gestures, m_WelcomeMessage, home, clientIP, m_MapTileURL); |
366 | 368 | ||
367 | m_log.DebugFormat("[LLOGIN SERVICE]: All clear. Sending login response to client."); | 369 | m_log.DebugFormat("[LLOGIN SERVICE]: All clear. Sending login response to client."); |
368 | return response; | 370 | return response; |