Compare commits
427 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0a949a20ca | |||
| bb3aa1440d | |||
| 1d4bee454e | |||
| d95e6ca0c6 | |||
| 78fd487a70 | |||
| 4ab479bf58 | |||
| 3e6043bb47 | |||
| 679533f632 | |||
| fb44e7b636 | |||
| 2b339bfd97 | |||
| f9dd4ed89c | |||
| a798b98f85 | |||
| 0838c5288f | |||
| 35fa8b454d | |||
| 4b278c64d6 | |||
| 78c0028179 | |||
| 27845de7ea | |||
| 0f277dfa17 | |||
| fb18476032 | |||
| 74776c4ee0 | |||
| 952ad59c1f | |||
| c066f528ef | |||
| 0591a85787 | |||
| d4a370a5f2 | |||
| 7c534e558d | |||
| 7a686ef124 | |||
| 931c28888b | |||
| 0d566aa385 | |||
| d4a6ed3d98 | |||
| 806082cd6e | |||
| 9637e50956 | |||
| b8eafc6280 | |||
| 5509d981d4 | |||
| cce760dbfc | |||
| 7d8bb33c5b | |||
| 4f4ca1625f | |||
| 90a2296983 | |||
| 70b5a2dace | |||
| 33e91f1088 | |||
| 4a58d4c5a4 | |||
| 3af1cd65f9 | |||
| 47108bb351 | |||
| f2903db390 | |||
| c3a8c00ce0 | |||
| 627efc172b | |||
| 908cebbea8 | |||
| 6a9f36788d | |||
| 4c32f79c10 | |||
| 7435582b70 | |||
| 25b3edc21c | |||
| 953fe46811 | |||
| 6eaff18961 | |||
| 8fd86c9156 | |||
| e324fb2415 | |||
| cdbe34716f | |||
| 1aab096a83 | |||
| de1d213117 | |||
| f494e6b086 | |||
| 2d9971ea93 | |||
| 67537f3596 | |||
| 8f45eb913c | |||
| e4406c846d | |||
| 600a86bcae | |||
| f266e19243 | |||
| e4a69297f6 | |||
| a5d6b624f6 | |||
| 36c8fa16c0 | |||
| 4fa5fa5e08 | |||
| d2cd39d0d8 | |||
| a4cb9639cc | |||
| 9a9923405a | |||
| 639c6bdd62 | |||
| 633f4bb3d8 | |||
| e480e25d8b | |||
| 7468299673 | |||
| b3ecf935cd | |||
| 4c5b3adb96 | |||
| 335d167ead | |||
| 36daea4480 | |||
| 5c92aa262a | |||
| 445caca18b | |||
| 4b90dcfb73 | |||
| ade1acc9d4 | |||
| e8eb9b7e84 | |||
| 6e7f13a72d | |||
| 32a953fed7 | |||
| f0406f9fe2 | |||
| 387d7fdad5 | |||
| 38d241a317 | |||
| 69fc8c4985 | |||
| c2b98cfd4e | |||
| 874140f950 | |||
| 5a8ed50639 | |||
| e5343bccdf | |||
| 269e479cdc | |||
| 3525c876c8 | |||
| 1ef62ca75e | |||
| bce7964ac2 | |||
| 59157d9d63 | |||
| b8d383da0a | |||
| 30db0ac5e2 | |||
| bf09d6a22b | |||
| 012b01f224 | |||
| cd3f3cbdde | |||
| 22a85b947a | |||
| 62b1c807c2 | |||
| bd83676d6c | |||
| 93ac47f0d3 | |||
| a1de9bc33f | |||
| c52ff5cf7b | |||
| 5a82d939e6 | |||
| 532e3dad26 | |||
| 964cae4f37 | |||
| d9f7b8549b | |||
| 7aa0c05fba | |||
| 33df0c2efd | |||
| 4138880464 | |||
| 6bf4d88397 | |||
| 874bf1f8e5 | |||
| 51dc1e709c | |||
| 03766c010f | |||
| af96b99356 | |||
| 614c404923 | |||
| 4007f62158 | |||
| 300968e933 | |||
| b24605d526 | |||
| 514a9fdf8e | |||
| 12d3ea3029 | |||
| a43e804e59 | |||
| 0463a00d34 | |||
| 8c0f1e9058 | |||
| 710c14fb57 | |||
| 445e8bc560 | |||
| cb41fb64be | |||
| 37603ca6da | |||
| db5f46fa23 | |||
| b74a89bc12 | |||
| 5e07336672 | |||
| 91950b3147 | |||
| 19837ff4dd | |||
| 5d37a31436 | |||
| 7223b63563 | |||
| 971d32fda3 | |||
| 0247d738e2 | |||
| de242a29ca | |||
| 2e2634896d | |||
| 8131a24cde | |||
| b78224176e | |||
| 09c85a6a6c | |||
| 1aa1a9eb3d | |||
| 872d513daa | |||
| 84c9bd52d3 | |||
| ad865ab4fc | |||
| 2fcdecf090 | |||
| f8879e06d2 | |||
| 3691e39178 | |||
| 3810e98474 | |||
| 7e0936e4b6 | |||
| 055269805d | |||
| 98a6c78943 | |||
| c9c01d5226 | |||
| ac0f1ff0a6 | |||
| d7cc194e83 | |||
| cb44808504 | |||
| a07fa0395f | |||
| a14437ad5a | |||
| 4f17537555 | |||
| f03c3c062e | |||
| f53c6b2594 | |||
| cf61c74e90 | |||
| 07388071d4 | |||
| ff54b3c366 | |||
| 3f53b7bc91 | |||
| 142de1d02f | |||
| 1273f259e4 | |||
| 2f6e8564fe | |||
| 1a738caeca | |||
| de24feb275 | |||
| 6ecdadb329 | |||
| b22d040169 | |||
| 6c50442625 | |||
| 975184b3f9 | |||
| 164706043d | |||
| 6b87a29c86 | |||
| d4beb2f5bc | |||
| e5b182fb41 | |||
| 54887bf386 | |||
| 4ed833bc9d | |||
| 349454ca27 | |||
| c0672cb7db | |||
| 176bba4f67 | |||
| 18b3f1132e | |||
| 4ee8b3e23e | |||
| a9995ede65 | |||
| bc2963d42a | |||
| 08b8ebcc7e | |||
| c903813e00 | |||
| 40b9b519b8 | |||
| efe61b2481 | |||
| 15c2499ccd | |||
| c1d064e1ca | |||
| 5bf45b9b98 | |||
| 760010d6fb | |||
| 3bcf71c647 | |||
| c4b2d24f33 | |||
| df624c13c9 | |||
| 25e5b6a76c | |||
| 6bc1ccf234 | |||
| b5d0bc2488 | |||
| 45b588cf00 | |||
| 6146e7ef25 | |||
| a8c87bab64 | |||
| c98e3a6422 | |||
| 06c81a2afe | |||
| 4bfd9e28ca | |||
| 9949ac2f9f | |||
| 71ec84d77f | |||
| 1a8769e6ef | |||
| 7783c93802 | |||
| cb2727cf6e | |||
| 6c55fd93a3 | |||
| 898a16802b | |||
| 3e7e166124 | |||
| eafc3d6c47 | |||
| 5170cd7577 | |||
| 4a9ca3ca8f | |||
| d8bcb78b10 | |||
| 8ad426f329 | |||
| 1089e9b842 | |||
| 5abe1b4fce | |||
| 91cc09b7bf | |||
| d49dd5573b | |||
| 54a8a5baba | |||
| de53aa32e0 | |||
| ab243f4a57 | |||
| 9671e43497 | |||
| 7a0d7be44c | |||
| 69a9a6993e | |||
| 91a001d3cf | |||
| 9e8b194356 | |||
| 742acc0a3c | |||
| f7c61790b7 | |||
| 022366a074 | |||
| 841b4232f6 | |||
| 3fa51f66ec | |||
| d08ad6459a | |||
| 7bf628ab31 | |||
| 4c41b53a4b | |||
| 02f9caf6ce | |||
| 3701f893d3 | |||
| c39fba8f9d | |||
| 8bdd38b804 | |||
| 30b2a8c778 | |||
| bd1f848bf6 | |||
| 9ed3532c1b | |||
| 86bd287b53 | |||
| 5f2a65c976 | |||
| a3abd65e3d | |||
| 8c911ddaf0 | |||
| 4cbaf053cf | |||
| 1c0f3a1f21 | |||
| e9271ec653 | |||
| e2b1c569da | |||
| 437f18bc41 | |||
| 4972491efb | |||
| ab54ce1907 | |||
| d1256536b5 | |||
| 441ef301a3 | |||
| 7dfa0309c6 | |||
| 92b1ade78e | |||
| 1a4fdd2666 | |||
| d87a5758fb | |||
| 33c14cb107 | |||
| 4a57112f19 | |||
| 1e4180fc93 | |||
| a4dca88a57 | |||
| a2009ffe2e | |||
| 59b6f6a6e0 | |||
| bece2023e7 | |||
| 9497a7c7bd | |||
| 922d8c9312 | |||
| 6e8f80f1ab | |||
| 05bb2e4275 | |||
| 05a1493fff | |||
| 421b562a04 | |||
| 78e992dbd0 | |||
| b19be657b6 | |||
| aa881e8065 | |||
| 34f6f87b6c | |||
| 8550a4a07e | |||
| c386b68373 | |||
| 7df4a544fe | |||
| a4b01ef38a | |||
| 0548eeb571 | |||
| 18d1d6d3b4 | |||
| df144eb9e2 | |||
| f52917288a | |||
| 5a9560db28 | |||
| e5612553ce | |||
| 8b5298a62e | |||
| 402ff75d78 | |||
| fd4ad82367 | |||
| 10731732b4 | |||
| 697ac7fd9d | |||
| acb1355ff2 | |||
| 2d32401e23 | |||
| f0c1746063 | |||
| 5ddda89238 | |||
| 2f81e53f63 | |||
| 12cebb12d5 | |||
| d6dd3c42d1 | |||
| 479dd65a63 | |||
| 5a09572393 | |||
| 95ec96bf86 | |||
| 37828c9b9a | |||
| 4eb2605c79 | |||
| 25592bbd85 | |||
| e0dd38f672 | |||
| 1547fe959e | |||
| 13fb582c12 | |||
| 824eb7ed20 | |||
| 291dc39691 | |||
| 05e821c444 | |||
| 6e26f17923 | |||
| 5507752dc5 | |||
| 1693799623 | |||
| 3a5928f813 | |||
| d6ebf2d6ca | |||
| 7b8e9d88e3 | |||
| bdc968f1fc | |||
| 5c5a493791 | |||
| 35f2479858 | |||
| a58152bd2a | |||
| 81869c4a3f | |||
| f545d669de | |||
| 7db5ba7702 | |||
| 06dda14505 | |||
| 205c36d3a4 | |||
| 94e58ff6b9 | |||
| b454326273 | |||
| c22446ede0 | |||
| 8a34d1b710 | |||
| 73c47f7205 | |||
| 42a7a85062 | |||
| df4b06aed1 | |||
| 034c9d6bcc | |||
| 3c5bd7c35a | |||
| 0cbdf9dad2 | |||
| 9c8ef96301 | |||
| 675d40357c | |||
| fa2a64564a | |||
| dfdb0e140c | |||
| 650d761c06 | |||
| 430304c176 | |||
| 749c3fef8a | |||
| 6bdea15ecf | |||
| a1b28a61a6 | |||
| 7769362687 | |||
| f3678d217f | |||
| 23aba007dd | |||
| 3376979923 | |||
| 98251cdab3 | |||
| e9d8eb5a27 | |||
| 0f4cdc0c5b | |||
| b3449e998a | |||
| a92153ed88 | |||
| 85198a45cb | |||
| 1dc03e5c4f | |||
| d44b7c486a | |||
| 413bc1e77e | |||
| 441449e240 | |||
| fd2b285b1b | |||
| ac934e2dbb | |||
| 33a154e446 | |||
| 3780df8a32 | |||
| 75dc8b1aed | |||
| 2535a4cafc | |||
| 94b323d1d8 | |||
| 7113b44bdd | |||
| 98ad6ed255 | |||
| e81b3502ef | |||
| c2c102d33e | |||
| 089fd61a3b | |||
| d242d47e5c | |||
| 6fc350725d | |||
| 64a036b4cf | |||
| 8d249f8456 | |||
| 6e3523e25e | |||
| 2a2656f629 | |||
| be4199c3bc | |||
| 8fccd2b555 | |||
| e8779cd9e5 | |||
| dd63cd1656 | |||
| ec48a2f32b | |||
| 94971bf3b9 | |||
| d8c4985527 | |||
| dcfd05c8ea | |||
| 8a375f3c30 | |||
| 7a88d21e59 | |||
| a2b0ed537e | |||
| 0007711eb5 | |||
| 255afbf08a | |||
| aabbbb32ff | |||
| 1e95b01f13 | |||
| 69c999033b | |||
| 1a54e76948 | |||
| df75f5ae37 | |||
| afc9a7d3f9 | |||
| 9f597c2d42 | |||
| a181fae722 | |||
| 40c838896c | |||
| 670c7842a4 | |||
| 2fce7dd593 | |||
| a813e7ffdd | |||
| 4268427ac3 | |||
| 142f8a4aec | |||
| 4177571a78 | |||
| 01f454242d | |||
| 4a5f9fe6a2 | |||
| 6159110258 | |||
| ca19b9078f | |||
| 6138662716 | |||
| 3fbcd21916 | |||
| af377470e1 | |||
| 165ae251ec | |||
| 67bea681e2 | |||
| 7cf970fb27 |
@@ -8,6 +8,24 @@
|
||||
<copy file="bin/OpenSim.ini.example" tofile="bin/OpenSim.ini"/>
|
||||
<copy file="bin/config-include/StandaloneCommon.ini.example" tofile="bin/config-include/StandaloneCommon.ini"/>
|
||||
<copy file="bin/config-include/FlotsamCache.ini.example" tofile="bin/config-include/FlotsamCache.ini"/>
|
||||
<!-- delete files generated by runprebuild.sh which had to be run in order to generate the build file for this target-->
|
||||
<delete>
|
||||
<fileset basedir="OpenSim">
|
||||
<include name="**/*.build"/>
|
||||
<include name="**/*.csproj*"/>
|
||||
<include name="**/*.dll.build"/>
|
||||
<include name="**/*.pidb"/>
|
||||
<exclude name="Tools/OpenSim.32BitLaunch/**"/>
|
||||
<exclude name="Tools/Robust.32BitLaunch/**"/>
|
||||
<exclude name="Tools/LaunchSLClient/**"/>
|
||||
</fileset>
|
||||
</delete>
|
||||
<delete>
|
||||
<fileset>
|
||||
<include name="OpenSim.build"/>
|
||||
<include name="OpenSim.sln"/>
|
||||
</fileset>
|
||||
</delete>
|
||||
</target>
|
||||
|
||||
<property name="distbindir" value="distbin" />
|
||||
|
||||
+6
-1
@@ -1,4 +1,4 @@
|
||||
The following people have contributed to OpenSim (Thank you
|
||||
<<<>>>>The following people have contributed to OpenSim (Thank you
|
||||
for your effort!)
|
||||
|
||||
= Current OpenSim Developers (in very rough order of appearance) =
|
||||
@@ -71,6 +71,7 @@ what it is today.
|
||||
* CharlieO
|
||||
* ChrisDown
|
||||
* Chris Yeoh (IBM)
|
||||
* controlbreak
|
||||
* coyled
|
||||
* Daedius
|
||||
* Dong Jun Lan (IBM)
|
||||
@@ -86,8 +87,10 @@ what it is today.
|
||||
* Grumly57
|
||||
* GuduleLapointe
|
||||
* Ewe Loon
|
||||
* Fernando Oliveira
|
||||
* Fly-Man
|
||||
* Flyte Xevious
|
||||
* Garmin Kawaguichi
|
||||
* Imaze Rhiano
|
||||
* Intimidated
|
||||
* Jeremy Bongio (IBM)
|
||||
@@ -106,6 +109,7 @@ what it is today.
|
||||
* M.Igarashi
|
||||
* maimedleech
|
||||
* Mana Janus
|
||||
* MarcelEdward
|
||||
* Mic Bowman
|
||||
* Michelle Argus
|
||||
* Michael Cortez (The Flotsam Project, http://osflotsam.org/)
|
||||
@@ -135,6 +139,7 @@ what it is today.
|
||||
* Ruud Lathorp
|
||||
* SachaMagne
|
||||
* Salahzar Stenvaag
|
||||
* satguru p srivastava
|
||||
* sempuki
|
||||
* SignpostMarv
|
||||
* SpotOn3D
|
||||
|
||||
@@ -135,7 +135,11 @@ namespace OpenSim.ApplicationPlugins.LoadRegions
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//[TODO]: Temporary fix for an issue after the mono-addis upgrade
|
||||
// PostInilise can fire before the region is loaded, so need to
|
||||
// track down the cause of that
|
||||
Thread.Sleep(300);
|
||||
m_openSim.ModuleLoader.PostInitialise();
|
||||
m_openSim.ModuleLoader.ClearCache();
|
||||
}
|
||||
|
||||
+2
-2
@@ -162,7 +162,7 @@ namespace OpenSim.Capabilities.Handlers
|
||||
invFetch.owner_id, invFetch.folder_id, invFetch.owner_id,
|
||||
invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version);
|
||||
|
||||
if (inv.Folders != null)
|
||||
if (inv != null && inv.Folders != null)
|
||||
{
|
||||
foreach (InventoryFolderBase invFolder in inv.Folders)
|
||||
{
|
||||
@@ -170,7 +170,7 @@ namespace OpenSim.Capabilities.Handlers
|
||||
}
|
||||
}
|
||||
|
||||
if (inv.Items != null)
|
||||
if (inv != null && inv.Items != null)
|
||||
{
|
||||
foreach (InventoryItemBase invItem in inv.Items)
|
||||
{
|
||||
|
||||
@@ -49,6 +49,7 @@ namespace OpenSim.Data
|
||||
bool Store(PresenceData data);
|
||||
|
||||
PresenceData Get(UUID sessionID);
|
||||
PresenceData Verify(UUID s_sessionID);
|
||||
void LogoutRegionAgents(UUID regionID);
|
||||
bool ReportAgent(UUID sessionID, UUID regionID);
|
||||
PresenceData[] Get(string field, string data);
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
|
||||
namespace OpenSim.Data
|
||||
{
|
||||
/// <summary>
|
||||
/// This interface exists to distinguish between the normal IAssetDataPlugin and the one used by XAssetService
|
||||
/// for now.
|
||||
/// </summary>
|
||||
public interface IXAssetDataPlugin : IPlugin
|
||||
{
|
||||
AssetBase GetAsset(UUID uuid);
|
||||
void StoreAsset(AssetBase asset);
|
||||
bool ExistsAsset(UUID uuid);
|
||||
List<AssetMetadata> FetchAssetMetadataSet(int start, int count);
|
||||
void Initialise(string connect);
|
||||
bool Delete(string id);
|
||||
}
|
||||
}
|
||||
@@ -89,5 +89,11 @@ namespace OpenSim.Data.MSSQL
|
||||
return DoQuery(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
public FriendsData[] GetFriends(Guid principalID)
|
||||
{
|
||||
return GetFriends(principalID.ToString());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -813,7 +813,7 @@ namespace OpenSim.Data.MSSQL
|
||||
{
|
||||
try
|
||||
{
|
||||
using (SqlCommand command = new SqlCommand("DELETE FROM inventoryfolders WHERE folderID=@folderID", connection))
|
||||
using (SqlCommand command = new SqlCommand("DELETE FROM inventoryfolders WHERE folderID=@folderID and type=-1", connection))
|
||||
{
|
||||
command.Parameters.Add(database.CreateParameter("folderID", folderID));
|
||||
|
||||
|
||||
@@ -104,6 +104,11 @@ namespace OpenSim.Data.MSSQL
|
||||
{
|
||||
return SqlDbType.BigInt;
|
||||
}
|
||||
if (type == typeof(DateTime))
|
||||
{
|
||||
return SqlDbType.DateTime;
|
||||
}
|
||||
|
||||
return SqlDbType.VarChar;
|
||||
}
|
||||
|
||||
|
||||
@@ -61,6 +61,17 @@ namespace OpenSim.Data.MSSQL
|
||||
return ret[0];
|
||||
}
|
||||
|
||||
public PresenceData Verify(UUID s_sessionID)
|
||||
{
|
||||
PresenceData[] ret = Get("SecureSessionID",
|
||||
s_sessionID.ToString());
|
||||
|
||||
if (ret.Length == 0)
|
||||
return null;
|
||||
|
||||
return ret[0];
|
||||
}
|
||||
|
||||
public void LogoutRegionAgents(UUID regionID)
|
||||
{
|
||||
using (SqlConnection conn = new SqlConnection(m_ConnectionString))
|
||||
|
||||
@@ -675,7 +675,7 @@ VALUES
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
sql = "INSERT INTO [landaccesslist] ([LandUUID],[AccessUUID],[Flags]) VALUES (@LandUUID,@AccessUUID,@Flags)";
|
||||
sql = "INSERT INTO [landaccesslist] ([LandUUID],[AccessUUID],[Flags],[Expires]) VALUES (@LandUUID,@AccessUUID,@Flags,@Expires)";
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
@@ -1215,6 +1215,8 @@ VALUES
|
||||
//Store new values
|
||||
StoreNewRegionSettings(regionSettings);
|
||||
|
||||
LoadSpawnPoints(regionSettings);
|
||||
|
||||
return regionSettings;
|
||||
}
|
||||
|
||||
@@ -1252,7 +1254,7 @@ VALUES
|
||||
,[elevation_1_ne] = @elevation_1_ne ,[elevation_2_ne] = @elevation_2_ne ,[elevation_1_se] = @elevation_1_se ,[elevation_2_se] = @elevation_2_se
|
||||
,[elevation_1_sw] = @elevation_1_sw ,[elevation_2_sw] = @elevation_2_sw ,[water_height] = @water_height ,[terrain_raise_limit] = @terrain_raise_limit
|
||||
,[terrain_lower_limit] = @terrain_lower_limit ,[use_estate_sun] = @use_estate_sun ,[fixed_sun] = @fixed_sun ,[sun_position] = @sun_position
|
||||
,[covenant] = @covenant ,[covenant_datetime] = @covenant_datetime, [sunvectorx] = @sunvectorx, [sunvectory] = @sunvectory, [sunvectorz] = @sunvectorz, [Sandbox] = @Sandbox, [loaded_creation_datetime] = @loaded_creation_datetime, [loaded_creation_id] = @loaded_creation_id
|
||||
,[covenant] = @covenant ,[covenant_datetime] = @covenant_datetime, [sunvectorx] = @sunvectorx, [sunvectory] = @sunvectory, [sunvectorz] = @sunvectorz, [Sandbox] = @Sandbox, [loaded_creation_datetime] = @loaded_creation_datetime, [loaded_creation_id] = @loaded_creation_id, [map_tile_id] = @TerrainImageID, [telehubobject] = @telehubobject, [parcel_tile_id] = @ParcelImageID
|
||||
WHERE [regionUUID] = @regionUUID";
|
||||
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
@@ -1263,6 +1265,7 @@ VALUES
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
SaveSpawnPoints(regionSettings);
|
||||
}
|
||||
|
||||
public void Shutdown()
|
||||
@@ -1367,7 +1370,7 @@ VALUES
|
||||
newSettings.TerrainRaiseLimit = Convert.ToDouble(row["terrain_raise_limit"]);
|
||||
newSettings.TerrainLowerLimit = Convert.ToDouble(row["terrain_lower_limit"]);
|
||||
newSettings.UseEstateSun = Convert.ToBoolean(row["use_estate_sun"]);
|
||||
newSettings.Sandbox = Convert.ToBoolean(row["sandbox"]);
|
||||
newSettings.Sandbox = Convert.ToBoolean(row["Sandbox"]);
|
||||
newSettings.FixedSun = Convert.ToBoolean(row["fixed_sun"]);
|
||||
newSettings.SunPosition = Convert.ToDouble(row["sun_position"]);
|
||||
newSettings.SunVector = new Vector3(
|
||||
@@ -1383,6 +1386,11 @@ VALUES
|
||||
newSettings.LoadedCreationID = "";
|
||||
else
|
||||
newSettings.LoadedCreationID = (String)row["loaded_creation_id"];
|
||||
|
||||
newSettings.TerrainImageID = new UUID((string)row["map_tile_ID"]);
|
||||
newSettings.ParcelImageID = new UUID((Guid)row["parcel_tile_ID"]);
|
||||
newSettings.TelehubObject = new UUID((Guid)row["TelehubObject"]);
|
||||
|
||||
return newSettings;
|
||||
}
|
||||
|
||||
@@ -1454,6 +1462,13 @@ VALUES
|
||||
}
|
||||
|
||||
newData.ParcelAccessList = new List<LandAccessEntry>();
|
||||
newData.MediaDescription = (string)row["MediaDescription"];
|
||||
newData.MediaType = (string)row["MediaType"];
|
||||
newData.MediaWidth = Convert.ToInt32((((string)row["MediaSize"]).Split(','))[0]);
|
||||
newData.MediaHeight = Convert.ToInt32((((string)row["MediaSize"]).Split(','))[1]);
|
||||
newData.MediaLoop = Convert.ToBoolean(row["MediaLoop"]);
|
||||
newData.ObscureMusic = Convert.ToBoolean(row["ObscureMusic"]);
|
||||
newData.ObscureMedia = Convert.ToBoolean(row["ObscureMedia"]);
|
||||
|
||||
return newData;
|
||||
}
|
||||
@@ -1468,7 +1483,7 @@ VALUES
|
||||
LandAccessEntry entry = new LandAccessEntry();
|
||||
entry.AgentID = new UUID((Guid)row["AccessUUID"]);
|
||||
entry.Flags = (AccessList)Convert.ToInt32(row["Flags"]);
|
||||
entry.Expires = 0;
|
||||
entry.Expires = Convert.ToInt32(row["Expires"]);
|
||||
return entry;
|
||||
}
|
||||
|
||||
@@ -1497,7 +1512,8 @@ VALUES
|
||||
prim.TouchName = (string)primRow["TouchName"];
|
||||
// permissions
|
||||
prim.Flags = (PrimFlags)Convert.ToUInt32(primRow["ObjectFlags"]);
|
||||
prim.CreatorID = new UUID((Guid)primRow["CreatorID"]);
|
||||
//prim.CreatorID = new UUID((Guid)primRow["CreatorID"]);
|
||||
prim.CreatorIdentification = (string)primRow["CreatorID"];
|
||||
prim.OwnerID = new UUID((Guid)primRow["OwnerID"]);
|
||||
prim.GroupID = new UUID((Guid)primRow["GroupID"]);
|
||||
prim.LastOwnerID = new UUID((Guid)primRow["LastOwnerID"]);
|
||||
@@ -1691,7 +1707,8 @@ VALUES
|
||||
taskItem.Name = (string)inventoryRow["name"];
|
||||
taskItem.Description = (string)inventoryRow["description"];
|
||||
taskItem.CreationDate = Convert.ToUInt32(inventoryRow["creationDate"]);
|
||||
taskItem.CreatorID = new UUID((Guid)inventoryRow["creatorID"]);
|
||||
//taskItem.CreatorID = new UUID((Guid)inventoryRow["creatorID"]);
|
||||
taskItem.CreatorIdentification = (string)inventoryRow["creatorID"];
|
||||
taskItem.OwnerID = new UUID((Guid)inventoryRow["ownerID"]);
|
||||
taskItem.LastOwnerID = new UUID((Guid)inventoryRow["lastOwnerID"]);
|
||||
taskItem.GroupID = new UUID((Guid)inventoryRow["groupID"]);
|
||||
@@ -1782,7 +1799,7 @@ VALUES
|
||||
parameters.Add(_Database.CreateParameter("terrain_raise_limit", settings.TerrainRaiseLimit));
|
||||
parameters.Add(_Database.CreateParameter("terrain_lower_limit", settings.TerrainLowerLimit));
|
||||
parameters.Add(_Database.CreateParameter("use_estate_sun", settings.UseEstateSun));
|
||||
parameters.Add(_Database.CreateParameter("sandbox", settings.Sandbox));
|
||||
parameters.Add(_Database.CreateParameter("Sandbox", settings.Sandbox));
|
||||
parameters.Add(_Database.CreateParameter("fixed_sun", settings.FixedSun));
|
||||
parameters.Add(_Database.CreateParameter("sun_position", settings.SunPosition));
|
||||
parameters.Add(_Database.CreateParameter("sunvectorx", settings.SunVector.X));
|
||||
@@ -1792,6 +1809,9 @@ VALUES
|
||||
parameters.Add(_Database.CreateParameter("covenant_datetime", settings.CovenantChangedDateTime));
|
||||
parameters.Add(_Database.CreateParameter("Loaded_Creation_DateTime", settings.LoadedCreationDateTime));
|
||||
parameters.Add(_Database.CreateParameter("Loaded_Creation_ID", settings.LoadedCreationID));
|
||||
parameters.Add(_Database.CreateParameter("TerrainImageID", settings.TerrainImageID));
|
||||
parameters.Add(_Database.CreateParameter("ParcelImageID", settings.ParcelImageID));
|
||||
parameters.Add(_Database.CreateParameter("TelehubObject", settings.TelehubObject));
|
||||
|
||||
return parameters.ToArray();
|
||||
}
|
||||
@@ -1859,6 +1879,7 @@ VALUES
|
||||
parameters.Add(_Database.CreateParameter("LandUUID", parcelID));
|
||||
parameters.Add(_Database.CreateParameter("AccessUUID", parcelAccessEntry.AgentID));
|
||||
parameters.Add(_Database.CreateParameter("Flags", parcelAccessEntry.Flags));
|
||||
parameters.Add(_Database.CreateParameter("Expires", parcelAccessEntry.Expires));
|
||||
|
||||
return parameters.ToArray();
|
||||
}
|
||||
@@ -2063,5 +2084,57 @@ VALUES
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
private void LoadSpawnPoints(RegionSettings rs)
|
||||
{
|
||||
rs.ClearSpawnPoints();
|
||||
|
||||
string sql = "SELECT Yaw, Pitch, Distance FROM spawn_points WHERE RegionUUID = @RegionUUID";
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", rs.RegionUUID.ToString()));
|
||||
conn.Open();
|
||||
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
SpawnPoint sp = new SpawnPoint();
|
||||
|
||||
sp.Yaw = (float)reader["Yaw"];
|
||||
sp.Pitch = (float)reader["Pitch"];
|
||||
sp.Distance = (float)reader["Distance"];
|
||||
|
||||
rs.AddSpawnPoint(sp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveSpawnPoints(RegionSettings rs)
|
||||
{
|
||||
string sql = "DELETE FROM spawn_points WHERE RegionUUID = @RegionUUID";
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", rs.RegionUUID));
|
||||
conn.Open();
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
foreach (SpawnPoint p in rs.SpawnPoints())
|
||||
{
|
||||
sql = "INSERT INTO spawn_points (RegionUUID, Yaw, Pitch, Distance) VALUES (@RegionUUID, @Yaw, @Pitch, @Distance)";
|
||||
using (SqlConnection conn = new SqlConnection(m_connectionString))
|
||||
using (SqlCommand cmd = new SqlCommand(sql, conn))
|
||||
{
|
||||
cmd.Parameters.Add(_Database.CreateParameter("@RegionUUID", rs.RegionUUID));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("@Yaw", p.Yaw));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("@Pitch", p.Pitch));
|
||||
cmd.Parameters.Add(_Database.CreateParameter("@Distance", p.Distance));
|
||||
conn.Open();
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1044,10 +1044,93 @@ ALTER TABLE primitems ALTER COLUMN CreatorID uniqueidentifier NOT NULL
|
||||
|
||||
COMMIT
|
||||
|
||||
:VERSION 29 #---------------------
|
||||
:VERSION 29 #----------------- Region Covenant changed time
|
||||
|
||||
BEGIN TRANSACTION
|
||||
|
||||
ALTER TABLE regionsettings ADD covenant_datetime int NOT NULL default 0
|
||||
|
||||
COMMIT
|
||||
|
||||
:VERSION 30 #------------------Migrate creatorID storage to varchars instead of UUIDs for HG support
|
||||
|
||||
BEGIN TRANSACTION
|
||||
|
||||
EXECUTE sp_rename N'dbo.prims.creatorid', N'creatoridold', 'COLUMN'
|
||||
EXECUTE sp_rename N'dbo.primitems.creatorid', N'creatoridold', 'COLUMN'
|
||||
|
||||
COMMIT
|
||||
|
||||
:VERSION 31 #---------------------
|
||||
|
||||
BEGIN TRANSACTION
|
||||
|
||||
ALTER TABLE prims ADD CreatorID varchar(255)
|
||||
ALTER TABLE primitems ADD CreatorID varchar(255)
|
||||
|
||||
COMMIT
|
||||
|
||||
:VERSION 32 #---------------------
|
||||
|
||||
BEGIN TRANSACTION
|
||||
|
||||
UPDATE prims SET prims.CreatorID = CONVERT(varchar(255), creatoridold)
|
||||
UPDATE primitems SET primitems.CreatorID = CONVERT(varchar(255), creatoridold)
|
||||
|
||||
COMMIT
|
||||
|
||||
:VERSION 33 #---------------------
|
||||
|
||||
BEGIN TRANSACTION
|
||||
|
||||
ALTER TABLE prims
|
||||
ADD CONSTRAINT DF_prims_CreatorIDNew
|
||||
DEFAULT '00000000-0000-0000-0000-000000000000'
|
||||
FOR CreatorID
|
||||
|
||||
ALTER TABLE prims ALTER COLUMN CreatorID varchar(255) NOT NULL
|
||||
|
||||
ALTER TABLE primitems
|
||||
ADD CONSTRAINT DF_primitems_CreatorIDNew
|
||||
DEFAULT '00000000-0000-0000-0000-000000000000'
|
||||
FOR CreatorID
|
||||
|
||||
ALTER TABLE primitems ALTER COLUMN CreatorID varchar(255) NOT NULL
|
||||
|
||||
COMMIT
|
||||
|
||||
:VERSION 34 #--------------- Telehub support
|
||||
|
||||
BEGIN TRANSACTION
|
||||
|
||||
CREATE TABLE [dbo].[Spawn_Points](
|
||||
[RegionUUID] [uniqueidentifier] NOT NULL,
|
||||
[Yaw] [float] NOT NULL,
|
||||
[Pitch] [float] NOT NULL,
|
||||
[Distance] [float] NOT NULL,
|
||||
PRIMARY KEY CLUSTERED
|
||||
(
|
||||
[RegionUUID] ASC
|
||||
)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
|
||||
) ON [PRIMARY]
|
||||
|
||||
ALTER TABLE regionsettings ADD TelehubObject uniqueidentifier NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000';
|
||||
|
||||
COMMIT
|
||||
|
||||
:VERSION 35 #---------------- Parcels for sale
|
||||
|
||||
BEGIN TRANSACTION
|
||||
|
||||
ALTER TABLE regionsettings ADD parcel_tile_ID uniqueidentifier NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000';
|
||||
|
||||
COMMIT
|
||||
|
||||
:VERSION 36 #---------------- Timed bans/access
|
||||
|
||||
BEGIN TRANSACTION
|
||||
|
||||
ALTER TABLE landaccesslist ADD Expires integer NOT NULL DEFAULT 0;
|
||||
|
||||
COMMIT
|
||||
|
||||
|
||||
@@ -61,6 +61,17 @@ namespace OpenSim.Data.MySQL
|
||||
return ret[0];
|
||||
}
|
||||
|
||||
public PresenceData Verify(UUID s_sessionID)
|
||||
{
|
||||
PresenceData[] ret = Get("SecureSessionID",
|
||||
s_sessionID.ToString());
|
||||
|
||||
if (ret.Length == 0)
|
||||
return null;
|
||||
|
||||
return ret[0];
|
||||
}
|
||||
|
||||
public void LogoutRegionAgents(UUID regionID)
|
||||
{
|
||||
MySqlCommand cmd = new MySqlCommand();
|
||||
|
||||
@@ -1283,7 +1283,7 @@ namespace OpenSim.Data.MySQL
|
||||
newSettings.TerrainRaiseLimit = Convert.ToDouble(row["terrain_raise_limit"]);
|
||||
newSettings.TerrainLowerLimit = Convert.ToDouble(row["terrain_lower_limit"]);
|
||||
newSettings.UseEstateSun = Convert.ToBoolean(row["use_estate_sun"]);
|
||||
newSettings.Sandbox = Convert.ToBoolean(row["sandbox"]);
|
||||
newSettings.Sandbox = Convert.ToBoolean(row["Sandbox"]);
|
||||
newSettings.SunVector = new Vector3 (
|
||||
Convert.ToSingle(row["sunvectorx"]),
|
||||
Convert.ToSingle(row["sunvectory"]),
|
||||
|
||||
@@ -0,0 +1,500 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Reflection;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using log4net;
|
||||
using MySql.Data.MySqlClient;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Data;
|
||||
|
||||
namespace OpenSim.Data.MySQL
|
||||
{
|
||||
public class MySQLXAssetData : IXAssetDataPlugin
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
protected virtual Assembly Assembly
|
||||
{
|
||||
get { return GetType().Assembly; }
|
||||
}
|
||||
|
||||
private bool m_enableCompression = false;
|
||||
private string m_connectionString;
|
||||
private object m_dbLock = new object();
|
||||
|
||||
/// <summary>
|
||||
/// We can reuse this for all hashing since all methods are single-threaded through m_dbBLock
|
||||
/// </summary>
|
||||
private HashAlgorithm hasher = new SHA256CryptoServiceProvider();
|
||||
|
||||
#region IPlugin Members
|
||||
|
||||
public string Version { get { return "1.0.0.0"; } }
|
||||
|
||||
/// <summary>
|
||||
/// <para>Initialises Asset interface</para>
|
||||
/// <para>
|
||||
/// <list type="bullet">
|
||||
/// <item>Loads and initialises the MySQL storage plugin.</item>
|
||||
/// <item>Warns and uses the obsolete mysql_connection.ini if connect string is empty.</item>
|
||||
/// <item>Check for migration</item>
|
||||
/// </list>
|
||||
/// </para>
|
||||
/// </summary>
|
||||
/// <param name="connect">connect string</param>
|
||||
public void Initialise(string connect)
|
||||
{
|
||||
m_log.ErrorFormat("[MYSQL XASSETDATA]: ***********************************************************");
|
||||
m_log.ErrorFormat("[MYSQL XASSETDATA]: ***********************************************************");
|
||||
m_log.ErrorFormat("[MYSQL XASSETDATA]: ***********************************************************");
|
||||
m_log.ErrorFormat("[MYSQL XASSETDATA]: THIS PLUGIN IS STRICTLY EXPERIMENTAL.");
|
||||
m_log.ErrorFormat("[MYSQL XASSETDATA]: DO NOT USE FOR ANY DATA THAT YOU DO NOT MIND LOSING.");
|
||||
m_log.ErrorFormat("[MYSQL XASSETDATA]: DATABASE TABLES CAN CHANGE AT ANY TIME, CAUSING EXISTING DATA TO BE LOST.");
|
||||
m_log.ErrorFormat("[MYSQL XASSETDATA]: ***********************************************************");
|
||||
m_log.ErrorFormat("[MYSQL XASSETDATA]: ***********************************************************");
|
||||
m_log.ErrorFormat("[MYSQL XASSETDATA]: ***********************************************************");
|
||||
|
||||
m_connectionString = connect;
|
||||
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
dbcon.Open();
|
||||
Migration m = new Migration(dbcon, Assembly, "XAssetStore");
|
||||
m.Update();
|
||||
}
|
||||
}
|
||||
|
||||
public void Initialise()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Dispose() { }
|
||||
|
||||
/// <summary>
|
||||
/// The name of this DB provider
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get { return "MySQL XAsset storage engine"; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IAssetDataPlugin Members
|
||||
|
||||
/// <summary>
|
||||
/// Fetch Asset <paramref name="assetID"/> from database
|
||||
/// </summary>
|
||||
/// <param name="assetID">Asset UUID to fetch</param>
|
||||
/// <returns>Return the asset</returns>
|
||||
/// <remarks>On failure : throw an exception and attempt to reconnect to database</remarks>
|
||||
public AssetBase GetAsset(UUID assetID)
|
||||
{
|
||||
// m_log.DebugFormat("[MYSQL XASSET DATA]: Looking for asset {0}", assetID);
|
||||
|
||||
AssetBase asset = null;
|
||||
lock (m_dbLock)
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd = new MySqlCommand(
|
||||
"SELECT name, description, asset_type, local, temporary, asset_flags, creator_id, data FROM xassetsmeta JOIN xassetsdata ON xassetsmeta.hash = xassetsdata.hash WHERE id=?id",
|
||||
dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("?id", assetID.ToString());
|
||||
|
||||
try
|
||||
{
|
||||
using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
|
||||
{
|
||||
if (dbReader.Read())
|
||||
{
|
||||
asset = new AssetBase(assetID, (string)dbReader["name"], (sbyte)dbReader["asset_type"], dbReader["creator_id"].ToString());
|
||||
asset.Data = (byte[])dbReader["data"];
|
||||
asset.Description = (string)dbReader["description"];
|
||||
|
||||
string local = dbReader["local"].ToString();
|
||||
if (local.Equals("1") || local.Equals("true", StringComparison.InvariantCultureIgnoreCase))
|
||||
asset.Local = true;
|
||||
else
|
||||
asset.Local = false;
|
||||
|
||||
asset.Temporary = Convert.ToBoolean(dbReader["temporary"]);
|
||||
asset.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]);
|
||||
|
||||
if (m_enableCompression)
|
||||
{
|
||||
using (GZipStream decompressionStream = new GZipStream(new MemoryStream(asset.Data), CompressionMode.Decompress))
|
||||
{
|
||||
MemoryStream outputStream = new MemoryStream();
|
||||
WebUtil.CopyStream(decompressionStream, outputStream, int.MaxValue);
|
||||
// int compressedLength = asset.Data.Length;
|
||||
asset.Data = outputStream.ToArray();
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[XASSET DB]: Decompressed {0} {1} to {2} bytes from {3}",
|
||||
// asset.ID, asset.Name, asset.Data.Length, compressedLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error("[MYSQL XASSET DATA]: MySql failure fetching asset " + assetID + ": " + e.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return asset;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create an asset in database, or update it if existing.
|
||||
/// </summary>
|
||||
/// <param name="asset">Asset UUID to create</param>
|
||||
/// <remarks>On failure : Throw an exception and attempt to reconnect to database</remarks>
|
||||
public void StoreAsset(AssetBase asset)
|
||||
{
|
||||
lock (m_dbLock)
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlTransaction transaction = dbcon.BeginTransaction())
|
||||
{
|
||||
string assetName = asset.Name;
|
||||
if (asset.Name.Length > 64)
|
||||
{
|
||||
assetName = asset.Name.Substring(0, 64);
|
||||
m_log.Warn("[XASSET DB]: Name field truncated from " + asset.Name.Length + " to " + assetName.Length + " characters on add");
|
||||
}
|
||||
|
||||
string assetDescription = asset.Description;
|
||||
if (asset.Description.Length > 64)
|
||||
{
|
||||
assetDescription = asset.Description.Substring(0, 64);
|
||||
m_log.Warn("[XASSET DB]: Description field truncated from " + asset.Description.Length + " to " + assetDescription.Length + " characters on add");
|
||||
}
|
||||
|
||||
if (m_enableCompression)
|
||||
{
|
||||
MemoryStream outputStream = new MemoryStream();
|
||||
|
||||
using (GZipStream compressionStream = new GZipStream(outputStream, CompressionMode.Compress, false))
|
||||
{
|
||||
// Console.WriteLine(WebUtil.CopyTo(new MemoryStream(asset.Data), compressionStream, int.MaxValue));
|
||||
// We have to close the compression stream in order to make sure it writes everything out to the underlying memory output stream.
|
||||
compressionStream.Close();
|
||||
byte[] compressedData = outputStream.ToArray();
|
||||
asset.Data = compressedData;
|
||||
}
|
||||
}
|
||||
|
||||
byte[] hash = hasher.ComputeHash(asset.Data);
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[XASSET DB]: Compressed data size for {0} {1}, hash {2} is {3}",
|
||||
// asset.ID, asset.Name, hash, compressedData.Length);
|
||||
|
||||
try
|
||||
{
|
||||
using (MySqlCommand cmd =
|
||||
new MySqlCommand(
|
||||
"replace INTO xassetsmeta(id, hash, name, description, asset_type, local, temporary, create_time, access_time, asset_flags, creator_id)" +
|
||||
"VALUES(?id, ?hash, ?name, ?description, ?asset_type, ?local, ?temporary, ?create_time, ?access_time, ?asset_flags, ?creator_id)",
|
||||
dbcon))
|
||||
{
|
||||
// create unix epoch time
|
||||
int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
|
||||
cmd.Parameters.AddWithValue("?id", asset.ID);
|
||||
cmd.Parameters.AddWithValue("?hash", hash);
|
||||
cmd.Parameters.AddWithValue("?name", assetName);
|
||||
cmd.Parameters.AddWithValue("?description", assetDescription);
|
||||
cmd.Parameters.AddWithValue("?asset_type", asset.Type);
|
||||
cmd.Parameters.AddWithValue("?local", asset.Local);
|
||||
cmd.Parameters.AddWithValue("?temporary", asset.Temporary);
|
||||
cmd.Parameters.AddWithValue("?create_time", now);
|
||||
cmd.Parameters.AddWithValue("?access_time", now);
|
||||
cmd.Parameters.AddWithValue("?creator_id", asset.Metadata.CreatorID);
|
||||
cmd.Parameters.AddWithValue("?asset_flags", (int)asset.Flags);
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset metadata {0} with name \"{1}\". Error: {2}",
|
||||
asset.FullID, asset.Name, e.Message);
|
||||
|
||||
transaction.Rollback();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ExistsData(dbcon, transaction, hash))
|
||||
{
|
||||
try
|
||||
{
|
||||
using (MySqlCommand cmd =
|
||||
new MySqlCommand(
|
||||
"INSERT INTO xassetsdata(hash, data) VALUES(?hash, ?data)",
|
||||
dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("?hash", hash);
|
||||
cmd.Parameters.AddWithValue("?data", asset.Data);
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[XASSET DB]: MySQL failure creating asset data {0} with name \"{1}\". Error: {2}",
|
||||
asset.FullID, asset.Name, e.Message);
|
||||
|
||||
transaction.Rollback();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
transaction.Commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// private void UpdateAccessTime(AssetBase asset)
|
||||
// {
|
||||
// lock (m_dbLock)
|
||||
// {
|
||||
// using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
// {
|
||||
// dbcon.Open();
|
||||
// MySqlCommand cmd =
|
||||
// new MySqlCommand("update assets set access_time=?access_time where id=?id",
|
||||
// dbcon);
|
||||
//
|
||||
// // need to ensure we dispose
|
||||
// try
|
||||
// {
|
||||
// using (cmd)
|
||||
// {
|
||||
// // create unix epoch time
|
||||
// int now = (int)Utils.DateTimeToUnixTime(DateTime.UtcNow);
|
||||
// cmd.Parameters.AddWithValue("?id", asset.ID);
|
||||
// cmd.Parameters.AddWithValue("?access_time", now);
|
||||
// cmd.ExecuteNonQuery();
|
||||
// cmd.Dispose();
|
||||
// }
|
||||
// }
|
||||
// catch (Exception e)
|
||||
// {
|
||||
// m_log.ErrorFormat(
|
||||
// "[ASSETS DB]: " +
|
||||
// "MySql failure updating access_time for asset {0} with name {1}" + Environment.NewLine + e.ToString()
|
||||
// + Environment.NewLine + "Attempting reconnection", asset.FullID, asset.Name);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// We assume we already have the m_dbLock.
|
||||
/// </summary>
|
||||
/// TODO: need to actually use the transaction.
|
||||
/// <param name="dbcon"></param>
|
||||
/// <param name="transaction"></param>
|
||||
/// <param name="hash"></param>
|
||||
/// <returns></returns>
|
||||
private bool ExistsData(MySqlConnection dbcon, MySqlTransaction transaction, byte[] hash)
|
||||
{
|
||||
// m_log.DebugFormat("[ASSETS DB]: Checking for asset {0}", uuid);
|
||||
|
||||
bool exists = false;
|
||||
|
||||
using (MySqlCommand cmd = new MySqlCommand("SELECT hash FROM xassetsdata WHERE hash=?hash", dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("?hash", hash);
|
||||
|
||||
try
|
||||
{
|
||||
using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
|
||||
{
|
||||
if (dbReader.Read())
|
||||
{
|
||||
// m_log.DebugFormat("[ASSETS DB]: Found asset {0}", uuid);
|
||||
exists = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[XASSETS DB]: MySql failure in ExistsData fetching hash {0}. Exception {1}{2}",
|
||||
hash, e.Message, e.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
return exists;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if the asset exists in the database
|
||||
/// </summary>
|
||||
/// <param name="uuid">The asset UUID</param>
|
||||
/// <returns>true if it exists, false otherwise.</returns>
|
||||
public bool ExistsAsset(UUID uuid)
|
||||
{
|
||||
// m_log.DebugFormat("[ASSETS DB]: Checking for asset {0}", uuid);
|
||||
|
||||
bool assetExists = false;
|
||||
|
||||
lock (m_dbLock)
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
dbcon.Open();
|
||||
using (MySqlCommand cmd = new MySqlCommand("SELECT id FROM xassetsmeta WHERE id=?id", dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("?id", uuid.ToString());
|
||||
|
||||
try
|
||||
{
|
||||
using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow))
|
||||
{
|
||||
if (dbReader.Read())
|
||||
{
|
||||
// m_log.DebugFormat("[ASSETS DB]: Found asset {0}", uuid);
|
||||
assetExists = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[XASSETS DB]: MySql failure fetching asset {0}" + Environment.NewLine + e.ToString(), uuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return assetExists;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of AssetMetadata objects. The list is a subset of
|
||||
/// the entire data set offset by <paramref name="start" /> containing
|
||||
/// <paramref name="count" /> elements.
|
||||
/// </summary>
|
||||
/// <param name="start">The number of results to discard from the total data set.</param>
|
||||
/// <param name="count">The number of rows the returned list should contain.</param>
|
||||
/// <returns>A list of AssetMetadata objects.</returns>
|
||||
public List<AssetMetadata> FetchAssetMetadataSet(int start, int count)
|
||||
{
|
||||
List<AssetMetadata> retList = new List<AssetMetadata>(count);
|
||||
|
||||
lock (m_dbLock)
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
dbcon.Open();
|
||||
MySqlCommand cmd = new MySqlCommand("SELECT name,description,asset_type,temporary,id,asset_flags,creator_id FROM xassetsmeta LIMIT ?start, ?count", dbcon);
|
||||
cmd.Parameters.AddWithValue("?start", start);
|
||||
cmd.Parameters.AddWithValue("?count", count);
|
||||
|
||||
try
|
||||
{
|
||||
using (MySqlDataReader dbReader = cmd.ExecuteReader())
|
||||
{
|
||||
while (dbReader.Read())
|
||||
{
|
||||
AssetMetadata metadata = new AssetMetadata();
|
||||
metadata.Name = (string)dbReader["name"];
|
||||
metadata.Description = (string)dbReader["description"];
|
||||
metadata.Type = (sbyte)dbReader["asset_type"];
|
||||
metadata.Temporary = Convert.ToBoolean(dbReader["temporary"]); // Not sure if this is correct.
|
||||
metadata.Flags = (AssetFlags)Convert.ToInt32(dbReader["asset_flags"]);
|
||||
metadata.FullID = DBGuid.FromDB(dbReader["id"]);
|
||||
metadata.CreatorID = dbReader["creator_id"].ToString();
|
||||
|
||||
// We'll ignore this for now - it appears unused!
|
||||
// metadata.SHA1 = dbReader["hash"]);
|
||||
|
||||
retList.Add(metadata);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error("[XASSETS DB]: MySql failure fetching asset set" + Environment.NewLine + e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retList;
|
||||
}
|
||||
|
||||
public bool Delete(string id)
|
||||
{
|
||||
// m_log.DebugFormat("[XASSETS DB]: Deleting asset {0}", id);
|
||||
|
||||
lock (m_dbLock)
|
||||
{
|
||||
using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
|
||||
{
|
||||
dbcon.Open();
|
||||
|
||||
using (MySqlCommand cmd = new MySqlCommand("delete from xassetsmeta where id=?id", dbcon))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("?id", id);
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
// TODO: How do we deal with data from deleted assets? Probably not easily reapable unless we
|
||||
// keep a reference count (?)
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
# -----------------
|
||||
:VERSION 1
|
||||
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE `xassetsmeta` (
|
||||
`id` char(36) NOT NULL,
|
||||
`hash` binary(32) NOT NULL,
|
||||
`name` varchar(64) NOT NULL,
|
||||
`description` varchar(64) NOT NULL,
|
||||
`asset_type` tinyint(4) NOT NULL,
|
||||
`local` tinyint(1) NOT NULL,
|
||||
`temporary` tinyint(1) NOT NULL,
|
||||
`create_time` int(11) NOT NULL,
|
||||
`access_time` int(11) NOT NULL,
|
||||
`asset_flags` int(11) NOT NULL,
|
||||
`creator_id` varchar(128) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Version 1';
|
||||
|
||||
CREATE TABLE `xassetsdata` (
|
||||
`hash` binary(32) NOT NULL,
|
||||
`data` longblob NOT NULL,
|
||||
PRIMARY KEY (`hash`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Version 1';
|
||||
|
||||
COMMIT;
|
||||
@@ -28,6 +28,9 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Data;
|
||||
@@ -36,12 +39,26 @@ namespace OpenSim.Data.Null
|
||||
{
|
||||
public class NullFriendsData : IFriendsData
|
||||
{
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private static List<FriendsData> m_Data = new List<FriendsData>();
|
||||
|
||||
public NullFriendsData(string connectionString, string realm)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear all friends data
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is required by unit tests to clear the static data between test runs.
|
||||
/// </remarks>
|
||||
public static void Clear()
|
||||
{
|
||||
lock (m_Data)
|
||||
m_Data.Clear();
|
||||
}
|
||||
|
||||
public FriendsData[] GetFriends(UUID principalID)
|
||||
{
|
||||
return GetFriends(principalID.ToString());
|
||||
@@ -56,20 +73,30 @@ namespace OpenSim.Data.Null
|
||||
/// <returns></returns>
|
||||
public FriendsData[] GetFriends(string userID)
|
||||
{
|
||||
List<FriendsData> lst = m_Data.FindAll(fdata =>
|
||||
lock (m_Data)
|
||||
{
|
||||
return fdata.PrincipalID == userID.ToString();
|
||||
});
|
||||
|
||||
if (lst != null)
|
||||
{
|
||||
lst.ForEach(f =>
|
||||
List<FriendsData> lst = m_Data.FindAll(fdata =>
|
||||
{
|
||||
FriendsData f2 = m_Data.Find(candidateF2 => f.Friend == candidateF2.PrincipalID);
|
||||
if (f2 != null) { f.Data["TheirFlags"] = f2.Data["Flags"]; }
|
||||
return fdata.PrincipalID == userID.ToString();
|
||||
});
|
||||
|
||||
return lst.ToArray();
|
||||
|
||||
if (lst != null)
|
||||
{
|
||||
lst.ForEach(f =>
|
||||
{
|
||||
FriendsData f2 = m_Data.Find(candidateF2 => f.Friend == candidateF2.PrincipalID);
|
||||
if (f2 != null)
|
||||
f.Data["TheirFlags"] = f2.Data["Flags"];
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[NULL FRIENDS DATA]: Got {0} {1} {2} for {3}",
|
||||
// f.Friend, f.Data["Flags"], f2 != null ? f.Data["TheirFlags"] : "not found!", f.PrincipalID);
|
||||
});
|
||||
|
||||
// m_log.DebugFormat("[NULL FRIENDS DATA]: Got {0} friends for {1}", lst.Count, userID);
|
||||
|
||||
return lst.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
return new FriendsData[0];
|
||||
@@ -80,7 +107,11 @@ namespace OpenSim.Data.Null
|
||||
if (data == null)
|
||||
return false;
|
||||
|
||||
m_Data.Add(data);
|
||||
// m_log.DebugFormat(
|
||||
// "[NULL FRIENDS DATA]: Storing {0} {1} {2}", data.PrincipalID, data.Friend, data.Data["Flags"]);
|
||||
|
||||
lock (m_Data)
|
||||
m_Data.Add(data);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -92,14 +123,21 @@ namespace OpenSim.Data.Null
|
||||
|
||||
public bool Delete(string userID, string friendID)
|
||||
{
|
||||
List<FriendsData> lst = m_Data.FindAll(delegate(FriendsData fdata) { return fdata.PrincipalID == userID.ToString(); });
|
||||
if (lst != null)
|
||||
lock (m_Data)
|
||||
{
|
||||
FriendsData friend = lst.Find(delegate(FriendsData fdata) { return fdata.Friend == friendID; });
|
||||
if (friendID != null)
|
||||
List<FriendsData> lst = m_Data.FindAll(delegate(FriendsData fdata) { return fdata.PrincipalID == userID.ToString(); });
|
||||
if (lst != null)
|
||||
{
|
||||
m_Data.Remove(friend);
|
||||
return true;
|
||||
FriendsData friend = lst.Find(delegate(FriendsData fdata) { return fdata.Friend == friendID; });
|
||||
if (friendID != null)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[NULL FRIENDS DATA]: Deleting friend {0} {1} for {2}",
|
||||
// friend.Friend, friend.Data["Flags"], friend.PrincipalID);
|
||||
|
||||
m_Data.Remove(friend);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -79,6 +79,19 @@ namespace OpenSim.Data.Null
|
||||
return null;
|
||||
}
|
||||
|
||||
public PresenceData Verify(UUID s_sessionID)
|
||||
{
|
||||
if (Instance != this)
|
||||
return Instance.Verify(s_sessionID);
|
||||
|
||||
if (m_presenceData.ContainsKey(s_sessionID))
|
||||
{
|
||||
return m_presenceData[s_sessionID];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void LogoutRegionAgents(UUID regionID)
|
||||
{
|
||||
if (Instance != this)
|
||||
@@ -110,7 +123,6 @@ namespace OpenSim.Data.Null
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public PresenceData[] Get(string field, string data)
|
||||
{
|
||||
if (Instance != this)
|
||||
|
||||
@@ -2157,7 +2157,7 @@ namespace OpenSim.Data.SQLite
|
||||
row["terrain_raise_limit"] = settings.TerrainRaiseLimit;
|
||||
row["terrain_lower_limit"] = settings.TerrainLowerLimit;
|
||||
row["use_estate_sun"] = settings.UseEstateSun;
|
||||
row["Sandbox"] = settings.Sandbox; // database uses upper case S for sandbox
|
||||
row["sandbox"] = settings.Sandbox; // unlike other database modules, sqlite uses a lower case s for sandbox!
|
||||
row["sunvectorx"] = settings.SunVector.X;
|
||||
row["sunvectory"] = settings.SunVector.Y;
|
||||
row["sunvectorz"] = settings.SunVector.Z;
|
||||
|
||||
@@ -244,10 +244,10 @@ namespace OpenSim.Data.Tests
|
||||
SceneObjectPart[] newparts = newsog.Parts;
|
||||
Assert.That(newparts.Length,Is.EqualTo(4), "Assert.That(newparts.Length,Is.EqualTo(4))");
|
||||
|
||||
Assert.That(newsog.HasChildPrim(tmp0), "Assert.That(newsog.HasChildPrim(tmp0))");
|
||||
Assert.That(newsog.HasChildPrim(tmp1), "Assert.That(newsog.HasChildPrim(tmp1))");
|
||||
Assert.That(newsog.HasChildPrim(tmp2), "Assert.That(newsog.HasChildPrim(tmp2))");
|
||||
Assert.That(newsog.HasChildPrim(tmp3), "Assert.That(newsog.HasChildPrim(tmp3))");
|
||||
Assert.That(newsog.ContainsPart(tmp0), "Assert.That(newsog.ContainsPart(tmp0))");
|
||||
Assert.That(newsog.ContainsPart(tmp1), "Assert.That(newsog.ContainsPart(tmp1))");
|
||||
Assert.That(newsog.ContainsPart(tmp2), "Assert.That(newsog.ContainsPart(tmp2))");
|
||||
Assert.That(newsog.ContainsPart(tmp3), "Assert.That(newsog.ContainsPart(tmp3))");
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
|
||||
namespace OpenSim.Framework.Client
|
||||
{
|
||||
public interface IClientInventory
|
||||
{
|
||||
void SendRemoveInventoryFolders(UUID[] folders);
|
||||
void SendRemoveInventoryItems(UUID[] folders);
|
||||
void SendBulkUpdateInventory(InventoryFolderBase[] folders, InventoryItemBase[] items);
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,7 @@ using System;
|
||||
using System.Xml;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
@@ -40,6 +41,8 @@ namespace OpenSim.Framework.Console
|
||||
{
|
||||
public class Commands : ICommands
|
||||
{
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <summary>
|
||||
/// Encapsulates a command that can be invoked from the console
|
||||
/// </summary>
|
||||
@@ -76,12 +79,19 @@ namespace OpenSim.Framework.Console
|
||||
public List<CommandDelegate> fn;
|
||||
}
|
||||
|
||||
public const string GeneralHelpText = "For more information, type 'help <item>' where <item> is one of the following categories:";
|
||||
|
||||
/// <value>
|
||||
/// Commands organized by keyword in a tree
|
||||
/// </value>
|
||||
private Dictionary<string, object> tree =
|
||||
new Dictionary<string, object>();
|
||||
|
||||
/// <summary>
|
||||
/// Commands organized by module
|
||||
/// </summary>
|
||||
private Dictionary<string, List<CommandInfo>> m_modulesCommands = new Dictionary<string, List<CommandInfo>>();
|
||||
|
||||
/// <summary>
|
||||
/// Get help for the given help string
|
||||
/// </summary>
|
||||
@@ -98,8 +108,8 @@ namespace OpenSim.Framework.Console
|
||||
// General help
|
||||
if (helpParts.Count == 0)
|
||||
{
|
||||
help.AddRange(CollectHelp(tree));
|
||||
help.Sort();
|
||||
help.Add(GeneralHelpText);
|
||||
help.AddRange(CollectModulesHelp(tree));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -118,6 +128,13 @@ namespace OpenSim.Framework.Console
|
||||
{
|
||||
string originalHelpRequest = string.Join(" ", helpParts.ToArray());
|
||||
List<string> help = new List<string>();
|
||||
|
||||
// Check modules first to see if we just need to display a list of those commands
|
||||
if (TryCollectModuleHelp(originalHelpRequest, help))
|
||||
{
|
||||
help.Insert(0, GeneralHelpText);
|
||||
return help;
|
||||
}
|
||||
|
||||
Dictionary<string, object> dict = tree;
|
||||
while (helpParts.Count > 0)
|
||||
@@ -161,25 +178,63 @@ namespace OpenSim.Framework.Console
|
||||
return help;
|
||||
}
|
||||
|
||||
private List<string> CollectHelp(Dictionary<string, object> dict)
|
||||
/// <summary>
|
||||
/// Try to collect help for the given module if that module exists.
|
||||
/// </summary>
|
||||
/// <param name="moduleName"></param>
|
||||
/// <param name="helpText">/param>
|
||||
/// <returns>true if there was the module existed, false otherwise.</returns>
|
||||
private bool TryCollectModuleHelp(string moduleName, List<string> helpText)
|
||||
{
|
||||
List<string> result = new List<string>();
|
||||
|
||||
foreach (KeyValuePair<string, object> kvp in dict)
|
||||
lock (m_modulesCommands)
|
||||
{
|
||||
if (kvp.Value is Dictionary<string, Object>)
|
||||
foreach (string key in m_modulesCommands.Keys)
|
||||
{
|
||||
result.AddRange(CollectHelp((Dictionary<string, Object>)kvp.Value));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (((CommandInfo)kvp.Value).long_help != String.Empty)
|
||||
result.Add(((CommandInfo)kvp.Value).help_text+" - "+
|
||||
((CommandInfo)kvp.Value).long_help);
|
||||
// Allow topic help requests to succeed whether they are upper or lowercase.
|
||||
if (moduleName.ToLower() == key.ToLower())
|
||||
{
|
||||
List<CommandInfo> commands = m_modulesCommands[key];
|
||||
var ourHelpText = commands.ConvertAll(c => string.Format("{0} - {1}", c.help_text, c.long_help));
|
||||
ourHelpText.Sort();
|
||||
helpText.AddRange(ourHelpText);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<string> CollectModulesHelp(Dictionary<string, object> dict)
|
||||
{
|
||||
lock (m_modulesCommands)
|
||||
{
|
||||
List<string> helpText = new List<string>(m_modulesCommands.Keys);
|
||||
helpText.Sort();
|
||||
return helpText;
|
||||
}
|
||||
}
|
||||
|
||||
// private List<string> CollectHelp(Dictionary<string, object> dict)
|
||||
// {
|
||||
// List<string> result = new List<string>();
|
||||
//
|
||||
// foreach (KeyValuePair<string, object> kvp in dict)
|
||||
// {
|
||||
// if (kvp.Value is Dictionary<string, Object>)
|
||||
// {
|
||||
// result.AddRange(CollectHelp((Dictionary<string, Object>)kvp.Value));
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if (((CommandInfo)kvp.Value).long_help != String.Empty)
|
||||
// result.Add(((CommandInfo)kvp.Value).help_text+" - "+
|
||||
// ((CommandInfo)kvp.Value).long_help);
|
||||
// }
|
||||
// }
|
||||
// return result;
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// Add a command to those which can be invoked from the console.
|
||||
@@ -212,21 +267,19 @@ namespace OpenSim.Framework.Console
|
||||
|
||||
Dictionary<string, Object> current = tree;
|
||||
|
||||
foreach (string s in parts)
|
||||
foreach (string part in parts)
|
||||
{
|
||||
if (current.ContainsKey(s))
|
||||
if (current.ContainsKey(part))
|
||||
{
|
||||
if (current[s] is Dictionary<string, Object>)
|
||||
{
|
||||
current = (Dictionary<string, Object>)current[s];
|
||||
}
|
||||
if (current[part] is Dictionary<string, Object>)
|
||||
current = (Dictionary<string, Object>)current[part];
|
||||
else
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
current[s] = new Dictionary<string, Object>();
|
||||
current = (Dictionary<string, Object>)current[s];
|
||||
current[part] = new Dictionary<string, Object>();
|
||||
current = (Dictionary<string, Object>)current[part];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,6 +303,24 @@ namespace OpenSim.Framework.Console
|
||||
info.fn = new List<CommandDelegate>();
|
||||
info.fn.Add(fn);
|
||||
current[String.Empty] = info;
|
||||
|
||||
// Now add command to modules dictionary
|
||||
lock (m_modulesCommands)
|
||||
{
|
||||
List<CommandInfo> commands;
|
||||
if (m_modulesCommands.ContainsKey(module))
|
||||
{
|
||||
commands = m_modulesCommands[module];
|
||||
}
|
||||
else
|
||||
{
|
||||
commands = new List<CommandInfo>();
|
||||
m_modulesCommands[module] = commands;
|
||||
}
|
||||
|
||||
// m_log.DebugFormat("[COMMAND CONSOLE]: Adding to category {0} command {1}", module, command);
|
||||
commands.Add(info);
|
||||
}
|
||||
}
|
||||
|
||||
public string[] FindNextOption(string[] cmd, bool term)
|
||||
@@ -607,8 +678,9 @@ namespace OpenSim.Framework.Console
|
||||
{
|
||||
Commands = new Commands();
|
||||
|
||||
Commands.AddCommand("console", false, "help", "help [<command>]",
|
||||
"Get general command list or more detailed help on a specific command", Help);
|
||||
Commands.AddCommand(
|
||||
"Help", false, "help", "help [<item>]",
|
||||
"Display help on a particular command or on a list of commands in a category", Help);
|
||||
}
|
||||
|
||||
private void Help(string module, string[] cmd)
|
||||
|
||||
@@ -29,6 +29,7 @@ using System;
|
||||
using System.Threading;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
namespace OpenSim.Framework.Console
|
||||
{
|
||||
@@ -37,28 +38,42 @@ namespace OpenSim.Framework.Console
|
||||
/// Don't use this except for Unit Testing or you're in for a world of hurt when the
|
||||
/// sim gets to ReadLine
|
||||
/// </summary>
|
||||
public class MockConsole : CommandConsole
|
||||
public class MockConsole : ICommandConsole
|
||||
{
|
||||
public MockConsole(string defaultPrompt) : base(defaultPrompt)
|
||||
{
|
||||
}
|
||||
public override void Output(string text)
|
||||
{
|
||||
}
|
||||
public override void Output(string text, string level)
|
||||
{
|
||||
}
|
||||
private MockCommands m_commands = new MockCommands();
|
||||
|
||||
public override string ReadLine(string p, bool isCommand, bool e)
|
||||
{
|
||||
//Thread.CurrentThread.Join(1000);
|
||||
return string.Empty;
|
||||
}
|
||||
public override void UnlockOutput()
|
||||
{
|
||||
}
|
||||
public override void LockOutput()
|
||||
{
|
||||
}
|
||||
public ICommands Commands { get { return m_commands; } }
|
||||
|
||||
public void Prompt() {}
|
||||
|
||||
public void RunCommand(string cmd) {}
|
||||
|
||||
public string ReadLine(string p, bool isCommand, bool e) { return ""; }
|
||||
|
||||
public object ConsoleScene { get { return null; } }
|
||||
|
||||
public void Output(string text, string level) {}
|
||||
public void Output(string text) {}
|
||||
public void OutputFormat(string format, params object[] components) {}
|
||||
|
||||
public string CmdPrompt(string p) { return ""; }
|
||||
public string CmdPrompt(string p, string def) { return ""; }
|
||||
public string CmdPrompt(string p, List<char> excludedCharacters) { return ""; }
|
||||
public string CmdPrompt(string p, string def, List<char> excludedCharacters) { return ""; }
|
||||
|
||||
public string CmdPrompt(string prompt, string defaultresponse, List<string> options) { return ""; }
|
||||
|
||||
public string PasswdPrompt(string p) { return ""; }
|
||||
}
|
||||
}
|
||||
|
||||
public class MockCommands : ICommands
|
||||
{
|
||||
public void FromXml(XmlElement root, CommandDelegate fn) {}
|
||||
public List<string> GetHelp(string[] cmd) { return null; }
|
||||
public void AddCommand(string module, bool shared, string command, string help, string longhelp, CommandDelegate fn) {}
|
||||
public void AddCommand(string module, bool shared, string command, string help, string longhelp, string descriptivehelp, CommandDelegate fn) {}
|
||||
public string[] FindNextOption(string[] cmd, bool term) { return null; }
|
||||
public string[] Resolve(string[] cmd) { return null; }
|
||||
public XmlElement GetXml(XmlDocument doc) { return null; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
|
||||
public class GcNotify
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public static bool Enabled
|
||||
{
|
||||
get { return s_initialized; }
|
||||
set
|
||||
{
|
||||
if (!s_initialized && value)
|
||||
new GcNotify();
|
||||
|
||||
s_initialized = value;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool s_initialized = false;
|
||||
|
||||
private GcNotify() {}
|
||||
|
||||
~GcNotify()
|
||||
{
|
||||
if (!Environment.HasShutdownStarted && !AppDomain.CurrentDomain.IsFinalizingForUnload())
|
||||
{
|
||||
m_log.DebugFormat("[GC NOTIFY]: Garbage collection triggered.");
|
||||
|
||||
if (Enabled)
|
||||
new GcNotify();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -296,9 +296,9 @@ namespace OpenSim.Framework
|
||||
public delegate void ConfirmXfer(IClientAPI remoteClient, ulong xferID, uint packetID);
|
||||
|
||||
public delegate void FriendActionDelegate(
|
||||
IClientAPI remoteClient, UUID agentID, UUID transactionID, List<UUID> callingCardFolders);
|
||||
IClientAPI remoteClient, UUID transactionID, List<UUID> callingCardFolders);
|
||||
|
||||
public delegate void FriendshipTermination(IClientAPI remoteClient, UUID agentID, UUID ExID);
|
||||
public delegate void FriendshipTermination(IClientAPI remoteClient, UUID ExID);
|
||||
|
||||
public delegate void MoneyTransferRequest(
|
||||
UUID sourceID, UUID destID, int amount, int transactionType, string description);
|
||||
@@ -458,7 +458,7 @@ namespace OpenSim.Framework
|
||||
public delegate void AvatarNotesUpdate(IClientAPI client, UUID targetID, string notes);
|
||||
public delegate void MuteListRequest(IClientAPI client, uint muteCRC);
|
||||
public delegate void AvatarInterestUpdate(IClientAPI client, uint wantmask, string wanttext, uint skillsmask, string skillstext, string languages);
|
||||
public delegate void GrantUserFriendRights(IClientAPI client, UUID requester, UUID target, int rights);
|
||||
public delegate void GrantUserFriendRights(IClientAPI client, UUID target, int rights);
|
||||
public delegate void PlacesQuery(UUID QueryID, UUID TransactionID, string QueryText, uint QueryFlags, byte Category, string SimName, IClientAPI client);
|
||||
|
||||
public delegate void AgentFOV(IClientAPI client, float verticalAngle);
|
||||
@@ -710,7 +710,7 @@ namespace OpenSim.Framework
|
||||
/// The scene agent for this client. This will only be set if the client has an agent in a scene (i.e. if it
|
||||
/// is connected).
|
||||
/// </summary>
|
||||
ISceneAgent SceneAgent { get; }
|
||||
ISceneAgent SceneAgent { get; set; }
|
||||
|
||||
UUID SessionId { get; }
|
||||
|
||||
@@ -1215,10 +1215,9 @@ namespace OpenSim.Framework
|
||||
/// <param name="OrbitalPosition">The orbital position is given in radians, and must be "adjusted" for the linden client, see LLClientView</param>
|
||||
void SendSunPos(Vector3 sunPos, Vector3 sunVel, ulong CurrentTime, uint SecondsPerSunCycle, uint SecondsPerYear,
|
||||
float OrbitalPosition);
|
||||
|
||||
|
||||
void SendViewerEffect(ViewerEffectPacket.EffectBlock[] effectBlocks);
|
||||
void SendViewerTime(int phase);
|
||||
UUID GetDefaultAnimation(string name);
|
||||
|
||||
void SendAvatarProperties(UUID avatarID, string aboutText, string bornOn, Byte[] charterMember, string flAbout,
|
||||
uint flags, UUID flImageID, UUID imageID, string profileURL, UUID partnerID);
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace OpenSim.Framework
|
||||
/// <summary>
|
||||
/// Get help for the given help string
|
||||
/// </summary>
|
||||
/// <param name="helpParts">Parsed parts of the help string. If empty then general help is returned.</param>
|
||||
/// <param name="cmd">Parsed parts of the help string. If empty then general help is returned.</param>
|
||||
/// <returns></returns>
|
||||
List<string> GetHelp(string[] cmd);
|
||||
|
||||
|
||||
@@ -71,6 +71,7 @@ namespace OpenSim.Framework
|
||||
bool IsEitherBannedOrRestricted(UUID avatar);
|
||||
bool IsBannedFromLand(UUID avatar);
|
||||
bool IsRestrictedFromLand(UUID avatar);
|
||||
bool IsInLandAccessList(UUID avatar);
|
||||
void SendLandUpdateToClient(IClientAPI remote_client);
|
||||
void SendLandUpdateToClient(bool snap_selection, IClientAPI remote_client);
|
||||
List<LandAccessEntry> CreateAccessListArrayByFlag(AccessList flag);
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace OpenSim.Framework
|
||||
(uint) ParcelFlags.AllowAPrimitiveEntry |
|
||||
(uint) ParcelFlags.AllowDeedToGroup | (uint) ParcelFlags.AllowTerraform |
|
||||
(uint) ParcelFlags.CreateObjects | (uint) ParcelFlags.AllowOtherScripts |
|
||||
(uint) ParcelFlags.SoundLocal;
|
||||
(uint) ParcelFlags.SoundLocal | (uint) ParcelFlags.AllowVoiceChat;
|
||||
|
||||
private byte _landingType = 0;
|
||||
private string _name = "Your Parcel";
|
||||
|
||||
@@ -119,7 +119,7 @@ namespace OpenSim.Framework
|
||||
// Copy the temporary stream to the network stream
|
||||
formDataStream.Seek(0, SeekOrigin.Begin);
|
||||
using (Stream requestStream = request.GetRequestStream())
|
||||
formDataStream.CopyTo(requestStream, (int)formDataStream.Length);
|
||||
formDataStream.CopyStream(requestStream, (int)formDataStream.Length);
|
||||
}
|
||||
|
||||
#endregion Stream Writing
|
||||
|
||||
@@ -421,12 +421,18 @@ namespace OpenSim.Framework
|
||||
set { m_internalEndPoint = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The x co-ordinate of this region in map tiles (e.g. 1000).
|
||||
/// </summary>
|
||||
public uint RegionLocX
|
||||
{
|
||||
get { return m_regionLocX.Value; }
|
||||
set { m_regionLocX = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The y co-ordinate of this region in map tiles (e.g. 1000).
|
||||
/// </summary>
|
||||
public uint RegionLocY
|
||||
{
|
||||
get { return m_regionLocY.Value; }
|
||||
|
||||
@@ -27,7 +27,9 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Xml;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
|
||||
@@ -375,4 +377,4 @@ namespace OpenSim.Framework
|
||||
return output;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -161,43 +161,43 @@ namespace OpenSim.Framework.Servers
|
||||
Notice(String.Format("Console log level is {0}", m_consoleAppender.Threshold));
|
||||
}
|
||||
|
||||
m_console.Commands.AddCommand("base", false, "quit",
|
||||
m_console.Commands.AddCommand("General", false, "quit",
|
||||
"quit",
|
||||
"Quit the application", HandleQuit);
|
||||
|
||||
m_console.Commands.AddCommand("base", false, "shutdown",
|
||||
m_console.Commands.AddCommand("General", false, "shutdown",
|
||||
"shutdown",
|
||||
"Quit the application", HandleQuit);
|
||||
|
||||
m_console.Commands.AddCommand("base", false, "set log level",
|
||||
m_console.Commands.AddCommand("General", false, "set log level",
|
||||
"set log level <level>",
|
||||
"Set the console logging level", HandleLogLevel);
|
||||
|
||||
m_console.Commands.AddCommand("base", false, "show info",
|
||||
m_console.Commands.AddCommand("General", false, "show info",
|
||||
"show info",
|
||||
"Show general information about the server", HandleShow);
|
||||
|
||||
m_console.Commands.AddCommand("base", false, "show stats",
|
||||
m_console.Commands.AddCommand("General", false, "show stats",
|
||||
"show stats",
|
||||
"Show statistics", HandleShow);
|
||||
|
||||
m_console.Commands.AddCommand("base", false, "show threads",
|
||||
m_console.Commands.AddCommand("General", false, "show threads",
|
||||
"show threads",
|
||||
"Show thread status", HandleShow);
|
||||
|
||||
m_console.Commands.AddCommand("base", false, "show uptime",
|
||||
m_console.Commands.AddCommand("General", false, "show uptime",
|
||||
"show uptime",
|
||||
"Show server uptime", HandleShow);
|
||||
|
||||
m_console.Commands.AddCommand("base", false, "show version",
|
||||
m_console.Commands.AddCommand("General", false, "show version",
|
||||
"show version",
|
||||
"Show server version", HandleShow);
|
||||
|
||||
m_console.Commands.AddCommand("base", false, "threads abort",
|
||||
m_console.Commands.AddCommand("General", false, "threads abort",
|
||||
"threads abort <thread-id>",
|
||||
"Abort a managed thread. Use \"show threads\" to find possible threads.", HandleThreadsAbort);
|
||||
|
||||
m_console.Commands.AddCommand("base", false, "threads show",
|
||||
m_console.Commands.AddCommand("General", false, "threads show",
|
||||
"threads show",
|
||||
"Show thread status. Synonym for \"show threads\"",
|
||||
(string module, string[] args) => Notice(GetThreadsReport()));
|
||||
@@ -269,15 +269,19 @@ namespace OpenSim.Framework.Servers
|
||||
t.Priority,
|
||||
t.ThreadState);
|
||||
|
||||
sb.Append(Environment.NewLine);
|
||||
sb.Append("\n");
|
||||
}
|
||||
|
||||
int workers = 0, ports = 0, maxWorkers = 0, maxPorts = 0;
|
||||
ThreadPool.GetAvailableThreads(out workers, out ports);
|
||||
ThreadPool.GetMaxThreads(out maxWorkers, out maxPorts);
|
||||
sb.Append("\n");
|
||||
|
||||
sb.Append(Environment.NewLine + "*** ThreadPool threads ***" + Environment.NewLine);
|
||||
sb.Append("workers: " + (maxWorkers - workers) + " (" + maxWorkers + "); ports: " + (maxPorts - ports) + " (" + maxPorts + ")" + Environment.NewLine);
|
||||
// For some reason mono 2.6.7 returns an empty threads set! Not going to confuse people by reporting
|
||||
// zero active threads.
|
||||
int totalThreads = Process.GetCurrentProcess().Threads.Count;
|
||||
if (totalThreads > 0)
|
||||
sb.AppendFormat("Total threads active: {0}\n\n", totalThreads);
|
||||
|
||||
sb.Append("Main threadpool (excluding script engine pools)\n");
|
||||
sb.Append(Util.GetThreadPoolReport());
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
@@ -662,11 +662,11 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw ", e);
|
||||
m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0}", e);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw " + e.ToString());
|
||||
m_log.ErrorFormat("[BASE HTTP SERVER]: HandleRequest() threw {0}", e.StackTrace);
|
||||
SendHTML500(response);
|
||||
}
|
||||
finally
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace OpenSim
|
||||
{
|
||||
public class VersionInfo
|
||||
{
|
||||
private const string VERSION_NUMBER = "0.7.3";
|
||||
private const string VERSION_NUMBER = "0.7.4";
|
||||
private const Flavour VERSION_FLAVOUR = Flavour.Dev;
|
||||
|
||||
public enum Flavour
|
||||
@@ -39,7 +39,8 @@ namespace OpenSim
|
||||
RC1,
|
||||
RC2,
|
||||
Release,
|
||||
Post_Fixes
|
||||
Post_Fixes,
|
||||
Extended
|
||||
}
|
||||
|
||||
public static string Version
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
|
||||
@@ -46,8 +46,12 @@ namespace OpenSim.Framework.Statistics
|
||||
sb.Append(Environment.NewLine);
|
||||
sb.Append(
|
||||
string.Format(
|
||||
"Allocated to OpenSim : {0} MB" + Environment.NewLine,
|
||||
"Allocated to OpenSim objects: {0} MB\n",
|
||||
Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0)));
|
||||
sb.Append(
|
||||
string.Format(
|
||||
"Process memory : {0} MB\n",
|
||||
Math.Round(Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0)));
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
+168
-64
@@ -35,7 +35,7 @@ using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Reflection;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
@@ -81,12 +81,15 @@ namespace OpenSim.Framework
|
||||
|
||||
private static uint nextXferID = 5000;
|
||||
private static Random randomClass = new Random();
|
||||
|
||||
// Get a list of invalid file characters (OS dependent)
|
||||
private static string regexInvalidFileChars = "[" + new String(Path.GetInvalidFileNameChars()) + "]";
|
||||
private static string regexInvalidPathChars = "[" + new String(Path.GetInvalidPathChars()) + "]";
|
||||
private static object XferLock = new object();
|
||||
/// <summary>Thread pool used for Util.FireAndForget if
|
||||
/// FireAndForgetMethod.SmartThreadPool is used</summary>
|
||||
|
||||
/// <summary>
|
||||
/// Thread pool used for Util.FireAndForget if FireAndForgetMethod.SmartThreadPool is used
|
||||
/// </summary>
|
||||
private static SmartThreadPool m_ThreadPool;
|
||||
|
||||
// Unix-epoch starts at January 1st 1970, 00:00:00 UTC. And all our times in the server are (or at least should be) in UTC.
|
||||
@@ -144,7 +147,6 @@ namespace OpenSim.Framework
|
||||
return lerp(y, lerp(x, a, b), lerp(x, c, d));
|
||||
}
|
||||
|
||||
|
||||
public static Encoding UTF8 = Encoding.UTF8;
|
||||
|
||||
/// <value>
|
||||
@@ -376,20 +378,20 @@ namespace OpenSim.Framework
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is the platform Windows?
|
||||
/// </summary>
|
||||
/// <returns>true if so, false otherwise</returns>
|
||||
public static bool IsWindows()
|
||||
{
|
||||
PlatformID platformId = Environment.OSVersion.Platform;
|
||||
|
||||
return (platformId == PlatformID.Win32NT
|
||||
|| platformId == PlatformID.Win32S
|
||||
|| platformId == PlatformID.Win32Windows
|
||||
|| platformId == PlatformID.WinCE);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is the platform Windows?
|
||||
/// </summary>
|
||||
/// <returns>true if so, false otherwise</returns>
|
||||
public static bool IsWindows()
|
||||
{
|
||||
PlatformID platformId = Environment.OSVersion.Platform;
|
||||
|
||||
return (platformId == PlatformID.Win32NT
|
||||
|| platformId == PlatformID.Win32S
|
||||
|| platformId == PlatformID.Win32Windows
|
||||
|| platformId == PlatformID.WinCE);
|
||||
}
|
||||
|
||||
public static bool LoadArchSpecificWindowsDll(string libraryName)
|
||||
@@ -1502,27 +1504,27 @@ namespace OpenSim.Framework
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to trigger an early library load on Windows systems.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Required to get 32-bit and 64-bit processes to automatically use the
|
||||
/// appropriate native library.
|
||||
/// </remarks>
|
||||
/// <param name="dllToLoad"></param>
|
||||
/// <returns></returns>
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern IntPtr LoadLibrary(string dllToLoad);
|
||||
|
||||
/// <summary>
|
||||
/// Determine whether the current process is 64 bit
|
||||
/// </summary>
|
||||
/// <returns>true if so, false if not</returns>
|
||||
public static bool Is64BitProcess()
|
||||
{
|
||||
return IntPtr.Size == 8;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to trigger an early library load on Windows systems.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Required to get 32-bit and 64-bit processes to automatically use the
|
||||
/// appropriate native library.
|
||||
/// </remarks>
|
||||
/// <param name="dllToLoad"></param>
|
||||
/// <returns></returns>
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern IntPtr LoadLibrary(string dllToLoad);
|
||||
|
||||
/// <summary>
|
||||
/// Determine whether the current process is 64 bit
|
||||
/// </summary>
|
||||
/// <returns>true if so, false if not</returns>
|
||||
public static bool Is64BitProcess()
|
||||
{
|
||||
return IntPtr.Size == 8;
|
||||
}
|
||||
|
||||
#region FireAndForget Threading Pattern
|
||||
@@ -1671,6 +1673,61 @@ namespace OpenSim.Framework
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a thread pool report.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string GetThreadPoolReport()
|
||||
{
|
||||
string threadPoolUsed = null;
|
||||
int maxThreads = 0;
|
||||
int minThreads = 0;
|
||||
int allocatedThreads = 0;
|
||||
int inUseThreads = 0;
|
||||
int waitingCallbacks = 0;
|
||||
int completionPortThreads = 0;
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool)
|
||||
{
|
||||
threadPoolUsed = "SmartThreadPool";
|
||||
maxThreads = m_ThreadPool.MaxThreads;
|
||||
minThreads = m_ThreadPool.MinThreads;
|
||||
inUseThreads = m_ThreadPool.InUseThreads;
|
||||
allocatedThreads = m_ThreadPool.ActiveThreads;
|
||||
waitingCallbacks = m_ThreadPool.WaitingCallbacks;
|
||||
}
|
||||
else if (
|
||||
FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem
|
||||
|| FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem)
|
||||
{
|
||||
threadPoolUsed = "BuiltInThreadPool";
|
||||
ThreadPool.GetMaxThreads(out maxThreads, out completionPortThreads);
|
||||
ThreadPool.GetMinThreads(out minThreads, out completionPortThreads);
|
||||
int availableThreads;
|
||||
ThreadPool.GetAvailableThreads(out availableThreads, out completionPortThreads);
|
||||
inUseThreads = maxThreads - availableThreads;
|
||||
allocatedThreads = -1;
|
||||
waitingCallbacks = -1;
|
||||
}
|
||||
|
||||
if (threadPoolUsed != null)
|
||||
{
|
||||
sb.AppendFormat("Thread pool used : {0}\n", threadPoolUsed);
|
||||
sb.AppendFormat("Max threads : {0}\n", maxThreads);
|
||||
sb.AppendFormat("Min threads : {0}\n", minThreads);
|
||||
sb.AppendFormat("Allocated threads : {0}\n", allocatedThreads < 0 ? "not applicable" : allocatedThreads.ToString());
|
||||
sb.AppendFormat("In use threads : {0}\n", inUseThreads);
|
||||
sb.AppendFormat("Work items waiting : {0}\n", waitingCallbacks < 0 ? "not available" : waitingCallbacks.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendFormat("Thread pool not used\n");
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static object SmartThreadPoolCallback(object o)
|
||||
{
|
||||
object[] array = (object[])o;
|
||||
@@ -1696,6 +1753,20 @@ namespace OpenSim.Framework
|
||||
}
|
||||
const Int32 EnvironmentTickCountMask = 0x3fffffff;
|
||||
|
||||
/// <summary>
|
||||
/// Environment.TickCount is an int but it counts all 32 bits so it goes positive
|
||||
/// and negative every 24.9 days. Subtracts the passed value (previously fetched by
|
||||
/// 'EnvironmentTickCount()') and accounts for any wrapping.
|
||||
/// </summary>
|
||||
/// <param name="newValue"></param>
|
||||
/// <param name="prevValue"></param>
|
||||
/// <returns>subtraction of passed prevValue from current Environment.TickCount</returns>
|
||||
public static Int32 EnvironmentTickCountSubtract(Int32 newValue, Int32 prevValue)
|
||||
{
|
||||
Int32 diff = newValue - prevValue;
|
||||
return (diff >= 0) ? diff : (diff + EnvironmentTickCountMask + 1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Environment.TickCount is an int but it counts all 32 bits so it goes positive
|
||||
/// and negative every 24.9 days. Subtracts the passed value (previously fetched by
|
||||
@@ -1704,8 +1775,7 @@ namespace OpenSim.Framework
|
||||
/// <returns>subtraction of passed prevValue from current Environment.TickCount</returns>
|
||||
public static Int32 EnvironmentTickCountSubtract(Int32 prevValue)
|
||||
{
|
||||
Int32 diff = EnvironmentTickCount() - prevValue;
|
||||
return (diff >= 0) ? diff : (diff + EnvironmentTickCountMask + 1);
|
||||
return EnvironmentTickCountSubtract(EnvironmentTickCount(), prevValue);
|
||||
}
|
||||
|
||||
// Returns value of Tick Count A - TickCount B accounting for wrapping of TickCount
|
||||
@@ -1870,11 +1940,12 @@ namespace OpenSim.Framework
|
||||
#region Universal User Identifiers
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
/// <param name="value">uuid[;endpoint[;name]]</param>
|
||||
/// <param name="uuid"></param>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="firstname"></param>
|
||||
/// <param name="lastname"></param>
|
||||
/// <param name="value">uuid[;endpoint[;first last[;secret]]]</param>
|
||||
/// <param name="uuid">the uuid part</param>
|
||||
/// <param name="url">the endpoint part (e.g. http://foo.com)</param>
|
||||
/// <param name="firstname">the first name part (e.g. Test)</param>
|
||||
/// <param name="lastname">the last name part (e.g User)</param>
|
||||
/// <param name="secret">the secret part</param>
|
||||
public static bool ParseUniversalUserIdentifier(string value, out UUID uuid, out string url, out string firstname, out string lastname, out string secret)
|
||||
{
|
||||
uuid = UUID.Zero; url = string.Empty; firstname = "Unknown"; lastname = "User"; secret = string.Empty;
|
||||
@@ -1903,31 +1974,64 @@ namespace OpenSim.Framework
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// Produces a universal (HG) system-facing identifier given the information
|
||||
/// </summary>
|
||||
/// <param name="acircuit"></param>
|
||||
/// <returns>uuid[;endpoint[;name]]</returns>
|
||||
/// <returns>uuid[;homeURI[;first last]]</returns>
|
||||
public static string ProduceUserUniversalIdentifier(AgentCircuitData acircuit)
|
||||
{
|
||||
if (acircuit.ServiceURLs.ContainsKey("HomeURI"))
|
||||
{
|
||||
string agentsURI = acircuit.ServiceURLs["HomeURI"].ToString();
|
||||
if (!agentsURI.EndsWith("/"))
|
||||
agentsURI += "/";
|
||||
|
||||
// This is ugly, but there's no other way, given that the name is changed
|
||||
// in the agent circuit data for foreigners
|
||||
if (acircuit.lastname.Contains("@"))
|
||||
{
|
||||
string[] parts = acircuit.firstname.Split(new char[] { '.' });
|
||||
if (parts.Length == 2)
|
||||
return acircuit.AgentID.ToString() + ";" + agentsURI + ";" + parts[0] + " " + parts[1];
|
||||
}
|
||||
return acircuit.AgentID.ToString() + ";" + agentsURI + ";" + acircuit.firstname + " " + acircuit.lastname;
|
||||
}
|
||||
return UniversalIdentifier(acircuit.AgentID, acircuit.firstname, acircuit.lastname, acircuit.ServiceURLs["HomeURI"].ToString());
|
||||
else
|
||||
return acircuit.AgentID.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Produces a universal (HG) system-facing identifier given the information
|
||||
/// </summary>
|
||||
/// <param name="id">UUID of the user</param>
|
||||
/// <param name="firstName">first name (e.g Test)</param>
|
||||
/// <param name="lastName">last name (e.g. User)</param>
|
||||
/// <param name="homeURI">homeURI (e.g. http://foo.com)</param>
|
||||
/// <returns>a string of the form uuid[;homeURI[;first last]]</returns>
|
||||
public static string UniversalIdentifier(UUID id, String firstName, String lastName, String homeURI)
|
||||
{
|
||||
string agentsURI = homeURI;
|
||||
if (!agentsURI.EndsWith("/"))
|
||||
agentsURI += "/";
|
||||
|
||||
// This is ugly, but there's no other way, given that the name is changed
|
||||
// in the agent circuit data for foreigners
|
||||
if (lastName.Contains("@"))
|
||||
{
|
||||
string[] parts = firstName.Split(new char[] { '.' });
|
||||
if (parts.Length == 2)
|
||||
return id.ToString() + ";" + agentsURI + ";" + parts[0] + " " + parts[1];
|
||||
}
|
||||
return id.ToString() + ";" + agentsURI + ";" + firstName + " " + lastName;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Produces a universal (HG) user-facing name given the information
|
||||
/// </summary>
|
||||
/// <param name="firstName"></param>
|
||||
/// <param name="lastName"></param>
|
||||
/// <param name="homeURI"></param>
|
||||
/// <returns>string of the form first.last @foo.com or first last</returns>
|
||||
public static string UniversalName(String firstName, String lastName, String homeURI)
|
||||
{
|
||||
Uri uri = null;
|
||||
try
|
||||
{
|
||||
uri = new Uri(homeURI);
|
||||
}
|
||||
catch (UriFormatException)
|
||||
{
|
||||
return firstName + " " + lastName;
|
||||
}
|
||||
return firstName + "." + lastName + " " + "@" + uri.Authority;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,77 +63,32 @@ namespace OpenSim.Framework
|
||||
// a "long" call for warning & debugging purposes
|
||||
public const int LongCallTime = 500;
|
||||
|
||||
// /// <summary>
|
||||
// /// Send LLSD to an HTTP client in application/llsd+json form
|
||||
// /// </summary>
|
||||
// /// <param name="response">HTTP response to send the data in</param>
|
||||
// /// <param name="body">LLSD to send to the client</param>
|
||||
// public static void SendJSONResponse(OSHttpResponse response, OSDMap body)
|
||||
// {
|
||||
// byte[] responseData = Encoding.UTF8.GetBytes(OSDParser.SerializeJsonString(body));
|
||||
//
|
||||
// response.ContentEncoding = Encoding.UTF8;
|
||||
// response.ContentLength = responseData.Length;
|
||||
// response.ContentType = "application/llsd+json";
|
||||
// response.Body.Write(responseData, 0, responseData.Length);
|
||||
// }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Send LLSD to an HTTP client in application/llsd+xml form
|
||||
// /// </summary>
|
||||
// /// <param name="response">HTTP response to send the data in</param>
|
||||
// /// <param name="body">LLSD to send to the client</param>
|
||||
// public static void SendXMLResponse(OSHttpResponse response, OSDMap body)
|
||||
// {
|
||||
// byte[] responseData = OSDParser.SerializeLLSDXmlBytes(body);
|
||||
//
|
||||
// response.ContentEncoding = Encoding.UTF8;
|
||||
// response.ContentLength = responseData.Length;
|
||||
// response.ContentType = "application/llsd+xml";
|
||||
// response.Body.Write(responseData, 0, responseData.Length);
|
||||
// }
|
||||
// dictionary of end points
|
||||
private static Dictionary<string,object> m_endpointSerializer = new Dictionary<string,object>();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Make a GET or GET-like request to a web service that returns LLSD
|
||||
/// or JSON data
|
||||
/// </summary>
|
||||
public static OSDMap ServiceRequest(string url, string httpVerb)
|
||||
private static object EndPointLock(string url)
|
||||
{
|
||||
string errorMessage;
|
||||
System.Uri uri = new System.Uri(url);
|
||||
string endpoint = string.Format("{0}:{1}",uri.Host,uri.Port);
|
||||
|
||||
try
|
||||
lock (m_endpointSerializer)
|
||||
{
|
||||
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
|
||||
request.Method = httpVerb;
|
||||
object eplock = null;
|
||||
|
||||
using (WebResponse response = request.GetResponse())
|
||||
if (! m_endpointSerializer.TryGetValue(endpoint,out eplock))
|
||||
{
|
||||
using (Stream responseStream = response.GetResponseStream())
|
||||
{
|
||||
try
|
||||
{
|
||||
string responseStr = responseStream.GetStreamString();
|
||||
OSD responseOSD = OSDParser.Deserialize(responseStr);
|
||||
if (responseOSD.Type == OSDType.Map)
|
||||
return (OSDMap)responseOSD;
|
||||
else
|
||||
errorMessage = "Response format was invalid.";
|
||||
}
|
||||
catch
|
||||
{
|
||||
errorMessage = "Failed to parse the response.";
|
||||
}
|
||||
}
|
||||
eplock = new object();
|
||||
m_endpointSerializer.Add(endpoint,eplock);
|
||||
// m_log.WarnFormat("[WEB UTIL] add a new host to end point serializer {0}",endpoint);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
m_log.Warn(httpVerb + " on URL " + url + " failed: " + ex.Message);
|
||||
errorMessage = ex.Message;
|
||||
}
|
||||
|
||||
return new OSDMap { { "Message", OSD.FromString("Service request failed. " + errorMessage) } };
|
||||
return eplock;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#region JSONRequest
|
||||
|
||||
/// <summary>
|
||||
/// PUT JSON-encoded data to a web service that returns LLSD or
|
||||
@@ -165,6 +120,14 @@ namespace OpenSim.Framework
|
||||
}
|
||||
|
||||
public static OSDMap ServiceOSDRequest(string url, OSDMap data, string method, int timeout, bool compressed)
|
||||
{
|
||||
lock (EndPointLock(url))
|
||||
{
|
||||
return ServiceOSDRequestWorker(url,data,method,timeout,compressed);
|
||||
}
|
||||
}
|
||||
|
||||
private static OSDMap ServiceOSDRequestWorker(string url, OSDMap data, string method, int timeout, bool compressed)
|
||||
{
|
||||
int reqnum = m_requestNumber++;
|
||||
// m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method);
|
||||
@@ -303,6 +266,10 @@ namespace OpenSim.Framework
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion JSONRequest
|
||||
|
||||
#region FormRequest
|
||||
|
||||
/// <summary>
|
||||
/// POST URL-encoded form data to a web service that returns LLSD or
|
||||
/// JSON data
|
||||
@@ -313,6 +280,14 @@ namespace OpenSim.Framework
|
||||
}
|
||||
|
||||
public static OSDMap ServiceFormRequest(string url, NameValueCollection data, int timeout)
|
||||
{
|
||||
lock (EndPointLock(url))
|
||||
{
|
||||
return ServiceFormRequestWorker(url,data,timeout);
|
||||
}
|
||||
}
|
||||
|
||||
private static OSDMap ServiceFormRequestWorker(string url, NameValueCollection data, int timeout)
|
||||
{
|
||||
int reqnum = m_requestNumber++;
|
||||
string method = (data != null && data["RequestMethod"] != null) ? data["RequestMethod"] : "unknown";
|
||||
@@ -397,6 +372,8 @@ namespace OpenSim.Framework
|
||||
result["Message"] = OSD.FromString("Service request failed: " + msg);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion FormRequest
|
||||
|
||||
#region Uri
|
||||
|
||||
@@ -533,8 +510,13 @@ namespace OpenSim.Framework
|
||||
/// <remarks>
|
||||
/// Copying begins at the streams' current positions. The positions are
|
||||
/// NOT reset after copying is complete.
|
||||
/// NOTE!! .NET 4.0 adds the method 'Stream.CopyTo(stream, bufferSize)'.
|
||||
/// This function could be replaced with that method once we move
|
||||
/// totally to .NET 4.0. For versions before, this routine exists.
|
||||
/// This routine used to be named 'CopyTo' but the int parameter has
|
||||
/// a different meaning so this method was renamed to avoid any confusion.
|
||||
/// </remarks>
|
||||
public static int CopyTo(this Stream copyFrom, Stream copyTo, int maximumBytesToCopy)
|
||||
public static int CopyStream(this Stream copyFrom, Stream copyTo, int maximumBytesToCopy)
|
||||
{
|
||||
byte[] buffer = new byte[4096];
|
||||
int readBytes;
|
||||
|
||||
@@ -225,12 +225,12 @@ namespace OpenSim
|
||||
/// </summary>
|
||||
private void RegisterConsoleCommands()
|
||||
{
|
||||
m_console.Commands.AddCommand("region", false, "force update",
|
||||
m_console.Commands.AddCommand("Regions", false, "force update",
|
||||
"force update",
|
||||
"Force the update of all objects on clients",
|
||||
HandleForceUpdate);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "debug packet",
|
||||
m_console.Commands.AddCommand("Comms", false, "debug packet",
|
||||
"debug packet <level> [<avatar-first-name> <avatar-last-name>]",
|
||||
"Turn on packet debugging",
|
||||
"If level > 255 then all incoming and outgoing packets are logged.\n"
|
||||
@@ -242,7 +242,7 @@ namespace OpenSim
|
||||
+ "If an avatar name is given then only packets from that avatar are logged",
|
||||
Debug);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "debug http",
|
||||
m_console.Commands.AddCommand("Comms", false, "debug http",
|
||||
"debug http <level>",
|
||||
"Turn on inbound http request debugging for everything except the event queue (see debug eq).",
|
||||
"If level >= 2 then the handler used to service the request is logged.\n"
|
||||
@@ -250,37 +250,37 @@ namespace OpenSim
|
||||
+ "If level <= 0 then no extra http logging is done.\n",
|
||||
Debug);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "debug teleport", "debug teleport", "Toggle teleport route debugging", Debug);
|
||||
m_console.Commands.AddCommand("Comms", false, "debug teleport", "debug teleport", "Toggle teleport route debugging", Debug);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "debug scene",
|
||||
m_console.Commands.AddCommand("Regions", false, "debug scene",
|
||||
"debug scene <scripting> <collisions> <physics>",
|
||||
"Turn on scene debugging", Debug);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "change region",
|
||||
m_console.Commands.AddCommand("General", false, "change region",
|
||||
"change region <region name>",
|
||||
"Change current console region", ChangeSelectedRegion);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "save xml",
|
||||
m_console.Commands.AddCommand("Archiving", false, "save xml",
|
||||
"save xml",
|
||||
"Save a region's data in XML format", SaveXml);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "save xml2",
|
||||
m_console.Commands.AddCommand("Archiving", false, "save xml2",
|
||||
"save xml2",
|
||||
"Save a region's data in XML2 format", SaveXml2);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "load xml",
|
||||
m_console.Commands.AddCommand("Archiving", false, "load xml",
|
||||
"load xml [-newIDs [<x> <y> <z>]]",
|
||||
"Load a region's data from XML format", LoadXml);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "load xml2",
|
||||
m_console.Commands.AddCommand("Archiving", false, "load xml2",
|
||||
"load xml2",
|
||||
"Load a region's data from XML2 format", LoadXml2);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "save prims xml2",
|
||||
m_console.Commands.AddCommand("Archiving", false, "save prims xml2",
|
||||
"save prims xml2 [<prim name> <file name>]",
|
||||
"Save named prim to XML2", SavePrimsXml2);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "load oar",
|
||||
m_console.Commands.AddCommand("Archiving", false, "load oar",
|
||||
"load oar [--merge] [--skip-assets] [<OAR path>]",
|
||||
"Load a region's data from an OAR archive.",
|
||||
"--merge will merge the OAR with the existing scene." + Environment.NewLine
|
||||
@@ -289,7 +289,7 @@ namespace OpenSim
|
||||
+ " If this is not given then the command looks for an OAR named region.oar in the current directory.",
|
||||
LoadOar);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "save oar",
|
||||
m_console.Commands.AddCommand("Archiving", false, "save oar",
|
||||
//"save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]",
|
||||
"save oar [-h|--home=<url>] [--noassets] [--publish] [--perm=<permissions>] [<OAR path>]",
|
||||
"Save a region's data to an OAR archive.",
|
||||
@@ -306,54 +306,54 @@ namespace OpenSim
|
||||
+ " If this is not given then the oar is saved to region.oar in the current directory.",
|
||||
SaveOar);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "edit scale",
|
||||
m_console.Commands.AddCommand("Regions", false, "edit scale",
|
||||
"edit scale <name> <x> <y> <z>",
|
||||
"Change the scale of a named prim", HandleEditScale);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "kick user",
|
||||
m_console.Commands.AddCommand("Users", false, "kick user",
|
||||
"kick user <first> <last> [message]",
|
||||
"Kick a user off the simulator", KickUserCommand);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "show users",
|
||||
m_console.Commands.AddCommand("Users", false, "show users",
|
||||
"show users [full]",
|
||||
"Show user data for users currently on the region",
|
||||
"Without the 'full' option, only users actually on the region are shown."
|
||||
+ " With the 'full' option child agents of users in neighbouring regions are also shown.",
|
||||
HandleShow);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "show connections",
|
||||
m_console.Commands.AddCommand("Comms", false, "show connections",
|
||||
"show connections",
|
||||
"Show connection data", HandleShow);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "show circuits",
|
||||
m_console.Commands.AddCommand("Comms", false, "show circuits",
|
||||
"show circuits",
|
||||
"Show agent circuit data", HandleShow);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "show http-handlers",
|
||||
m_console.Commands.AddCommand("Comms", false, "show http-handlers",
|
||||
"show http-handlers",
|
||||
"Show all registered http handlers", HandleShow);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "show pending-objects",
|
||||
m_console.Commands.AddCommand("Comms", false, "show pending-objects",
|
||||
"show pending-objects",
|
||||
"Show # of objects on the pending queues of all scene viewers", HandleShow);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "show modules",
|
||||
m_console.Commands.AddCommand("General", false, "show modules",
|
||||
"show modules",
|
||||
"Show module data", HandleShow);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "show regions",
|
||||
m_console.Commands.AddCommand("Regions", false, "show regions",
|
||||
"show regions",
|
||||
"Show region data", HandleShow);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "show ratings",
|
||||
m_console.Commands.AddCommand("Regions", false, "show ratings",
|
||||
"show ratings",
|
||||
"Show rating data", HandleShow);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "backup",
|
||||
m_console.Commands.AddCommand("Regions", false, "backup",
|
||||
"backup",
|
||||
"Persist currently unsaved object changes immediately instead of waiting for the normal persistence call.", RunCommand);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "create region",
|
||||
m_console.Commands.AddCommand("Regions", false, "create region",
|
||||
"create region [\"region name\"] <region_file.ini>",
|
||||
"Create a new region.",
|
||||
"The settings for \"region name\" are read from <region_file.ini>. Paths specified with <region_file.ini> are relative to your Regions directory, unless an absolute path is given."
|
||||
@@ -362,62 +362,57 @@ namespace OpenSim
|
||||
+ "If <region_file.ini> does not exist, it will be created.",
|
||||
HandleCreateRegion);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "restart",
|
||||
m_console.Commands.AddCommand("Regions", false, "restart",
|
||||
"restart",
|
||||
"Restart all sims in this instance", RunCommand);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "config set",
|
||||
m_console.Commands.AddCommand("General", false, "config set",
|
||||
"config set <section> <key> <value>",
|
||||
"Set a config option. In most cases this is not useful since changed parameters are not dynamically reloaded. Neither do changed parameters persist - you will have to change a config file manually and restart.", HandleConfig);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "config get",
|
||||
m_console.Commands.AddCommand("General", false, "config get",
|
||||
"config get [<section>] [<key>]",
|
||||
"Synonym for config show",
|
||||
HandleConfig);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "config show",
|
||||
m_console.Commands.AddCommand("General", false, "config show",
|
||||
"config show [<section>] [<key>]",
|
||||
"Show config information",
|
||||
"If neither section nor field are specified, then the whole current configuration is printed." + Environment.NewLine
|
||||
+ "If a section is given but not a field, then all fields in that section are printed.",
|
||||
HandleConfig);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "config save",
|
||||
m_console.Commands.AddCommand("General", false, "config save",
|
||||
"config save <path>",
|
||||
"Save current configuration to a file at the given path", HandleConfig);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "command-script",
|
||||
m_console.Commands.AddCommand("General", false, "command-script",
|
||||
"command-script <script>",
|
||||
"Run a command script from file", RunCommand);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "remove-region",
|
||||
m_console.Commands.AddCommand("Regions", false, "remove-region",
|
||||
"remove-region <name>",
|
||||
"Remove a region from this simulator", RunCommand);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "delete-region",
|
||||
m_console.Commands.AddCommand("Regions", false, "delete-region",
|
||||
"delete-region <name>",
|
||||
"Delete a region from disk", RunCommand);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "modules list",
|
||||
m_console.Commands.AddCommand("General", false, "modules list",
|
||||
"modules list",
|
||||
"List modules", HandleModules);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "modules load",
|
||||
m_console.Commands.AddCommand("General", false, "modules load",
|
||||
"modules load <name>",
|
||||
"Load a module", HandleModules);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "modules unload",
|
||||
m_console.Commands.AddCommand("General", false, "modules unload",
|
||||
"modules unload <name>",
|
||||
"Unload a module", HandleModules);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "Add-InventoryHost",
|
||||
"Add-InventoryHost <host>",
|
||||
String.Empty, RunCommand);
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "kill uuid",
|
||||
m_console.Commands.AddCommand("Regions", false, "kill uuid",
|
||||
"kill uuid <UUID>",
|
||||
"Kill an object by UUID", KillUUID);
|
||||
|
||||
}
|
||||
|
||||
public override void ShutdownSpecific()
|
||||
@@ -508,7 +503,11 @@ namespace OpenSim
|
||||
string currentCommand;
|
||||
while ((currentCommand = readFile.ReadLine()) != null)
|
||||
{
|
||||
if (currentCommand != String.Empty)
|
||||
currentCommand = currentCommand.Trim();
|
||||
if (!(currentCommand == ""
|
||||
|| currentCommand.StartsWith(";")
|
||||
|| currentCommand.StartsWith("//")
|
||||
|| currentCommand.StartsWith("#")))
|
||||
{
|
||||
m_log.Info("[COMMANDFILE]: Running '" + currentCommand + "'");
|
||||
m_console.RunCommand(currentCommand);
|
||||
@@ -829,14 +828,6 @@ namespace OpenSim
|
||||
case "restart":
|
||||
m_sceneManager.RestartCurrentScene();
|
||||
break;
|
||||
|
||||
case "Add-InventoryHost":
|
||||
if (cmdparams.Length > 0)
|
||||
{
|
||||
MainConsole.Instance.Output("Not implemented.");
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -928,7 +919,7 @@ namespace OpenSim
|
||||
break;
|
||||
|
||||
case "scene":
|
||||
if (args.Length == 5)
|
||||
if (args.Length == 4)
|
||||
{
|
||||
if (m_sceneManager.CurrentScene == null)
|
||||
{
|
||||
@@ -936,39 +927,21 @@ namespace OpenSim
|
||||
}
|
||||
else
|
||||
{
|
||||
bool scriptingOn = !Convert.ToBoolean(args[2]);
|
||||
bool collisionsOn = !Convert.ToBoolean(args[3]);
|
||||
bool physicsOn = !Convert.ToBoolean(args[4]);
|
||||
m_sceneManager.CurrentScene.SetSceneCoreDebug(scriptingOn, collisionsOn, physicsOn);
|
||||
string key = args[2];
|
||||
string value = args[3];
|
||||
m_sceneManager.CurrentScene.SetSceneCoreDebug(
|
||||
new Dictionary<string, string>() { { key, value } });
|
||||
|
||||
MainConsole.Instance.Output(
|
||||
String.Format(
|
||||
"Set debug scene scripting = {0}, collisions = {1}, physics = {2}",
|
||||
!scriptingOn, !collisionsOn, !physicsOn));
|
||||
MainConsole.Instance.OutputFormat("Set debug scene {0} = {1}", key, value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: debug scene <scripting> <collisions> <physics> (where inside <> is true/false)");
|
||||
MainConsole.Instance.Output("Usage: debug scene scripting|collisions|physics|teleport true|false");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "teleport":
|
||||
foreach(Scene s in m_sceneManager.Scenes)
|
||||
{
|
||||
if (s.DEBUG)
|
||||
{
|
||||
s.DEBUG = false;
|
||||
MainConsole.Instance.Output("Teleport debugging is disabled!");
|
||||
}
|
||||
else{
|
||||
s.DEBUG = true;
|
||||
MainConsole.Instance.Output("Teleport debugging is enabled!");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
MainConsole.Instance.Output("Unknown debug command");
|
||||
break;
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
@@ -67,6 +68,9 @@ namespace OpenSim
|
||||
private const string PLUGIN_ASSET_CACHE = "/OpenSim/AssetCache";
|
||||
private const string PLUGIN_ASSET_SERVER_CLIENT = "/OpenSim/AssetClient";
|
||||
|
||||
// OpenSim.ini Section name for ESTATES Settings
|
||||
public const string ESTATE_SECTION_NAME = "Estates";
|
||||
|
||||
protected string proxyUrl;
|
||||
protected int proxyOffset = 0;
|
||||
|
||||
@@ -242,15 +246,18 @@ namespace OpenSim
|
||||
|
||||
foreach (string topic in topics)
|
||||
{
|
||||
m_console.Commands.AddCommand("plugin", false, "help " + topic,
|
||||
"help " + topic,
|
||||
string capitalizedTopic = char.ToUpper(topic[0]) + topic.Substring(1);
|
||||
|
||||
// This is a hack to allow the user to enter the help command in upper or lowercase. This will go
|
||||
// away at some point.
|
||||
m_console.Commands.AddCommand(capitalizedTopic, false, "help " + topic,
|
||||
"help " + capitalizedTopic,
|
||||
"Get help on plugin command '" + topic + "'",
|
||||
HandleCommanderHelp);
|
||||
m_console.Commands.AddCommand(capitalizedTopic, false, "help " + capitalizedTopic,
|
||||
"help " + capitalizedTopic,
|
||||
"Get help on plugin command '" + topic + "'",
|
||||
HandleCommanderHelp);
|
||||
|
||||
m_console.Commands.AddCommand("plugin", false, topic,
|
||||
topic,
|
||||
"Execute subcommand for plugin '" + topic + "'",
|
||||
null);
|
||||
|
||||
ICommander commander = null;
|
||||
|
||||
@@ -267,7 +274,7 @@ namespace OpenSim
|
||||
|
||||
foreach (string command in commander.Commands.Keys)
|
||||
{
|
||||
m_console.Commands.AddCommand(topic, false,
|
||||
m_console.Commands.AddCommand(capitalizedTopic, false,
|
||||
topic + " " + command,
|
||||
topic + " " + commander.Commands[command].ShortHelp(),
|
||||
String.Empty, HandleCommanderCommand);
|
||||
@@ -286,7 +293,7 @@ namespace OpenSim
|
||||
// Only safe for the interactive console, since it won't
|
||||
// let us come here unless both scene and commander exist
|
||||
//
|
||||
ICommander moduleCommander = SceneManager.CurrentOrFirstScene.GetCommander(cmd[1]);
|
||||
ICommander moduleCommander = SceneManager.CurrentOrFirstScene.GetCommander(cmd[1].ToLower());
|
||||
if (moduleCommander != null)
|
||||
m_console.Output(moduleCommander.Help);
|
||||
}
|
||||
@@ -424,7 +431,7 @@ namespace OpenSim
|
||||
|
||||
mscene = scene;
|
||||
|
||||
scene.StartTimer();
|
||||
scene.Start();
|
||||
|
||||
scene.StartScripts();
|
||||
|
||||
@@ -443,12 +450,42 @@ namespace OpenSim
|
||||
{
|
||||
RegionInfo regionInfo = scene.RegionInfo;
|
||||
|
||||
string estateOwnerFirstName = null;
|
||||
string estateOwnerLastName = null;
|
||||
string estateOwnerEMail = null;
|
||||
string estateOwnerPassword = null;
|
||||
string rawEstateOwnerUuid = null;
|
||||
|
||||
if (m_config.Source.Configs[ESTATE_SECTION_NAME] != null)
|
||||
{
|
||||
string defaultEstateOwnerName
|
||||
= m_config.Source.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateOwnerName", "").Trim();
|
||||
string[] ownerNames = defaultEstateOwnerName.Split(' ');
|
||||
|
||||
if (ownerNames.Length >= 2)
|
||||
{
|
||||
estateOwnerFirstName = ownerNames[0];
|
||||
estateOwnerLastName = ownerNames[1];
|
||||
}
|
||||
|
||||
// Info to be used only on Standalone Mode
|
||||
rawEstateOwnerUuid = m_config.Source.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateOwnerUUID", null);
|
||||
estateOwnerEMail = m_config.Source.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateOwnerEMail", null);
|
||||
estateOwnerPassword = m_config.Source.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateOwnerPassword", null);
|
||||
}
|
||||
|
||||
MainConsole.Instance.OutputFormat("Estate {0} has no owner set.", regionInfo.EstateSettings.EstateName);
|
||||
List<char> excluded = new List<char>(new char[1]{' '});
|
||||
string first = MainConsole.Instance.CmdPrompt("Estate owner first name", "Test", excluded);
|
||||
string last = MainConsole.Instance.CmdPrompt("Estate owner last name", "User", excluded);
|
||||
|
||||
UserAccount account = scene.UserAccountService.GetUserAccount(regionInfo.ScopeID, first, last);
|
||||
|
||||
if (estateOwnerFirstName == null || estateOwnerLastName == null)
|
||||
{
|
||||
estateOwnerFirstName = MainConsole.Instance.CmdPrompt("Estate owner first name", "Test", excluded);
|
||||
estateOwnerLastName = MainConsole.Instance.CmdPrompt("Estate owner last name", "User", excluded);
|
||||
}
|
||||
|
||||
UserAccount account
|
||||
= scene.UserAccountService.GetUserAccount(regionInfo.ScopeID, estateOwnerFirstName, estateOwnerLastName);
|
||||
|
||||
if (account == null)
|
||||
{
|
||||
@@ -467,23 +504,35 @@ namespace OpenSim
|
||||
|
||||
if (scene.UserAccountService is UserAccountService)
|
||||
{
|
||||
string password = MainConsole.Instance.PasswdPrompt("Password");
|
||||
string email = MainConsole.Instance.CmdPrompt("Email", "");
|
||||
if (estateOwnerPassword == null)
|
||||
estateOwnerPassword = MainConsole.Instance.PasswdPrompt("Password");
|
||||
|
||||
string rawPrincipalId = MainConsole.Instance.CmdPrompt("User ID", UUID.Random().ToString());
|
||||
if (estateOwnerEMail == null)
|
||||
estateOwnerEMail = MainConsole.Instance.CmdPrompt("Email");
|
||||
|
||||
if (rawEstateOwnerUuid == null)
|
||||
rawEstateOwnerUuid = MainConsole.Instance.CmdPrompt("User ID", UUID.Random().ToString());
|
||||
|
||||
UUID principalId = UUID.Zero;
|
||||
if (!UUID.TryParse(rawPrincipalId, out principalId))
|
||||
UUID estateOwnerUuid = UUID.Zero;
|
||||
if (!UUID.TryParse(rawEstateOwnerUuid, out estateOwnerUuid))
|
||||
{
|
||||
m_log.ErrorFormat("[OPENSIM]: ID {0} is not a valid UUID", rawPrincipalId);
|
||||
m_log.ErrorFormat("[OPENSIM]: ID {0} is not a valid UUID", rawEstateOwnerUuid);
|
||||
return;
|
||||
}
|
||||
|
||||
// If we've been given a zero uuid then this signals that we should use a random user id
|
||||
if (estateOwnerUuid == UUID.Zero)
|
||||
estateOwnerUuid = UUID.Random();
|
||||
|
||||
account
|
||||
= ((UserAccountService)scene.UserAccountService).CreateUser(
|
||||
regionInfo.ScopeID, principalId, first, last, password, email);
|
||||
regionInfo.ScopeID,
|
||||
estateOwnerUuid,
|
||||
estateOwnerFirstName,
|
||||
estateOwnerLastName,
|
||||
estateOwnerPassword,
|
||||
estateOwnerEMail);
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
if (account == null)
|
||||
@@ -883,15 +932,21 @@ namespace OpenSim
|
||||
/// This method doesn't allow an estate to be created with the same name as existing estates.
|
||||
/// </remarks>
|
||||
/// <param name="regInfo"></param>
|
||||
/// <param name="existingName">A list of estate names that already exist.</param>
|
||||
/// <param name="estatesByName">A list of estate names that already exist.</param>
|
||||
/// <param name="estateName">Estate name to create if already known</param>
|
||||
/// <returns>true if the estate was created, false otherwise</returns>
|
||||
public bool CreateEstate(RegionInfo regInfo, List<string> existingNames)
|
||||
public bool CreateEstate(RegionInfo regInfo, Dictionary<string, EstateSettings> estatesByName, string estateName)
|
||||
{
|
||||
// Create a new estate
|
||||
regInfo.EstateSettings = EstateDataService.LoadEstateSettings(regInfo.RegionID, true);
|
||||
string newName = MainConsole.Instance.CmdPrompt("New estate name", regInfo.EstateSettings.EstateName);
|
||||
|
||||
if (existingNames.Contains(newName))
|
||||
string newName;
|
||||
if (estateName != null && estateName != "")
|
||||
newName = estateName;
|
||||
else
|
||||
newName = MainConsole.Instance.CmdPrompt("New estate name", regInfo.EstateSettings.EstateName);
|
||||
|
||||
if (estatesByName.ContainsKey(newName))
|
||||
{
|
||||
MainConsole.Instance.OutputFormat("An estate named {0} already exists. Please try again.", newName);
|
||||
return false;
|
||||
@@ -918,66 +973,102 @@ namespace OpenSim
|
||||
if (EstateDataService != null)
|
||||
regInfo.EstateSettings = EstateDataService.LoadEstateSettings(regInfo.RegionID, false);
|
||||
|
||||
if (regInfo.EstateSettings.EstateID == 0) // No record at all
|
||||
if (regInfo.EstateSettings.EstateID != 0)
|
||||
return;
|
||||
|
||||
m_log.WarnFormat("[ESTATE] Region {0} is not part of an estate.", regInfo.RegionName);
|
||||
|
||||
List<EstateSettings> estates = EstateDataService.LoadEstateSettingsAll();
|
||||
Dictionary<string, EstateSettings> estatesByName = new Dictionary<string, EstateSettings>();
|
||||
|
||||
foreach (EstateSettings estate in estates)
|
||||
estatesByName[estate.EstateName] = estate;
|
||||
|
||||
string defaultEstateName = null;
|
||||
|
||||
if (m_config.Source.Configs[ESTATE_SECTION_NAME] != null)
|
||||
{
|
||||
m_log.WarnFormat("[ESTATE] Region {0} is not part of an estate.", regInfo.RegionName);
|
||||
|
||||
List<EstateSettings> estates = EstateDataService.LoadEstateSettingsAll();
|
||||
List<string> estateNames = new List<string>();
|
||||
foreach (EstateSettings estate in estates)
|
||||
estateNames.Add(estate.EstateName);
|
||||
|
||||
while (true)
|
||||
defaultEstateName = m_config.Source.Configs[ESTATE_SECTION_NAME].GetString("DefaultEstateName", null);
|
||||
|
||||
if (defaultEstateName != null)
|
||||
{
|
||||
if (estates.Count == 0)
|
||||
{
|
||||
m_log.Info("[ESTATE] No existing estates found. You must create a new one.");
|
||||
|
||||
if (CreateEstate(regInfo, estateNames))
|
||||
break;
|
||||
EstateSettings defaultEstate;
|
||||
bool defaultEstateJoined = false;
|
||||
|
||||
if (estatesByName.ContainsKey(defaultEstateName))
|
||||
{
|
||||
defaultEstate = estatesByName[defaultEstateName];
|
||||
|
||||
if (EstateDataService.LinkRegion(regInfo.RegionID, (int)defaultEstate.EstateID))
|
||||
defaultEstateJoined = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CreateEstate(regInfo, estatesByName, defaultEstateName))
|
||||
defaultEstateJoined = true;
|
||||
}
|
||||
|
||||
if (defaultEstateJoined)
|
||||
return;
|
||||
else
|
||||
m_log.ErrorFormat(
|
||||
"[OPENSIM BASE]: Joining default estate {0} failed", defaultEstateName);
|
||||
}
|
||||
}
|
||||
|
||||
// If we have no default estate or creation of the default estate failed then ask the user.
|
||||
while (true)
|
||||
{
|
||||
if (estates.Count == 0)
|
||||
{
|
||||
m_log.Info("[ESTATE]: No existing estates found. You must create a new one.");
|
||||
|
||||
if (CreateEstate(regInfo, estatesByName, null))
|
||||
break;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
string response
|
||||
= MainConsole.Instance.CmdPrompt(
|
||||
string.Format(
|
||||
"Do you wish to join region {0} to an existing estate (yes/no)?", regInfo.RegionName),
|
||||
"yes",
|
||||
new List<string>() { "yes", "no" });
|
||||
|
||||
if (response == "no")
|
||||
{
|
||||
if (CreateEstate(regInfo, estatesByName, null))
|
||||
break;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
string response
|
||||
string[] estateNames = estatesByName.Keys.ToArray();
|
||||
response
|
||||
= MainConsole.Instance.CmdPrompt(
|
||||
string.Format(
|
||||
"Do you wish to join region {0} to an existing estate (yes/no)?", regInfo.RegionName),
|
||||
"yes",
|
||||
new List<string>() { "yes", "no" });
|
||||
|
||||
if (response == "no")
|
||||
"Name of estate to join. Existing estate names are ({0})",
|
||||
string.Join(", ", estateNames)),
|
||||
estateNames[0]);
|
||||
|
||||
List<int> estateIDs = EstateDataService.GetEstates(response);
|
||||
if (estateIDs.Count < 1)
|
||||
{
|
||||
if (CreateEstate(regInfo, estateNames))
|
||||
break;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
response
|
||||
= MainConsole.Instance.CmdPrompt(
|
||||
string.Format(
|
||||
"Name of estate to join. Existing estate names are ({0})", string.Join(", ", estateNames.ToArray())),
|
||||
estateNames[0]);
|
||||
|
||||
List<int> estateIDs = EstateDataService.GetEstates(response);
|
||||
if (estateIDs.Count < 1)
|
||||
{
|
||||
MainConsole.Instance.Output("The name you have entered matches no known estate. Please try again.");
|
||||
continue;
|
||||
}
|
||||
|
||||
int estateID = estateIDs[0];
|
||||
|
||||
regInfo.EstateSettings = EstateDataService.LoadEstateSettings(estateID);
|
||||
|
||||
if (EstateDataService.LinkRegion(regInfo.RegionID, estateID))
|
||||
break;
|
||||
|
||||
MainConsole.Instance.Output("Joining the estate failed. Please try again.");
|
||||
MainConsole.Instance.Output("The name you have entered matches no known estate. Please try again.");
|
||||
continue;
|
||||
}
|
||||
|
||||
int estateID = estateIDs[0];
|
||||
|
||||
regInfo.EstateSettings = EstateDataService.LoadEstateSettings(estateID);
|
||||
|
||||
if (EstateDataService.LinkRegion(regInfo.RegionID, estateID))
|
||||
break;
|
||||
|
||||
MainConsole.Instance.Output("Joining the estate failed. Please try again.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,6 +111,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
private IAssetService m_assetService;
|
||||
private bool m_dumpAssetsToFile = false;
|
||||
private string m_regionName;
|
||||
private int m_levelUpload = 0;
|
||||
|
||||
public BunchOfCaps(Scene scene, Caps caps)
|
||||
{
|
||||
@@ -121,7 +122,10 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
{
|
||||
IConfig sconfig = config.Configs["Startup"];
|
||||
if (sconfig != null)
|
||||
{
|
||||
m_persistBakedTextures = sconfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures);
|
||||
m_levelUpload = sconfig.GetInt("LevelUpload", 0);
|
||||
}
|
||||
}
|
||||
|
||||
m_assetService = m_Scene.AssetService;
|
||||
@@ -262,7 +266,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
{
|
||||
try
|
||||
{
|
||||
m_log.Debug("[CAPS]: ScriptTaskInventory Request in region: " + m_regionName);
|
||||
// m_log.Debug("[CAPS]: ScriptTaskInventory Request in region: " + m_regionName);
|
||||
//m_log.DebugFormat("[CAPS]: request: {0}, path: {1}, param: {2}", request, path, param);
|
||||
|
||||
Hashtable hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
|
||||
@@ -357,21 +361,37 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
llsdRequest.asset_type == "animation" ||
|
||||
llsdRequest.asset_type == "sound")
|
||||
{
|
||||
ScenePresence avatar = null;
|
||||
IClientAPI client = null;
|
||||
IScene scene = null;
|
||||
if (GetClient != null)
|
||||
{
|
||||
client = GetClient(m_HostCapsObj.AgentID);
|
||||
scene = client.Scene;
|
||||
m_Scene.TryGetScenePresence(m_HostCapsObj.AgentID, out avatar);
|
||||
|
||||
IMoneyModule mm = scene.RequestModuleInterface<IMoneyModule>();
|
||||
// check user level
|
||||
if (avatar != null)
|
||||
{
|
||||
client = avatar.ControllingClient;
|
||||
|
||||
if (avatar.UserLevel < m_levelUpload)
|
||||
{
|
||||
if (client != null)
|
||||
client.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false);
|
||||
|
||||
LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse();
|
||||
errorResponse.uploader = "";
|
||||
errorResponse.state = "error";
|
||||
return errorResponse;
|
||||
}
|
||||
}
|
||||
|
||||
// check funds
|
||||
if (client != null)
|
||||
{
|
||||
IMoneyModule mm = m_Scene.RequestModuleInterface<IMoneyModule>();
|
||||
|
||||
if (mm != null)
|
||||
{
|
||||
if (!mm.UploadCovered(client.AgentId, mm.UploadCharge))
|
||||
{
|
||||
if (client != null)
|
||||
client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
|
||||
client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
|
||||
|
||||
LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse();
|
||||
errorResponse.uploader = "";
|
||||
@@ -761,7 +781,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
SceneObjectPart part = m_Scene.GetSceneObjectPart(objectID);
|
||||
if (part != null)
|
||||
{
|
||||
TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(notecardID);
|
||||
// TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(notecardID);
|
||||
if (!m_Scene.Permissions.CanCopyObjectInventory(notecardID, objectID, m_HostCapsObj.AgentID))
|
||||
{
|
||||
return LLSDHelpers.SerialiseLLSDReply(response);
|
||||
|
||||
@@ -106,7 +106,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
scene.EventManager.OnRegisterCaps += OnRegisterCaps;
|
||||
|
||||
MainConsole.Instance.Commands.AddCommand(
|
||||
"event queue",
|
||||
"Comms",
|
||||
false,
|
||||
"debug eq",
|
||||
"debug eq [0|1]",
|
||||
|
||||
+30
-12
@@ -56,6 +56,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
// private IAssetService m_assetService;
|
||||
private bool m_dumpAssetsToFile = false;
|
||||
private bool m_enabled = true;
|
||||
private int m_levelUpload = 0;
|
||||
|
||||
#region IRegionModuleBase Members
|
||||
|
||||
@@ -72,6 +73,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
return;
|
||||
|
||||
m_enabled = meshConfig.GetBoolean("AllowMeshUpload", true);
|
||||
m_levelUpload = meshConfig.GetInt("LevelUpload", 0);
|
||||
}
|
||||
|
||||
public void AddRegion(Scene pScene)
|
||||
@@ -137,25 +139,41 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||
// llsdRequest.asset_type == "animation" ||
|
||||
// llsdRequest.asset_type == "sound")
|
||||
// {
|
||||
// check user level
|
||||
ScenePresence avatar = null;
|
||||
IClientAPI client = null;
|
||||
m_scene.TryGetScenePresence(agentID, out avatar);
|
||||
|
||||
|
||||
if (avatar != null)
|
||||
{
|
||||
client = avatar.ControllingClient;
|
||||
|
||||
if (avatar.UserLevel < m_levelUpload)
|
||||
{
|
||||
if (client != null)
|
||||
client.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false);
|
||||
|
||||
LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
|
||||
errorResponse.rsvp = "";
|
||||
errorResponse.state = "error";
|
||||
return errorResponse;
|
||||
}
|
||||
}
|
||||
|
||||
// check funds
|
||||
IMoneyModule mm = m_scene.RequestModuleInterface<IMoneyModule>();
|
||||
|
||||
|
||||
if (mm != null)
|
||||
{
|
||||
if (m_scene.TryGetClient(agentID, out client))
|
||||
if (!mm.UploadCovered(agentID, mm.UploadCharge))
|
||||
{
|
||||
if (!mm.UploadCovered(client.AgentId, mm.UploadCharge))
|
||||
{
|
||||
if (client != null)
|
||||
client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
|
||||
if (client != null)
|
||||
client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
|
||||
|
||||
LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
|
||||
errorResponse.rsvp = "";
|
||||
errorResponse.state = "error";
|
||||
return errorResponse;
|
||||
}
|
||||
LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
|
||||
errorResponse.rsvp = "";
|
||||
errorResponse.state = "error";
|
||||
return errorResponse;
|
||||
}
|
||||
}
|
||||
// }
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
/// Handles new client connections
|
||||
/// Constructor takes a single Packet and authenticates everything
|
||||
/// </summary>
|
||||
public class LLClientView : IClientAPI, IClientCore, IClientIM, IClientChat, IClientIPEndpoint, IStatsCollector
|
||||
public class LLClientView : IClientAPI, IClientCore, IClientIM, IClientChat, IClientInventory, IClientIPEndpoint, IStatsCollector
|
||||
{
|
||||
/// <value>
|
||||
/// Debug packet level. See OpenSim.RegisterConsoleCommands() for more details.
|
||||
@@ -317,7 +317,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
protected readonly UUID m_agentId;
|
||||
private readonly uint m_circuitCode;
|
||||
private readonly byte[] m_channelVersion = Utils.EmptyBytes;
|
||||
private readonly Dictionary<string, UUID> m_defaultAnimations = new Dictionary<string, UUID>();
|
||||
private readonly IGroupsModule m_GroupsModule;
|
||||
|
||||
private int m_cachedTextureSerial;
|
||||
@@ -385,7 +384,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
set { m_startpos = value; }
|
||||
}
|
||||
public UUID AgentId { get { return m_agentId; } }
|
||||
public ISceneAgent SceneAgent { get; private set; }
|
||||
public ISceneAgent SceneAgent { get; set; }
|
||||
public UUID ActiveGroupId { get { return m_activeGroupID; } }
|
||||
public string ActiveGroupName { get { return m_activeGroupName; } }
|
||||
public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } }
|
||||
@@ -449,13 +448,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
// DebugPacketLevel = 1;
|
||||
|
||||
RegisterInterface<IClientIM>(this);
|
||||
RegisterInterface<IClientInventory>(this);
|
||||
RegisterInterface<IClientChat>(this);
|
||||
RegisterInterface<IClientIPEndpoint>(this);
|
||||
|
||||
InitDefaultAnimations();
|
||||
|
||||
m_scene = scene;
|
||||
|
||||
m_entityUpdates = new PriorityQueue(m_scene.Entities.Count);
|
||||
m_entityProps = new PriorityQueue(m_scene.Entities.Count);
|
||||
m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>();
|
||||
@@ -698,7 +695,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
public virtual void Start()
|
||||
{
|
||||
SceneAgent = m_scene.AddNewClient(this, PresenceType.User);
|
||||
m_scene.AddNewClient(this, PresenceType.User);
|
||||
|
||||
RefreshGroupMembership();
|
||||
}
|
||||
@@ -1916,7 +1913,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
|
||||
folderBlock.FolderID = folder.ID;
|
||||
folderBlock.ParentID = folder.ParentID;
|
||||
folderBlock.Type = -1;
|
||||
//folderBlock.Type = -1;
|
||||
folderBlock.Type = (sbyte)folder.Type;
|
||||
folderBlock.Name = Util.StringToBytes256(folder.Name);
|
||||
|
||||
return folderBlock;
|
||||
@@ -4273,7 +4271,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
block.OwnerID = sop.OwnerID;
|
||||
|
||||
block.ItemID = sop.FromUserInventoryItemID;
|
||||
block.FolderID = UUID.Zero; // sop.FromFolderID ??
|
||||
block.FolderID = UUID.Zero; // sog.FromFolderID ??
|
||||
block.FromTaskID = UUID.Zero; // ???
|
||||
block.InventorySerial = (short)sop.InventorySerial;
|
||||
|
||||
@@ -4959,7 +4957,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim
|
||||
if (data.ParentGroup.IsAttachment)
|
||||
{
|
||||
update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.FromItemID);
|
||||
update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.ParentGroup.FromItemID);
|
||||
update.State = (byte)((data.ParentGroup.AttachmentPoint % 16) * 16 + (data.ParentGroup.AttachmentPoint / 16));
|
||||
}
|
||||
else
|
||||
@@ -5787,7 +5785,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
// My guess is this is the folder to stick the calling card into
|
||||
List<UUID> callingCardFolders = new List<UUID>();
|
||||
|
||||
UUID agentID = afriendpack.AgentData.AgentID;
|
||||
UUID transactionID = afriendpack.TransactionBlock.TransactionID;
|
||||
|
||||
for (int fi = 0; fi < afriendpack.FolderData.Length; fi++)
|
||||
@@ -5798,10 +5795,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
FriendActionDelegate handlerApproveFriendRequest = OnApproveFriendRequest;
|
||||
if (handlerApproveFriendRequest != null)
|
||||
{
|
||||
handlerApproveFriendRequest(this, agentID, transactionID, callingCardFolders);
|
||||
handlerApproveFriendRequest(this, transactionID, callingCardFolders);
|
||||
}
|
||||
return true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool HandlerDeclineFriendship(IClientAPI sender, Packet Pack)
|
||||
@@ -5820,7 +5817,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
if (OnDenyFriendRequest != null)
|
||||
{
|
||||
OnDenyFriendRequest(this,
|
||||
dfriendpack.AgentData.AgentID,
|
||||
dfriendpack.TransactionBlock.TransactionID,
|
||||
null);
|
||||
}
|
||||
@@ -5840,14 +5836,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
}
|
||||
#endregion
|
||||
|
||||
UUID listOwnerAgentID = tfriendpack.AgentData.AgentID;
|
||||
UUID exFriendID = tfriendpack.ExBlock.OtherID;
|
||||
FriendshipTermination TerminateFriendshipHandler = OnTerminateFriendship;
|
||||
if (TerminateFriendshipHandler != null)
|
||||
{
|
||||
TerminateFriendshipHandler(this, listOwnerAgentID, exFriendID);
|
||||
TerminateFriendshipHandler(this, exFriendID);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -11165,12 +11161,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
return true;
|
||||
}
|
||||
#endregion
|
||||
|
||||
GrantUserFriendRights GrantUserRightsHandler = OnGrantUserRights;
|
||||
if (GrantUserRightsHandler != null)
|
||||
GrantUserRightsHandler(this,
|
||||
GrantUserRights.AgentData.AgentID,
|
||||
GrantUserRights.Rights[0].AgentRelated,
|
||||
GrantUserRights.Rights[0].RelatedRights);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -11206,36 +11203,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
scriptQuestion.Data.Questions = question;
|
||||
scriptQuestion.Data.ObjectName = Util.StringToBytes256(taskName);
|
||||
scriptQuestion.Data.ObjectOwner = Util.StringToBytes256(ownerName);
|
||||
|
||||
|
||||
OutPacket(scriptQuestion, ThrottleOutPacketType.Task);
|
||||
}
|
||||
|
||||
private void InitDefaultAnimations()
|
||||
{
|
||||
using (XmlTextReader reader = new XmlTextReader("data/avataranimations.xml"))
|
||||
{
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load(reader);
|
||||
if (doc.DocumentElement != null)
|
||||
foreach (XmlNode nod in doc.DocumentElement.ChildNodes)
|
||||
{
|
||||
if (nod.Attributes["name"] != null)
|
||||
{
|
||||
string name = nod.Attributes["name"].Value.ToLower();
|
||||
string id = nod.InnerText;
|
||||
m_defaultAnimations.Add(name, (UUID)id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public UUID GetDefaultAnimation(string name)
|
||||
{
|
||||
if (m_defaultAnimations.ContainsKey(name))
|
||||
return m_defaultAnimations[name];
|
||||
return UUID.Zero;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handler called when we receive a logout packet.
|
||||
/// </summary>
|
||||
@@ -12292,5 +12263,175 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||
if (reply != null)
|
||||
OutPacket(reply, ThrottleOutPacketType.Task);
|
||||
}
|
||||
|
||||
public void SendRemoveInventoryItems(UUID[] items)
|
||||
{
|
||||
IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
|
||||
|
||||
if (eq == null)
|
||||
{
|
||||
m_log.DebugFormat("[LLCLIENT]: Null event queue");
|
||||
return;
|
||||
}
|
||||
|
||||
OSDMap llsd = new OSDMap(3);
|
||||
|
||||
OSDMap AgentDataMap = new OSDMap(1);
|
||||
AgentDataMap.Add("AgentID", OSD.FromUUID(AgentId));
|
||||
AgentDataMap.Add("SessionID", OSD.FromUUID(SessionId));
|
||||
|
||||
OSDArray AgentData = new OSDArray(1);
|
||||
AgentData.Add(AgentDataMap);
|
||||
|
||||
llsd.Add("AgentData", AgentData);
|
||||
|
||||
OSDArray ItemData = new OSDArray();
|
||||
|
||||
foreach (UUID item in items)
|
||||
{
|
||||
OSDMap ItemDataMap = new OSDMap(2);
|
||||
ItemDataMap.Add("ItemID", OSD.FromUUID(item));
|
||||
ItemDataMap.Add("AgentID", OSD.FromUUID(AgentId));
|
||||
|
||||
ItemData.Add(ItemDataMap);
|
||||
}
|
||||
|
||||
llsd.Add("InventoryData", ItemData);
|
||||
|
||||
eq.Enqueue(BuildEvent("RemoveInventoryItem",
|
||||
llsd), AgentId);
|
||||
}
|
||||
|
||||
public void SendRemoveInventoryFolders(UUID[] folders)
|
||||
{
|
||||
IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
|
||||
|
||||
if (eq == null)
|
||||
{
|
||||
m_log.DebugFormat("[LLCLIENT]: Null event queue");
|
||||
return;
|
||||
}
|
||||
|
||||
OSDMap llsd = new OSDMap(3);
|
||||
|
||||
OSDMap AgentDataMap = new OSDMap(1);
|
||||
AgentDataMap.Add("AgentID", OSD.FromUUID(AgentId));
|
||||
AgentDataMap.Add("SessionID", OSD.FromUUID(SessionId));
|
||||
|
||||
OSDArray AgentData = new OSDArray(1);
|
||||
AgentData.Add(AgentDataMap);
|
||||
|
||||
llsd.Add("AgentData", AgentData);
|
||||
|
||||
OSDArray FolderData = new OSDArray();
|
||||
|
||||
foreach (UUID folder in folders)
|
||||
{
|
||||
OSDMap FolderDataMap = new OSDMap(2);
|
||||
FolderDataMap.Add("FolderID", OSD.FromUUID(folder));
|
||||
FolderDataMap.Add("AgentID", OSD.FromUUID(AgentId));
|
||||
|
||||
FolderData.Add(FolderDataMap);
|
||||
}
|
||||
|
||||
llsd.Add("FolderData", FolderData);
|
||||
|
||||
eq.Enqueue(BuildEvent("RemoveInventoryFolder",
|
||||
llsd), AgentId);
|
||||
}
|
||||
|
||||
private byte[] EncodeU32(uint val)
|
||||
{
|
||||
byte[] ret = BitConverter.GetBytes(val);
|
||||
if (BitConverter.IsLittleEndian)
|
||||
Array.Reverse(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void SendBulkUpdateInventory(InventoryFolderBase[] folders, InventoryItemBase[] items)
|
||||
{
|
||||
IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
|
||||
|
||||
if (eq == null)
|
||||
{
|
||||
m_log.DebugFormat("[LLCLIENT]: Null event queue");
|
||||
return;
|
||||
}
|
||||
|
||||
OSDMap llsd = new OSDMap(3);
|
||||
|
||||
OSDMap AgentDataMap = new OSDMap(1);
|
||||
AgentDataMap.Add("AgentID", OSD.FromUUID(AgentId));
|
||||
AgentDataMap.Add("SessionID", OSD.FromUUID(SessionId));
|
||||
AgentDataMap.Add("TransactionID", OSD.FromUUID(UUID.Random()));
|
||||
|
||||
OSDArray AgentData = new OSDArray(1);
|
||||
AgentData.Add(AgentDataMap);
|
||||
|
||||
llsd.Add("AgentData", AgentData);
|
||||
|
||||
OSDArray FolderData = new OSDArray();
|
||||
|
||||
foreach (InventoryFolderBase folder in folders)
|
||||
{
|
||||
OSDMap FolderDataMap = new OSDMap(5);
|
||||
FolderDataMap.Add("FolderID", OSD.FromUUID(folder.ID));
|
||||
FolderDataMap.Add("AgentID", OSD.FromUUID(AgentId));
|
||||
FolderDataMap.Add("ParentID", OSD.FromUUID(folder.ParentID));
|
||||
FolderDataMap.Add("Type", OSD.FromInteger(folder.Type));
|
||||
FolderDataMap.Add("Name", OSD.FromString(folder.Name));
|
||||
|
||||
FolderData.Add(FolderDataMap);
|
||||
}
|
||||
|
||||
llsd.Add("FolderData", FolderData);
|
||||
|
||||
OSDArray ItemData = new OSDArray();
|
||||
|
||||
foreach (InventoryItemBase item in items)
|
||||
{
|
||||
OSDMap ItemDataMap = new OSDMap();
|
||||
|
||||
ItemDataMap.Add("ItemID", OSD.FromUUID(item.ID));
|
||||
ItemDataMap.Add("FolderID", OSD.FromUUID(item.Folder));
|
||||
|
||||
ItemDataMap.Add("CreatorID", OSD.FromUUID(item.CreatorIdAsUuid));
|
||||
ItemDataMap.Add("OwnerID", OSD.FromUUID(item.Owner));
|
||||
ItemDataMap.Add("GroupID", OSD.FromUUID(item.GroupID));
|
||||
ItemDataMap.Add("BaseMask", OSD.FromBinary(EncodeU32((uint)item.BasePermissions)));
|
||||
ItemDataMap.Add("OwnerMask", OSD.FromBinary(EncodeU32((uint)item.CurrentPermissions)));
|
||||
ItemDataMap.Add("GroupMask", OSD.FromBinary(EncodeU32((uint)item.GroupPermissions)));
|
||||
ItemDataMap.Add("EveryoneMask", OSD.FromBinary(EncodeU32((uint)item.EveryOnePermissions)));
|
||||
ItemDataMap.Add("NextOwnerMask", OSD.FromBinary(EncodeU32((uint)item.NextPermissions)));
|
||||
ItemDataMap.Add("GroupOwned", OSD.FromBoolean(item.GroupOwned));
|
||||
ItemDataMap.Add("AssetID", OSD.FromUUID(item.AssetID));
|
||||
ItemDataMap.Add("Type", OSD.FromInteger(item.AssetType));
|
||||
ItemDataMap.Add("InvType", OSD.FromInteger(item.InvType));
|
||||
ItemDataMap.Add("Flags", OSD.FromBinary(EncodeU32((uint)item.Flags)));
|
||||
ItemDataMap.Add("SaleType", OSD.FromInteger((byte)item.SaleType));
|
||||
ItemDataMap.Add("SalePrice", OSD.FromInteger(item.SalePrice));
|
||||
ItemDataMap.Add("Name", OSD.FromString(item.Name));
|
||||
ItemDataMap.Add("Description", OSD.FromString(item.Description));
|
||||
ItemDataMap.Add("CreationDate", OSD.FromInteger(item.CreationDate));
|
||||
|
||||
ItemDataMap.Add("CRC", OSD.FromBinary(EncodeU32(
|
||||
Helpers.InventoryCRC(1000, 0, (sbyte)item.InvType,
|
||||
(sbyte)item.AssetType, item.AssetID,
|
||||
item.GroupID, 100,
|
||||
item.Owner, item.CreatorIdAsUuid,
|
||||
item.ID, item.Folder,
|
||||
(uint)PermissionMask.All, 1, (uint)PermissionMask.All, (uint)PermissionMask.All,
|
||||
(uint)PermissionMask.All)
|
||||
)));
|
||||
ItemDataMap.Add("CallbackID", 0);
|
||||
|
||||
ItemData.Add(ItemDataMap);
|
||||
}
|
||||
|
||||
llsd.Add("ItemData", ItemData);
|
||||
|
||||
eq.Enqueue(BuildEvent("BulkUpdateInventory",
|
||||
llsd), AgentId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
|
||||
m_regStatus = RegionStatus.Up;
|
||||
}
|
||||
|
||||
public override void Update() {}
|
||||
public override void Update(int frames) {}
|
||||
public override void LoadWorldMap() {}
|
||||
|
||||
public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type)
|
||||
|
||||
@@ -47,6 +47,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||
|
||||
protected Scene m_Scene;
|
||||
private bool m_dumpAssetsToFile = false;
|
||||
private int m_levelUpload = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Each agent has its own singleton collection of transactions
|
||||
@@ -56,8 +57,13 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||
|
||||
#region IRegionModule Members
|
||||
|
||||
public void Initialise(IConfigSource config)
|
||||
public void Initialise(IConfigSource source)
|
||||
{
|
||||
IConfig sconfig = source.Configs["Startup"];
|
||||
if (sconfig != null)
|
||||
{
|
||||
m_levelUpload = sconfig.GetInt("LevelUpload", 0);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddRegion(Scene scene)
|
||||
@@ -241,7 +247,21 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
|
||||
(AssetType)type == AssetType.Animation) &&
|
||||
tempFile == false)
|
||||
{
|
||||
ScenePresence avatar = null;
|
||||
Scene scene = (Scene)remoteClient.Scene;
|
||||
scene.TryGetScenePresence(remoteClient.AgentId, out avatar);
|
||||
|
||||
// check user level
|
||||
if (avatar != null)
|
||||
{
|
||||
if (avatar.UserLevel < m_levelUpload)
|
||||
{
|
||||
remoteClient.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// check funds
|
||||
IMoneyModule mm = scene.RequestModuleInterface<IMoneyModule>();
|
||||
|
||||
if (mm != null)
|
||||
|
||||
@@ -203,10 +203,10 @@ namespace Flotsam.RegionModules.AssetCache
|
||||
m_CacheDirectoryTierLen = 4;
|
||||
}
|
||||
|
||||
MainConsole.Instance.Commands.AddCommand(Name, true, "fcache status", "fcache status", "Display cache status", HandleConsoleCommand);
|
||||
MainConsole.Instance.Commands.AddCommand(Name, true, "fcache clear", "fcache clear [file] [memory]", "Remove all assets in the cache. If file or memory is specified then only this cache is cleared.", HandleConsoleCommand);
|
||||
MainConsole.Instance.Commands.AddCommand(Name, true, "fcache assets", "fcache assets", "Attempt a deep scan and cache of all assets in all scenes", HandleConsoleCommand);
|
||||
MainConsole.Instance.Commands.AddCommand(Name, true, "fcache expire", "fcache expire <datetime>", "Purge cached assets older then the specified date/time", HandleConsoleCommand);
|
||||
MainConsole.Instance.Commands.AddCommand("Assets", true, "fcache status", "fcache status", "Display cache status", HandleConsoleCommand);
|
||||
MainConsole.Instance.Commands.AddCommand("Assets", true, "fcache clear", "fcache clear [file] [memory]", "Remove all assets in the cache. If file or memory is specified then only this cache is cleared.", HandleConsoleCommand);
|
||||
MainConsole.Instance.Commands.AddCommand("Assets", true, "fcache assets", "fcache assets", "Attempt a deep scan and cache of all assets in all scenes", HandleConsoleCommand);
|
||||
MainConsole.Instance.Commands.AddCommand("Assets", true, "fcache expire", "fcache expire <datetime>", "Purge cached assets older then the specified date/time", HandleConsoleCommand);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,7 +239,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
// At the moment we can only deal with a single attachment
|
||||
if (attachments.Count != 0)
|
||||
{
|
||||
UUID oldAttachmentItemID = attachments[0].GetFromItemID();
|
||||
UUID oldAttachmentItemID = attachments[0].FromItemID;
|
||||
|
||||
if (oldAttachmentItemID != UUID.Zero)
|
||||
DetachSingleAttachmentToInvInternal(sp, oldAttachmentItemID);
|
||||
@@ -250,7 +250,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
}
|
||||
|
||||
// Add the new attachment to inventory if we don't already have it.
|
||||
UUID newAttachmentItemID = group.GetFromItemID();
|
||||
UUID newAttachmentItemID = group.FromItemID;
|
||||
if (newAttachmentItemID == UUID.Zero)
|
||||
newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID;
|
||||
|
||||
@@ -285,7 +285,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
List<SceneObjectGroup> existingAttachments = sp.GetAttachments();
|
||||
foreach (SceneObjectGroup so in existingAttachments)
|
||||
{
|
||||
if (so.GetFromItemID() == itemID)
|
||||
if (so.FromItemID == itemID)
|
||||
{
|
||||
alreadyOn = true;
|
||||
break;
|
||||
@@ -342,7 +342,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
if (so.AttachedAvatar != sp.UUID)
|
||||
return;
|
||||
|
||||
UUID inventoryID = so.GetFromItemID();
|
||||
UUID inventoryID = so.FromItemID;
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[ATTACHMENTS MODULE]: In DetachSingleAttachmentToGround(), object is {0} {1}, associated item is {2}",
|
||||
@@ -359,9 +359,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
|
||||
|
||||
sp.RemoveAttachment(so);
|
||||
so.FromItemID = UUID.Zero;
|
||||
|
||||
SceneObjectPart rootPart = so.RootPart;
|
||||
rootPart.FromItemID = UUID.Zero;
|
||||
so.AbsolutePosition = sp.AbsolutePosition;
|
||||
so.AttachedAvatar = UUID.Zero;
|
||||
rootPart.SetParentLocalId(0);
|
||||
@@ -475,7 +475,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
|
||||
string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp);
|
||||
|
||||
InventoryItemBase item = new InventoryItemBase(grp.GetFromItemID(), sp.UUID);
|
||||
InventoryItemBase item = new InventoryItemBase(grp.FromItemID, sp.UUID);
|
||||
item = m_scene.InventoryService.GetItem(item);
|
||||
|
||||
if (item != null)
|
||||
@@ -647,7 +647,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
item.CreationDate = Util.UnixTimeSinceEpoch();
|
||||
|
||||
// sets itemID so client can show item as 'attached' in inventory
|
||||
grp.SetFromItemID(item.ID);
|
||||
grp.FromItemID = item.ID;
|
||||
|
||||
if (m_scene.AddInventoryItem(item))
|
||||
{
|
||||
@@ -683,7 +683,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
if (entity is SceneObjectGroup)
|
||||
{
|
||||
group = (SceneObjectGroup)entity;
|
||||
if (group.GetFromItemID() == itemID)
|
||||
if (group.FromItemID == itemID)
|
||||
{
|
||||
m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero);
|
||||
sp.RemoveAttachment(group);
|
||||
@@ -889,7 +889,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
// Calls attach with a Zero position
|
||||
if (AttachObject(sp, part.ParentGroup, AttachmentPt, false))
|
||||
{
|
||||
m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId);
|
||||
m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.FromItemID, remoteClient.AgentId);
|
||||
|
||||
// Save avatar attachment information
|
||||
m_log.Debug(
|
||||
@@ -912,7 +912,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
||||
ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
|
||||
SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID);
|
||||
if (sp != null && group != null)
|
||||
DetachSingleAttachmentToInv(sp, group.GetFromItemID());
|
||||
DetachSingleAttachmentToInv(sp, group.FromItemID);
|
||||
}
|
||||
|
||||
private void Client_OnDetachAttachmentIntoInv(UUID itemID, IClientAPI remoteClient)
|
||||
|
||||
@@ -120,8 +120,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
|
||||
Assert.That(attSo.IsTemporary, Is.False);
|
||||
|
||||
// Check item status
|
||||
Assert.That(m_presence.Appearance.GetAttachpoint(
|
||||
attSo.GetFromItemID()), Is.EqualTo((int)AttachmentPoint.Chest));
|
||||
Assert.That(
|
||||
m_presence.Appearance.GetAttachpoint(attSo.FromItemID),
|
||||
Is.EqualTo((int)AttachmentPoint.Chest));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -51,12 +51,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
|
||||
m_scene.RegisterModuleInterface<IDialogModule>(this);
|
||||
|
||||
m_scene.AddCommand(
|
||||
this, "alert", "alert <message>",
|
||||
"Users", this, "alert", "alert <message>",
|
||||
"Send an alert to everyone",
|
||||
HandleAlertConsoleCommand);
|
||||
|
||||
m_scene.AddCommand(
|
||||
this, "alert-user", "alert-user <first> <last> <message>",
|
||||
"Users", this, "alert-user", "alert-user <first> <last> <message>",
|
||||
"Send an alert to a user",
|
||||
HandleAlertConsoleCommand);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,313 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using Mono.Addins;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
{
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "XCallingCard")]
|
||||
public class CallingCardModule : ISharedRegionModule, ICallingCardModule
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
protected List<Scene> m_Scenes = new List<Scene>();
|
||||
protected bool m_Enabled = true;
|
||||
|
||||
public void Initialise(IConfigSource source)
|
||||
{
|
||||
IConfig ccConfig = source.Configs["XCallingCard"];
|
||||
if (ccConfig != null)
|
||||
m_Enabled = ccConfig.GetBoolean("Enabled", true);
|
||||
}
|
||||
|
||||
public void AddRegion(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
m_Scenes.Add(scene);
|
||||
|
||||
scene.RegisterModuleInterface<ICallingCardModule>(this);
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
m_Scenes.Remove(scene);
|
||||
|
||||
scene.EventManager.OnNewClient -= OnNewClient;
|
||||
scene.EventManager.OnIncomingInstantMessage +=
|
||||
OnIncomingInstantMessage;
|
||||
|
||||
scene.UnregisterModuleInterface<ICallingCardModule>(this);
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
scene.EventManager.OnNewClient += OnNewClient;
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
}
|
||||
|
||||
public Type ReplaceableInterface
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return "XCallingCardModule"; }
|
||||
}
|
||||
|
||||
private void OnNewClient(IClientAPI client)
|
||||
{
|
||||
client.OnOfferCallingCard += OnOfferCallingCard;
|
||||
client.OnAcceptCallingCard += OnAcceptCallingCard;
|
||||
client.OnDeclineCallingCard += OnDeclineCallingCard;
|
||||
}
|
||||
|
||||
private void OnOfferCallingCard(IClientAPI client, UUID destID, UUID transactionID)
|
||||
{
|
||||
ScenePresence sp = GetClientPresence(client.AgentId);
|
||||
if (sp != null)
|
||||
{
|
||||
// If we're in god mode, we reverse the meaning. Offer
|
||||
// calling card becomes "Take a calling card" for that
|
||||
// person, no matter if they agree or not.
|
||||
if (sp.GodLevel >= 200)
|
||||
{
|
||||
CreateCallingCard(client.AgentId, destID, UUID.Zero, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
IClientAPI dest = FindClientObject(destID);
|
||||
if (dest != null)
|
||||
{
|
||||
DoCallingCardOffer(dest, client.AgentId);
|
||||
return;
|
||||
}
|
||||
|
||||
IMessageTransferModule transferModule =
|
||||
m_Scenes[0].RequestModuleInterface<IMessageTransferModule>();
|
||||
|
||||
if (transferModule != null)
|
||||
{
|
||||
transferModule.SendInstantMessage(new GridInstantMessage(
|
||||
client.Scene, client.AgentId,
|
||||
client.FirstName+" "+client.LastName,
|
||||
destID, (byte)211, false,
|
||||
String.Empty,
|
||||
transactionID, false, new Vector3(), new byte[0]),
|
||||
delegate(bool success) {} );
|
||||
}
|
||||
}
|
||||
|
||||
private void DoCallingCardOffer(IClientAPI dest, UUID from)
|
||||
{
|
||||
UUID itemID = CreateCallingCard(dest.AgentId, from, UUID.Zero, false);
|
||||
|
||||
dest.SendOfferCallingCard(from, itemID);
|
||||
}
|
||||
|
||||
// Create a calling card in the user's inventory. This is called
|
||||
// from direct calling card creation, when the offer is forwarded,
|
||||
// and from the friends module when the friend is confirmed.
|
||||
// Because of the latter, it will send a bulk inventory update
|
||||
// if the receiving user is in the same simulator.
|
||||
public UUID CreateCallingCard(UUID userID, UUID creatorID, UUID folderID)
|
||||
{
|
||||
return CreateCallingCard(userID, creatorID, folderID, false);
|
||||
}
|
||||
|
||||
private UUID CreateCallingCard(UUID userID, UUID creatorID, UUID folderID, bool isGod)
|
||||
{
|
||||
IUserAccountService userv = m_Scenes[0].UserAccountService;
|
||||
if (userv == null)
|
||||
return UUID.Zero;
|
||||
|
||||
UserAccount info = userv.GetUserAccount(UUID.Zero, creatorID);
|
||||
if (info == null)
|
||||
return UUID.Zero;
|
||||
|
||||
IInventoryService inv = m_Scenes[0].InventoryService;
|
||||
if (inv == null)
|
||||
return UUID.Zero;
|
||||
|
||||
if (folderID == UUID.Zero)
|
||||
{
|
||||
InventoryFolderBase folder = inv.GetFolderForType(userID,
|
||||
AssetType.CallingCard);
|
||||
|
||||
if (folder == null) // Nowhere to put it
|
||||
return UUID.Zero;
|
||||
|
||||
folderID = folder.ID;
|
||||
}
|
||||
|
||||
m_log.DebugFormat("[XCALLINGCARD]: Creating calling card for {0} in inventory of {1}", info.Name, userID);
|
||||
|
||||
InventoryItemBase item = new InventoryItemBase();
|
||||
item.AssetID = UUID.Zero;
|
||||
item.AssetType = (int)AssetType.CallingCard;
|
||||
item.BasePermissions = (uint)(PermissionMask.Copy | PermissionMask.Modify);
|
||||
if (isGod)
|
||||
item.BasePermissions = (uint)(PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Move);
|
||||
|
||||
item.EveryOnePermissions = (uint)PermissionMask.None;
|
||||
item.CurrentPermissions = item.BasePermissions;
|
||||
item.NextPermissions = (uint)(PermissionMask.Copy | PermissionMask.Modify);
|
||||
|
||||
item.ID = UUID.Random();
|
||||
item.CreatorId = creatorID.ToString();
|
||||
item.Owner = userID;
|
||||
item.GroupID = UUID.Zero;
|
||||
item.GroupOwned = false;
|
||||
item.Folder = folderID;
|
||||
|
||||
item.CreationDate = Util.UnixTimeSinceEpoch();
|
||||
item.InvType = (int)InventoryType.CallingCard;
|
||||
item.Flags = 0;
|
||||
|
||||
item.Name = info.Name;
|
||||
item.Description = "";
|
||||
|
||||
item.SalePrice = 10;
|
||||
item.SaleType = (byte)SaleType.Not;
|
||||
|
||||
inv.AddItem(item);
|
||||
|
||||
IClientAPI client = FindClientObject(userID);
|
||||
if (client != null)
|
||||
client.SendBulkUpdateInventory(item);
|
||||
|
||||
return item.ID;
|
||||
}
|
||||
|
||||
private void OnAcceptCallingCard(IClientAPI client, UUID transactionID, UUID folderID)
|
||||
{
|
||||
}
|
||||
|
||||
private void OnDeclineCallingCard(IClientAPI client, UUID transactionID)
|
||||
{
|
||||
IInventoryService invService = m_Scenes[0].InventoryService;
|
||||
|
||||
InventoryFolderBase trashFolder =
|
||||
invService.GetFolderForType(client.AgentId, AssetType.TrashFolder);
|
||||
|
||||
InventoryItemBase item = new InventoryItemBase(transactionID, client.AgentId);
|
||||
item = invService.GetItem(item);
|
||||
|
||||
if (item != null && trashFolder != null)
|
||||
{
|
||||
item.Folder = trashFolder.ID;
|
||||
List<UUID> uuids = new List<UUID>();
|
||||
uuids.Add(item.ID);
|
||||
invService.DeleteItems(item.Owner, uuids);
|
||||
m_Scenes[0].AddInventoryItem(client, item);
|
||||
}
|
||||
}
|
||||
|
||||
public IClientAPI FindClientObject(UUID agentID)
|
||||
{
|
||||
Scene scene = GetClientScene(agentID);
|
||||
if (scene == null)
|
||||
return null;
|
||||
|
||||
ScenePresence presence = scene.GetScenePresence(agentID);
|
||||
if (presence == null)
|
||||
return null;
|
||||
|
||||
return presence.ControllingClient;
|
||||
}
|
||||
|
||||
private Scene GetClientScene(UUID agentId)
|
||||
{
|
||||
lock (m_Scenes)
|
||||
{
|
||||
foreach (Scene scene in m_Scenes)
|
||||
{
|
||||
ScenePresence presence = scene.GetScenePresence(agentId);
|
||||
if (presence != null)
|
||||
{
|
||||
if (!presence.IsChildAgent)
|
||||
return scene;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private ScenePresence GetClientPresence(UUID agentId)
|
||||
{
|
||||
lock (m_Scenes)
|
||||
{
|
||||
foreach (Scene scene in m_Scenes)
|
||||
{
|
||||
ScenePresence presence = scene.GetScenePresence(agentId);
|
||||
if (presence != null)
|
||||
{
|
||||
if (!presence.IsChildAgent)
|
||||
return presence;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void OnIncomingInstantMessage(GridInstantMessage msg)
|
||||
{
|
||||
if (msg.dialog == (uint)211)
|
||||
{
|
||||
IClientAPI client = FindClientObject(new UUID(msg.toAgentID));
|
||||
if (client == null)
|
||||
return;
|
||||
|
||||
DoCallingCardOffer(client, new UUID(msg.fromAgentID));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,6 +51,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
{
|
||||
public class FriendsModule : ISharedRegionModule, IFriendsModule
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
protected bool m_Enabled = false;
|
||||
|
||||
protected class UserFriendData
|
||||
@@ -72,7 +74,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
}
|
||||
|
||||
protected static readonly FriendInfo[] EMPTY_FRIENDS = new FriendInfo[0];
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
protected List<Scene> m_Scenes = new List<Scene>();
|
||||
|
||||
@@ -109,7 +110,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
}
|
||||
}
|
||||
|
||||
protected IFriendsService FriendsService
|
||||
public IFriendsService FriendsService
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -156,7 +157,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
InitModule(config);
|
||||
|
||||
m_Enabled = true;
|
||||
m_log.InfoFormat("[FRIENDS MODULE]: {0} enabled.", Name);
|
||||
m_log.DebugFormat("[FRIENDS MODULE]: {0} enabled.", Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -201,7 +202,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name);
|
||||
// m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name);
|
||||
|
||||
m_Scenes.Add(scene);
|
||||
scene.RegisterModuleInterface<IFriendsModule>(this);
|
||||
@@ -212,9 +213,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
scene.EventManager.OnClientLogin += OnClientLogin;
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
{
|
||||
}
|
||||
public virtual void RegionLoaded(Scene scene) {}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
{
|
||||
@@ -236,13 +235,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
#endregion
|
||||
|
||||
public virtual uint GetFriendPerms(UUID principalID, UUID friendID)
|
||||
public virtual int GetRightsGrantedByFriend(UUID principalID, UUID friendID)
|
||||
{
|
||||
FriendInfo[] friends = GetFriends(principalID);
|
||||
FriendInfo[] friends = GetFriendsFromCache(principalID);
|
||||
FriendInfo finfo = GetFriend(friends, friendID);
|
||||
if (finfo != null)
|
||||
{
|
||||
return (uint)finfo.TheirFlags;
|
||||
return finfo.TheirFlags;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -253,9 +252,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
client.OnInstantMessage += OnInstantMessage;
|
||||
client.OnApproveFriendRequest += OnApproveFriendRequest;
|
||||
client.OnDenyFriendRequest += OnDenyFriendRequest;
|
||||
client.OnTerminateFriendship += (thisClient, agentID, exfriendID) => RemoveFriendship(thisClient, exfriendID);
|
||||
client.OnGrantUserRights += OnGrantUserRights;
|
||||
client.OnTerminateFriendship += RemoveFriendship;
|
||||
client.OnGrantUserRights += GrantRights;
|
||||
|
||||
// We need to cache information for child agents as well as root agents so that friend edit/move/delete
|
||||
// permissions will work across borders where both regions are on different simulators.
|
||||
//
|
||||
// Do not do this asynchronously. If we do, then subsequent code can outrace CacheFriends() and
|
||||
// return misleading results from the still empty friends cache.
|
||||
// If we absolutely need to do this asynchronously, then a signalling mechanism is needed so that calls
|
||||
@@ -328,7 +330,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
//m_log.DebugFormat("[XXX]: OnClientLogin!");
|
||||
// Inform the friends that this user is online
|
||||
StatusChange(agentID, true);
|
||||
|
||||
|
||||
// Register that we need to send the list of online friends to this user
|
||||
lock (m_NeedsListOfOnlineFriends)
|
||||
m_NeedsListOfOnlineFriends.Add(agentID);
|
||||
@@ -347,18 +349,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
// Send the friends online
|
||||
List<UUID> online = GetOnlineFriends(agentID);
|
||||
if (online.Count > 0)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[FRIENDS MODULE]: User {0} in region {1} has {2} friends online",
|
||||
client.Name, client.Scene.RegionInfo.RegionName, online.Count);
|
||||
|
||||
if (online.Count > 0)
|
||||
client.SendAgentOnline(online.ToArray());
|
||||
}
|
||||
|
||||
// Send outstanding friendship offers
|
||||
List<string> outstanding = new List<string>();
|
||||
FriendInfo[] friends = GetFriends(agentID);
|
||||
FriendInfo[] friends = GetFriendsFromCache(agentID);
|
||||
foreach (FriendInfo fi in friends)
|
||||
{
|
||||
if (fi.TheirFlags == -1)
|
||||
@@ -414,23 +411,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
List<UUID> GetOnlineFriends(UUID userID)
|
||||
{
|
||||
List<string> friendList = new List<string>();
|
||||
List<UUID> online = new List<UUID>();
|
||||
|
||||
FriendInfo[] friends = GetFriends(userID);
|
||||
FriendInfo[] friends = GetFriendsFromCache(userID);
|
||||
foreach (FriendInfo fi in friends)
|
||||
{
|
||||
if (((fi.TheirFlags & 1) != 0) && (fi.TheirFlags != -1))
|
||||
if (((fi.TheirFlags & (int)FriendRights.CanSeeOnline) != 0) && (fi.TheirFlags != -1))
|
||||
friendList.Add(fi.Friend);
|
||||
}
|
||||
|
||||
List<UUID> online = new List<UUID>();
|
||||
|
||||
if (friendList.Count > 0)
|
||||
GetOnlineFriends(userID, friendList, online);
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[FRIENDS MODULE]: User {0} has {1} friends online", userID, online.Count);
|
||||
|
||||
return online;
|
||||
}
|
||||
|
||||
protected virtual void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[FRIENDS MODULE]: Looking for online presence of {0} users for {1}", friendList.Count, userID);
|
||||
|
||||
PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray());
|
||||
foreach (PresenceInfo pi in presence)
|
||||
{
|
||||
@@ -481,13 +485,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
/// <param name="online"></param>
|
||||
private void StatusChange(UUID agentID, bool online)
|
||||
{
|
||||
FriendInfo[] friends = GetFriends(agentID);
|
||||
FriendInfo[] friends = GetFriendsFromCache(agentID);
|
||||
if (friends.Length > 0)
|
||||
{
|
||||
List<FriendInfo> friendList = new List<FriendInfo>();
|
||||
foreach (FriendInfo fi in friends)
|
||||
{
|
||||
if (((fi.MyFlags & 1) != 0) && (fi.TheirFlags != -1))
|
||||
if (((fi.MyFlags & (int)FriendRights.CanSeeOnline) != 0) && (fi.TheirFlags != -1))
|
||||
friendList.Add(fi);
|
||||
}
|
||||
|
||||
@@ -550,7 +554,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
UUID principalID = new UUID(im.fromAgentID);
|
||||
UUID friendID = new UUID(im.toAgentID);
|
||||
|
||||
m_log.DebugFormat("[FRIENDS]: {0} ({1}) offered friendship to {2}", principalID, im.fromAgentName, friendID);
|
||||
m_log.DebugFormat("[FRIENDS]: {0} ({1}) offered friendship to {2} ({3})", principalID, client.FirstName + client.LastName, friendID, im.fromAgentName);
|
||||
|
||||
// Check that the friendship doesn't exist yet
|
||||
FriendInfo[] finfos = GetFriendsFromCache(principalID);
|
||||
if (finfos != null)
|
||||
{
|
||||
FriendInfo f = GetFriend(finfos, friendID);
|
||||
if (f != null)
|
||||
{
|
||||
client.SendAgentAlertMessage("This person is already your friend. Please delete it first if you want to reestablish the friendship.", false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// This user wants to be friends with the other user.
|
||||
// Let's add the relation backwards, in case the other is not online
|
||||
@@ -561,7 +577,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
}
|
||||
}
|
||||
|
||||
private void ForwardFriendshipOffer(UUID agentID, UUID friendID, GridInstantMessage im)
|
||||
protected virtual bool ForwardFriendshipOffer(UUID agentID, UUID friendID, GridInstantMessage im)
|
||||
{
|
||||
// !!!!!!!! This is a hack so that we don't have to keep state (transactionID/imSessionID)
|
||||
// We stick this agent's ID as imSession, so that it's directly available on the receiving end
|
||||
@@ -570,7 +586,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
// Try the local sim
|
||||
if (LocalFriendshipOffered(friendID, im))
|
||||
return;
|
||||
return true;
|
||||
|
||||
// The prospective friend is not here [as root]. Let's forward.
|
||||
PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
|
||||
@@ -581,9 +597,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
{
|
||||
GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
|
||||
m_FriendsSimConnector.FriendshipOffered(region, agentID, friendID, im.message);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// If the prospective friend is not online, he'll get the message upon login.
|
||||
return false;
|
||||
}
|
||||
|
||||
protected virtual string GetFriendshipRequesterName(UUID agentID)
|
||||
@@ -592,7 +610,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
return (account == null) ? "Unknown" : account.FirstName + " " + account.LastName;
|
||||
}
|
||||
|
||||
private void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders)
|
||||
protected virtual void OnApproveFriendRequest(IClientAPI client, UUID friendID, List<UUID> callingCardFolders)
|
||||
{
|
||||
m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", client.AgentId, friendID);
|
||||
|
||||
@@ -603,7 +621,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
{
|
||||
StoreFriendships(client.AgentId, friendID);
|
||||
|
||||
// Update the local cache
|
||||
ICallingCardModule ccm = client.Scene.RequestModuleInterface<ICallingCardModule>();
|
||||
if (ccm != null)
|
||||
{
|
||||
ccm.CreateCallingCard(client.AgentId, friendID, UUID.Zero);
|
||||
}
|
||||
|
||||
// Update the local cache.
|
||||
RecacheFriends(client);
|
||||
|
||||
//
|
||||
@@ -631,18 +655,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDenyFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders)
|
||||
private void OnDenyFriendRequest(IClientAPI client, UUID friendID, List<UUID> callingCardFolders)
|
||||
{
|
||||
m_log.DebugFormat("[FRIENDS]: {0} denied friendship to {1}", agentID, friendID);
|
||||
m_log.DebugFormat("[FRIENDS]: {0} denied friendship to {1}", client.AgentId, friendID);
|
||||
|
||||
DeleteFriendship(agentID, friendID);
|
||||
DeleteFriendship(client.AgentId, friendID);
|
||||
|
||||
//
|
||||
// Notify the friend
|
||||
//
|
||||
|
||||
// Try local
|
||||
if (LocalFriendshipDenied(agentID, client.Name, friendID))
|
||||
if (LocalFriendshipDenied(client.AgentId, client.Name, friendID))
|
||||
return;
|
||||
|
||||
PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
|
||||
@@ -653,7 +677,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
{
|
||||
GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
|
||||
if (region != null)
|
||||
m_FriendsSimConnector.FriendshipDenied(region, agentID, client.Name, friendID);
|
||||
m_FriendsSimConnector.FriendshipDenied(region, client.AgentId, client.Name, friendID);
|
||||
else
|
||||
m_log.WarnFormat("[FRIENDS]: Could not find region {0} in locating {1}", friendSession.RegionID, friendID);
|
||||
}
|
||||
@@ -690,23 +714,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
}
|
||||
}
|
||||
|
||||
private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights)
|
||||
public void GrantRights(IClientAPI remoteClient, UUID friendID, int rights)
|
||||
{
|
||||
m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target);
|
||||
UUID requester = remoteClient.AgentId;
|
||||
|
||||
FriendInfo[] friends = GetFriends(remoteClient.AgentId);
|
||||
m_log.DebugFormat(
|
||||
"[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}",
|
||||
requester, rights, friendID);
|
||||
|
||||
FriendInfo[] friends = GetFriendsFromCache(requester);
|
||||
if (friends.Length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Let's find the friend in this user's friend list
|
||||
FriendInfo friend = GetFriend(friends, target);
|
||||
FriendInfo friend = GetFriend(friends, friendID);
|
||||
|
||||
if (friend != null) // Found it
|
||||
{
|
||||
// Store it on the DB
|
||||
if (!StoreRights(requester, target, rights))
|
||||
if (!StoreRights(requester, friendID, rights))
|
||||
{
|
||||
remoteClient.SendAlertMessage("Unable to grant rights.");
|
||||
return;
|
||||
@@ -717,17 +745,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
friend.MyFlags = rights;
|
||||
|
||||
// Always send this back to the original client
|
||||
remoteClient.SendChangeUserRights(requester, target, rights);
|
||||
remoteClient.SendChangeUserRights(requester, friendID, rights);
|
||||
|
||||
//
|
||||
// Notify the friend
|
||||
//
|
||||
|
||||
// Try local
|
||||
if (LocalGrantRights(requester, target, myFlags, rights))
|
||||
if (LocalGrantRights(requester, friendID, myFlags, rights))
|
||||
return;
|
||||
|
||||
PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { target.ToString() });
|
||||
PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
|
||||
if (friendSessions != null && friendSessions.Length > 0)
|
||||
{
|
||||
PresenceInfo friendSession = friendSessions[0];
|
||||
@@ -736,12 +764,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
|
||||
// TODO: You might want to send the delta to save the lookup
|
||||
// on the other end!!
|
||||
m_FriendsSimConnector.GrantRights(region, requester, target, myFlags, rights);
|
||||
m_FriendsSimConnector.GrantRights(region, requester, friendID, myFlags, rights);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
m_log.DebugFormat("[FRIENDS MODULE]: friend {0} not found for {1}", target, requester);
|
||||
{
|
||||
m_log.DebugFormat("[FRIENDS MODULE]: friend {0} not found for {1}", friendID, requester);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual FriendInfo GetFriend(FriendInfo[] friends, UUID friendID)
|
||||
@@ -756,7 +786,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
#region Local
|
||||
|
||||
public bool LocalFriendshipOffered(UUID toID, GridInstantMessage im)
|
||||
public virtual bool LocalFriendshipOffered(UUID toID, GridInstantMessage im)
|
||||
{
|
||||
IClientAPI friendClient = LocateClientObject(toID);
|
||||
if (friendClient != null)
|
||||
@@ -779,6 +809,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
(byte)OpenMetaverse.InstantMessageDialog.FriendshipAccepted, userID.ToString(), false, Vector3.Zero);
|
||||
friendClient.SendInstantMessage(im);
|
||||
|
||||
ICallingCardModule ccm = friendClient.Scene.RequestModuleInterface<ICallingCardModule>();
|
||||
if (ccm != null)
|
||||
{
|
||||
ccm.CreateCallingCard(friendID, userID, UUID.Zero);
|
||||
}
|
||||
|
||||
// Update the local cache
|
||||
RecacheFriends(friendClient);
|
||||
|
||||
@@ -801,7 +837,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
// we're done
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -853,7 +889,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
public bool LocalStatusNotification(UUID userID, UUID friendID, bool online)
|
||||
{
|
||||
// m_log.DebugFormat("[FRIENDS]: Local Status Notify {0} that user {1} is {2}", friendID, userID, online);
|
||||
//m_log.DebugFormat("[FRIENDS]: Local Status Notify {0} that user {1} is {2}", friendID, userID, online);
|
||||
IClientAPI friendClient = LocateClientObject(friendID);
|
||||
if (friendClient != null)
|
||||
{
|
||||
@@ -872,18 +908,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
#endregion
|
||||
|
||||
#region Get / Set friends in several flavours
|
||||
/// <summary>
|
||||
/// Get friends from local cache only
|
||||
/// </summary>
|
||||
/// <param name="agentID"></param>
|
||||
/// <returns></returns>
|
||||
protected FriendInfo[] GetFriends(UUID agentID)
|
||||
|
||||
public FriendInfo[] GetFriendsFromCache(UUID userID)
|
||||
{
|
||||
UserFriendData friendsData;
|
||||
|
||||
lock (m_Friends)
|
||||
{
|
||||
if (m_Friends.TryGetValue(agentID, out friendsData))
|
||||
if (m_Friends.TryGetValue(userID, out friendsData))
|
||||
return friendsData.Friends;
|
||||
}
|
||||
|
||||
@@ -901,18 +933,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
// Update local cache
|
||||
lock (m_Friends)
|
||||
{
|
||||
FriendInfo[] friends = GetFriends(friendID);
|
||||
FriendInfo[] friends = GetFriendsFromCache(friendID);
|
||||
FriendInfo finfo = GetFriend(friends, userID);
|
||||
finfo.TheirFlags = rights;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual FriendInfo[] GetFriendsFromService(IClientAPI client)
|
||||
public virtual FriendInfo[] GetFriendsFromService(IClientAPI client)
|
||||
{
|
||||
return FriendsService.GetFriends(client.AgentId);
|
||||
}
|
||||
|
||||
private void RecacheFriends(IClientAPI client)
|
||||
protected void RecacheFriends(IClientAPI client)
|
||||
{
|
||||
// FIXME: Ideally, we want to avoid doing this here since it sits the EventManager.OnMakeRootAgent event
|
||||
// is on the critical path for transferring an avatar from one region to another.
|
||||
@@ -925,6 +957,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
}
|
||||
}
|
||||
|
||||
public bool AreFriendsCached(UUID userID)
|
||||
{
|
||||
lock (m_Friends)
|
||||
return m_Friends.ContainsKey(userID);
|
||||
}
|
||||
|
||||
protected virtual bool StoreRights(UUID agentID, UUID friendID, int rights)
|
||||
{
|
||||
FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), rights);
|
||||
@@ -938,8 +976,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
protected virtual void StoreFriendships(UUID agentID, UUID friendID)
|
||||
{
|
||||
FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), 1);
|
||||
FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 1);
|
||||
FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), (int)FriendRights.CanSeeOnline);
|
||||
FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), (int)FriendRights.CanSeeOnline);
|
||||
}
|
||||
|
||||
protected virtual bool DeleteFriendship(UUID agentID, UUID exfriendID)
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
IUserManagement m_uMan;
|
||||
IUserManagement UserManagementModule
|
||||
public IUserManagement UserManagementModule
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -61,6 +61,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
}
|
||||
}
|
||||
|
||||
protected HGFriendsServicesConnector m_HGFriendsConnector = new HGFriendsServicesConnector();
|
||||
protected HGStatusNotifier m_StatusNotifier;
|
||||
|
||||
#region ISharedRegionModule
|
||||
public override string Name
|
||||
{
|
||||
@@ -76,6 +79,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
scene.RegisterModuleInterface<IFriendsSimConnector>(this);
|
||||
}
|
||||
|
||||
public override void RegionLoaded(Scene scene)
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
if (m_StatusNotifier == null)
|
||||
m_StatusNotifier = new HGStatusNotifier(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IFriendsSimConnector
|
||||
@@ -94,6 +105,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
#endregion
|
||||
|
||||
protected override void OnApproveFriendRequest(IClientAPI client, UUID friendID, List<UUID> callingCardFolders)
|
||||
{
|
||||
// Update the local cache. Yes, we need to do it right here
|
||||
// because the HGFriendsService placed something on the DB
|
||||
// from under the sim
|
||||
base.OnApproveFriendRequest(client, friendID, callingCardFolders);
|
||||
}
|
||||
|
||||
protected override bool CacheFriends(IClientAPI client)
|
||||
{
|
||||
// m_log.DebugFormat("[HGFRIENDS MODULE]: Entered CacheFriends for {0}", client.Name);
|
||||
@@ -144,7 +163,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, client.AgentId);
|
||||
if (account == null) // foreign
|
||||
{
|
||||
FriendInfo[] friends = GetFriends(client.AgentId);
|
||||
FriendInfo[] friends = GetFriendsFromCache(client.AgentId);
|
||||
foreach (FriendInfo f in friends)
|
||||
{
|
||||
client.SendChangeUserRights(new UUID(f.Friend), client.AgentId, f.TheirFlags);
|
||||
@@ -183,91 +202,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting GetOnlineFriends for {0}", userID);
|
||||
}
|
||||
|
||||
//protected override void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
|
||||
//{
|
||||
// // Let's single out the UUIs
|
||||
// List<string> localFriends = new List<string>();
|
||||
// List<string> foreignFriends = new List<string>();
|
||||
// string tmp = string.Empty;
|
||||
|
||||
// foreach (string s in friendList)
|
||||
// {
|
||||
// UUID id;
|
||||
// if (UUID.TryParse(s, out id))
|
||||
// localFriends.Add(s);
|
||||
// else if (Util.ParseUniversalUserIdentifier(s, out id, out tmp, out tmp, out tmp, out tmp))
|
||||
// {
|
||||
// foreignFriends.Add(s);
|
||||
// // add it here too, who knows maybe the foreign friends happens to be on this grid
|
||||
// localFriends.Add(id.ToString());
|
||||
// }
|
||||
// }
|
||||
|
||||
// // OK, see who's present on this grid
|
||||
// List<string> toBeRemoved = new List<string>();
|
||||
// PresenceInfo[] presence = PresenceService.GetAgents(localFriends.ToArray());
|
||||
// foreach (PresenceInfo pi in presence)
|
||||
// {
|
||||
// UUID presenceID;
|
||||
// if (UUID.TryParse(pi.UserID, out presenceID))
|
||||
// {
|
||||
// online.Add(presenceID);
|
||||
// foreach (string s in foreignFriends)
|
||||
// if (s.StartsWith(pi.UserID))
|
||||
// toBeRemoved.Add(s);
|
||||
// }
|
||||
// }
|
||||
|
||||
// foreach (string s in toBeRemoved)
|
||||
// foreignFriends.Remove(s);
|
||||
|
||||
// // OK, let's send this up the stack, and leave a closure here
|
||||
// // collecting online friends in other grids
|
||||
// Util.FireAndForget(delegate { CollectOnlineFriendsElsewhere(userID, foreignFriends); });
|
||||
|
||||
//}
|
||||
|
||||
//private void CollectOnlineFriendsElsewhere(UUID userID, List<string> foreignFriends)
|
||||
//{
|
||||
// // let's divide the friends on a per-domain basis
|
||||
// Dictionary<string, List<string>> friendsPerDomain = new Dictionary<string, List<string>>();
|
||||
// foreach (string friend in foreignFriends)
|
||||
// {
|
||||
// UUID friendID;
|
||||
// if (!UUID.TryParse(friend, out friendID))
|
||||
// {
|
||||
// // it's a foreign friend
|
||||
// string url = string.Empty, tmp = string.Empty;
|
||||
// if (Util.ParseUniversalUserIdentifier(friend, out friendID, out url, out tmp, out tmp, out tmp))
|
||||
// {
|
||||
// if (!friendsPerDomain.ContainsKey(url))
|
||||
// friendsPerDomain[url] = new List<string>();
|
||||
// friendsPerDomain[url].Add(friend);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// // Now, call those worlds
|
||||
|
||||
// foreach (KeyValuePair<string, List<string>> kvp in friendsPerDomain)
|
||||
// {
|
||||
// List<string> ids = new List<string>();
|
||||
// foreach (string f in kvp.Value)
|
||||
// ids.Add(f);
|
||||
// UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key);
|
||||
// List<UUID> online = uConn.GetOnlineFriends(userID, ids);
|
||||
// // Finally send the notifications to the user
|
||||
// // this whole process may take a while, so let's check at every
|
||||
// // iteration that the user is still here
|
||||
// IClientAPI client = LocateClientObject(userID);
|
||||
// if (client != null)
|
||||
// client.SendAgentOnline(online.ToArray());
|
||||
// else
|
||||
// break;
|
||||
// }
|
||||
|
||||
//}
|
||||
|
||||
protected override void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online)
|
||||
{
|
||||
// m_log.DebugFormat("[HGFRIENDS MODULE]: Entering StatusNotify for {0}", userID);
|
||||
@@ -305,25 +239,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
if (friendsPerDomain.ContainsKey("local"))
|
||||
base.StatusNotify(friendsPerDomain["local"], userID, online);
|
||||
|
||||
foreach (KeyValuePair<string, List<FriendInfo>> kvp in friendsPerDomain)
|
||||
{
|
||||
if (kvp.Key != "local")
|
||||
{
|
||||
// For the others, call the user agent service
|
||||
List<string> ids = new List<string>();
|
||||
foreach (FriendInfo f in kvp.Value)
|
||||
ids.Add(f.Friend);
|
||||
UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key);
|
||||
List<UUID> friendsOnline = uConn.StatusNotification(ids, userID, online);
|
||||
|
||||
if (online && friendsOnline.Count > 0)
|
||||
{
|
||||
IClientAPI client = LocateClientObject(userID);
|
||||
if (client != null)
|
||||
client.SendAgentOnline(friendsOnline.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
m_StatusNotifier.Notify(userID, friendsPerDomain, online);
|
||||
|
||||
// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting StatusNotify for {0}", userID);
|
||||
}
|
||||
@@ -335,26 +251,34 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
return true;
|
||||
|
||||
// fid is not a UUID...
|
||||
string url = string.Empty, tmp = string.Empty;
|
||||
if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out first, out last, out tmp))
|
||||
string url = string.Empty, tmp = string.Empty, f = string.Empty, l = string.Empty;
|
||||
if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out f, out l, out tmp))
|
||||
{
|
||||
IUserManagement userMan = m_Scenes[0].RequestModuleInterface<IUserManagement>();
|
||||
userMan.AddUser(agentID, first, last, url);
|
||||
if (!agentID.Equals(UUID.Zero))
|
||||
{
|
||||
m_uMan.AddUser(agentID, f, l, url);
|
||||
|
||||
return true;
|
||||
string name = m_uMan.GetUserName(agentID);
|
||||
string[] parts = name.Trim().Split(new char[] { ' ' });
|
||||
if (parts.Length == 2)
|
||||
{
|
||||
first = parts[0];
|
||||
last = parts[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
first = f;
|
||||
last = l;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override string GetFriendshipRequesterName(UUID agentID)
|
||||
{
|
||||
// For the time being we assume that HG friendship requests can only happen
|
||||
// when avies are on the same region.
|
||||
IClientAPI client = LocateClientObject(agentID);
|
||||
if (client != null)
|
||||
return client.FirstName + " " + client.LastName;
|
||||
else
|
||||
return base.GetFriendshipRequesterName(agentID);
|
||||
return m_uMan.GetUserName(agentID);
|
||||
}
|
||||
|
||||
protected override string FriendshipMessage(string friendID)
|
||||
@@ -376,8 +300,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
protected override FriendInfo[] GetFriendsFromService(IClientAPI client)
|
||||
public override FriendInfo[] GetFriendsFromService(IClientAPI client)
|
||||
{
|
||||
// m_log.DebugFormat("[HGFRIENDS MODULE]: Entering GetFriendsFromService for {0}", client.Name);
|
||||
Boolean agentIsLocal = true;
|
||||
@@ -392,10 +315,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
AgentCircuitData agentClientCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode);
|
||||
if (agentClientCircuit != null)
|
||||
{
|
||||
string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
|
||||
//[XXX] string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
|
||||
|
||||
finfos = FriendsService.GetFriends(agentUUI);
|
||||
m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, agentUUI);
|
||||
finfos = FriendsService.GetFriends(client.AgentId.ToString());
|
||||
m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, client.AgentId.ToString());
|
||||
}
|
||||
|
||||
// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting GetFriendsFromService for {0}", client.Name);
|
||||
@@ -422,7 +345,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
if (agentIsLocal) // agent is local, friend is foreigner
|
||||
{
|
||||
FriendInfo[] finfos = GetFriends(agentID);
|
||||
FriendInfo[] finfos = GetFriendsFromCache(agentID);
|
||||
FriendInfo finfo = GetFriend(finfos, friendID);
|
||||
if (finfo != null)
|
||||
{
|
||||
@@ -454,16 +377,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
friendIsLocal = UserManagementModule.IsLocalGridUser(friendID);
|
||||
}
|
||||
|
||||
// Are they both local users?
|
||||
if (agentIsLocal && friendIsLocal)
|
||||
// Is the requester a local user?
|
||||
if (agentIsLocal)
|
||||
{
|
||||
// local grid users
|
||||
m_log.DebugFormat("[HGFRIENDS MODULE]: Users are both local");
|
||||
m_log.DebugFormat("[HGFRIENDS MODULE]: Friendship requester is local. Storing backwards.");
|
||||
|
||||
base.StoreBackwards(friendID, agentID);
|
||||
return;
|
||||
}
|
||||
|
||||
// no provision for this temporary friendship state
|
||||
// no provision for this temporary friendship state when user is not local
|
||||
//FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0);
|
||||
}
|
||||
|
||||
@@ -501,12 +425,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode);
|
||||
agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
|
||||
agentFriendService = agentClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
|
||||
RecacheFriends(agentClient);
|
||||
}
|
||||
if (friendClient != null)
|
||||
{
|
||||
friendClientCircuit = ((Scene)(friendClient.Scene)).AuthenticateHandler.GetAgentCircuitData(friendClient.CircuitCode);
|
||||
friendUUI = Util.ProduceUserUniversalIdentifier(friendClientCircuit);
|
||||
friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
|
||||
RecacheFriends(friendClient);
|
||||
}
|
||||
|
||||
m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}",
|
||||
@@ -515,14 +441,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
// Generate a random 8-character hex number that will sign this friendship
|
||||
string secret = UUID.Random().ToString().Substring(0, 8);
|
||||
|
||||
string theFriendUUID = friendUUI + ";" + secret;
|
||||
string agentUUID = agentUUI + ";" + secret;
|
||||
|
||||
if (agentIsLocal) // agent is local, 'friend' is foreigner
|
||||
{
|
||||
// This may happen when the agent returned home, in which case the friend is not there
|
||||
// We need to look for its information in the friends list itself
|
||||
FriendInfo[] finfos = null;
|
||||
bool confirming = false;
|
||||
if (friendUUI == string.Empty)
|
||||
{
|
||||
FriendInfo[] finfos = GetFriends(agentID);
|
||||
finfos = GetFriendsFromCache(agentID);
|
||||
foreach (FriendInfo finfo in finfos)
|
||||
{
|
||||
if (finfo.TheirFlags == -1)
|
||||
@@ -530,29 +460,57 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
if (finfo.Friend.StartsWith(friendID.ToString()))
|
||||
{
|
||||
friendUUI = finfo.Friend;
|
||||
theFriendUUID = friendUUI;
|
||||
UUID utmp = UUID.Zero; String url = String.Empty; String first = String.Empty, last = String.Empty, tmp = String.Empty;
|
||||
// If it's confirming the friendship, we already have the full UUI with the secret
|
||||
if (Util.ParseUniversalUserIdentifier(theFriendUUID, out utmp, out url, out first, out last, out secret))
|
||||
{
|
||||
agentUUID = agentUUI + ";" + secret;
|
||||
m_uMan.AddUser(utmp, first, last, url);
|
||||
}
|
||||
confirming = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!confirming)
|
||||
{
|
||||
friendUUI = m_uMan.GetUserUUI(friendID);
|
||||
theFriendUUID = friendUUI + ";" + secret;
|
||||
}
|
||||
|
||||
// If it's confirming the friendship, we already have the full friendUUI with the secret
|
||||
string theFriendUUID = confirming ? friendUUI : friendUUI + ";" + secret;
|
||||
friendFriendService = m_uMan.GetUserServerURL(friendID, "FriendsServerURI");
|
||||
|
||||
// m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}",
|
||||
// agentUUI, friendUUI, agentFriendService, friendFriendService);
|
||||
|
||||
}
|
||||
|
||||
// Delete any previous friendship relations
|
||||
DeletePreviousRelations(agentID, friendID);
|
||||
|
||||
// store in the local friends service a reference to the foreign friend
|
||||
FriendsService.StoreFriend(agentID.ToString(), theFriendUUID, 1);
|
||||
// and also the converse
|
||||
FriendsService.StoreFriend(theFriendUUID, agentID.ToString(), 1);
|
||||
|
||||
if (!confirming && friendClientCircuit != null)
|
||||
{
|
||||
//if (!confirming)
|
||||
//{
|
||||
// store in the foreign friends service a reference to the local agent
|
||||
HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID);
|
||||
friendsConn.NewFriendship(friendID, agentUUI + ";" + secret);
|
||||
}
|
||||
HGFriendsServicesConnector friendsConn = null;
|
||||
if (friendClientCircuit != null) // the friend is here, validate session
|
||||
friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID);
|
||||
else // the friend is not here, he initiated the request in his home world
|
||||
friendsConn = new HGFriendsServicesConnector(friendFriendService);
|
||||
|
||||
friendsConn.NewFriendship(friendID, agentUUID);
|
||||
//}
|
||||
}
|
||||
else if (friendIsLocal) // 'friend' is local, agent is foreigner
|
||||
{
|
||||
// Delete any previous friendship relations
|
||||
DeletePreviousRelations(agentID, friendID);
|
||||
|
||||
// store in the local friends service a reference to the foreign agent
|
||||
FriendsService.StoreFriend(friendID.ToString(), agentUUI + ";" + secret, 1);
|
||||
// and also the converse
|
||||
@@ -582,6 +540,36 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
// my brain hurts now
|
||||
}
|
||||
|
||||
private void DeletePreviousRelations(UUID a1, UUID a2)
|
||||
{
|
||||
// Delete any previous friendship relations
|
||||
FriendInfo[] finfos = null;
|
||||
FriendInfo f = null;
|
||||
finfos = GetFriendsFromCache(a1);
|
||||
if (finfos != null)
|
||||
{
|
||||
f = GetFriend(finfos, a2);
|
||||
if (f != null)
|
||||
{
|
||||
FriendsService.Delete(a1, f.Friend);
|
||||
// and also the converse
|
||||
FriendsService.Delete(f.Friend, a1.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
finfos = GetFriendsFromCache(a2);
|
||||
if (finfos != null)
|
||||
{
|
||||
f = GetFriend(finfos, a1);
|
||||
if (f != null)
|
||||
{
|
||||
FriendsService.Delete(a2, f.Friend);
|
||||
// and also the converse
|
||||
FriendsService.Delete(f.Friend, a2.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool DeleteFriendship(UUID agentID, UUID exfriendID)
|
||||
{
|
||||
Boolean agentIsLocal = true;
|
||||
@@ -606,7 +594,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
if (agentIsLocal) // agent is local, 'friend' is foreigner
|
||||
{
|
||||
// We need to look for its information in the friends list itself
|
||||
FriendInfo[] finfos = GetFriends(agentID);
|
||||
FriendInfo[] finfos = GetFriendsFromCache(agentID);
|
||||
FriendInfo finfo = GetFriend(finfos, exfriendID);
|
||||
if (finfo != null)
|
||||
{
|
||||
@@ -650,7 +638,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
private string GetUUI(UUID localUser, UUID foreignUser)
|
||||
{
|
||||
// Let's see if the user is here by any chance
|
||||
FriendInfo[] finfos = GetFriends(localUser);
|
||||
FriendInfo[] finfos = GetFriendsFromCache(localUser);
|
||||
if (finfos != EMPTY_FRIENDS) // friend is here, cool
|
||||
{
|
||||
FriendInfo finfo = GetFriend(finfos, foreignUser);
|
||||
@@ -684,5 +672,80 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
friendConn.DeleteFriendship(foreignUser, localUser, secret);
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool ForwardFriendshipOffer(UUID agentID, UUID friendID, GridInstantMessage im)
|
||||
{
|
||||
if (base.ForwardFriendshipOffer(agentID, friendID, im))
|
||||
return true;
|
||||
|
||||
// OK, that didn't work, so let's try to find this user somewhere
|
||||
if (!m_uMan.IsLocalGridUser(friendID))
|
||||
{
|
||||
string friendsURL = m_uMan.GetUserServerURL(friendID, "FriendsServerURI");
|
||||
if (friendsURL != string.Empty)
|
||||
{
|
||||
m_log.DebugFormat("[HGFRIENDS MODULE]: Forwading friendship from {0} to {1} @ {2}", agentID, friendID, friendsURL);
|
||||
GridRegion region = new GridRegion();
|
||||
region.ServerURI = friendsURL;
|
||||
|
||||
string name = im.fromAgentName;
|
||||
if (m_uMan.IsLocalGridUser(agentID))
|
||||
{
|
||||
IClientAPI agentClient = LocateClientObject(agentID);
|
||||
AgentCircuitData agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode);
|
||||
string agentHomeService = string.Empty;
|
||||
try
|
||||
{
|
||||
agentHomeService = agentClientCircuit.ServiceURLs["HomeURI"].ToString();
|
||||
string lastname = "@" + new Uri(agentHomeService).Authority;
|
||||
string firstname = im.fromAgentName.Replace(" ", ".");
|
||||
name = firstname + lastname;
|
||||
}
|
||||
catch (KeyNotFoundException)
|
||||
{
|
||||
m_log.DebugFormat("[HGFRIENDS MODULE]: Key HomeURI not found for user {0}", agentID);
|
||||
return false;
|
||||
}
|
||||
catch (NullReferenceException)
|
||||
{
|
||||
m_log.DebugFormat("[HGFRIENDS MODULE]: Null HomeUri for local user {0}", agentID);
|
||||
return false;
|
||||
}
|
||||
catch (UriFormatException)
|
||||
{
|
||||
m_log.DebugFormat("[HGFRIENDS MODULE]: Malformed HomeUri {0} for local user {1}", agentHomeService, agentID);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
m_HGFriendsConnector.FriendshipOffered(region, agentID, friendID, im.message, name);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool LocalFriendshipOffered(UUID toID, GridInstantMessage im)
|
||||
{
|
||||
if (base.LocalFriendshipOffered(toID, im))
|
||||
{
|
||||
if (im.fromAgentName.Contains("@"))
|
||||
{
|
||||
string[] parts = im.fromAgentName.Split(new char[] { '@' });
|
||||
if (parts.Length == 2)
|
||||
{
|
||||
string[] fl = parts[0].Trim().Split(new char[] { '.' });
|
||||
if (fl.Length == 2)
|
||||
m_uMan.AddUser(new UUID(im.fromAgentID), fl[0], fl[1], "http://" + parts[1]);
|
||||
else
|
||||
m_uMan.AddUser(new UUID(im.fromAgentID), fl[0], "", "http://" + parts[1]);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Services.Connectors.Hypergrid;
|
||||
using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
|
||||
|
||||
using OpenMetaverse;
|
||||
|
||||
using log4net;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
{
|
||||
public class HGStatusNotifier
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private HGFriendsModule m_FriendsModule;
|
||||
|
||||
public HGStatusNotifier(HGFriendsModule friendsModule)
|
||||
{
|
||||
m_FriendsModule = friendsModule;
|
||||
}
|
||||
|
||||
public void Notify(UUID userID, Dictionary<string, List<FriendInfo>> friendsPerDomain, bool online)
|
||||
{
|
||||
foreach (KeyValuePair<string, List<FriendInfo>> kvp in friendsPerDomain)
|
||||
{
|
||||
if (kvp.Key != "local")
|
||||
{
|
||||
// For the others, call the user agent service
|
||||
List<string> ids = new List<string>();
|
||||
foreach (FriendInfo f in kvp.Value)
|
||||
ids.Add(f.Friend);
|
||||
|
||||
if (ids.Count == 0)
|
||||
continue; // no one to notify. caller don't do this
|
||||
|
||||
m_log.DebugFormat("[HG STATUS NOTIFIER]: Notifying {0} friends in {1}", ids.Count, kvp.Key);
|
||||
// ASSUMPTION: we assume that all users for one home domain
|
||||
// have exactly the same set of service URLs.
|
||||
// If this is ever not true, we need to change this.
|
||||
UUID friendID = UUID.Zero; String tmp = String.Empty;
|
||||
if (Util.ParseUniversalUserIdentifier(ids[0], out friendID, out tmp, out tmp, out tmp, out tmp))
|
||||
{
|
||||
string friendsServerURI = m_FriendsModule.UserManagementModule.GetUserServerURL(friendID, "FriendsServerURI");
|
||||
if (friendsServerURI != string.Empty)
|
||||
{
|
||||
HGFriendsServicesConnector fConn = new HGFriendsServicesConnector(friendsServerURI);
|
||||
|
||||
List<UUID> friendsOnline = fConn.StatusNotification(ids, userID, online);
|
||||
|
||||
if (online && friendsOnline.Count > 0)
|
||||
{
|
||||
IClientAPI client = m_FriendsModule.LocateClientObject(userID);
|
||||
if (client != null)
|
||||
client.SendAgentOnline(friendsOnline.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,7 @@ using System.Collections.Generic;
|
||||
using Nini.Config;
|
||||
using NUnit.Framework;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Data.Null;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.CoreModules.Avatar.Friends;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
@@ -44,9 +45,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests
|
||||
private FriendsModule m_fm;
|
||||
private TestScene m_scene;
|
||||
|
||||
[TestFixtureSetUp]
|
||||
public void FixtureInit()
|
||||
{
|
||||
// Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
|
||||
Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest;
|
||||
}
|
||||
|
||||
[TestFixtureTearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
// We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
|
||||
// threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression
|
||||
// tests really shouldn't).
|
||||
Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void Init()
|
||||
{
|
||||
// We must clear friends data between tests since Data.Null holds it in static properties. This is necessary
|
||||
// so that different services and simulator can share the data in standalone mode. This is pretty horrible
|
||||
// effectively the statics are global variables.
|
||||
NullFriendsData.Clear();
|
||||
|
||||
IConfigSource config = new IniConfigSource();
|
||||
config.AddConfig("Modules");
|
||||
// Not strictly necessary since FriendsModule assumes it is the default (!)
|
||||
@@ -62,7 +84,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestNoFriends()
|
||||
public void TestLoginWithNoFriends()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
@@ -75,6 +97,76 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests
|
||||
Assert.That(((TestClient)sp.ControllingClient).ReceivedOnlineNotifications.Count, Is.EqualTo(0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestLoginWithOfflineFriends()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
UUID user1Id = TestHelpers.ParseTail(0x1);
|
||||
UUID user2Id = TestHelpers.ParseTail(0x2);
|
||||
|
||||
// UserAccountHelpers.CreateUserWithInventory(m_scene, user1Id);
|
||||
// UserAccountHelpers.CreateUserWithInventory(m_scene, user2Id);
|
||||
//
|
||||
// m_fm.AddFriendship(user1Id, user2Id);
|
||||
|
||||
ScenePresence sp1 = SceneHelpers.AddScenePresence(m_scene, user1Id);
|
||||
ScenePresence sp2 = SceneHelpers.AddScenePresence(m_scene, user2Id);
|
||||
|
||||
m_fm.AddFriendship(sp1.ControllingClient, user2Id);
|
||||
|
||||
// Not necessary for this test. CanSeeOnline is automatically granted.
|
||||
// m_fm.GrantRights(sp1.ControllingClient, user2Id, (int)FriendRights.CanSeeOnline);
|
||||
|
||||
// We must logout from the client end so that the presence service is correctly updated by the presence
|
||||
// detector. This is listening to the OnConnectionClosed event on the client.
|
||||
((TestClient)sp1.ControllingClient).Logout();
|
||||
((TestClient)sp2.ControllingClient).Logout();
|
||||
// m_scene.RemoveClient(sp1.UUID, true);
|
||||
// m_scene.RemoveClient(sp2.UUID, true);
|
||||
|
||||
ScenePresence sp1Redux = SceneHelpers.AddScenePresence(m_scene, user1Id);
|
||||
|
||||
// We don't expect to receive notifications of offline friends on login, just online.
|
||||
Assert.That(((TestClient)sp1Redux.ControllingClient).ReceivedOfflineNotifications.Count, Is.EqualTo(0));
|
||||
Assert.That(((TestClient)sp1Redux.ControllingClient).ReceivedOnlineNotifications.Count, Is.EqualTo(0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestLoginWithOnlineFriends()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// log4net.Config.XmlConfigurator.Configure();
|
||||
|
||||
UUID user1Id = TestHelpers.ParseTail(0x1);
|
||||
UUID user2Id = TestHelpers.ParseTail(0x2);
|
||||
|
||||
// UserAccountHelpers.CreateUserWithInventory(m_scene, user1Id);
|
||||
// UserAccountHelpers.CreateUserWithInventory(m_scene, user2Id);
|
||||
//
|
||||
// m_fm.AddFriendship(user1Id, user2Id);
|
||||
|
||||
ScenePresence sp1 = SceneHelpers.AddScenePresence(m_scene, user1Id);
|
||||
ScenePresence sp2 = SceneHelpers.AddScenePresence(m_scene, user2Id);
|
||||
|
||||
m_fm.AddFriendship(sp1.ControllingClient, user2Id);
|
||||
|
||||
// Not necessary for this test. CanSeeOnline is automatically granted.
|
||||
// m_fm.GrantRights(sp1.ControllingClient, user2Id, (int)FriendRights.CanSeeOnline);
|
||||
|
||||
// We must logout from the client end so that the presence service is correctly updated by the presence
|
||||
// detector. This is listening to the OnConnectionClosed event on the client.
|
||||
// ((TestClient)sp1.ControllingClient).Logout();
|
||||
((TestClient)sp2.ControllingClient).Logout();
|
||||
// m_scene.RemoveClient(user2Id, true);
|
||||
|
||||
ScenePresence sp2Redux = SceneHelpers.AddScenePresence(m_scene, user2Id);
|
||||
|
||||
Assert.That(((TestClient)sp2Redux.ControllingClient).ReceivedOfflineNotifications.Count, Is.EqualTo(0));
|
||||
Assert.That(((TestClient)sp2Redux.ControllingClient).ReceivedOnlineNotifications.Count, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAddFriendshipWhileOnline()
|
||||
{
|
||||
|
||||
+3
-2
@@ -270,12 +270,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
|
||||
m_archiveWriter = new TarArchiveWriter(m_saveStream);
|
||||
|
||||
m_log.InfoFormat("[INVENTORY ARCHIVER]: Adding control file to archive.");
|
||||
|
||||
// Write out control file. This has to be done first so that subsequent loaders will see this file first
|
||||
// XXX: I know this is a weak way of doing it since external non-OAR aware tar executables will not do this
|
||||
// not sure how to fix this though, short of going with a completely different file format.
|
||||
m_archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, CreateControlFile(options));
|
||||
m_log.InfoFormat("[INVENTORY ARCHIVER]: Added control file to archive.");
|
||||
|
||||
|
||||
if (inventoryFolder != null)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
|
||||
@@ -108,7 +108,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
OnInventoryArchiveSaved += SaveInvConsoleCommandCompleted;
|
||||
|
||||
scene.AddCommand(
|
||||
this, "load iar",
|
||||
"Archiving", this, "load iar",
|
||||
"load iar [-m|--merge] <first> <last> <inventory path> <password> [<IAR path>]",
|
||||
"Load user inventory archive (IAR).",
|
||||
"-m|--merge is an option which merges the loaded IAR with existing inventory folders where possible, rather than always creating new ones"
|
||||
@@ -121,18 +121,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
|
||||
HandleLoadInvConsoleCommand);
|
||||
|
||||
scene.AddCommand(
|
||||
this, "save iar",
|
||||
"Archiving", this, "save iar",
|
||||
"save iar [-h|--home=<url>] [--noassets] <first> <last> <inventory path> <password> [<IAR path>] [-c|--creators] [-v|--verbose]",
|
||||
"Save user inventory archive (IAR).",
|
||||
"<first> is the user's first name." + Environment.NewLine
|
||||
+ "<last> is the user's last name." + Environment.NewLine
|
||||
+ "<inventory path> is the path inside the user's inventory for the folder/item to be saved." + Environment.NewLine
|
||||
+ "-h|--home=<url> adds the url of the profile service to the saved user information." + Environment.NewLine
|
||||
+ "-c|--creators preserves information about foreign creators." + Environment.NewLine
|
||||
+ "-v|--verbose extra debug messages." + Environment.NewLine
|
||||
+ "--noassets stops assets being saved to the IAR."
|
||||
"<first> is the user's first name.\n"
|
||||
+ "<last> is the user's last name.\n"
|
||||
+ "<inventory path> is the path inside the user's inventory for the folder/item to be saved.\n"
|
||||
+ "<IAR path> is the filesystem path at which to save the IAR."
|
||||
+ string.Format(" If this is not given then the filename {0} in the current directory is used", DEFAULT_INV_BACKUP_FILENAME),
|
||||
+ string.Format(" If this is not given then the filename {0} in the current directory is used.\n", DEFAULT_INV_BACKUP_FILENAME)
|
||||
+ "-h|--home=<url> adds the url of the profile service to the saved user information.\n"
|
||||
+ "-c|--creators preserves information about foreign creators.\n"
|
||||
+ "-v|--verbose extra debug messages.\n"
|
||||
+ "--noassets stops assets being saved to the IAR.",
|
||||
HandleSaveInvConsoleCommand);
|
||||
|
||||
m_aScene = scene;
|
||||
|
||||
@@ -150,7 +150,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Profile
|
||||
string skillsText = String.Empty;
|
||||
string languages = String.Empty;
|
||||
|
||||
Byte[] charterMember = Utils.StringToBytes("Avatar");
|
||||
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, avatarID);
|
||||
|
||||
string name = "Avatar";
|
||||
int created = 0;
|
||||
if (account != null)
|
||||
{
|
||||
name = account.FirstName + " " + account.LastName;
|
||||
created = account.Created;
|
||||
}
|
||||
Byte[] charterMember = Utils.StringToBytes(name);
|
||||
|
||||
profileUrl = "No profile data";
|
||||
aboutText = string.Empty;
|
||||
@@ -160,7 +169,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Profile
|
||||
partner = UUID.Zero;
|
||||
|
||||
remoteClient.SendAvatarProperties(avatarID, aboutText,
|
||||
Util.ToDateTime(0).ToString(
|
||||
Util.ToDateTime(created).ToString(
|
||||
"M/d/yyyy", CultureInfo.InvariantCulture),
|
||||
charterMember, firstLifeAboutText,
|
||||
(uint)(0 & 0xff),
|
||||
|
||||
@@ -69,9 +69,10 @@ namespace OpenSim.Region.CoreModules.Framework
|
||||
{
|
||||
m_scene = scene;
|
||||
m_scene.RegisterModuleInterface<ICapabilitiesModule>(this);
|
||||
MainConsole.Instance.Commands.AddCommand("Capabilities", false, "show caps",
|
||||
|
||||
MainConsole.Instance.Commands.AddCommand("Comms", false, "show caps",
|
||||
"show caps",
|
||||
"Shows all registered capabilities", HandleShowCapsCommand);
|
||||
"Shows all registered capabilities for users", HandleShowCapsCommand);
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
|
||||
@@ -36,6 +36,7 @@ using OpenSim.Framework.Capabilities;
|
||||
using OpenSim.Framework.Client;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
using OpenSim.Services.Interfaces;
|
||||
|
||||
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
|
||||
@@ -60,6 +61,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
set { m_MaxTransferDistance = value; }
|
||||
}
|
||||
|
||||
private int m_levelHGTeleport = 0;
|
||||
|
||||
protected bool m_Enabled = false;
|
||||
protected Scene m_aScene;
|
||||
protected List<Scene> m_Scenes = new List<Scene>();
|
||||
@@ -101,7 +104,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
{
|
||||
IConfig transferConfig = source.Configs["EntityTransfer"];
|
||||
if (transferConfig != null)
|
||||
{
|
||||
MaxTransferDistance = transferConfig.GetInt("max_distance", 4095);
|
||||
m_levelHGTeleport = transferConfig.GetInt("LevelHGTeleport", 0);
|
||||
}
|
||||
|
||||
m_agentsInTransit = new List<UUID>();
|
||||
m_Enabled = true;
|
||||
@@ -227,6 +233,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
return;
|
||||
}
|
||||
|
||||
// check if HyperGrid teleport is allowed, based on user level
|
||||
int flags = m_aScene.GridService.GetRegionFlags(sp.Scene.RegionInfo.ScopeID, reg.RegionID);
|
||||
|
||||
if (((flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) && (sp.UserLevel < m_levelHGTeleport))
|
||||
{
|
||||
m_log.WarnFormat("[ENTITY TRANSFER MODULE]: Final destination link is non permitted hypergrid region. Unable to teleport agent.");
|
||||
sp.ControllingClient.SendTeleportFailed("HyperGrid teleport not permitted");
|
||||
return;
|
||||
}
|
||||
|
||||
uint curX = 0, curY = 0;
|
||||
Utils.LongToUInts(sp.Scene.RegionInfo.RegionHandle, out curX, out curY);
|
||||
int curCellX = (int)(curX / Constants.RegionSize);
|
||||
@@ -304,6 +320,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsInTransit(sp.UUID)) // Avie is already on the way. Caller shouldn't do this.
|
||||
return;
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[ENTITY TRANSFER MODULE]: Request Teleport to {0} ({1}) {2}/{3}",
|
||||
reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position);
|
||||
@@ -444,7 +463,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
"[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1}. Returning avatar to source region.",
|
||||
sp.Name, finalDestination.RegionName);
|
||||
|
||||
Fail(sp, finalDestination);
|
||||
Fail(sp, finalDestination, logout);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -476,7 +495,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
"[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} failed due to no callback from destination region. Returning avatar to source region.",
|
||||
sp.Name, finalDestination.RegionName);
|
||||
|
||||
Fail(sp, finalDestination);
|
||||
Fail(sp, finalDestination, logout);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -527,7 +546,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
}
|
||||
}
|
||||
|
||||
private void Fail(ScenePresence sp, GridRegion finalDestination)
|
||||
protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout)
|
||||
{
|
||||
// Client never contacted destination. Let's restore everything back
|
||||
sp.ControllingClient.SendTeleportFailed("Problems connecting to destination.");
|
||||
@@ -542,12 +561,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
// Finally, kill the agent we just created at the destination.
|
||||
m_aScene.SimulationService.CloseAgent(finalDestination, sp.UUID);
|
||||
|
||||
sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout);
|
||||
}
|
||||
|
||||
protected virtual bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout)
|
||||
{
|
||||
logout = false;
|
||||
return m_aScene.SimulationService.CreateAgent(finalDestination, agentCircuit, teleportFlags, out reason);
|
||||
bool success = m_aScene.SimulationService.CreateAgent(finalDestination, agentCircuit, teleportFlags, out reason);
|
||||
|
||||
if (success)
|
||||
sp.Scene.EventManager.TriggerTeleportStart(sp.ControllingClient, reg, finalDestination, teleportFlags, logout);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
protected virtual bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agent)
|
||||
@@ -1785,10 +1810,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
{
|
||||
if (!grp.IsDeleted)
|
||||
{
|
||||
if (grp.RootPart.PhysActor != null)
|
||||
{
|
||||
grp.RootPart.PhysActor.CrossingFailure();
|
||||
}
|
||||
PhysicsActor pa = grp.RootPart.PhysActor;
|
||||
if (pa != null)
|
||||
pa.CrossingFailure();
|
||||
}
|
||||
|
||||
m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp);
|
||||
@@ -1861,6 +1885,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
}
|
||||
}
|
||||
|
||||
protected bool IsInTransit(UUID id)
|
||||
{
|
||||
lock (m_agentsInTransit)
|
||||
{
|
||||
if (m_agentsInTransit.Contains(id))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected bool ResetFromTransit(UUID id)
|
||||
{
|
||||
lock (m_agentsInTransit)
|
||||
|
||||
@@ -30,6 +30,7 @@ using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Client;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Services.Connectors.Hypergrid;
|
||||
@@ -89,7 +90,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
client.OnConnectionClosed += new Action<IClientAPI>(OnConnectionClosed);
|
||||
}
|
||||
|
||||
|
||||
public override void RegionLoaded(Scene scene)
|
||||
{
|
||||
base.RegionLoaded(scene);
|
||||
@@ -98,6 +98,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
{
|
||||
m_GatekeeperConnector = new GatekeeperServiceConnector(scene.AssetService);
|
||||
m_Initialized = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -170,6 +171,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
bool success = connector.LoginAgentToGrid(agentCircuit, reg, finalDestination, out reason);
|
||||
logout = success; // flag for later logout from this grid; this is an HG TP
|
||||
|
||||
if (success)
|
||||
sp.Scene.EventManager.TriggerTeleportStart(sp.ControllingClient, reg, finalDestination, teleportFlags, logout);
|
||||
|
||||
return success;
|
||||
}
|
||||
else
|
||||
@@ -179,7 +183,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
}
|
||||
}
|
||||
|
||||
return m_aScene.SimulationService.CreateAgent(reg, agentCircuit, teleportFlags, out reason);
|
||||
return base.CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout);
|
||||
}
|
||||
|
||||
public override void TeleportHome(UUID id, IClientAPI client)
|
||||
@@ -337,6 +341,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
private GridRegion MakeRegion(AgentCircuitData aCircuit)
|
||||
{
|
||||
GridRegion region = new GridRegion();
|
||||
@@ -353,5 +358,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
||||
region.InternalEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("0.0.0.0"), (int)0);
|
||||
return region;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Client;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Services.Connectors.Hypergrid;
|
||||
@@ -57,6 +58,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
private string m_HomeURI;
|
||||
private bool m_OutboundPermission;
|
||||
private string m_ThisGatekeeper;
|
||||
private bool m_RestrictInventoryAccessAbroad;
|
||||
|
||||
// private bool m_Initialized = false;
|
||||
|
||||
@@ -90,6 +92,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
m_HomeURI = thisModuleConfig.GetString("HomeURI", m_HomeURI);
|
||||
m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true);
|
||||
m_ThisGatekeeper = thisModuleConfig.GetString("Gatekeeper", string.Empty);
|
||||
m_RestrictInventoryAccessAbroad = thisModuleConfig.GetBoolean("RestrictInventoryAccessAbroad", false);
|
||||
}
|
||||
else
|
||||
m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!");
|
||||
@@ -105,19 +108,85 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
base.AddRegion(scene);
|
||||
m_assMapper = new HGAssetMapper(scene, m_HomeURI);
|
||||
scene.EventManager.OnNewInventoryItemUploadComplete += UploadInventoryItem;
|
||||
|
||||
scene.EventManager.OnTeleportStart += TeleportStart;
|
||||
scene.EventManager.OnTeleportFail += TeleportFail;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event handlers
|
||||
|
||||
protected override void OnNewClient(IClientAPI client)
|
||||
{
|
||||
base.OnNewClient(client);
|
||||
client.OnCompleteMovementToRegion += new Action<IClientAPI, bool>(OnCompleteMovementToRegion);
|
||||
}
|
||||
|
||||
protected void OnCompleteMovementToRegion(IClientAPI client, bool arg2)
|
||||
{
|
||||
//m_log.DebugFormat("[HG INVENTORY ACCESS MODULE]: OnCompleteMovementToRegion of user {0}", client.Name);
|
||||
object sp = null;
|
||||
if (client.Scene.TryGetScenePresence(client.AgentId, out sp))
|
||||
{
|
||||
if (sp is ScenePresence)
|
||||
{
|
||||
AgentCircuitData aCircuit = ((ScenePresence)sp).Scene.AuthenticateHandler.GetAgentCircuitData(client.AgentId);
|
||||
if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0)
|
||||
{
|
||||
if (m_RestrictInventoryAccessAbroad)
|
||||
{
|
||||
IUserManagement uMan = m_Scene.RequestModuleInterface<IUserManagement>();
|
||||
if (uMan.IsLocalGridUser(client.AgentId))
|
||||
ProcessInventoryForComingHome(client);
|
||||
else
|
||||
ProcessInventoryForArriving(client);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void TeleportStart(IClientAPI client, GridRegion destination, GridRegion finalDestination, uint teleportFlags, bool gridLogout)
|
||||
{
|
||||
if (gridLogout && m_RestrictInventoryAccessAbroad)
|
||||
{
|
||||
IUserManagement uMan = m_Scene.RequestModuleInterface<IUserManagement>();
|
||||
if (uMan != null && uMan.IsLocalGridUser(client.AgentId))
|
||||
{
|
||||
// local grid user
|
||||
ProcessInventoryForHypergriding(client);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Foreigner
|
||||
ProcessInventoryForLeaving(client);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void TeleportFail(IClientAPI client, bool gridLogout)
|
||||
{
|
||||
if (gridLogout && m_RestrictInventoryAccessAbroad)
|
||||
{
|
||||
IUserManagement uMan = m_Scene.RequestModuleInterface<IUserManagement>();
|
||||
if (uMan.IsLocalGridUser(client.AgentId))
|
||||
{
|
||||
ProcessInventoryForComingHome(client);
|
||||
}
|
||||
else
|
||||
{
|
||||
ProcessInventoryForArriving(client);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void UploadInventoryItem(UUID avatarID, UUID assetID, string name, int userlevel)
|
||||
{
|
||||
string userAssetServer = string.Empty;
|
||||
if (IsForeignUser(avatarID, out userAssetServer) && userAssetServer != string.Empty && m_OutboundPermission)
|
||||
{
|
||||
Util.FireAndForget(delegate { m_assMapper.Post(assetID, avatarID, userAssetServer); });
|
||||
m_assMapper.Post(assetID, avatarID, userAssetServer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,8 +305,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
protected override InventoryItemBase GetItem(UUID agentID, UUID itemID)
|
||||
{
|
||||
InventoryItemBase item = base.GetItem(agentID, itemID);
|
||||
@@ -248,5 +315,84 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Inventory manipulation upon arriving/leaving
|
||||
|
||||
//
|
||||
// These 2 are for local and foreign users coming back, respectively
|
||||
//
|
||||
|
||||
private void ProcessInventoryForComingHome(IClientAPI client)
|
||||
{
|
||||
m_log.DebugFormat("[HG INVENTORY ACCESS MODULE]: Restoring root folder for local user {0}", client.Name);
|
||||
if (client is IClientCore)
|
||||
{
|
||||
IClientCore core = (IClientCore)client;
|
||||
IClientInventory inv;
|
||||
|
||||
if (core.TryGet<IClientInventory>(out inv))
|
||||
{
|
||||
InventoryFolderBase root = m_Scene.InventoryService.GetRootFolder(client.AgentId);
|
||||
InventoryCollection content = m_Scene.InventoryService.GetFolderContent(client.AgentId, root.ID);
|
||||
|
||||
inv.SendBulkUpdateInventory(content.Folders.ToArray(), content.Items.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessInventoryForArriving(IClientAPI client)
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// These 2 are for local and foreign users going away respectively
|
||||
//
|
||||
|
||||
private void ProcessInventoryForHypergriding(IClientAPI client)
|
||||
{
|
||||
if (client is IClientCore)
|
||||
{
|
||||
IClientCore core = (IClientCore)client;
|
||||
IClientInventory inv;
|
||||
|
||||
if (core.TryGet<IClientInventory>(out inv))
|
||||
{
|
||||
InventoryFolderBase root = m_Scene.InventoryService.GetRootFolder(client.AgentId);
|
||||
if (root != null)
|
||||
{
|
||||
m_log.DebugFormat("[HG INVENTORY ACCESS MODULE]: Changing root inventory for user {0}", client.Name);
|
||||
InventoryCollection content = m_Scene.InventoryService.GetFolderContent(client.AgentId, root.ID);
|
||||
List<UUID> fids = new List<UUID>();
|
||||
List<UUID> iids = new List<UUID>();
|
||||
List<InventoryFolderBase> keep = new List<InventoryFolderBase>();
|
||||
|
||||
foreach (InventoryFolderBase f in content.Folders)
|
||||
{
|
||||
if (f.Name != "My Suitcase")
|
||||
{
|
||||
f.Name = f.Name + " (Unavailable)";
|
||||
keep.Add(f);
|
||||
}
|
||||
}
|
||||
|
||||
// items directly under the root folder
|
||||
foreach (InventoryItemBase it in content.Items)
|
||||
it.Name = it.Name + " (Unavailable)"; ;
|
||||
|
||||
// Send the new names
|
||||
inv.SendBulkUpdateInventory(keep.ToArray(), content.Items.ToArray());
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessInventoryForLeaving(IClientAPI client)
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -654,9 +654,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
//
|
||||
if (action == DeRezAction.Take || action == DeRezAction.TakeCopy)
|
||||
{
|
||||
if (so.RootPart.FromFolderID != UUID.Zero && userID == remoteClient.AgentId)
|
||||
if (so.FromFolderID != UUID.Zero && userID == remoteClient.AgentId)
|
||||
{
|
||||
InventoryFolderBase f = new InventoryFolderBase(so.RootPart.FromFolderID, userID);
|
||||
InventoryFolderBase f = new InventoryFolderBase(so.FromFolderID, userID);
|
||||
folder = m_Scene.InventoryService.GetFolder(f);
|
||||
}
|
||||
}
|
||||
@@ -935,6 +935,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!isAttachment))
|
||||
remoteClient.SendBulkUpdateInventory(item);
|
||||
|
||||
ILandObject land = m_Scene.LandChannel.GetLandObject(pos.X, pos.Y);
|
||||
remoteClient.SendAlertMessage(string.Format(
|
||||
"Can't rez object '{0}' at <{1:F3}, {2:F3}, {3:F3}> on parcel '{4}' in region {5}.",
|
||||
item.Name, pos.X, pos.Y, pos.Z, land != null ? land.LandData.Name : "Unknown", m_Scene.RegionInfo.RegionName));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -957,7 +962,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
rootPart.SalePrice = item.SalePrice;
|
||||
}
|
||||
|
||||
rootPart.FromFolderID = item.Folder;
|
||||
so.FromFolderID = item.Folder;
|
||||
|
||||
// Console.WriteLine("rootPart.OwnedID {0}, item.Owner {1}, item.CurrentPermissions {2:X}",
|
||||
// rootPart.OwnerID, item.Owner, item.CurrentPermissions);
|
||||
@@ -1003,7 +1008,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
||||
rootPart.TrimPermissions();
|
||||
|
||||
if (isAttachment)
|
||||
so.SetFromItemID(item.ID);
|
||||
so.FromItemID = item.ID;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -72,7 +72,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
|
||||
|
||||
m_scene = scene;
|
||||
|
||||
m_scene.AddCommand(this, "monitor report",
|
||||
m_scene.AddCommand("General", this, "monitor report",
|
||||
"monitor report",
|
||||
"Returns a variety of statistics about the current region and/or simulator",
|
||||
DebugMonitors);
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Console;
|
||||
using OpenSim.Region.Framework;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Services.Connectors.Hypergrid;
|
||||
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.Packets;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||
{
|
||||
public class HGUserManagementModule : UserManagementModule, ISharedRegionModule, IUserManagement
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
|
||||
#region ISharedRegionModule
|
||||
|
||||
public new void Initialise(IConfigSource config)
|
||||
{
|
||||
string umanmod = config.Configs["Modules"].GetString("UserManagementModule", base.Name);
|
||||
if (umanmod == Name)
|
||||
{
|
||||
m_Enabled = true;
|
||||
RegisterConsoleCmds();
|
||||
m_log.DebugFormat("[USER MANAGEMENT MODULE]: {0} is enabled", Name);
|
||||
}
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return "HGUserManagementModule"; }
|
||||
}
|
||||
|
||||
#endregion ISharedRegionModule
|
||||
|
||||
protected override void AddAdditionalUsers(UUID avatarID, string query, List<UserData> users)
|
||||
{
|
||||
if (query.Contains("@")) // First.Last@foo.com, maybe?
|
||||
{
|
||||
string[] words = query.Split(new char[] { '@' });
|
||||
if (words.Length != 2)
|
||||
{
|
||||
m_log.DebugFormat("[USER MANAGEMENT MODULE]: Malformed address {0}", query);
|
||||
return;
|
||||
}
|
||||
|
||||
words[0] = words[0].Trim(); // it has at least 1
|
||||
words[1] = words[1].Trim();
|
||||
|
||||
if (words[0] == String.Empty) // query was @foo.com?
|
||||
{
|
||||
foreach (UserData d in m_UserCache.Values)
|
||||
{
|
||||
if (d.LastName.ToLower().StartsWith("@" + words[1].ToLower()))
|
||||
users.Add(d);
|
||||
}
|
||||
|
||||
// We're done
|
||||
return;
|
||||
}
|
||||
|
||||
// words.Length == 2 and words[0] != string.empty
|
||||
// first.last@foo.com ?
|
||||
foreach (UserData d in m_UserCache.Values)
|
||||
{
|
||||
if (d.LastName.StartsWith("@") &&
|
||||
d.FirstName.ToLower().Equals(words[0].ToLower()) &&
|
||||
d.LastName.ToLower().Equals("@" + words[1].ToLower()))
|
||||
{
|
||||
users.Add(d);
|
||||
// It's cached. We're done
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// This is it! Let's ask the other world
|
||||
if (words[0].Contains("."))
|
||||
{
|
||||
string[] names = words[0].Split(new char[] { '.' });
|
||||
if (names.Length >= 2)
|
||||
{
|
||||
|
||||
string uriStr = "http://" + words[1];
|
||||
// Let's check that the last name is a valid address
|
||||
try
|
||||
{
|
||||
new Uri(uriStr);
|
||||
}
|
||||
catch (UriFormatException)
|
||||
{
|
||||
m_log.DebugFormat("[USER MANAGEMENT MODULE]: Malformed address {0}", uriStr);
|
||||
return;
|
||||
}
|
||||
|
||||
UserAgentServiceConnector uasConn = new UserAgentServiceConnector(uriStr);
|
||||
UUID userID = uasConn.GetUUID(names[0], names[1]);
|
||||
if (!userID.Equals(UUID.Zero))
|
||||
{
|
||||
UserData ud = new UserData();
|
||||
ud.Id = userID;
|
||||
ud.FirstName = words[0];
|
||||
ud.LastName = "@" + words[1];
|
||||
users.Add(ud);
|
||||
AddUser(userID, names[0], names[1], uriStr);
|
||||
m_log.DebugFormat("[USER MANAGEMENT MODULE]: User {0}@{1} found", words[0], words[1]);
|
||||
}
|
||||
else
|
||||
m_log.DebugFormat("[USER MANAGEMENT MODULE]: User {0}@{1} not found", words[0], words[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// foreach (UserData d in m_UserCache.Values)
|
||||
// {
|
||||
// if (d.LastName.StartsWith("@") &&
|
||||
// (d.FirstName.ToLower().StartsWith(query.ToLower()) ||
|
||||
// d.LastName.ToLower().StartsWith(query.ToLower())))
|
||||
// users.Add(d);
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -38,12 +38,13 @@ using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Services.Connectors.Hypergrid;
|
||||
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.Packets;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||
{
|
||||
class UserData
|
||||
public class UserData
|
||||
{
|
||||
public UUID Id { get; set; }
|
||||
public string FirstName { get; set; }
|
||||
@@ -56,36 +57,23 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private List<Scene> m_Scenes = new List<Scene>();
|
||||
protected bool m_Enabled;
|
||||
protected List<Scene> m_Scenes = new List<Scene>();
|
||||
|
||||
// The cache
|
||||
Dictionary<UUID, UserData> m_UserCache = new Dictionary<UUID, UserData>();
|
||||
protected Dictionary<UUID, UserData> m_UserCache = new Dictionary<UUID, UserData>();
|
||||
|
||||
#region ISharedRegionModule
|
||||
|
||||
public void Initialise(IConfigSource config)
|
||||
{
|
||||
//m_Enabled = config.Configs["Modules"].GetBoolean("LibraryModule", m_Enabled);
|
||||
//if (m_Enabled)
|
||||
//{
|
||||
// IConfig libConfig = config.Configs["LibraryService"];
|
||||
// if (libConfig != null)
|
||||
// {
|
||||
// string dllName = libConfig.GetString("LocalServiceModule", string.Empty);
|
||||
// m_log.Debug("[LIBRARY MODULE]: Library service dll is " + dllName);
|
||||
// if (dllName != string.Empty)
|
||||
// {
|
||||
// Object[] args = new Object[] { config };
|
||||
// m_Library = ServerUtils.LoadPlugin<ILibraryService>(dllName, args);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
MainConsole.Instance.Commands.AddCommand("grid", true,
|
||||
"show names",
|
||||
"show names",
|
||||
"Show the bindings between user UUIDs and user names",
|
||||
String.Empty,
|
||||
HandleShowUsers);
|
||||
string umanmod = config.Configs["Modules"].GetString("UserManagementModule", Name);
|
||||
if (umanmod == Name)
|
||||
{
|
||||
m_Enabled = true;
|
||||
RegisterConsoleCmds();
|
||||
m_log.DebugFormat("[USER MANAGEMENT MODULE]: {0} is enabled", Name);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsSharedModule
|
||||
@@ -93,9 +81,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public string Name
|
||||
public virtual string Name
|
||||
{
|
||||
get { return "UserManagement Module"; }
|
||||
get { return "BasicUserManagementModule"; }
|
||||
}
|
||||
|
||||
public Type ReplaceableInterface
|
||||
@@ -105,17 +93,23 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||
|
||||
public void AddRegion(Scene scene)
|
||||
{
|
||||
m_Scenes.Add(scene);
|
||||
if (m_Enabled)
|
||||
{
|
||||
m_Scenes.Add(scene);
|
||||
|
||||
scene.RegisterModuleInterface<IUserManagement>(this);
|
||||
scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(EventManager_OnNewClient);
|
||||
scene.EventManager.OnPrimsLoaded += new EventManager.PrimsLoaded(EventManager_OnPrimsLoaded);
|
||||
scene.RegisterModuleInterface<IUserManagement>(this);
|
||||
scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(EventManager_OnNewClient);
|
||||
scene.EventManager.OnPrimsLoaded += new EventManager.PrimsLoaded(EventManager_OnPrimsLoaded);
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
{
|
||||
scene.UnregisterModuleInterface<IUserManagement>(this);
|
||||
m_Scenes.Remove(scene);
|
||||
if (m_Enabled)
|
||||
{
|
||||
scene.UnregisterModuleInterface<IUserManagement>(this);
|
||||
m_Scenes.Remove(scene);
|
||||
}
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene s)
|
||||
@@ -149,7 +143,15 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||
|
||||
void EventManager_OnNewClient(IClientAPI client)
|
||||
{
|
||||
client.OnConnectionClosed += new Action<IClientAPI>(HandleConnectionClosed);
|
||||
client.OnNameFromUUIDRequest += new UUIDNameRequest(HandleUUIDNameRequest);
|
||||
client.OnAvatarPickerRequest += new AvatarPickerRequest(HandleAvatarPickerRequest);
|
||||
}
|
||||
|
||||
void HandleConnectionClosed(IClientAPI client)
|
||||
{
|
||||
client.OnNameFromUUIDRequest -= new UUIDNameRequest(HandleUUIDNameRequest);
|
||||
client.OnAvatarPickerRequest -= new AvatarPickerRequest(HandleAvatarPickerRequest);
|
||||
}
|
||||
|
||||
void HandleUUIDNameRequest(UUID uuid, IClientAPI remote_client)
|
||||
@@ -170,6 +172,77 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||
}
|
||||
}
|
||||
|
||||
public void HandleAvatarPickerRequest(IClientAPI client, UUID avatarID, UUID RequestID, string query)
|
||||
{
|
||||
//EventManager.TriggerAvatarPickerRequest();
|
||||
|
||||
m_log.DebugFormat("[USER MANAGEMENT MODULE]: HandleAvatarPickerRequest for {0}", query);
|
||||
|
||||
List<UserAccount> accs = m_Scenes[0].UserAccountService.GetUserAccounts(m_Scenes[0].RegionInfo.ScopeID, query);
|
||||
|
||||
List<UserData> users = new List<UserData>();
|
||||
if (accs != null)
|
||||
{
|
||||
foreach (UserAccount acc in accs)
|
||||
{
|
||||
UserData ud = new UserData();
|
||||
ud.FirstName = acc.FirstName;
|
||||
ud.LastName = acc.LastName;
|
||||
ud.Id = acc.PrincipalID;
|
||||
users.Add(ud);
|
||||
}
|
||||
}
|
||||
|
||||
AddAdditionalUsers(avatarID, query, users);
|
||||
|
||||
AvatarPickerReplyPacket replyPacket = (AvatarPickerReplyPacket)PacketPool.Instance.GetPacket(PacketType.AvatarPickerReply);
|
||||
// TODO: don't create new blocks if recycling an old packet
|
||||
|
||||
AvatarPickerReplyPacket.DataBlock[] searchData =
|
||||
new AvatarPickerReplyPacket.DataBlock[users.Count];
|
||||
AvatarPickerReplyPacket.AgentDataBlock agentData = new AvatarPickerReplyPacket.AgentDataBlock();
|
||||
|
||||
agentData.AgentID = avatarID;
|
||||
agentData.QueryID = RequestID;
|
||||
replyPacket.AgentData = agentData;
|
||||
//byte[] bytes = new byte[AvatarResponses.Count*32];
|
||||
|
||||
int i = 0;
|
||||
foreach (UserData item in users)
|
||||
{
|
||||
UUID translatedIDtem = item.Id;
|
||||
searchData[i] = new AvatarPickerReplyPacket.DataBlock();
|
||||
searchData[i].AvatarID = translatedIDtem;
|
||||
searchData[i].FirstName = Utils.StringToBytes((string)item.FirstName);
|
||||
searchData[i].LastName = Utils.StringToBytes((string)item.LastName);
|
||||
i++;
|
||||
}
|
||||
if (users.Count == 0)
|
||||
{
|
||||
searchData = new AvatarPickerReplyPacket.DataBlock[0];
|
||||
}
|
||||
replyPacket.Data = searchData;
|
||||
|
||||
AvatarPickerReplyAgentDataArgs agent_data = new AvatarPickerReplyAgentDataArgs();
|
||||
agent_data.AgentID = replyPacket.AgentData.AgentID;
|
||||
agent_data.QueryID = replyPacket.AgentData.QueryID;
|
||||
|
||||
List<AvatarPickerReplyDataArgs> data_args = new List<AvatarPickerReplyDataArgs>();
|
||||
for (i = 0; i < replyPacket.Data.Length; i++)
|
||||
{
|
||||
AvatarPickerReplyDataArgs data_arg = new AvatarPickerReplyDataArgs();
|
||||
data_arg.AvatarID = replyPacket.Data[i].AvatarID;
|
||||
data_arg.FirstName = replyPacket.Data[i].FirstName;
|
||||
data_arg.LastName = replyPacket.Data[i].LastName;
|
||||
data_args.Add(data_arg);
|
||||
}
|
||||
client.SendAvatarPickerReply(agent_data, data_args);
|
||||
}
|
||||
|
||||
protected virtual void AddAdditionalUsers(UUID avatarID, string query, List<UserData> users)
|
||||
{
|
||||
}
|
||||
|
||||
#endregion Event Handlers
|
||||
|
||||
private void CacheCreators(SceneObjectGroup sog)
|
||||
@@ -224,9 +297,37 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||
|
||||
#region IUserManagement
|
||||
|
||||
public UUID GetUserIdByName(string name)
|
||||
{
|
||||
string[] parts = name.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length < 2)
|
||||
throw new Exception("Name must have 2 components");
|
||||
|
||||
return GetUserIdByName(parts[0], parts[1]);
|
||||
}
|
||||
|
||||
public UUID GetUserIdByName(string firstName, string lastName)
|
||||
{
|
||||
// TODO: Optimize for reverse lookup if this gets used by non-console commands.
|
||||
lock (m_UserCache)
|
||||
{
|
||||
foreach (UserData user in m_UserCache.Values)
|
||||
{
|
||||
if (user.FirstName == firstName && user.LastName == lastName)
|
||||
return user.Id;
|
||||
}
|
||||
}
|
||||
|
||||
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(UUID.Zero, firstName, lastName);
|
||||
|
||||
if (account != null)
|
||||
return account.PrincipalID;
|
||||
|
||||
return UUID.Zero;
|
||||
}
|
||||
|
||||
public string GetUserName(UUID uuid)
|
||||
{
|
||||
//m_log.DebugFormat("[XXX] GetUserName {0}", uuid);
|
||||
string[] names = GetUserNames(uuid);
|
||||
if (names.Length == 2)
|
||||
{
|
||||
@@ -267,9 +368,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||
|
||||
if (userdata.HomeURL != null && userdata.HomeURL != string.Empty)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[USER MANAGEMENT MODULE]: Did not find url type {0} so requesting urls from '{1}' for {2}",
|
||||
serverType, userdata.HomeURL, userID);
|
||||
//m_log.DebugFormat(
|
||||
// "[USER MANAGEMENT MODULE]: Did not find url type {0} so requesting urls from '{1}' for {2}",
|
||||
// serverType, userdata.HomeURL, userID);
|
||||
|
||||
UserAgentServiceConnector uConn = new UserAgentServiceConnector(userdata.HomeURL);
|
||||
userdata.ServerURLs = uConn.GetServerURLs(userID);
|
||||
@@ -328,11 +429,15 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||
|
||||
public void AddUser(UUID uuid, string first, string last, string homeURL)
|
||||
{
|
||||
// m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, first {1}, last {2}, url {3}", uuid, first, last, homeURL);
|
||||
|
||||
AddUser(uuid, homeURL + ";" + first + " " + last);
|
||||
}
|
||||
|
||||
public void AddUser (UUID id, string creatorData)
|
||||
{
|
||||
//m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, creatorData {1}", id, creatorData);
|
||||
|
||||
UserData oldUser;
|
||||
//lock the whole block - prevent concurrent update
|
||||
lock (m_UserCache)
|
||||
@@ -358,9 +463,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||
return;
|
||||
}
|
||||
}
|
||||
// m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, creatorData {1}", id, creatorData);
|
||||
|
||||
UserAccount account = m_Scenes [0].UserAccountService.GetUserAccount (m_Scenes [0].RegionInfo.ScopeID, id);
|
||||
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount (m_Scenes [0].RegionInfo.ScopeID, id);
|
||||
|
||||
if (account != null)
|
||||
{
|
||||
@@ -409,9 +513,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||
lock (m_UserCache)
|
||||
m_UserCache[user.Id] = user;
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}",
|
||||
// user.Id, user.FirstName, user.LastName, user.HomeURL);
|
||||
//m_log.DebugFormat(
|
||||
// "[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}",
|
||||
// user.Id, user.FirstName, user.LastName, user.HomeURL);
|
||||
}
|
||||
|
||||
public bool IsLocalGridUser(UUID uuid)
|
||||
@@ -425,13 +529,23 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||
|
||||
#endregion IUserManagement
|
||||
|
||||
protected void RegisterConsoleCmds()
|
||||
{
|
||||
MainConsole.Instance.Commands.AddCommand("Users", true,
|
||||
"show names",
|
||||
"show names",
|
||||
"Show the bindings between user UUIDs and user names",
|
||||
String.Empty,
|
||||
HandleShowUsers);
|
||||
}
|
||||
|
||||
private void HandleShowUsers(string module, string[] cmd)
|
||||
{
|
||||
lock (m_UserCache)
|
||||
{
|
||||
if (m_UserCache.Count == 0)
|
||||
{
|
||||
MainConsole.Instance.Output("No users not found");
|
||||
MainConsole.Instance.Output("No users found");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
<Extension path = "/OpenSim/RegionModules">
|
||||
<RegionModule id="UserManagementModule" type="OpenSim.Region.CoreModules.Framework.UserManagement.UserManagementModule" />
|
||||
<RegionModule id="HGUserManagementModule" type="OpenSim.Region.CoreModules.Framework.UserManagement.HGUserManagementModule" />
|
||||
<RegionModule id="EntityTransferModule" type="OpenSim.Region.CoreModules.Framework.EntityTransfer.EntityTransferModule" />
|
||||
<RegionModule id="HGEntityTransferModule" type="OpenSim.Region.CoreModules.Framework.EntityTransfer.HGEntityTransferModule" />
|
||||
<RegionModule id="InventoryAccessModule" type="OpenSim.Region.CoreModules.Framework.InventoryAccess.BasicInventoryAccessModule" />
|
||||
|
||||
@@ -151,6 +151,14 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
|
||||
|
||||
#region IWorldComm Members
|
||||
|
||||
public int ListenerCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_listenerManager.ListenerCount;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a listen event callback with the specified filters.
|
||||
/// The parameters localID,itemID are needed to uniquely identify
|
||||
@@ -311,7 +319,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
|
||||
// Send message to avatar
|
||||
if (channel == 0)
|
||||
{
|
||||
m_scene.SimChatBroadcast(Utils.StringToBytes(msg), ChatTypeEnum.Owner, 0, pos, name, id, false);
|
||||
m_scene.SimChatBroadcast(Utils.StringToBytes(msg), ChatTypeEnum.Broadcast, 0, pos, name, id, false);
|
||||
}
|
||||
|
||||
List<SceneObjectGroup> attachments = sp.GetAttachments();
|
||||
@@ -438,6 +446,18 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
|
||||
private int m_maxhandles;
|
||||
private int m_curlisteners;
|
||||
|
||||
/// <summary>
|
||||
/// Total number of listeners
|
||||
/// </summary>
|
||||
public int ListenerCount
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (m_listeners)
|
||||
return m_listeners.Count;
|
||||
}
|
||||
}
|
||||
|
||||
public ListenerManager(int maxlisteners, int maxhandles)
|
||||
{
|
||||
m_maxlisteners = maxlisteners;
|
||||
|
||||
+20
-6
@@ -48,8 +48,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
|
||||
private static bool m_Enabled = false;
|
||||
|
||||
private IConfigSource m_Config;
|
||||
bool m_Registered = false;
|
||||
GatekeeperServiceInConnector m_HypergridHandler;
|
||||
private bool m_Registered = false;
|
||||
private string m_LocalServiceDll = String.Empty;
|
||||
private GatekeeperServiceInConnector m_HypergridHandler;
|
||||
private UserAgentServerConnector m_UASHandler;
|
||||
|
||||
#region IRegionModule interface
|
||||
|
||||
@@ -63,6 +65,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
|
||||
if (m_Enabled)
|
||||
{
|
||||
m_log.Info("[HGGRID IN CONNECTOR]: Hypergrid Service In Connector enabled");
|
||||
IConfig fconfig = config.Configs["FriendsService"];
|
||||
if (fconfig != null)
|
||||
{
|
||||
m_LocalServiceDll = fconfig.GetString("LocalServiceModule", m_LocalServiceDll);
|
||||
if (m_LocalServiceDll == String.Empty)
|
||||
m_log.WarnFormat("[HGGRID IN CONNECTOR]: Friends LocalServiceModule config missing");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -91,7 +100,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
@@ -112,14 +120,20 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
|
||||
m_log.Info("[HypergridService]: Starting...");
|
||||
|
||||
ISimulationService simService = scene.RequestModuleInterface<ISimulationService>();
|
||||
IFriendsSimConnector friendsConn = scene.RequestModuleInterface<IFriendsSimConnector>();
|
||||
Object[] args = new Object[] { m_Config };
|
||||
IFriendsService friendsService = ServerUtils.LoadPlugin<IFriendsService>(m_LocalServiceDll, args);
|
||||
|
||||
m_HypergridHandler = new GatekeeperServiceInConnector(m_Config, MainServer.Instance, simService);
|
||||
|
||||
IFriendsSimConnector friendsConn = scene.RequestModuleInterface<IFriendsSimConnector>();
|
||||
new UserAgentServerConnector(m_Config, MainServer.Instance, friendsConn);
|
||||
m_UASHandler = new UserAgentServerConnector(m_Config, MainServer.Instance, friendsConn);
|
||||
|
||||
new HeloServiceInConnector(m_Config, MainServer.Instance, "HeloService");
|
||||
new HGFriendsServerConnector(m_Config, MainServer.Instance, "HGFriendsService");
|
||||
|
||||
new HGFriendsServerConnector(m_Config, MainServer.Instance, "HGFriendsService", friendsConn);
|
||||
}
|
||||
scene.RegisterModuleInterface<IGatekeeperService>(m_HypergridHandler.GateKeeper);
|
||||
scene.RegisterModuleInterface<IUserAgentService>(m_UASHandler.HomeUsersService);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -73,14 +73,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
|
||||
return;
|
||||
}
|
||||
|
||||
string serviceDll = assetConfig.GetString("LocalServiceModule",
|
||||
String.Empty);
|
||||
string serviceDll = assetConfig.GetString("LocalServiceModule", String.Empty);
|
||||
|
||||
if (serviceDll == String.Empty)
|
||||
{
|
||||
m_log.Error("[LOCAL ASSET SERVICES CONNECTOR]: No LocalServiceModule named in section AssetService");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.DebugFormat("[LOCAL ASSET SERVICES CONNECTOR]: Loading asset service at {0}", serviceDll);
|
||||
}
|
||||
|
||||
Object[] args = new Object[] { source };
|
||||
m_AssetService = ServerUtils.LoadPlugin<IAssetService>(serviceDll, args);
|
||||
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Nini.Config;
|
||||
using log4net;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenMetaverse;
|
||||
|
||||
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
|
||||
{
|
||||
public class AuthorizationService : IAuthorizationService
|
||||
{
|
||||
private enum AccessFlags
|
||||
{
|
||||
None = 0, /* No restrictions */
|
||||
DisallowResidents = 1, /* Only gods and managers*/
|
||||
DisallowForeigners = 2, /* Only local people */
|
||||
}
|
||||
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(
|
||||
MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private IUserManagement m_UserManagement;
|
||||
private IGridService m_GridService;
|
||||
|
||||
private Scene m_Scene;
|
||||
AccessFlags m_accessValue = AccessFlags.None;
|
||||
|
||||
|
||||
public AuthorizationService(IConfig config, Scene scene)
|
||||
{
|
||||
m_Scene = scene;
|
||||
m_UserManagement = scene.RequestModuleInterface<IUserManagement>();
|
||||
m_GridService = scene.GridService;
|
||||
|
||||
if (config != null)
|
||||
{
|
||||
string accessStr = config.GetString("Region_" + scene.RegionInfo.RegionName.Replace(' ', '_'), String.Empty);
|
||||
if (accessStr != string.Empty)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_accessValue = (AccessFlags)Enum.Parse(typeof(AccessFlags), accessStr);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
m_log.WarnFormat("[AuthorizationService]: {0} is not a valid access flag", accessStr);
|
||||
}
|
||||
}
|
||||
m_log.DebugFormat("[AuthorizationService]: Region {0} access restrictions: {1}", m_Scene.RegionInfo.RegionName, m_accessValue);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public bool IsAuthorizedForRegion(
|
||||
string user, string firstName, string lastName, string regionID, out string message)
|
||||
{
|
||||
message = "authorized";
|
||||
|
||||
// This should not happen
|
||||
if (m_Scene.RegionInfo.RegionID.ToString() != regionID)
|
||||
{
|
||||
m_log.WarnFormat("[AuthorizationService]: Service for region {0} received request to authorize for region {1}",
|
||||
m_Scene.RegionInfo.RegionID, regionID);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (m_accessValue == AccessFlags.None)
|
||||
return true;
|
||||
|
||||
UUID userID = new UUID(user);
|
||||
bool authorized = true;
|
||||
if ((m_accessValue & AccessFlags.DisallowForeigners) == AccessFlags.DisallowForeigners)
|
||||
{
|
||||
authorized = m_UserManagement.IsLocalGridUser(userID);
|
||||
if (!authorized)
|
||||
message = "no foreigner users allowed in this region";
|
||||
}
|
||||
if (authorized && (m_accessValue & AccessFlags.DisallowResidents) == AccessFlags.DisallowResidents)
|
||||
{
|
||||
authorized = m_Scene.Permissions.IsGod(userID) | m_Scene.Permissions.IsAdministrator(userID);
|
||||
if (!authorized)
|
||||
message = "only Admins and Managers allowed in this region";
|
||||
}
|
||||
|
||||
return authorized;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+11
-27
@@ -39,13 +39,15 @@ using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
|
||||
{
|
||||
public class LocalAuthorizationServicesConnector : ISharedRegionModule, IAuthorizationService
|
||||
public class LocalAuthorizationServicesConnector : INonSharedRegionModule, IAuthorizationService
|
||||
{
|
||||
private static readonly ILog m_log =
|
||||
LogManager.GetLogger(
|
||||
MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private IAuthorizationService m_AuthorizationService;
|
||||
private Scene m_Scene;
|
||||
private IConfig m_AuthorizationConfig;
|
||||
|
||||
private bool m_Enabled = false;
|
||||
|
||||
@@ -69,33 +71,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
|
||||
string name = moduleConfig.GetString("AuthorizationServices", string.Empty);
|
||||
if (name == Name)
|
||||
{
|
||||
IConfig authorizationConfig = source.Configs["AuthorizationService"];
|
||||
if (authorizationConfig == null)
|
||||
{
|
||||
m_log.Error("[AUTHORIZATION CONNECTOR]: AuthorizationService missing from OpenSim.ini");
|
||||
return;
|
||||
}
|
||||
|
||||
string serviceDll = authorizationConfig.GetString("LocalServiceModule",
|
||||
String.Empty);
|
||||
|
||||
if (serviceDll == String.Empty)
|
||||
{
|
||||
m_log.Error("[AUTHORIZATION CONNECTOR]: No LocalServiceModule named in section AuthorizationService");
|
||||
return;
|
||||
}
|
||||
|
||||
Object[] args = new Object[] { source };
|
||||
m_AuthorizationService =
|
||||
ServerUtils.LoadPlugin<IAuthorizationService>(serviceDll,
|
||||
args);
|
||||
|
||||
if (m_AuthorizationService == null)
|
||||
{
|
||||
m_log.Error("[AUTHORIZATION CONNECTOR]: Can't load authorization service");
|
||||
return;
|
||||
}
|
||||
m_Enabled = true;
|
||||
m_AuthorizationConfig = source.Configs["AuthorizationService"];
|
||||
m_log.Info("[AUTHORIZATION CONNECTOR]: Local authorization connector enabled");
|
||||
}
|
||||
}
|
||||
@@ -115,6 +92,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
|
||||
return;
|
||||
|
||||
scene.RegisterModuleInterface<IAuthorizationService>(this);
|
||||
m_Scene = scene;
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
@@ -126,6 +104,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
m_AuthorizationService = new AuthorizationService(m_AuthorizationConfig, m_Scene);
|
||||
|
||||
m_log.InfoFormat(
|
||||
"[AUTHORIZATION CONNECTOR]: Enabled local authorization for region {0}",
|
||||
scene.RegionInfo.RegionName);
|
||||
@@ -134,6 +114,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
|
||||
public bool IsAuthorizedForRegion(
|
||||
string userID, string firstName, string lastName, string regionID, out string message)
|
||||
{
|
||||
message = "";
|
||||
if (!m_Enabled)
|
||||
return true;
|
||||
|
||||
return m_AuthorizationService.IsAuthorizedForRegion(userID, firstName, lastName, regionID, out message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,8 +48,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||
LogManager.GetLogger(
|
||||
MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private static LocalGridServicesConnector m_MainInstance;
|
||||
|
||||
private IGridService m_GridService;
|
||||
private Dictionary<UUID, RegionCache> m_LocalCache = new Dictionary<UUID, RegionCache>();
|
||||
|
||||
@@ -62,7 +60,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||
public LocalGridServicesConnector(IConfigSource source)
|
||||
{
|
||||
m_log.Debug("[LOCAL GRID CONNECTOR]: LocalGridServicesConnector instantiated");
|
||||
m_MainInstance = this;
|
||||
InitialiseService(source);
|
||||
}
|
||||
|
||||
@@ -87,7 +84,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||
if (name == Name)
|
||||
{
|
||||
InitialiseService(source);
|
||||
m_MainInstance = this;
|
||||
m_Enabled = true;
|
||||
m_log.Info("[LOCAL GRID CONNECTOR]: Local grid connector enabled");
|
||||
}
|
||||
@@ -126,12 +122,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
if (m_MainInstance == this)
|
||||
{
|
||||
MainConsole.Instance.Commands.AddCommand("LocalGridConnector", false, "show neighbours",
|
||||
"show neighbours",
|
||||
"Shows the local regions' neighbours", NeighboursCommand);
|
||||
}
|
||||
MainConsole.Instance.Commands.AddCommand("Regions", false, "show neighbours",
|
||||
"show neighbours",
|
||||
"Shows the local regions' neighbours", NeighboursCommand);
|
||||
}
|
||||
|
||||
public void Close()
|
||||
@@ -143,22 +136,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||
if (m_Enabled)
|
||||
scene.RegisterModuleInterface<IGridService>(this);
|
||||
|
||||
if (m_MainInstance == this)
|
||||
{
|
||||
if (m_LocalCache.ContainsKey(scene.RegionInfo.RegionID))
|
||||
m_log.ErrorFormat("[LOCAL GRID CONNECTOR]: simulator seems to have more than one region with the same UUID. Please correct this!");
|
||||
else
|
||||
m_LocalCache.Add(scene.RegionInfo.RegionID, new RegionCache(scene));
|
||||
}
|
||||
if (m_LocalCache.ContainsKey(scene.RegionInfo.RegionID))
|
||||
m_log.ErrorFormat("[LOCAL GRID CONNECTOR]: simulator seems to have more than one region with the same UUID. Please correct this!");
|
||||
else
|
||||
m_LocalCache.Add(scene.RegionInfo.RegionID, new RegionCache(scene));
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
{
|
||||
if (m_MainInstance == this)
|
||||
{
|
||||
m_LocalCache[scene.RegionInfo.RegionID].Clear();
|
||||
m_LocalCache.Remove(scene.RegionInfo.RegionID);
|
||||
}
|
||||
m_LocalCache[scene.RegionInfo.RegionID].Clear();
|
||||
m_LocalCache.Remove(scene.RegionInfo.RegionID);
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
@@ -259,6 +246,5 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
|
||||
|
||||
MainConsole.Instance.Output(caps.ToString());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -58,6 +58,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
|
||||
|
||||
private List<Scene> m_Scenes = new List<Scene>();
|
||||
|
||||
private InventoryCache m_Cache = new InventoryCache();
|
||||
|
||||
protected IUserManagement m_UserManagement;
|
||||
protected IUserManagement UserManagementModule
|
||||
{
|
||||
@@ -295,14 +297,35 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
|
||||
return m_LocalGridInventoryService.CreateUserInventory(userID);
|
||||
}
|
||||
|
||||
public List<InventoryFolderBase> GetInventorySkeleton(UUID userId)
|
||||
public List<InventoryFolderBase> GetInventorySkeleton(UUID userID)
|
||||
{
|
||||
return m_LocalGridInventoryService.GetInventorySkeleton(userId);
|
||||
string invURL = GetInventoryServiceURL(userID);
|
||||
|
||||
if (invURL == null) // not there, forward to local inventory connector to resolve
|
||||
return m_LocalGridInventoryService.GetInventorySkeleton(userID);
|
||||
|
||||
IInventoryService connector = GetConnector(invURL);
|
||||
|
||||
return connector.GetInventorySkeleton(userID);
|
||||
}
|
||||
|
||||
public InventoryCollection GetUserInventory(UUID userID)
|
||||
{
|
||||
return null;
|
||||
string invURL = GetInventoryServiceURL(userID);
|
||||
m_log.DebugFormat("[HG INVENTORY CONNECTOR]: GetUserInventory for {0} {1}", userID, invURL);
|
||||
|
||||
if (invURL == null) // not there, forward to local inventory connector to resolve
|
||||
return m_LocalGridInventoryService.GetUserInventory(userID);
|
||||
|
||||
InventoryCollection c = m_Cache.GetUserInventory(userID);
|
||||
if (c != null)
|
||||
return c;
|
||||
|
||||
IInventoryService connector = GetConnector(invURL);
|
||||
c = connector.GetUserInventory(userID);
|
||||
|
||||
m_Cache.Cache(userID, c);
|
||||
return c;
|
||||
}
|
||||
|
||||
public void GetUserInventory(UUID userID, InventoryReceiptCallback callback)
|
||||
@@ -312,6 +335,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
|
||||
public InventoryFolderBase GetRootFolder(UUID userID)
|
||||
{
|
||||
//m_log.DebugFormat("[HG INVENTORY CONNECTOR]: GetRootFolder for {0}", userID);
|
||||
InventoryFolderBase root = m_Cache.GetRootFolder(userID);
|
||||
if (root != null)
|
||||
return root;
|
||||
|
||||
string invURL = GetInventoryServiceURL(userID);
|
||||
|
||||
@@ -320,12 +346,19 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
|
||||
|
||||
IInventoryService connector = GetConnector(invURL);
|
||||
|
||||
return connector.GetRootFolder(userID);
|
||||
root = connector.GetRootFolder(userID);
|
||||
|
||||
m_Cache.Cache(userID, root);
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
public InventoryFolderBase GetFolderForType(UUID userID, AssetType type)
|
||||
{
|
||||
//m_log.DebugFormat("[HG INVENTORY CONNECTOR]: GetFolderForType {0} type {1}", userID, type);
|
||||
InventoryFolderBase f = m_Cache.GetFolderForType(userID, type);
|
||||
if (f != null)
|
||||
return f;
|
||||
|
||||
string invURL = GetInventoryServiceURL(userID);
|
||||
|
||||
@@ -334,7 +367,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
|
||||
|
||||
IInventoryService connector = GetConnector(invURL);
|
||||
|
||||
return connector.GetFolderForType(userID, type);
|
||||
f = connector.GetFolderForType(userID, type);
|
||||
|
||||
m_Cache.Cache(userID, type, f);
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
public InventoryCollection GetFolderContent(UUID userID, UUID folderID)
|
||||
@@ -346,8 +383,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
|
||||
if (invURL == null) // not there, forward to local inventory connector to resolve
|
||||
return m_LocalGridInventoryService.GetFolderContent(userID, folderID);
|
||||
|
||||
IInventoryService connector = GetConnector(invURL);
|
||||
InventoryCollection c = m_Cache.GetFolderContent(userID, folderID);
|
||||
if (c != null)
|
||||
{
|
||||
m_log.Debug("[HG INVENTORY CONNECTOR]: GetFolderContent found content in cache " + folderID);
|
||||
return c;
|
||||
}
|
||||
|
||||
IInventoryService connector = GetConnector(invURL);
|
||||
return connector.GetFolderContent(userID, folderID);
|
||||
|
||||
}
|
||||
@@ -361,8 +404,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
|
||||
if (invURL == null) // not there, forward to local inventory connector to resolve
|
||||
return m_LocalGridInventoryService.GetFolderItems(userID, folderID);
|
||||
|
||||
IInventoryService connector = GetConnector(invURL);
|
||||
List<InventoryItemBase> items = m_Cache.GetFolderItems(userID, folderID);
|
||||
if (items != null)
|
||||
{
|
||||
m_log.Debug("[HG INVENTORY CONNECTOR]: GetFolderItems found items in cache " + folderID);
|
||||
return items;
|
||||
}
|
||||
|
||||
IInventoryService connector = GetConnector(invURL);
|
||||
return connector.GetFolderItems(userID, folderID);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using OpenSim.Framework;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
|
||||
{
|
||||
public class InventoryCache
|
||||
{
|
||||
private const double CACHE_EXPIRATION_SECONDS = 3600.0; // 1 hour
|
||||
|
||||
private static ExpiringCache<UUID, InventoryFolderBase> m_RootFolders = new ExpiringCache<UUID, InventoryFolderBase>();
|
||||
private static ExpiringCache<UUID, Dictionary<AssetType, InventoryFolderBase>> m_FolderTypes = new ExpiringCache<UUID, Dictionary<AssetType, InventoryFolderBase>>();
|
||||
private static ExpiringCache<UUID, InventoryCollection> m_Inventories = new ExpiringCache<UUID, InventoryCollection>();
|
||||
|
||||
public void Cache(UUID userID, InventoryFolderBase root)
|
||||
{
|
||||
lock (m_RootFolders)
|
||||
m_RootFolders.AddOrUpdate(userID, root, CACHE_EXPIRATION_SECONDS);
|
||||
}
|
||||
|
||||
public InventoryFolderBase GetRootFolder(UUID userID)
|
||||
{
|
||||
InventoryFolderBase root = null;
|
||||
if (m_RootFolders.TryGetValue(userID, out root))
|
||||
return root;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void Cache(UUID userID, AssetType type, InventoryFolderBase folder)
|
||||
{
|
||||
lock (m_FolderTypes)
|
||||
{
|
||||
Dictionary<AssetType, InventoryFolderBase> ff = null;
|
||||
if (!m_FolderTypes.TryGetValue(userID, out ff))
|
||||
{
|
||||
ff = new Dictionary<AssetType, InventoryFolderBase>();
|
||||
m_FolderTypes.Add(userID, ff, CACHE_EXPIRATION_SECONDS);
|
||||
}
|
||||
if (!ff.ContainsKey(type))
|
||||
ff.Add(type, folder);
|
||||
}
|
||||
}
|
||||
|
||||
public InventoryFolderBase GetFolderForType(UUID userID, AssetType type)
|
||||
{
|
||||
Dictionary<AssetType, InventoryFolderBase> ff = null;
|
||||
if (m_FolderTypes.TryGetValue(userID, out ff))
|
||||
{
|
||||
InventoryFolderBase f = null;
|
||||
if (ff.TryGetValue(type, out f))
|
||||
return f;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void Cache(UUID userID, InventoryCollection inv)
|
||||
{
|
||||
lock (m_Inventories)
|
||||
m_Inventories.AddOrUpdate(userID, inv, 120);
|
||||
}
|
||||
|
||||
public InventoryCollection GetUserInventory(UUID userID)
|
||||
{
|
||||
InventoryCollection inv = null;
|
||||
if (m_Inventories.TryGetValue(userID, out inv))
|
||||
return inv;
|
||||
return null;
|
||||
}
|
||||
|
||||
public InventoryCollection GetFolderContent(UUID userID, UUID folderID)
|
||||
{
|
||||
InventoryCollection inv = null;
|
||||
InventoryCollection c;
|
||||
if (m_Inventories.TryGetValue(userID, out inv))
|
||||
{
|
||||
c = new InventoryCollection();
|
||||
c.UserID = userID;
|
||||
|
||||
c.Folders = inv.Folders.FindAll(delegate(InventoryFolderBase f)
|
||||
{
|
||||
return f.ParentID == folderID;
|
||||
});
|
||||
c.Items = inv.Items.FindAll(delegate(InventoryItemBase i)
|
||||
{
|
||||
return i.Folder == folderID;
|
||||
});
|
||||
return c;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID)
|
||||
{
|
||||
InventoryCollection inv = null;
|
||||
if (m_Inventories.TryGetValue(userID, out inv))
|
||||
{
|
||||
List<InventoryItemBase> items = inv.Items.FindAll(delegate(InventoryItemBase i)
|
||||
{
|
||||
return i.Folder == folderID;
|
||||
});
|
||||
return items;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
-8
@@ -167,12 +167,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
|
||||
|
||||
public List<InventoryFolderBase> GetInventorySkeleton(UUID userId)
|
||||
{
|
||||
return new List<InventoryFolderBase>();
|
||||
return m_RemoteConnector.GetInventorySkeleton(userId);
|
||||
}
|
||||
|
||||
public InventoryCollection GetUserInventory(UUID userID)
|
||||
{
|
||||
return null;
|
||||
return m_RemoteConnector.GetUserInventory(userID);
|
||||
}
|
||||
|
||||
public void GetUserInventory(UUID userID, InventoryReceiptCallback callback)
|
||||
@@ -193,16 +193,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
|
||||
{
|
||||
InventoryCollection invCol = m_RemoteConnector.GetFolderContent(userID, folderID);
|
||||
|
||||
if (UserManager != null)
|
||||
if (invCol != null && UserManager != null)
|
||||
{
|
||||
// Protect ourselves against the caller subsequently modifying the items list
|
||||
List<InventoryItemBase> items = new List<InventoryItemBase>(invCol.Items);
|
||||
|
||||
Util.FireAndForget(delegate
|
||||
{
|
||||
foreach (InventoryItemBase item in items)
|
||||
UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData);
|
||||
});
|
||||
if (items != null && items.Count > 0)
|
||||
Util.FireAndForget(delegate
|
||||
{
|
||||
foreach (InventoryItemBase item in items)
|
||||
UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData);
|
||||
});
|
||||
}
|
||||
|
||||
return invCol;
|
||||
|
||||
+5
@@ -193,6 +193,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
|
||||
return m_PresenceService.GetAgents(userIDs);
|
||||
}
|
||||
|
||||
public PresenceInfo VerifyAgent(UUID s_sessionID)
|
||||
{
|
||||
return m_PresenceService.VerifyAgent(s_sessionID);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
@@ -27,14 +27,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Services.Interfaces;
|
||||
|
||||
using OpenMetaverse;
|
||||
using log4net;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
|
||||
{
|
||||
public class PresenceDetector
|
||||
@@ -97,7 +95,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
|
||||
// m_log.DebugFormat("[PRESENCE DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName);
|
||||
m_PresenceService.LogoutAgent(client.SessionId);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
@@ -153,6 +153,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
|
||||
return m_RemoteConnector.GetAgents(userIDs);
|
||||
}
|
||||
|
||||
public PresenceInfo VerifyAgent(UUID sessionID)
|
||||
{
|
||||
return m_RemoteConnector.VerifyAgent(sessionID);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
@@ -47,21 +47,21 @@ namespace OpenSim.Region.CoreModules.World
|
||||
|
||||
public void Initialise(IConfigSource config)
|
||||
{
|
||||
MainConsole.Instance.Commands.AddCommand("access", true,
|
||||
MainConsole.Instance.Commands.AddCommand("Users", true,
|
||||
"login enable",
|
||||
"login enable",
|
||||
"Enable simulator logins",
|
||||
String.Empty,
|
||||
HandleLoginCommand);
|
||||
|
||||
MainConsole.Instance.Commands.AddCommand("access", true,
|
||||
MainConsole.Instance.Commands.AddCommand("Users", true,
|
||||
"login disable",
|
||||
"login disable",
|
||||
"Disable simulator logins",
|
||||
String.Empty,
|
||||
HandleLoginCommand);
|
||||
|
||||
MainConsole.Instance.Commands.AddCommand("access", true,
|
||||
MainConsole.Instance.Commands.AddCommand("Users", true,
|
||||
"login status",
|
||||
"login status",
|
||||
"Show login status",
|
||||
|
||||
@@ -108,12 +108,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||
// "[ARCHIVER]: Received {0} of {1} assets requested",
|
||||
// assetsFoundUuids.Count, assetsFoundUuids.Count + assetsNotFoundUuids.Count);
|
||||
|
||||
m_log.InfoFormat("[ARCHIVER]: Adding region settings to archive.");
|
||||
|
||||
// Write out region settings
|
||||
string settingsPath
|
||||
= String.Format("{0}{1}.xml", ArchiveConstants.SETTINGS_PATH, m_scene.RegionInfo.RegionName);
|
||||
m_archiveWriter.WriteFile(settingsPath, RegionSettingsSerializer.Serialize(m_scene.RegionInfo.RegionSettings));
|
||||
|
||||
m_log.InfoFormat("[ARCHIVER]: Added region settings to archive.");
|
||||
m_log.InfoFormat("[ARCHIVER]: Adding parcel settings to archive.");
|
||||
|
||||
// Write out land data (aka parcel) settings
|
||||
List<ILandObject>landObjects = m_scene.LandChannel.AllParcels();
|
||||
@@ -124,7 +126,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||
landData.GlobalID.ToString());
|
||||
m_archiveWriter.WriteFile(landDataPath, LandDataSerializer.Serialize(landData));
|
||||
}
|
||||
m_log.InfoFormat("[ARCHIVER]: Added parcel settings to archive.");
|
||||
|
||||
m_log.InfoFormat("[ARCHIVER]: Adding terrain information to archive.");
|
||||
|
||||
// Write out terrain
|
||||
string terrainPath
|
||||
@@ -135,7 +138,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||
m_archiveWriter.WriteFile(terrainPath, ms.ToArray());
|
||||
ms.Close();
|
||||
|
||||
m_log.InfoFormat("[ARCHIVER]: Added terrain information to archive.");
|
||||
m_log.InfoFormat("[ARCHIVER]: Adding scene objects to archive.");
|
||||
|
||||
// Write out scene object metadata
|
||||
foreach (SceneObjectGroup sceneObject in m_sceneObjects)
|
||||
@@ -145,10 +148,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||
string serializedObject = m_serialiser.SerializeGroupToXml2(sceneObject, m_options);
|
||||
m_archiveWriter.WriteFile(ArchiveHelpers.CreateObjectPath(sceneObject), serializedObject);
|
||||
}
|
||||
|
||||
m_log.InfoFormat("[ARCHIVER]: Added scene objects to archive.");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -219,12 +219,19 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||
m_log.InfoFormat("[ARCHIVER]: Added control file to archive.");
|
||||
|
||||
if (SaveAssets)
|
||||
new AssetsRequest(
|
||||
new AssetsArchiver(archiveWriter), assetUuids,
|
||||
m_scene.AssetService, m_scene.UserAccountService,
|
||||
m_scene.RegionInfo.ScopeID, options, awre.ReceivedAllAssets).Execute();
|
||||
{
|
||||
AssetsRequest ar
|
||||
= new AssetsRequest(
|
||||
new AssetsArchiver(archiveWriter), assetUuids,
|
||||
m_scene.AssetService, m_scene.UserAccountService,
|
||||
m_scene.RegionInfo.ScopeID, options, awre.ReceivedAllAssets);
|
||||
|
||||
Util.FireAndForget(o => ar.Execute());
|
||||
}
|
||||
else
|
||||
{
|
||||
awre.ReceivedAllAssets(new List<UUID>(), new List<UUID>());
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
@@ -141,13 +141,15 @@ namespace OpenSim.Region.CoreModules.World.Archiver
|
||||
PerformAssetsRequestCallback(null);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<UUID, AssetType> kvp in m_uuids)
|
||||
{
|
||||
m_assetService.Get(kvp.Key.ToString(), kvp.Value, PreAssetRequestCallback);
|
||||
}
|
||||
|
||||
m_requestCallbackTimer.Enabled = true;
|
||||
|
||||
foreach (KeyValuePair<UUID, AssetType> kvp in m_uuids)
|
||||
{
|
||||
// m_assetService.Get(kvp.Key.ToString(), kvp.Value, PreAssetRequestCallback);
|
||||
AssetBase asset = m_assetService.Get(kvp.Key.ToString());
|
||||
PreAssetRequestCallback(kvp.Key.ToString(), kvp.Value, asset);
|
||||
}
|
||||
}
|
||||
|
||||
protected void OnRequestCallbackTimeout(object source, ElapsedEventArgs args)
|
||||
|
||||
@@ -62,58 +62,25 @@ namespace OpenSim.Region.CoreModules.World.Estate
|
||||
{
|
||||
m_log.DebugFormat("[ESTATE MODULE]: Setting up estate commands for region {0}", m_module.Scene.RegionInfo.RegionName);
|
||||
|
||||
m_module.Scene.AddCommand(m_module, "set terrain texture",
|
||||
m_module.Scene.AddCommand("Regions", m_module, "set terrain texture",
|
||||
"set terrain texture <number> <uuid> [<x>] [<y>]",
|
||||
"Sets the terrain <number> to <uuid>, if <x> or <y> are specified, it will only " +
|
||||
"set it on regions with a matching coordinate. Specify -1 in <x> or <y> to wildcard" +
|
||||
" that coordinate.",
|
||||
consoleSetTerrainTexture);
|
||||
|
||||
m_module.Scene.AddCommand(m_module, "set terrain heights",
|
||||
m_module.Scene.AddCommand("Regions", m_module, "set terrain heights",
|
||||
"set terrain heights <corner> <min> <max> [<x>] [<y>]",
|
||||
"Sets the terrain texture heights on corner #<corner> to <min>/<max>, if <x> or <y> are specified, it will only " +
|
||||
"set it on regions with a matching coordinate. Specify -1 in <x> or <y> to wildcard" +
|
||||
" that coordinate. Corner # SW = 0, NW = 1, SE = 2, NE = 3.",
|
||||
consoleSetTerrainHeights);
|
||||
|
||||
Command showCommand
|
||||
= new Command("show", CommandIntentions.COMMAND_STATISTICAL, ShowEstatesCommand, "Shows all estates on the simulator.");
|
||||
consoleSetTerrainHeights);
|
||||
|
||||
m_commander.RegisterCommand("show", showCommand);
|
||||
|
||||
m_module.Scene.RegisterModuleCommander(m_commander);
|
||||
|
||||
m_module.Scene.EventManager.OnPluginConsole += EventManagerOnPluginConsole;
|
||||
m_module.Scene.AddCommand(
|
||||
"Estates", m_module, "estate show", "estate show", "Shows all estates on the simulator.", ShowEstatesCommand);
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
m_module.Scene.EventManager.OnPluginConsole -= EventManagerOnPluginConsole;
|
||||
m_module.Scene.UnregisterModuleCommander(m_commander.Name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes commandline input. Do not call directly.
|
||||
/// </summary>
|
||||
/// <param name="args">Commandline arguments</param>
|
||||
protected void EventManagerOnPluginConsole(string[] args)
|
||||
{
|
||||
if (args[0] == "estate")
|
||||
{
|
||||
if (args.Length == 1)
|
||||
{
|
||||
m_commander.ProcessConsoleCommand("help", new string[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
string[] tmpArgs = new string[args.Length - 2];
|
||||
int i;
|
||||
for (i = 2; i < args.Length; i++)
|
||||
tmpArgs[i - 2] = args[i];
|
||||
|
||||
m_commander.ProcessConsoleCommand(args[1], tmpArgs);
|
||||
}
|
||||
}
|
||||
public void Close() {}
|
||||
|
||||
protected void consoleSetTerrainTexture(string module, string[] args)
|
||||
{
|
||||
@@ -201,7 +168,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
|
||||
}
|
||||
}
|
||||
|
||||
protected void ShowEstatesCommand(Object[] args)
|
||||
protected void ShowEstatesCommand(string module, string[] cmd)
|
||||
{
|
||||
StringBuilder report = new StringBuilder();
|
||||
RegionInfo ri = m_module.Scene.RegionInfo;
|
||||
|
||||
@@ -26,8 +26,10 @@
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Security;
|
||||
using log4net;
|
||||
@@ -45,8 +47,6 @@ namespace OpenSim.Region.CoreModules.World.Estate
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private delegate void LookupUUIDS(List<UUID> uuidLst);
|
||||
|
||||
public Scene Scene { get; private set; }
|
||||
public IUserManagement UserManager { get; private set; }
|
||||
|
||||
@@ -157,12 +157,18 @@ namespace OpenSim.Region.CoreModules.World.Estate
|
||||
sendRegionInfoPacketToAll();
|
||||
}
|
||||
|
||||
public void setEstateTerrainBaseTexture(IClientAPI remoteClient, int corner, UUID texture)
|
||||
public void setEstateTerrainBaseTexture(int level, UUID texture)
|
||||
{
|
||||
setEstateTerrainBaseTexture(null, level, texture);
|
||||
sendRegionHandshakeToAll();
|
||||
}
|
||||
|
||||
public void setEstateTerrainBaseTexture(IClientAPI remoteClient, int level, UUID texture)
|
||||
{
|
||||
if (texture == UUID.Zero)
|
||||
return;
|
||||
|
||||
switch (corner)
|
||||
switch (level)
|
||||
{
|
||||
case 0:
|
||||
Scene.RegionInfo.RegionSettings.TerrainTexture1 = texture;
|
||||
@@ -182,6 +188,11 @@ namespace OpenSim.Region.CoreModules.World.Estate
|
||||
sendRegionInfoPacketToAll();
|
||||
}
|
||||
|
||||
public void setEstateTerrainTextureHeights(int corner, float lowValue, float highValue)
|
||||
{
|
||||
setEstateTerrainTextureHeights(null, corner, lowValue, highValue);
|
||||
}
|
||||
|
||||
public void setEstateTerrainTextureHeights(IClientAPI client, int corner, float lowValue, float highValue)
|
||||
{
|
||||
switch (corner)
|
||||
@@ -604,7 +615,6 @@ namespace OpenSim.Region.CoreModules.World.Estate
|
||||
|
||||
public void handleOnEstateManageTelehub (IClientAPI client, UUID invoice, UUID senderID, string cmd, uint param1)
|
||||
{
|
||||
uint ObjectLocalID;
|
||||
SceneObjectPart part;
|
||||
|
||||
switch (cmd)
|
||||
@@ -661,28 +671,23 @@ namespace OpenSim.Region.CoreModules.World.Estate
|
||||
TriggerEstateMessage(senderID, senderName, message);
|
||||
}
|
||||
|
||||
private void handleEstateDebugRegionRequest(IClientAPI remote_client, UUID invoice, UUID senderID, bool scripted, bool collisionEvents, bool physics)
|
||||
private void handleEstateDebugRegionRequest(
|
||||
IClientAPI remote_client, UUID invoice, UUID senderID,
|
||||
bool disableScripts, bool disableCollisions, bool disablePhysics)
|
||||
{
|
||||
if (physics)
|
||||
Scene.RegionInfo.RegionSettings.DisablePhysics = true;
|
||||
else
|
||||
Scene.RegionInfo.RegionSettings.DisablePhysics = false;
|
||||
|
||||
if (scripted)
|
||||
Scene.RegionInfo.RegionSettings.DisableScripts = true;
|
||||
else
|
||||
Scene.RegionInfo.RegionSettings.DisableScripts = false;
|
||||
|
||||
if (collisionEvents)
|
||||
Scene.RegionInfo.RegionSettings.DisableCollisions = true;
|
||||
else
|
||||
Scene.RegionInfo.RegionSettings.DisableCollisions = false;
|
||||
|
||||
|
||||
Scene.RegionInfo.RegionSettings.DisablePhysics = disablePhysics;
|
||||
Scene.RegionInfo.RegionSettings.DisableScripts = disableScripts;
|
||||
Scene.RegionInfo.RegionSettings.DisableCollisions = disableCollisions;
|
||||
Scene.RegionInfo.RegionSettings.Save();
|
||||
TriggerRegionInfoChange();
|
||||
|
||||
Scene.SetSceneCoreDebug(scripted, collisionEvents, physics);
|
||||
Scene.SetSceneCoreDebug(
|
||||
new Dictionary<string, string>() {
|
||||
{ "scripting", (!disableScripts).ToString() },
|
||||
{ "collisions", (!disableCollisions).ToString() },
|
||||
{ "physics", (!disablePhysics).ToString() }
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private void handleEstateTeleportOneUserHomeRequest(IClientAPI remover_client, UUID invoice, UUID senderID, UUID prey)
|
||||
@@ -876,98 +881,76 @@ namespace OpenSim.Region.CoreModules.World.Estate
|
||||
if (!Scene.Permissions.CanIssueEstateCommand(remoteClient.AgentId, false))
|
||||
return;
|
||||
|
||||
Dictionary<uint, float> SceneData = new Dictionary<uint,float>();
|
||||
List<UUID> uuidNameLookupList = new List<UUID>();
|
||||
Dictionary<uint, float> sceneData = null;
|
||||
|
||||
if (reportType == 1)
|
||||
{
|
||||
SceneData = Scene.PhysicsScene.GetTopColliders();
|
||||
sceneData = Scene.PhysicsScene.GetTopColliders();
|
||||
}
|
||||
else if (reportType == 0)
|
||||
{
|
||||
SceneData = Scene.SceneGraph.GetTopScripts();
|
||||
IScriptModule scriptModule = Scene.RequestModuleInterface<IScriptModule>();
|
||||
|
||||
if (scriptModule != null)
|
||||
sceneData = scriptModule.GetObjectScriptsExecutionTimes();
|
||||
}
|
||||
|
||||
List<LandStatReportItem> SceneReport = new List<LandStatReportItem>();
|
||||
lock (SceneData)
|
||||
if (sceneData != null)
|
||||
{
|
||||
foreach (uint obj in SceneData.Keys)
|
||||
var sortedSceneData
|
||||
= sceneData.Select(
|
||||
item => new { Measurement = item.Value, Part = Scene.GetSceneObjectPart(item.Key) });
|
||||
|
||||
sortedSceneData.OrderBy(item => item.Measurement);
|
||||
|
||||
int items = 0;
|
||||
|
||||
foreach (var entry in sortedSceneData)
|
||||
{
|
||||
SceneObjectPart prt = Scene.GetSceneObjectPart(obj);
|
||||
if (prt != null)
|
||||
// The object may have been deleted since we received the data.
|
||||
if (entry.Part == null)
|
||||
continue;
|
||||
|
||||
// Don't show scripts that haven't executed or where execution time is below one microsecond in
|
||||
// order to produce a more readable report.
|
||||
if (entry.Measurement < 0.001)
|
||||
continue;
|
||||
|
||||
items++;
|
||||
SceneObjectGroup so = entry.Part.ParentGroup;
|
||||
|
||||
LandStatReportItem lsri = new LandStatReportItem();
|
||||
lsri.LocationX = so.AbsolutePosition.X;
|
||||
lsri.LocationY = so.AbsolutePosition.Y;
|
||||
lsri.LocationZ = so.AbsolutePosition.Z;
|
||||
lsri.Score = entry.Measurement;
|
||||
lsri.TaskID = so.UUID;
|
||||
lsri.TaskLocalID = so.LocalId;
|
||||
lsri.TaskName = entry.Part.Name;
|
||||
lsri.OwnerName = UserManager.GetUserName(so.OwnerID);
|
||||
|
||||
if (filter.Length != 0)
|
||||
{
|
||||
SceneObjectGroup sog = prt.ParentGroup;
|
||||
LandStatReportItem lsri = new LandStatReportItem();
|
||||
lsri.LocationX = sog.AbsolutePosition.X;
|
||||
lsri.LocationY = sog.AbsolutePosition.Y;
|
||||
lsri.LocationZ = sog.AbsolutePosition.Z;
|
||||
lsri.Score = SceneData[obj];
|
||||
lsri.TaskID = sog.UUID;
|
||||
lsri.TaskLocalID = sog.LocalId;
|
||||
lsri.TaskName = sog.GetPartName(obj);
|
||||
lsri.OwnerName = "waiting";
|
||||
lock (uuidNameLookupList)
|
||||
uuidNameLookupList.Add(sog.OwnerID);
|
||||
|
||||
if (filter.Length != 0)
|
||||
if ((lsri.OwnerName.Contains(filter) || lsri.TaskName.Contains(filter)))
|
||||
{
|
||||
if ((lsri.OwnerName.Contains(filter) || lsri.TaskName.Contains(filter)))
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
SceneReport.Add(lsri);
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
SceneReport.Add(lsri);
|
||||
|
||||
if (items >= 100)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
remoteClient.SendLandStatReply(reportType, requestFlags, (uint)SceneReport.Count,SceneReport.ToArray());
|
||||
|
||||
if (uuidNameLookupList.Count > 0)
|
||||
LookupUUID(uuidNameLookupList);
|
||||
}
|
||||
|
||||
private static void LookupUUIDSCompleted(IAsyncResult iar)
|
||||
{
|
||||
LookupUUIDS icon = (LookupUUIDS)iar.AsyncState;
|
||||
icon.EndInvoke(iar);
|
||||
}
|
||||
|
||||
private void LookupUUID(List<UUID> uuidLst)
|
||||
{
|
||||
LookupUUIDS d = LookupUUIDsAsync;
|
||||
|
||||
d.BeginInvoke(uuidLst,
|
||||
LookupUUIDSCompleted,
|
||||
d);
|
||||
}
|
||||
|
||||
private void LookupUUIDsAsync(List<UUID> uuidLst)
|
||||
{
|
||||
UUID[] uuidarr;
|
||||
|
||||
lock (uuidLst)
|
||||
{
|
||||
uuidarr = uuidLst.ToArray();
|
||||
}
|
||||
|
||||
for (int i = 0; i < uuidarr.Length; i++)
|
||||
{
|
||||
// string lookupname = m_scene.CommsManager.UUIDNameRequestString(uuidarr[i]);
|
||||
|
||||
IUserManagement userManager = Scene.RequestModuleInterface<IUserManagement>();
|
||||
if (userManager != null)
|
||||
userManager.GetUserName(uuidarr[i]);
|
||||
|
||||
// we drop it. It gets cached though... so we're ready for the next request.
|
||||
// diva commnent 11/21/2010: uh?!? wft?
|
||||
// justincc comment 21/01/2011: A side effect of userManager.GetUserName() I presume.
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Outgoing Packets
|
||||
|
||||
@@ -56,6 +56,9 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||
protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>();
|
||||
protected Dictionary<uint, UUID> m_listTransactions = new Dictionary<uint, UUID>();
|
||||
|
||||
protected ExpiringCache<UUID, bool> m_groupMemberCache = new ExpiringCache<UUID, bool>();
|
||||
protected TimeSpan m_groupMemberCacheTimeout = TimeSpan.FromSeconds(30); // cache invalidation after 30 seconds
|
||||
|
||||
public bool[,] LandBitmap
|
||||
{
|
||||
get { return m_landBitmap; }
|
||||
@@ -417,6 +420,48 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool HasGroupAccess(UUID avatar)
|
||||
{
|
||||
if (LandData.GroupID != UUID.Zero && (LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup)
|
||||
{
|
||||
ScenePresence sp;
|
||||
if (!m_scene.TryGetScenePresence(avatar, out sp))
|
||||
{
|
||||
bool isMember;
|
||||
if (m_groupMemberCache.TryGetValue(avatar, out isMember))
|
||||
{
|
||||
m_groupMemberCache.Update(avatar, isMember, m_groupMemberCacheTimeout);
|
||||
return isMember;
|
||||
}
|
||||
|
||||
IGroupsModule groupsModule = m_scene.RequestModuleInterface<IGroupsModule>();
|
||||
if (groupsModule == null)
|
||||
return false;
|
||||
|
||||
GroupMembershipData[] membership = groupsModule.GetMembershipData(avatar);
|
||||
if (membership == null || membership.Length == 0)
|
||||
{
|
||||
m_groupMemberCache.Add(avatar, false, m_groupMemberCacheTimeout);
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (GroupMembershipData d in membership)
|
||||
{
|
||||
if (d.GroupID == LandData.GroupID)
|
||||
{
|
||||
m_groupMemberCache.Add(avatar, true, m_groupMemberCacheTimeout);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
m_groupMemberCache.Add(avatar, false, m_groupMemberCacheTimeout);
|
||||
return false;
|
||||
}
|
||||
|
||||
return sp.ControllingClient.IsGroupMember(LandData.GroupID);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool IsBannedFromLand(UUID avatar)
|
||||
{
|
||||
ExpireAccessList();
|
||||
@@ -448,7 +493,8 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||
|
||||
public bool IsRestrictedFromLand(UUID avatar)
|
||||
{
|
||||
ExpireAccessList();
|
||||
if ((LandData.Flags & (uint) ParcelFlags.UseAccessList) == 0)
|
||||
return false;
|
||||
|
||||
if (m_scene.Permissions.IsAdministrator(avatar))
|
||||
return false;
|
||||
@@ -459,20 +505,27 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||
if (avatar == LandData.OwnerID)
|
||||
return false;
|
||||
|
||||
if ((LandData.Flags & (uint) ParcelFlags.UseAccessList) > 0)
|
||||
if (HasGroupAccess(avatar))
|
||||
return false;
|
||||
|
||||
return !IsInLandAccessList(avatar);
|
||||
}
|
||||
|
||||
public bool IsInLandAccessList(UUID avatar)
|
||||
{
|
||||
ExpireAccessList();
|
||||
|
||||
if (LandData.ParcelAccessList.FindIndex(
|
||||
delegate(LandAccessEntry e)
|
||||
{
|
||||
if (e.AgentID == avatar && e.Flags == AccessList.Access)
|
||||
return true;
|
||||
return false;
|
||||
}) == -1)
|
||||
{
|
||||
if (LandData.ParcelAccessList.FindIndex(
|
||||
delegate(LandAccessEntry e)
|
||||
{
|
||||
if (e.AgentID == avatar && e.Flags == AccessList.Access)
|
||||
return true;
|
||||
return false;
|
||||
}) == -1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void SendLandUpdateToClient(IClientAPI remote_client)
|
||||
|
||||
@@ -78,45 +78,45 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
|
||||
m_scene = scene;
|
||||
m_console = MainConsole.Instance;
|
||||
|
||||
m_console.Commands.AddCommand("region", false, "delete object owner",
|
||||
m_console.Commands.AddCommand("Regions", false, "delete object owner",
|
||||
"delete object owner <UUID>",
|
||||
"Delete a scene object by owner", HandleDeleteObject);
|
||||
m_console.Commands.AddCommand("region", false, "delete object creator",
|
||||
m_console.Commands.AddCommand("Regions", false, "delete object creator",
|
||||
"delete object creator <UUID>",
|
||||
"Delete a scene object by creator", HandleDeleteObject);
|
||||
m_console.Commands.AddCommand("region", false, "delete object uuid",
|
||||
m_console.Commands.AddCommand("Regions", false, "delete object uuid",
|
||||
"delete object uuid <UUID>",
|
||||
"Delete a scene object by uuid", HandleDeleteObject);
|
||||
m_console.Commands.AddCommand("region", false, "delete object name",
|
||||
m_console.Commands.AddCommand("Regions", false, "delete object name",
|
||||
"delete object name <name>",
|
||||
"Delete a scene object by name", HandleDeleteObject);
|
||||
m_console.Commands.AddCommand("region", false, "delete object outside",
|
||||
m_console.Commands.AddCommand("Regions", false, "delete object outside",
|
||||
"delete object outside",
|
||||
"Delete all scene objects outside region boundaries", HandleDeleteObject);
|
||||
|
||||
m_console.Commands.AddCommand(
|
||||
"region",
|
||||
"Regions",
|
||||
false,
|
||||
"show object uuid",
|
||||
"show object uuid <UUID>",
|
||||
"Show details of a scene object with the given UUID", HandleShowObjectByUuid);
|
||||
|
||||
m_console.Commands.AddCommand(
|
||||
"region",
|
||||
"Regions",
|
||||
false,
|
||||
"show object name",
|
||||
"show object name <name>",
|
||||
"Show details of scene objects with the given name", HandleShowObjectByName);
|
||||
|
||||
m_console.Commands.AddCommand(
|
||||
"region",
|
||||
"Regions",
|
||||
false,
|
||||
"show part uuid",
|
||||
"show part uuid <UUID>",
|
||||
"Show details of a scene object parts with the given UUID", HandleShowPartByUuid);
|
||||
|
||||
m_console.Commands.AddCommand(
|
||||
"region",
|
||||
"Regions",
|
||||
false,
|
||||
"show part name",
|
||||
"show part name <name>",
|
||||
|
||||
@@ -94,7 +94,9 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
||||
private bool m_RegionOwnerIsGod = false;
|
||||
private bool m_RegionManagerIsGod = false;
|
||||
private bool m_ParcelOwnerIsGod = false;
|
||||
|
||||
|
||||
private bool m_SimpleBuildPermissions = false;
|
||||
|
||||
/// <value>
|
||||
/// The set of users that are allowed to create scripts. This is only active if permissions are not being
|
||||
/// bypassed. This overrides normal permissions.
|
||||
@@ -139,7 +141,9 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
||||
m_RegionOwnerIsGod = myConfig.GetBoolean("region_owner_is_god", true);
|
||||
m_RegionManagerIsGod = myConfig.GetBoolean("region_manager_is_god", false);
|
||||
m_ParcelOwnerIsGod = myConfig.GetBoolean("parcel_owner_is_god", true);
|
||||
|
||||
|
||||
m_SimpleBuildPermissions = myConfig.GetBoolean("simple_build_permissions", false);
|
||||
|
||||
m_allowedScriptCreators
|
||||
= ParseUserSetConfigSetting(myConfig, "allowed_script_creators", m_allowedScriptCreators);
|
||||
m_allowedScriptEditors
|
||||
@@ -206,17 +210,17 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
||||
m_scene.Permissions.OnControlPrimMedia += CanControlPrimMedia;
|
||||
m_scene.Permissions.OnInteractWithPrimMedia += CanInteractWithPrimMedia;
|
||||
|
||||
m_scene.AddCommand(this, "bypass permissions",
|
||||
m_scene.AddCommand("Users", this, "bypass permissions",
|
||||
"bypass permissions <true / false>",
|
||||
"Bypass permission checks",
|
||||
HandleBypassPermissions);
|
||||
|
||||
m_scene.AddCommand(this, "force permissions",
|
||||
m_scene.AddCommand("Users", this, "force permissions",
|
||||
"force permissions <true / false>",
|
||||
"Force permissions on or off",
|
||||
HandleForcePermissions);
|
||||
|
||||
m_scene.AddCommand(this, "debug permissions",
|
||||
m_scene.AddCommand("Users", this, "debug permissions",
|
||||
"debug permissions <true / false>",
|
||||
"Turn on permissions debugging",
|
||||
HandleDebugPermissions);
|
||||
@@ -483,7 +487,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
||||
return false;
|
||||
}
|
||||
|
||||
protected bool IsFriendWithPerms(UUID user,UUID objectOwner)
|
||||
protected bool IsFriendWithPerms(UUID user, UUID objectOwner)
|
||||
{
|
||||
if (user == UUID.Zero)
|
||||
return false;
|
||||
@@ -491,11 +495,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
||||
if (m_friendsModule == null)
|
||||
return false;
|
||||
|
||||
uint friendPerms = m_friendsModule.GetFriendPerms(user, objectOwner);
|
||||
if ((friendPerms & (uint)FriendRights.CanModifyObjects) != 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
int friendPerms = m_friendsModule.GetRightsGrantedByFriend(user, objectOwner);
|
||||
return (friendPerms & (int)FriendRights.CanModifyObjects) != 0;
|
||||
}
|
||||
|
||||
protected bool IsEstateManager(UUID user)
|
||||
@@ -504,6 +505,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
||||
|
||||
return m_scene.RegionInfo.EstateSettings.IsEstateManager(user);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public bool PropagatePermissions()
|
||||
@@ -824,6 +826,10 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
||||
permission = true;
|
||||
}
|
||||
|
||||
if (m_SimpleBuildPermissions &&
|
||||
(parcel.LandData.Flags & (uint)ParcelFlags.UseAccessList) == 0 && parcel.IsInLandAccessList(user))
|
||||
permission = true;
|
||||
|
||||
return permission;
|
||||
}
|
||||
|
||||
|
||||
@@ -66,21 +66,21 @@ namespace OpenSim.Region.CoreModules.World.Region
|
||||
m_Scene = scene;
|
||||
|
||||
scene.RegisterModuleInterface<IRestartModule>(this);
|
||||
MainConsole.Instance.Commands.AddCommand("RestartModule",
|
||||
MainConsole.Instance.Commands.AddCommand("Regions",
|
||||
false, "region restart bluebox",
|
||||
"region restart bluebox <message> <delta seconds>+",
|
||||
"Schedule a region restart",
|
||||
"Schedule a region restart after a given number of seconds. If one delta is given then the region is restarted in delta seconds time. A time to restart is sent to users in the region as a dismissable bluebox notice. If multiple deltas are given then a notice is sent when we reach each delta.",
|
||||
HandleRegionRestart);
|
||||
|
||||
MainConsole.Instance.Commands.AddCommand("RestartModule",
|
||||
MainConsole.Instance.Commands.AddCommand("Regions",
|
||||
false, "region restart notice",
|
||||
"region restart notice <message> <delta seconds>+",
|
||||
"Schedule a region restart",
|
||||
"Schedule a region restart after a given number of seconds. If one delta is given then the region is restarted in delta seconds time. A time to restart is sent to users in the region as a transient notice. If multiple deltas are given then a notice is sent when we reach each delta.",
|
||||
HandleRegionRestart);
|
||||
|
||||
MainConsole.Instance.Commands.AddCommand("RestartModule",
|
||||
MainConsole.Instance.Commands.AddCommand("Regions",
|
||||
false, "region restart abort",
|
||||
"region restart abort [<message>]",
|
||||
"Abort a region restart", HandleRegionRestart);
|
||||
|
||||
@@ -277,18 +277,19 @@ namespace OpenSim.Region.CoreModules
|
||||
m_frame = 0;
|
||||
|
||||
// This one puts an entry in the main help screen
|
||||
m_scene.AddCommand(this, String.Empty, "sun", "Usage: sun [param] [value] - Get or Update Sun module paramater", null);
|
||||
// m_scene.AddCommand("Regions", this, "sun", "sun", "Usage: sun [param] [value] - Get or Update Sun module paramater", null);
|
||||
|
||||
// This one enables the ability to type just "sun" without any parameters
|
||||
m_scene.AddCommand(this, "sun", "", "", HandleSunConsoleCommand);
|
||||
// m_scene.AddCommand("Regions", this, "sun", "", "", HandleSunConsoleCommand);
|
||||
foreach (KeyValuePair<string, string> kvp in GetParamList())
|
||||
{
|
||||
m_scene.AddCommand(this, String.Format("sun {0}", kvp.Key), String.Format("{0} - {1}", kvp.Key, kvp.Value), "", HandleSunConsoleCommand);
|
||||
string sunCommand = string.Format("sun {0}", kvp.Key);
|
||||
m_scene.AddCommand("Regions", this, sunCommand, string.Format("{0} [<value>]", sunCommand), kvp.Value, "", HandleSunConsoleCommand);
|
||||
}
|
||||
|
||||
TimeZone local = TimeZone.CurrentTimeZone;
|
||||
TicksUTCOffset = local.GetUtcOffset(local.ToLocalTime(DateTime.Now)).Ticks;
|
||||
m_log.Debug("[SUN]: localtime offset is " + TicksUTCOffset);
|
||||
m_log.DebugFormat("[SUN]: localtime offset is {0}", TicksUTCOffset);
|
||||
|
||||
// Align ticks with Second Life
|
||||
|
||||
|
||||
@@ -72,5 +72,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
|
||||
{
|
||||
return "BMP";
|
||||
}
|
||||
|
||||
//Returns true if this extension is supported for terrain save-tile
|
||||
public override bool SupportsTileSave()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,5 +57,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
|
||||
{
|
||||
return "GIF";
|
||||
}
|
||||
|
||||
//Returns true if this extension is supported for terrain save-tile
|
||||
public override bool SupportsTileSave()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,13 +132,13 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
|
||||
{
|
||||
// We need to do this because:
|
||||
// "Saving the image to the same file it was constructed from is not allowed and throws an exception."
|
||||
string tempName = offsetX + "_ " + offsetY + "_" + filename;
|
||||
string tempName = Path.GetTempFileName();
|
||||
|
||||
Bitmap entireBitmap = null;
|
||||
Bitmap thisBitmap = null;
|
||||
if (File.Exists(filename))
|
||||
{
|
||||
File.Copy(filename, tempName);
|
||||
File.Copy(filename, tempName, true);
|
||||
entireBitmap = new Bitmap(tempName);
|
||||
if (entireBitmap.Width != fileWidth * regionSizeX || entireBitmap.Height != fileHeight * regionSizeY)
|
||||
{
|
||||
@@ -152,7 +152,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
|
||||
}
|
||||
|
||||
thisBitmap = CreateGrayscaleBitmapFromMap(m_channel);
|
||||
Console.WriteLine("offsetX=" + offsetX + " offsetY=" + offsetY);
|
||||
// Console.WriteLine("offsetX=" + offsetX + " offsetY=" + offsetY);
|
||||
for (int x = 0; x < regionSizeX; x++)
|
||||
for (int y = 0; y < regionSizeY; y++)
|
||||
entireBitmap.SetPixel(x + offsetX * regionSizeX, y + (fileHeight - 1 - offsetY) * regionSizeY, thisBitmap.GetPixel(x, y));
|
||||
@@ -177,6 +177,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
|
||||
return "SYS.DRAWING";
|
||||
}
|
||||
|
||||
//Returns true if this extension is supported for terrain save-tile
|
||||
public virtual bool SupportsTileSave()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Protected method, generates a grayscale bitmap
|
||||
/// image from a specified terrain channel.
|
||||
|
||||
@@ -91,6 +91,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
|
||||
return "JPEG";
|
||||
}
|
||||
|
||||
//Returns true if this extension is supported for terrain save-tile
|
||||
public bool SupportsTileSave()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private static Bitmap CreateBitmapFromMap(ITerrainChannel map)
|
||||
{
|
||||
Bitmap gradientmapLd = new Bitmap("defaultstripe.png");
|
||||
|
||||
@@ -254,5 +254,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
|
||||
{
|
||||
return "LL/SL RAW";
|
||||
}
|
||||
|
||||
//Returns true if this extension is supported for terrain save-tile
|
||||
public bool SupportsTileSave()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,5 +57,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
|
||||
{
|
||||
return "PNG";
|
||||
}
|
||||
|
||||
//Returns true if this extension is supported for terrain save-tile
|
||||
public override bool SupportsTileSave()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,5 +173,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
|
||||
{
|
||||
return "RAW32";
|
||||
}
|
||||
|
||||
//Returns true if this extension is supported for terrain save-tile
|
||||
public bool SupportsTileSave()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,5 +57,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
|
||||
{
|
||||
return "TIFF";
|
||||
}
|
||||
|
||||
//Returns true if this extension is supported for terrain save-tile
|
||||
public bool SupportsTileSave()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -323,6 +323,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
|
||||
return "Terragen";
|
||||
}
|
||||
|
||||
//Returns true if this extension is supported for terrain save-tile
|
||||
public bool SupportsTileSave()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// terragen SCAL floats need to be written intel ordered regardless of
|
||||
/// big or little endian system
|
||||
|
||||
@@ -32,12 +32,31 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
{
|
||||
public interface ITerrainLoader
|
||||
{
|
||||
// Returns true if that extension can be used for terrain save-tile
|
||||
// (Look into each file in Region.CoreModules.World.Terrain.FileLoaders)
|
||||
bool SupportsTileSave();
|
||||
|
||||
string FileExtension { get; }
|
||||
ITerrainChannel LoadFile(string filename);
|
||||
ITerrainChannel LoadFile(string filename, int fileStartX, int fileStartY, int fileWidth, int fileHeight, int sectionWidth, int sectionHeight);
|
||||
ITerrainChannel LoadStream(Stream stream);
|
||||
void SaveFile(string filename, ITerrainChannel map);
|
||||
void SaveStream(Stream stream, ITerrainChannel map);
|
||||
|
||||
/// <summary>
|
||||
/// Save a number of map tiles to a single big image file.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If the image file already exists then the tiles saved will replace those already in the file - other tiles
|
||||
/// will be untouched.
|
||||
/// </remarks>
|
||||
/// <param name="filename">The terrain file to save</param>
|
||||
/// <param name="offsetX">The map x co-ordinate at which to begin the save.</param>
|
||||
/// <param name="offsetY">The may y co-ordinate at which to begin the save.</param>
|
||||
/// <param name="fileWidth">The number of tiles to save along the X axis.</param>
|
||||
/// <param name="fileHeight">The number of tiles to save along the Y axis.</param>
|
||||
/// <param name="regionSizeX">The width of a map tile.</param>
|
||||
/// <param name="regionSizeY">The height of a map tile.</param>
|
||||
void SaveFile(ITerrainChannel map, string filename, int offsetX, int offsetY, int fileWidth, int fileHeight, int regionSizeX, int regionSizeY);
|
||||
}
|
||||
}
|
||||
@@ -86,11 +86,16 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
private volatile bool m_tainted;
|
||||
private readonly Stack<LandUndoState> m_undo = new Stack<LandUndoState>(5);
|
||||
|
||||
private String m_InitialTerrain = "pinhead-island";
|
||||
|
||||
/// <summary>
|
||||
/// Human readable list of terrain file extensions that are supported.
|
||||
/// </summary>
|
||||
private string m_supportedFileExtensions = "";
|
||||
|
||||
//For terrain save-tile file extensions
|
||||
private string m_supportFileExtensionsForTileSave = "";
|
||||
|
||||
#region ICommandableModule Members
|
||||
|
||||
public ICommander CommandInterface
|
||||
@@ -109,6 +114,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
/// <param name="config">Config for the region</param>
|
||||
public void Initialise(IConfigSource config)
|
||||
{
|
||||
IConfig terrainConfig = config.Configs["Terrain"];
|
||||
if (terrainConfig != null)
|
||||
m_InitialTerrain = terrainConfig.GetString("InitialTerrain", m_InitialTerrain);
|
||||
}
|
||||
|
||||
public void AddRegion(Scene scene)
|
||||
@@ -120,7 +128,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
{
|
||||
if (m_scene.Heightmap == null)
|
||||
{
|
||||
m_channel = new TerrainChannel();
|
||||
m_channel = new TerrainChannel(m_InitialTerrain);
|
||||
m_scene.Heightmap = m_channel;
|
||||
m_revert = new TerrainChannel();
|
||||
UpdateRevertMap();
|
||||
@@ -143,11 +151,20 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
|
||||
// Generate user-readable extensions list
|
||||
string supportedFilesSeparator = "";
|
||||
string supportedFilesSeparatorForTileSave = "";
|
||||
|
||||
m_supportFileExtensionsForTileSave = "";
|
||||
foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
|
||||
{
|
||||
m_supportedFileExtensions += supportedFilesSeparator + loader.Key + " (" + loader.Value + ")";
|
||||
supportedFilesSeparator = ", ";
|
||||
|
||||
//For terrain save-tile file extensions
|
||||
if (loader.Value.SupportsTileSave() == true)
|
||||
{
|
||||
m_supportFileExtensionsForTileSave += supportedFilesSeparatorForTileSave + loader.Key + " (" + loader.Value + ")";
|
||||
supportedFilesSeparatorForTileSave = ", ";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -556,43 +573,56 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves the terrain to a larger terrain file.
|
||||
/// Save a number of map tiles to a single big image file.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If the image file already exists then the tiles saved will replace those already in the file - other tiles
|
||||
/// will be untouched.
|
||||
/// </remarks>
|
||||
/// <param name="filename">The terrain file to save</param>
|
||||
/// <param name="fileWidth">The width of the file in units</param>
|
||||
/// <param name="fileHeight">The height of the file in units</param>
|
||||
/// <param name="fileStartX">Where to begin our slice</param>
|
||||
/// <param name="fileStartY">Where to begin our slice</param>
|
||||
/// <param name="fileWidth">The number of tiles to save along the X axis.</param>
|
||||
/// <param name="fileHeight">The number of tiles to save along the Y axis.</param>
|
||||
/// <param name="fileStartX">The map x co-ordinate at which to begin the save.</param>
|
||||
/// <param name="fileStartY">The may y co-ordinate at which to begin the save.</param>
|
||||
public void SaveToFile(string filename, int fileWidth, int fileHeight, int fileStartX, int fileStartY)
|
||||
{
|
||||
int offsetX = (int)m_scene.RegionInfo.RegionLocX - fileStartX;
|
||||
int offsetY = (int)m_scene.RegionInfo.RegionLocY - fileStartY;
|
||||
|
||||
if (offsetX >= 0 && offsetX < fileWidth && offsetY >= 0 && offsetY < fileHeight)
|
||||
if (offsetX < 0 || offsetX >= fileWidth || offsetY < 0 || offsetY >= fileHeight)
|
||||
{
|
||||
// this region is included in the tile request
|
||||
foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
|
||||
{
|
||||
if (filename.EndsWith(loader.Key))
|
||||
{
|
||||
lock (m_scene)
|
||||
{
|
||||
loader.Value.SaveFile(m_channel, filename, offsetX, offsetY,
|
||||
fileWidth, fileHeight,
|
||||
(int)Constants.RegionSize,
|
||||
(int)Constants.RegionSize);
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"ERROR: file width + minimum X tile and file height + minimum Y tile must incorporate the current region at ({0},{1}). File width {2} from {3} and file height {4} from {5} does not.",
|
||||
m_scene.RegionInfo.RegionLocX, m_scene.RegionInfo.RegionLocY, fileWidth, fileStartX, fileHeight, fileStartY);
|
||||
|
||||
m_log.InfoFormat("[TERRAIN]: Saved terrain from {0} to {1}", m_scene.RegionInfo.RegionName, filename);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_log.ErrorFormat(
|
||||
"[TERRAIN]: Could not save terrain from {0} to {1}. Valid file extensions are {2}",
|
||||
m_scene.RegionInfo.RegionName, filename, m_supportedFileExtensions);
|
||||
return;
|
||||
}
|
||||
|
||||
// this region is included in the tile request
|
||||
foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders)
|
||||
{
|
||||
if (filename.EndsWith(loader.Key) && loader.Value.SupportsTileSave())
|
||||
{
|
||||
lock (m_scene)
|
||||
{
|
||||
loader.Value.SaveFile(m_channel, filename, offsetX, offsetY,
|
||||
fileWidth, fileHeight,
|
||||
(int)Constants.RegionSize,
|
||||
(int)Constants.RegionSize);
|
||||
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"Saved terrain from ({0},{1}) to ({2},{3}) from {4} to {5}",
|
||||
fileStartX, fileStartY, fileStartX + fileWidth - 1, fileStartY + fileHeight - 1,
|
||||
m_scene.RegionInfo.RegionName, filename);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"ERROR: Could not save terrain from {0} to {1}. Valid file extensions are {2}",
|
||||
m_scene.RegionInfo.RegionName, filename, m_supportFileExtensionsForTileSave);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1174,13 +1204,17 @@ namespace OpenSim.Region.CoreModules.World.Terrain
|
||||
new Command("save-tile", CommandIntentions.COMMAND_HAZARDOUS, InterfaceSaveTileFile, "Saves the current heightmap to the larger file.");
|
||||
saveToTileCommand.AddArgument("filename",
|
||||
"The file you wish to save to, the file extension determines the loader to be used. Supported extensions include: " +
|
||||
m_supportedFileExtensions, "String");
|
||||
m_supportFileExtensionsForTileSave, "String");
|
||||
saveToTileCommand.AddArgument("file width", "The width of the file in tiles", "Integer");
|
||||
saveToTileCommand.AddArgument("file height", "The height of the file in tiles", "Integer");
|
||||
saveToTileCommand.AddArgument("minimum X tile", "The X region coordinate of the first section on the file",
|
||||
"Integer");
|
||||
saveToTileCommand.AddArgument("minimum Y tile", "The Y region coordinate of the first section on the file",
|
||||
"Integer");
|
||||
saveToTileCommand.AddArgument("minimum Y tile", "The Y region coordinate of the first tile on the file\n"
|
||||
+ "= Example =\n"
|
||||
+ "To save a PNG file for a set of map tiles 2 regions wide and 3 regions high from map co-ordinate (9910,10234)\n"
|
||||
+ " # terrain save-tile ST06.png 2 3 9910 10234\n",
|
||||
"Integer");
|
||||
|
||||
// Terrain adjustments
|
||||
Command fillRegionCommand =
|
||||
new Command("fill", CommandIntentions.COMMAND_HAZARDOUS, InterfaceFillTerrain, "Fills the current heightmap with a specified value.");
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user