diff options
Diffstat (limited to '')
19 files changed, 431 insertions, 94 deletions
diff --git a/OpenSim/Region/Environment/Interfaces/IDynamicTextureManager.cs b/OpenSim/Region/Environment/Interfaces/IDynamicTextureManager.cs new file mode 100644 index 0000000..4da5a7e --- /dev/null +++ b/OpenSim/Region/Environment/Interfaces/IDynamicTextureManager.cs | |||
@@ -0,0 +1,26 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | using System.Text; | ||
4 | using System.IO; | ||
5 | using libsecondlife; | ||
6 | |||
7 | namespace OpenSim.Region.Environment.Interfaces | ||
8 | { | ||
9 | public interface IDynamicTextureManager | ||
10 | { | ||
11 | void RegisterRender(string handleType, IDynamicTextureRender render); | ||
12 | void ReturnData(LLUUID id, byte[] data); | ||
13 | LLUUID AddDynamicTextureURL(LLUUID simID, LLUUID primID, string contentType, string url, string extraParams, int updateTimer); | ||
14 | } | ||
15 | |||
16 | public interface IDynamicTextureRender | ||
17 | { | ||
18 | string GetName(); | ||
19 | string GetContentType(); | ||
20 | bool SupportsAsynchronous(); | ||
21 | byte[] ConvertUrl(string url, string extraParams); | ||
22 | byte[] ConvertStream(Stream data, string extraParams); | ||
23 | bool AsyncConvertUrl(LLUUID id, string url, string extraParams); | ||
24 | bool AsyncConvertStream(LLUUID id, Stream data, string extraParams); | ||
25 | } | ||
26 | } | ||
diff --git a/OpenSim/Region/Environment/Interfaces/IRegionModule.cs b/OpenSim/Region/Environment/Interfaces/IRegionModule.cs index 84e156f..11989fe 100644 --- a/OpenSim/Region/Environment/Interfaces/IRegionModule.cs +++ b/OpenSim/Region/Environment/Interfaces/IRegionModule.cs | |||
@@ -10,5 +10,6 @@ namespace OpenSim.Region.Environment.Interfaces | |||
10 | void PostInitialise(); | 10 | void PostInitialise(); |
11 | void CloseDown(); | 11 | void CloseDown(); |
12 | string GetName(); | 12 | string GetName(); |
13 | bool IsSharedModule(); | ||
13 | } | 14 | } |
14 | } | 15 | } |
diff --git a/OpenSim/Region/Environment/Interfaces/ISimChat.cs b/OpenSim/Region/Environment/Interfaces/ISimChat.cs new file mode 100644 index 0000000..0b83b34 --- /dev/null +++ b/OpenSim/Region/Environment/Interfaces/ISimChat.cs | |||
@@ -0,0 +1,12 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | using System.Text; | ||
4 | using libsecondlife; | ||
5 | |||
6 | namespace OpenSim.Region.Environment.Interfaces | ||
7 | { | ||
8 | public interface ISimChat | ||
9 | { | ||
10 | void SimChat(byte[] message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID); | ||
11 | } | ||
12 | } | ||
diff --git a/OpenSim/Region/Environment/ModuleLoader.cs b/OpenSim/Region/Environment/ModuleLoader.cs index 1787a57..e8e7bc2 100644 --- a/OpenSim/Region/Environment/ModuleLoader.cs +++ b/OpenSim/Region/Environment/ModuleLoader.cs | |||
@@ -14,37 +14,51 @@ namespace OpenSim.Region.Environment | |||
14 | 14 | ||
15 | public Dictionary<string, Assembly> LoadedAssemblys = new Dictionary<string, Assembly>(); | 15 | public Dictionary<string, Assembly> LoadedAssemblys = new Dictionary<string, Assembly>(); |
16 | 16 | ||
17 | public List<IRegionModule> LoadedModules = new List<IRegionModule>(); | ||
18 | public Dictionary<string, IRegionModule> LoadedSharedModules = new Dictionary<string, IRegionModule>(); | ||
19 | |||
17 | public ModuleLoader() | 20 | public ModuleLoader() |
18 | { | 21 | { |
19 | 22 | ||
20 | } | 23 | } |
21 | 24 | ||
22 | /// <summary> | 25 | /// <summary> |
23 | /// Really just a test method for loading a set of currently internal modules | 26 | /// Should have a module factory? |
24 | /// </summary> | 27 | /// </summary> |
25 | /// <param name="scene"></param> | 28 | /// <param name="scene"></param> |
26 | public void CreateDefaultModules(Scene scene) | 29 | public void CreateDefaultModules(Scene scene, string exceptModules) |
27 | { | 30 | { |
28 | //Testing IRegionModule ideas | ||
29 | XferModule xferManager = new XferModule(); | 31 | XferModule xferManager = new XferModule(); |
30 | xferManager.Initialise(scene); | 32 | xferManager.Initialise(scene); |
31 | scene.AddModule(xferManager.GetName(), xferManager); | 33 | scene.AddModule(xferManager.GetName(), xferManager); |
34 | LoadedModules.Add(xferManager); | ||
32 | 35 | ||
33 | ChatModule chatModule = new ChatModule(); | 36 | ChatModule chatModule = new ChatModule(); |
34 | chatModule.Initialise(scene); | 37 | chatModule.Initialise(scene); |
35 | scene.AddModule(chatModule.GetName(), chatModule); | 38 | scene.AddModule(chatModule.GetName(), chatModule); |
39 | LoadedModules.Add(chatModule); | ||
36 | 40 | ||
37 | AvatarProfilesModule avatarProfiles = new AvatarProfilesModule(); | 41 | AvatarProfilesModule avatarProfiles = new AvatarProfilesModule(); |
38 | avatarProfiles.Initialise(scene); | 42 | avatarProfiles.Initialise(scene); |
39 | scene.AddModule(avatarProfiles.GetName(), avatarProfiles); | 43 | scene.AddModule(avatarProfiles.GetName(), avatarProfiles); |
44 | LoadedModules.Add(avatarProfiles); | ||
40 | 45 | ||
41 | this.LoadModule("OpenSim.Region.ExtensionsScriptModule.dll", "ExtensionsScriptingModule", scene); | 46 | this.LoadRegionModule("OpenSim.Region.ExtensionsScriptModule.dll", "ExtensionsScriptingModule", scene); |
47 | } | ||
42 | 48 | ||
43 | // Post Initialise Modules, which most likely shouldn't be here | 49 | public void LoadDefaultSharedModules(string exceptModules) |
44 | // but should rather be in a separate method that is called after all modules are loaded/created/intialised | 50 | { |
45 | xferManager.PostInitialise(); | 51 | DynamicTextureModule dynamicModule = new DynamicTextureModule(); |
46 | // chatModule.PostInitialise(); //for now leave this disabled as it would start up a partially working irc bot | 52 | this.LoadedSharedModules.Add(dynamicModule.GetName(), dynamicModule); |
47 | avatarProfiles.PostInitialise(); | 53 | } |
54 | |||
55 | public void InitialiseSharedModules(Scene scene) | ||
56 | { | ||
57 | foreach (IRegionModule module in this.LoadedSharedModules.Values) | ||
58 | { | ||
59 | module.Initialise(scene); | ||
60 | scene.AddModule(module.GetName(), module); //should be doing this? | ||
61 | } | ||
48 | } | 62 | } |
49 | 63 | ||
50 | /// <summary> | 64 | /// <summary> |
@@ -53,18 +67,33 @@ namespace OpenSim.Region.Environment | |||
53 | /// <param name="dllName"></param> | 67 | /// <param name="dllName"></param> |
54 | /// <param name="moduleName"></param> | 68 | /// <param name="moduleName"></param> |
55 | /// <param name="scene"></param> | 69 | /// <param name="scene"></param> |
56 | public void LoadSharedModule(string dllName, string moduleName, Scene scene) | 70 | public void LoadSharedModule(string dllName, string moduleName) |
57 | { | 71 | { |
72 | IRegionModule module = this.LoadModule(dllName, moduleName); | ||
73 | if (module != null) | ||
74 | { | ||
75 | this.LoadedSharedModules.Add(module.GetName(), module); | ||
76 | } | ||
77 | } | ||
58 | 78 | ||
79 | public void LoadRegionModule(string dllName, string moduleName, Scene scene) | ||
80 | { | ||
81 | IRegionModule module = this.LoadModule(dllName, moduleName); | ||
82 | if (module != null) | ||
83 | { | ||
84 | module.Initialise(scene); | ||
85 | scene.AddModule(module.GetName(), module); | ||
86 | LoadedModules.Add(module); | ||
87 | } | ||
59 | } | 88 | } |
60 | 89 | ||
61 | /// <summary> | 90 | /// <summary> |
62 | /// Loads a external Module (if not already loaded) and creates a new instance of it for the passed Scene. | 91 | /// Loads a external Module (if not already loaded) and creates a new instance of it. |
63 | /// </summary> | 92 | /// </summary> |
64 | /// <param name="dllName"></param> | 93 | /// <param name="dllName"></param> |
65 | /// <param name="moduleName"></param> | 94 | /// <param name="moduleName"></param> |
66 | /// <param name="scene"></param> | 95 | /// <param name="scene"></param> |
67 | public void LoadModule(string dllName, string moduleName, Scene scene) | 96 | public IRegionModule LoadModule(string dllName, string moduleName) |
68 | { | 97 | { |
69 | Assembly pluginAssembly = null; | 98 | Assembly pluginAssembly = null; |
70 | if (LoadedAssemblys.ContainsKey(dllName)) | 99 | if (LoadedAssemblys.ContainsKey(dllName)) |
@@ -97,13 +126,26 @@ namespace OpenSim.Region.Environment | |||
97 | } | 126 | } |
98 | pluginAssembly = null; | 127 | pluginAssembly = null; |
99 | 128 | ||
100 | if (module.GetName() == moduleName) | 129 | if ((module != null ) || (module.GetName() == moduleName)) |
101 | { | 130 | { |
102 | module.Initialise(scene); | 131 | return module; |
103 | scene.AddModule(moduleName, module); | 132 | } |
104 | module.PostInitialise(); //shouldn't be done here | 133 | |
134 | return null; | ||
135 | |||
136 | } | ||
137 | |||
138 | public void PostInitialise() | ||
139 | { | ||
140 | foreach (IRegionModule module in this.LoadedSharedModules.Values) | ||
141 | { | ||
142 | module.PostInitialise(); | ||
105 | } | 143 | } |
106 | 144 | ||
145 | foreach (IRegionModule module in this.LoadedModules) | ||
146 | { | ||
147 | module.PostInitialise(); | ||
148 | } | ||
107 | } | 149 | } |
108 | 150 | ||
109 | public void ClearCache() | 151 | public void ClearCache() |
diff --git a/OpenSim/Region/Environment/Modules/AssetDownloadModule.cs b/OpenSim/Region/Environment/Modules/AssetDownloadModule.cs index 5d7e6a6..21a7e61 100644 --- a/OpenSim/Region/Environment/Modules/AssetDownloadModule.cs +++ b/OpenSim/Region/Environment/Modules/AssetDownloadModule.cs | |||
@@ -38,6 +38,11 @@ namespace OpenSim.Region.Environment.Modules | |||
38 | return "AssetDownloadModule"; | 38 | return "AssetDownloadModule"; |
39 | } | 39 | } |
40 | 40 | ||
41 | public bool IsSharedModule() | ||
42 | { | ||
43 | return false; | ||
44 | } | ||
45 | |||
41 | public void NewClient(IClientAPI client) | 46 | public void NewClient(IClientAPI client) |
42 | { | 47 | { |
43 | } | 48 | } |
diff --git a/OpenSim/Region/Environment/Modules/AvatarProfilesModule.cs b/OpenSim/Region/Environment/Modules/AvatarProfilesModule.cs index 1427c58..1ad061a 100644 --- a/OpenSim/Region/Environment/Modules/AvatarProfilesModule.cs +++ b/OpenSim/Region/Environment/Modules/AvatarProfilesModule.cs | |||
@@ -39,11 +39,21 @@ namespace OpenSim.Region.Environment.Modules | |||
39 | return "AvatarProfilesModule"; | 39 | return "AvatarProfilesModule"; |
40 | } | 40 | } |
41 | 41 | ||
42 | public bool IsSharedModule() | ||
43 | { | ||
44 | return false; | ||
45 | } | ||
46 | |||
42 | public void NewClient(IClientAPI client) | 47 | public void NewClient(IClientAPI client) |
43 | { | 48 | { |
44 | client.OnRequestAvatarProperties += RequestAvatarProperty; | 49 | client.OnRequestAvatarProperties += RequestAvatarProperty; |
45 | } | 50 | } |
46 | 51 | ||
52 | public void RemoveClient(IClientAPI client) | ||
53 | { | ||
54 | client.OnRequestAvatarProperties -= RequestAvatarProperty; | ||
55 | } | ||
56 | |||
47 | /// <summary> | 57 | /// <summary> |
48 | /// | 58 | /// |
49 | /// </summary> | 59 | /// </summary> |
diff --git a/OpenSim/Region/Environment/Modules/ChatModule.cs b/OpenSim/Region/Environment/Modules/ChatModule.cs index 752cde4..ac91b78 100644 --- a/OpenSim/Region/Environment/Modules/ChatModule.cs +++ b/OpenSim/Region/Environment/Modules/ChatModule.cs | |||
@@ -14,7 +14,7 @@ using OpenSim.Framework.Console; | |||
14 | 14 | ||
15 | namespace OpenSim.Region.Environment.Modules | 15 | namespace OpenSim.Region.Environment.Modules |
16 | { | 16 | { |
17 | public class ChatModule : IRegionModule | 17 | public class ChatModule : IRegionModule, ISimChat |
18 | { | 18 | { |
19 | private Scene m_scene; | 19 | private Scene m_scene; |
20 | 20 | ||
@@ -45,11 +45,12 @@ namespace OpenSim.Region.Environment.Modules | |||
45 | m_scene = scene; | 45 | m_scene = scene; |
46 | m_scene.EventManager.OnNewClient += NewClient; | 46 | m_scene.EventManager.OnNewClient += NewClient; |
47 | 47 | ||
48 | //should register a optional API Method, so other modules can send chat messages using this module | 48 | m_scene.RegisterModuleInterface<ISimChat>(this); |
49 | } | 49 | } |
50 | 50 | ||
51 | public void PostInitialise() | 51 | public void PostInitialise() |
52 | { | 52 | { |
53 | /* | ||
53 | try | 54 | try |
54 | { | 55 | { |
55 | m_irc = new TcpClient(m_server, m_port); | 56 | m_irc = new TcpClient(m_server, m_port); |
@@ -75,6 +76,7 @@ namespace OpenSim.Region.Environment.Modules | |||
75 | { | 76 | { |
76 | Console.WriteLine(e.ToString()); | 77 | Console.WriteLine(e.ToString()); |
77 | } | 78 | } |
79 | */ | ||
78 | } | 80 | } |
79 | 81 | ||
80 | public void CloseDown() | 82 | public void CloseDown() |
@@ -89,6 +91,11 @@ namespace OpenSim.Region.Environment.Modules | |||
89 | return "ChatModule"; | 91 | return "ChatModule"; |
90 | } | 92 | } |
91 | 93 | ||
94 | public bool IsSharedModule() | ||
95 | { | ||
96 | return false; | ||
97 | } | ||
98 | |||
92 | public void NewClient(IClientAPI client) | 99 | public void NewClient(IClientAPI client) |
93 | { | 100 | { |
94 | client.OnChatFromViewer += SimChat; | 101 | client.OnChatFromViewer += SimChat; |
diff --git a/OpenSim/Region/Environment/Modules/DynamicTextureModule.cs b/OpenSim/Region/Environment/Modules/DynamicTextureModule.cs new file mode 100644 index 0000000..6edebe7 --- /dev/null +++ b/OpenSim/Region/Environment/Modules/DynamicTextureModule.cs | |||
@@ -0,0 +1,136 @@ | |||
1 | using System.Text; | ||
2 | using System.Net; | ||
3 | using System.Net.Sockets; | ||
4 | using System.Threading; | ||
5 | using System.IO; | ||
6 | using System.Collections.Generic; | ||
7 | using libsecondlife; | ||
8 | using OpenJPEGNet; | ||
9 | using OpenSim.Region.Environment.Scenes; | ||
10 | using OpenSim.Region.Environment.Interfaces; | ||
11 | using OpenSim.Framework.Interfaces; | ||
12 | using OpenSim.Framework.Utilities; | ||
13 | using OpenSim.Framework.Console; | ||
14 | using OpenSim.Framework.Types; | ||
15 | |||
16 | namespace OpenSim.Region.Environment.Modules | ||
17 | { | ||
18 | public class DynamicTextureModule :IRegionModule, IDynamicTextureManager | ||
19 | { | ||
20 | private Dictionary<LLUUID, Scene> RegisteredScenes = new Dictionary<LLUUID, Scene>(); | ||
21 | private Dictionary<string, IDynamicTextureRender> RenderPlugins= new Dictionary<string, IDynamicTextureRender>(); | ||
22 | private Dictionary<LLUUID, DynamicTextureUpdater> Updaters = new Dictionary<LLUUID, DynamicTextureUpdater>(); | ||
23 | |||
24 | public void Initialise(Scene scene) | ||
25 | { | ||
26 | if (!RegisteredScenes.ContainsKey(scene.RegionInfo.SimUUID)) | ||
27 | { | ||
28 | RegisteredScenes.Add(scene.RegionInfo.SimUUID, scene); | ||
29 | scene.RegisterModuleInterface<IDynamicTextureManager>(this); | ||
30 | } | ||
31 | } | ||
32 | |||
33 | public void PostInitialise() | ||
34 | { | ||
35 | |||
36 | } | ||
37 | |||
38 | public void CloseDown() | ||
39 | { | ||
40 | } | ||
41 | |||
42 | public string GetName() | ||
43 | { | ||
44 | return "DynamicTextureModule"; | ||
45 | } | ||
46 | |||
47 | public bool IsSharedModule() | ||
48 | { | ||
49 | return true; | ||
50 | } | ||
51 | |||
52 | public void RegisterRender(string handleType, IDynamicTextureRender render) | ||
53 | { | ||
54 | if (!RenderPlugins.ContainsKey(handleType)) | ||
55 | { | ||
56 | RenderPlugins.Add(handleType, render); | ||
57 | } | ||
58 | } | ||
59 | |||
60 | public void ReturnData(LLUUID id, byte[] data) | ||
61 | { | ||
62 | if (Updaters.ContainsKey(id)) | ||
63 | { | ||
64 | DynamicTextureUpdater updater = Updaters[id]; | ||
65 | if (RegisteredScenes.ContainsKey(updater.SimUUID)) | ||
66 | { | ||
67 | Scene scene = RegisteredScenes[updater.SimUUID]; | ||
68 | updater.DataReceived(data, scene); | ||
69 | } | ||
70 | } | ||
71 | } | ||
72 | |||
73 | public LLUUID AddDynamicTextureURL(LLUUID simID, LLUUID primID, string contentType, string url, string extraParams, int updateTimer) | ||
74 | { | ||
75 | System.Console.WriteLine("dynamic texture being created " + url + " of type " + contentType); | ||
76 | if (this.RenderPlugins.ContainsKey(contentType)) | ||
77 | { | ||
78 | DynamicTextureUpdater updater = new DynamicTextureUpdater(); | ||
79 | updater.SimUUID = simID; | ||
80 | updater.PrimID = primID; | ||
81 | updater.ContentType = contentType; | ||
82 | updater.Url = url; | ||
83 | updater.UpdateTimer = updateTimer; | ||
84 | updater.UpdaterID = LLUUID.Random(); | ||
85 | updater.Params = extraParams; | ||
86 | |||
87 | if (!this.Updaters.ContainsKey(updater.UpdaterID)) | ||
88 | { | ||
89 | Updaters.Add(updater.UpdaterID, updater); | ||
90 | } | ||
91 | |||
92 | RenderPlugins[contentType].AsyncConvertUrl(updater.UpdaterID, url, extraParams); | ||
93 | return updater.UpdaterID; | ||
94 | } | ||
95 | return LLUUID.Zero; | ||
96 | } | ||
97 | |||
98 | public class DynamicTextureUpdater | ||
99 | { | ||
100 | public LLUUID SimUUID; | ||
101 | public LLUUID UpdaterID; | ||
102 | public string ContentType; | ||
103 | public string Url; | ||
104 | public Stream StreamData; | ||
105 | public LLUUID PrimID; | ||
106 | public int UpdateTimer; | ||
107 | public LLUUID LastAssetID; | ||
108 | public string Params; | ||
109 | |||
110 | public DynamicTextureUpdater() | ||
111 | { | ||
112 | LastAssetID = LLUUID.Zero; | ||
113 | UpdateTimer = 0; | ||
114 | StreamData = null; | ||
115 | } | ||
116 | |||
117 | public void DataReceived(byte[] data, Scene scene) | ||
118 | { | ||
119 | //TODO delete the last asset(data), if it was a dynamic texture | ||
120 | |||
121 | AssetBase asset = new AssetBase(); | ||
122 | asset.FullID = LLUUID.Random(); | ||
123 | asset.Data = data; | ||
124 | asset.Name = "DynamicImage" + Util.RandomClass.Next(1, 10000); | ||
125 | asset.Type = 0; | ||
126 | scene.commsManager.AssetCache.AddAsset(asset); | ||
127 | |||
128 | this.LastAssetID = asset.FullID; | ||
129 | |||
130 | SceneObjectPart part = scene.GetSceneObjectPart(PrimID); | ||
131 | part.Shape.TextureEntry = new LLObject.TextureEntry(asset.FullID).ToBytes(); | ||
132 | part.ScheduleFullUpdate(); | ||
133 | } | ||
134 | } | ||
135 | } | ||
136 | } | ||
diff --git a/OpenSim/Region/Environment/Modules/EmailModule.cs b/OpenSim/Region/Environment/Modules/EmailModule.cs new file mode 100644 index 0000000..2a90dd3 --- /dev/null +++ b/OpenSim/Region/Environment/Modules/EmailModule.cs | |||
@@ -0,0 +1,10 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | using System.Text; | ||
4 | |||
5 | namespace OpenSim.Region.Environment.Modules | ||
6 | { | ||
7 | class EmailModule | ||
8 | { | ||
9 | } | ||
10 | } | ||
diff --git a/OpenSim/Region/Environment/Modules/FriendsModule.cs b/OpenSim/Region/Environment/Modules/FriendsModule.cs index f952bb2..d46039c 100644 --- a/OpenSim/Region/Environment/Modules/FriendsModule.cs +++ b/OpenSim/Region/Environment/Modules/FriendsModule.cs | |||
@@ -31,5 +31,10 @@ namespace OpenSim.Region.Environment.Modules | |||
31 | { | 31 | { |
32 | return "FriendsModule"; | 32 | return "FriendsModule"; |
33 | } | 33 | } |
34 | |||
35 | public bool IsSharedModule() | ||
36 | { | ||
37 | return false; | ||
38 | } | ||
34 | } | 39 | } |
35 | } | 40 | } |
diff --git a/OpenSim/Region/Environment/Modules/GroupsModule.cs b/OpenSim/Region/Environment/Modules/GroupsModule.cs index 607b395..8e4b409 100644 --- a/OpenSim/Region/Environment/Modules/GroupsModule.cs +++ b/OpenSim/Region/Environment/Modules/GroupsModule.cs | |||
@@ -30,6 +30,11 @@ namespace OpenSim.Region.Environment.Modules | |||
30 | { | 30 | { |
31 | return "GroupsModule"; | 31 | return "GroupsModule"; |
32 | } | 32 | } |
33 | |||
34 | public bool IsSharedModule() | ||
35 | { | ||
36 | return false; | ||
37 | } | ||
33 | } | 38 | } |
34 | } | 39 | } |
35 | 40 | ||
diff --git a/OpenSim/Region/Environment/Modules/InstantMessageModule.cs b/OpenSim/Region/Environment/Modules/InstantMessageModule.cs index 9c09c48..acf031b 100644 --- a/OpenSim/Region/Environment/Modules/InstantMessageModule.cs +++ b/OpenSim/Region/Environment/Modules/InstantMessageModule.cs | |||
@@ -31,5 +31,10 @@ namespace OpenSim.Region.Environment.Modules | |||
31 | { | 31 | { |
32 | return "InstantMessageModule"; | 32 | return "InstantMessageModule"; |
33 | } | 33 | } |
34 | |||
35 | public bool IsSharedModule() | ||
36 | { | ||
37 | return false; | ||
38 | } | ||
34 | } | 39 | } |
35 | } | 40 | } |
diff --git a/OpenSim/Region/Environment/Modules/InventoryModule.cs b/OpenSim/Region/Environment/Modules/InventoryModule.cs index 94e7ba7..00b4d8e 100644 --- a/OpenSim/Region/Environment/Modules/InventoryModule.cs +++ b/OpenSim/Region/Environment/Modules/InventoryModule.cs | |||
@@ -31,5 +31,10 @@ namespace OpenSim.Region.Environment.Modules | |||
31 | { | 31 | { |
32 | return "InventoryModule"; | 32 | return "InventoryModule"; |
33 | } | 33 | } |
34 | |||
35 | public bool IsSharedModule() | ||
36 | { | ||
37 | return false; | ||
38 | } | ||
34 | } | 39 | } |
35 | } | 40 | } |
diff --git a/OpenSim/Region/Environment/Modules/ScriptsHttpRequests.cs b/OpenSim/Region/Environment/Modules/ScriptsHttpRequests.cs new file mode 100644 index 0000000..11af718 --- /dev/null +++ b/OpenSim/Region/Environment/Modules/ScriptsHttpRequests.cs | |||
@@ -0,0 +1,10 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | using System.Text; | ||
4 | |||
5 | namespace OpenSim.Region.Environment.Modules | ||
6 | { | ||
7 | class ScriptsHttpRequests | ||
8 | { | ||
9 | } | ||
10 | } | ||
diff --git a/OpenSim/Region/Environment/Modules/TeleportModule.cs b/OpenSim/Region/Environment/Modules/TeleportModule.cs new file mode 100644 index 0000000..08fc202 --- /dev/null +++ b/OpenSim/Region/Environment/Modules/TeleportModule.cs | |||
@@ -0,0 +1,10 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | using System.Text; | ||
4 | |||
5 | namespace OpenSim.Region.Environment.Modules | ||
6 | { | ||
7 | class TeleportModule | ||
8 | { | ||
9 | } | ||
10 | } | ||
diff --git a/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs b/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs index a92566d..7d31644 100644 --- a/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs +++ b/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs | |||
@@ -37,6 +37,11 @@ namespace OpenSim.Region.Environment.Modules | |||
37 | return "TextureDownloadModule"; | 37 | return "TextureDownloadModule"; |
38 | } | 38 | } |
39 | 39 | ||
40 | public bool IsSharedModule() | ||
41 | { | ||
42 | return false; | ||
43 | } | ||
44 | |||
40 | public void NewClient(IClientAPI client) | 45 | public void NewClient(IClientAPI client) |
41 | { | 46 | { |
42 | } | 47 | } |
diff --git a/OpenSim/Region/Environment/Modules/XferModule.cs b/OpenSim/Region/Environment/Modules/XferModule.cs index a0327e9..eec9f97 100644 --- a/OpenSim/Region/Environment/Modules/XferModule.cs +++ b/OpenSim/Region/Environment/Modules/XferModule.cs | |||
@@ -45,6 +45,11 @@ namespace OpenSim.Region.Environment.Modules | |||
45 | return "XferModule"; | 45 | return "XferModule"; |
46 | } | 46 | } |
47 | 47 | ||
48 | public bool IsSharedModule() | ||
49 | { | ||
50 | return false; | ||
51 | } | ||
52 | |||
48 | public void NewClient(IClientAPI client) | 53 | public void NewClient(IClientAPI client) |
49 | { | 54 | { |
50 | client.OnRequestXfer += RequestXfer; | 55 | client.OnRequestXfer += RequestXfer; |
diff --git a/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs index a9ded3f..90e4a1f 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs | |||
@@ -35,6 +35,7 @@ using OpenSim.Framework.Types; | |||
35 | using OpenSim.Framework.Communications.Caches; | 35 | using OpenSim.Framework.Communications.Caches; |
36 | using OpenSim.Framework.Data; | 36 | using OpenSim.Framework.Data; |
37 | using OpenSim.Framework.Utilities; | 37 | using OpenSim.Framework.Utilities; |
38 | using OpenSim.Region.Environment.Interfaces; | ||
38 | 39 | ||
39 | namespace OpenSim.Region.Environment.Scenes | 40 | namespace OpenSim.Region.Environment.Scenes |
40 | { | 41 | { |
@@ -94,7 +95,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
94 | } | 95 | } |
95 | 96 | ||
96 | /// <summary> | 97 | /// <summary> |
97 | /// Should be removed soon as the Chat modules should take over this function | 98 | /// |
98 | /// </summary> | 99 | /// </summary> |
99 | /// <param name="message"></param> | 100 | /// <param name="message"></param> |
100 | /// <param name="type"></param> | 101 | /// <param name="type"></param> |
@@ -103,56 +104,10 @@ namespace OpenSim.Region.Environment.Scenes | |||
103 | /// <param name="fromAgentID"></param> | 104 | /// <param name="fromAgentID"></param> |
104 | public void SimChat(byte[] message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID) | 105 | public void SimChat(byte[] message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID) |
105 | { | 106 | { |
106 | ScenePresence avatar = null; | 107 | if (m_simChatModule != null) |
107 | if (this.Avatars.ContainsKey(fromAgentID)) | ||
108 | { | 108 | { |
109 | avatar = this.Avatars[fromAgentID]; | 109 | m_simChatModule.SimChat(message, type, fromPos, fromName, fromAgentID); |
110 | fromPos = avatar.AbsolutePosition; | ||
111 | fromName = avatar.Firstname + " " + avatar.Lastname; | ||
112 | avatar = null; | ||
113 | } | 110 | } |
114 | |||
115 | this.ForEachScenePresence(delegate(ScenePresence presence) | ||
116 | { | ||
117 | int dis = -1000; | ||
118 | if (this.Avatars.ContainsKey(presence.ControllingClient.AgentId)) | ||
119 | { | ||
120 | avatar = this.Avatars[presence.ControllingClient.AgentId]; | ||
121 | dis = (int)avatar.AbsolutePosition.GetDistanceTo(fromPos); | ||
122 | } | ||
123 | |||
124 | switch (type) | ||
125 | { | ||
126 | case 0: // Whisper | ||
127 | if ((dis < 10) && (dis > -10)) | ||
128 | { | ||
129 | //should change so the message is sent through the avatar rather than direct to the ClientView | ||
130 | presence.ControllingClient.SendChatMessage(message, type, fromPos, fromName, | ||
131 | fromAgentID); | ||
132 | } | ||
133 | break; | ||
134 | case 1: // Say | ||
135 | if ((dis < 30) && (dis > -30)) | ||
136 | { | ||
137 | //Console.WriteLine("sending chat"); | ||
138 | presence.ControllingClient.SendChatMessage(message, type, fromPos, fromName, | ||
139 | fromAgentID); | ||
140 | } | ||
141 | break; | ||
142 | case 2: // Shout | ||
143 | if ((dis < 100) && (dis > -100)) | ||
144 | { | ||
145 | presence.ControllingClient.SendChatMessage(message, type, fromPos, fromName, | ||
146 | fromAgentID); | ||
147 | } | ||
148 | break; | ||
149 | |||
150 | case 0xff: // Broadcast | ||
151 | presence.ControllingClient.SendChatMessage(message, type, fromPos, fromName, | ||
152 | fromAgentID); | ||
153 | break; | ||
154 | } | ||
155 | }); | ||
156 | } | 111 | } |
157 | 112 | ||
158 | /// <summary> | 113 | /// <summary> |
diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index 46fc86b..b92f8c8 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs | |||
@@ -78,20 +78,23 @@ namespace OpenSim.Region.Environment.Scenes | |||
78 | protected StorageManager storageManager; | 78 | protected StorageManager storageManager; |
79 | protected AgentCircuitManager authenticateHandler; | 79 | protected AgentCircuitManager authenticateHandler; |
80 | protected RegionCommsListener regionCommsHost; | 80 | protected RegionCommsListener regionCommsHost; |
81 | protected CommunicationsManager commsManager; | 81 | public CommunicationsManager commsManager; |
82 | // protected XferManager xferManager; | 82 | // protected XferManager xferManager; |
83 | 83 | ||
84 | protected Dictionary<LLUUID, Caps> capsHandlers = new Dictionary<LLUUID, Caps>(); | 84 | protected Dictionary<LLUUID, Caps> capsHandlers = new Dictionary<LLUUID, Caps>(); |
85 | protected BaseHttpServer httpListener; | 85 | protected BaseHttpServer httpListener; |
86 | 86 | ||
87 | protected Dictionary<string, IRegionModule> Modules = new Dictionary<string, IRegionModule>(); | 87 | protected Dictionary<string, IRegionModule> Modules = new Dictionary<string, IRegionModule>(); |
88 | protected Dictionary<string, object> APIMethods = new Dictionary<string, object>(); | 88 | public Dictionary<Type, object> ModuleInterfaces = new Dictionary<Type, object>(); |
89 | protected Dictionary<string, object> ModuleAPIMethods = new Dictionary<string, object>(); | ||
89 | 90 | ||
90 | //API method Delegates | 91 | //API method Delegates and interfaces |
91 | 92 | ||
92 | // this most likely shouldn't be handled as a API method like this, but doing it for testing purposes | 93 | // this most likely shouldn't be handled as a API method like this, but doing it for testing purposes |
93 | public ModuleAPIMethod2<bool, string, byte[]>AddXferFile = null; | 94 | public ModuleAPIMethod2<bool, string, byte[]> AddXferFile = null; |
94 | 95 | ||
96 | private ISimChat m_simChatModule = null; | ||
97 | |||
95 | #region Properties | 98 | #region Properties |
96 | 99 | ||
97 | public AgentCircuitManager AuthenticateHandler | 100 | public AgentCircuitManager AuthenticateHandler |
@@ -152,7 +155,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
152 | AssetCache assetCach, StorageManager storeManager, BaseHttpServer httpServer, ModuleLoader moduleLoader) | 155 | AssetCache assetCach, StorageManager storeManager, BaseHttpServer httpServer, ModuleLoader moduleLoader) |
153 | { | 156 | { |
154 | updateLock = new Mutex(false); | 157 | updateLock = new Mutex(false); |
155 | 158 | ||
156 | m_moduleLoader = moduleLoader; | 159 | m_moduleLoader = moduleLoader; |
157 | authenticateHandler = authen; | 160 | authenticateHandler = authen; |
158 | commsManager = commsMan; | 161 | commsManager = commsMan; |
@@ -169,9 +172,6 @@ namespace OpenSim.Region.Environment.Scenes | |||
169 | m_eventManager = new EventManager(); | 172 | m_eventManager = new EventManager(); |
170 | m_permissionManager = new PermissionManager(this); | 173 | m_permissionManager = new PermissionManager(this); |
171 | 174 | ||
172 | MainLog.Instance.Verbose("Loading Region Modules"); | ||
173 | m_moduleLoader.CreateDefaultModules(this); | ||
174 | |||
175 | m_eventManager.OnParcelPrimCountAdd += | 175 | m_eventManager.OnParcelPrimCountAdd += |
176 | m_LandManager.addPrimToLandPrimCounts; | 176 | m_LandManager.addPrimToLandPrimCounts; |
177 | 177 | ||
@@ -189,13 +189,15 @@ namespace OpenSim.Region.Environment.Scenes | |||
189 | 189 | ||
190 | httpListener = httpServer; | 190 | httpListener = httpServer; |
191 | 191 | ||
192 | SetMethodDelegates(); | ||
193 | } | 192 | } |
194 | 193 | ||
195 | #endregion | 194 | #endregion |
196 | 195 | ||
197 | private void SetMethodDelegates() | 196 | public void SetModuleInterfaces() |
198 | { | 197 | { |
198 | m_simChatModule = this.RequestModuleInterface<ISimChat>(); | ||
199 | |||
200 | //should change so it uses the module interface functions | ||
199 | AddXferFile = (ModuleAPIMethod2<bool, string, byte[]>)this.RequestAPIMethod("API_AddXferFile"); | 201 | AddXferFile = (ModuleAPIMethod2<bool, string, byte[]>)this.RequestAPIMethod("API_AddXferFile"); |
200 | } | 202 | } |
201 | 203 | ||
@@ -526,7 +528,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
526 | MainLog.Instance.Verbose("Loaded " + PrimsFromDB.Count.ToString() + " SceneObject(s)"); | 528 | MainLog.Instance.Verbose("Loaded " + PrimsFromDB.Count.ToString() + " SceneObject(s)"); |
527 | } | 529 | } |
528 | 530 | ||
529 | 531 | ||
530 | 532 | ||
531 | /// <summary> | 533 | /// <summary> |
532 | /// Returns a new unallocated primitive ID | 534 | /// Returns a new unallocated primitive ID |
@@ -635,12 +637,12 @@ namespace OpenSim.Region.Environment.Scenes | |||
635 | //obj.RegenerateFullIDs(); | 637 | //obj.RegenerateFullIDs(); |
636 | AddEntity(obj); | 638 | AddEntity(obj); |
637 | 639 | ||
638 | SceneObjectPart rootPart = obj.GetChildPart(obj.UUID); | 640 | SceneObjectPart rootPart = obj.GetChildPart(obj.UUID); |
639 | rootPart.PhysActor = phyScene.AddPrim( | 641 | rootPart.PhysActor = phyScene.AddPrim( |
640 | new PhysicsVector(rootPart.AbsolutePosition.X, rootPart.AbsolutePosition.Y, rootPart.AbsolutePosition.Z), | 642 | new PhysicsVector(rootPart.AbsolutePosition.X, rootPart.AbsolutePosition.Y, rootPart.AbsolutePosition.Z), |
641 | new PhysicsVector(rootPart.Scale.X, rootPart.Scale.Y, rootPart.Scale.Z), | 643 | new PhysicsVector(rootPart.Scale.X, rootPart.Scale.Y, rootPart.Scale.Z), |
642 | new Axiom.Math.Quaternion(rootPart.RotationOffset.W, rootPart.RotationOffset.X, | 644 | new Axiom.Math.Quaternion(rootPart.RotationOffset.W, rootPart.RotationOffset.X, |
643 | rootPart.RotationOffset.Y, rootPart.RotationOffset.Z)); | 645 | rootPart.RotationOffset.Y, rootPart.RotationOffset.Z)); |
644 | primCount++; | 646 | primCount++; |
645 | } | 647 | } |
646 | } | 648 | } |
@@ -692,7 +694,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
692 | 694 | ||
693 | protected virtual void SubscribeToClientEvents(IClientAPI client) | 695 | protected virtual void SubscribeToClientEvents(IClientAPI client) |
694 | { | 696 | { |
695 | // client.OnStartAnim += StartAnimation; | 697 | // client.OnStartAnim += StartAnimation; |
696 | client.OnRegionHandShakeReply += SendLayerData; | 698 | client.OnRegionHandShakeReply += SendLayerData; |
697 | //remoteClient.OnRequestWearables += new GenericCall(this.GetInitialPrims); | 699 | //remoteClient.OnRequestWearables += new GenericCall(this.GetInitialPrims); |
698 | client.OnModifyTerrain += ModifyTerrain; | 700 | client.OnModifyTerrain += ModifyTerrain; |
@@ -742,7 +744,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
742 | client.OnRezScript += RezScript; | 744 | client.OnRezScript += RezScript; |
743 | client.OnRemoveTaskItem += RemoveTaskInventory; | 745 | client.OnRemoveTaskItem += RemoveTaskInventory; |
744 | 746 | ||
745 | // client.OnRequestAvatarProperties += RequestAvatarProperty; | 747 | // client.OnRequestAvatarProperties += RequestAvatarProperty; |
746 | 748 | ||
747 | client.OnGrabObject += ProcessObjectGrab; | 749 | client.OnGrabObject += ProcessObjectGrab; |
748 | 750 | ||
@@ -1071,13 +1073,12 @@ namespace OpenSim.Region.Environment.Scenes | |||
1071 | AgentCircuitData agent = remoteClient.RequestClientInfo(); | 1073 | AgentCircuitData agent = remoteClient.RequestClientInfo(); |
1072 | agent.BaseFolder = LLUUID.Zero; | 1074 | agent.BaseFolder = LLUUID.Zero; |
1073 | agent.InventoryFolder = LLUUID.Zero; | 1075 | agent.InventoryFolder = LLUUID.Zero; |
1074 | // agent.startpos = new LLVector3(128, 128, 70); | 1076 | // agent.startpos = new LLVector3(128, 128, 70); |
1075 | agent.startpos = position; | 1077 | agent.startpos = position; |
1076 | agent.child = true; | 1078 | agent.child = true; |
1077 | commsManager.InterRegion.InformRegionOfChildAgent(regionHandle, agent); | 1079 | commsManager.InterRegion.InformRegionOfChildAgent(regionHandle, agent); |
1078 | commsManager.InterRegion.ExpectAvatarCrossing(regionHandle, remoteClient.AgentId, position, false); | 1080 | commsManager.InterRegion.ExpectAvatarCrossing(regionHandle, remoteClient.AgentId, position, false); |
1079 | 1081 | ||
1080 | //TODO: following line is hard coded to port 9000, really need to change this as soon as possible | ||
1081 | AgentCircuitData circuitdata = remoteClient.RequestClientInfo(); | 1082 | AgentCircuitData circuitdata = remoteClient.RequestClientInfo(); |
1082 | string capsPath = Util.GetCapsURL(remoteClient.AgentId); | 1083 | string capsPath = Util.GetCapsURL(remoteClient.AgentId); |
1083 | remoteClient.SendRegionTeleport(regionHandle, 13, reg.ExternalEndPoint, 4, (1 << 4), capsPath); | 1084 | remoteClient.SendRegionTeleport(regionHandle, 13, reg.ExternalEndPoint, 4, (1 << 4), capsPath); |
@@ -1114,23 +1115,45 @@ namespace OpenSim.Region.Environment.Scenes | |||
1114 | } | 1115 | } |
1115 | } | 1116 | } |
1116 | 1117 | ||
1118 | //following delegate methods will be removed, so use the interface methods (below these) | ||
1117 | public void RegisterAPIMethod(string name, object method) | 1119 | public void RegisterAPIMethod(string name, object method) |
1118 | { | 1120 | { |
1119 | if (!this.APIMethods.ContainsKey(name)) | 1121 | if (!this.ModuleAPIMethods.ContainsKey(name)) |
1120 | { | 1122 | { |
1121 | this.APIMethods.Add(name, method); | 1123 | this.ModuleAPIMethods.Add(name, method); |
1122 | } | 1124 | } |
1123 | } | 1125 | } |
1124 | 1126 | ||
1125 | public object RequestAPIMethod(string name) | 1127 | public object RequestAPIMethod(string name) |
1126 | { | 1128 | { |
1127 | if (this.APIMethods.ContainsKey(name)) | 1129 | if (this.ModuleAPIMethods.ContainsKey(name)) |
1128 | { | 1130 | { |
1129 | return APIMethods[name]; | 1131 | return ModuleAPIMethods[name]; |
1130 | } | 1132 | } |
1131 | return false; | 1133 | return false; |
1132 | } | 1134 | } |
1133 | 1135 | ||
1136 | public void RegisterModuleInterface<M>( M mod) | ||
1137 | { | ||
1138 | //Console.WriteLine("registering module interface " + typeof(M)); | ||
1139 | if (!this.ModuleInterfaces.ContainsKey(typeof(M))) | ||
1140 | { | ||
1141 | ModuleInterfaces.Add(typeof(M), mod); | ||
1142 | } | ||
1143 | } | ||
1144 | |||
1145 | public T RequestModuleInterface<T>() | ||
1146 | { | ||
1147 | if (ModuleInterfaces.ContainsKey(typeof(T))) | ||
1148 | { | ||
1149 | return (T)ModuleInterfaces[typeof(T)]; | ||
1150 | } | ||
1151 | else | ||
1152 | { | ||
1153 | return default(T); | ||
1154 | } | ||
1155 | } | ||
1156 | |||
1134 | public void SetTimePhase(int phase) | 1157 | public void SetTimePhase(int phase) |
1135 | { | 1158 | { |
1136 | m_timePhase = phase; | 1159 | m_timePhase = phase; |
@@ -1205,6 +1228,49 @@ namespace OpenSim.Region.Environment.Scenes | |||
1205 | } | 1228 | } |
1206 | #endregion | 1229 | #endregion |
1207 | 1230 | ||
1231 | public void ProcessConsoleCmd(string command, string[] cmdparams) | ||
1232 | { | ||
1233 | switch (command) | ||
1234 | { | ||
1235 | case "save-xml": | ||
1236 | if (cmdparams.Length > 0) | ||
1237 | { | ||
1238 | SavePrimsToXml(cmdparams[0]); | ||
1239 | } | ||
1240 | else | ||
1241 | { | ||
1242 | SavePrimsToXml("test.xml"); | ||
1243 | } | ||
1244 | break; | ||
1245 | |||
1246 | case "load-xml": | ||
1247 | if (cmdparams.Length > 0) | ||
1248 | { | ||
1249 | LoadPrimsFromXml(cmdparams[0]); | ||
1250 | } | ||
1251 | else | ||
1252 | { | ||
1253 | LoadPrimsFromXml("test.xml"); | ||
1254 | } | ||
1255 | break; | ||
1256 | |||
1257 | case "set-time": | ||
1258 | break; | ||
1259 | |||
1260 | case "backup": | ||
1261 | Backup(); | ||
1262 | break; | ||
1263 | |||
1264 | case "alert": | ||
1265 | HandleAlertCommand(cmdparams); | ||
1266 | break; | ||
1267 | |||
1268 | default: | ||
1269 | MainLog.Instance.Error("Unknown command: " + command); | ||
1270 | break; | ||
1271 | } | ||
1272 | } | ||
1273 | |||
1208 | #region Script Engine | 1274 | #region Script Engine |
1209 | private List<OpenSim.Region.Environment.Scenes.Scripting.ScriptEngineInterface> ScriptEngines = new List<OpenSim.Region.Environment.Scenes.Scripting.ScriptEngineInterface>(); | 1275 | private List<OpenSim.Region.Environment.Scenes.Scripting.ScriptEngineInterface> ScriptEngines = new List<OpenSim.Region.Environment.Scenes.Scripting.ScriptEngineInterface>(); |
1210 | public void AddScriptEngine(OpenSim.Region.Environment.Scenes.Scripting.ScriptEngineInterface ScriptEngine, LogBase m_logger) | 1276 | public void AddScriptEngine(OpenSim.Region.Environment.Scenes.Scripting.ScriptEngineInterface ScriptEngine, LogBase m_logger) |
@@ -1248,5 +1314,22 @@ namespace OpenSim.Region.Environment.Scenes | |||
1248 | } | 1314 | } |
1249 | return null; | 1315 | return null; |
1250 | } | 1316 | } |
1317 | |||
1318 | public SceneObjectPart GetSceneObjectPart(LLUUID fullID) | ||
1319 | { | ||
1320 | bool hasPrim = false; | ||
1321 | foreach (EntityBase ent in Entities.Values) | ||
1322 | { | ||
1323 | if (ent is SceneObjectGroup) | ||
1324 | { | ||
1325 | hasPrim = ((SceneObjectGroup)ent).HasChildPrim(fullID); | ||
1326 | if (hasPrim != false) | ||
1327 | { | ||
1328 | return ((SceneObjectGroup)ent).GetChildPart(fullID); | ||
1329 | } | ||
1330 | } | ||
1331 | } | ||
1332 | return null; | ||
1333 | } | ||
1251 | } | 1334 | } |
1252 | } | 1335 | } |