diff options
author | gareth | 2007-02-27 23:00:49 +0000 |
---|---|---|
committer | gareth | 2007-02-27 23:00:49 +0000 |
commit | 09dd4bd6834861791008e66652826a66724efa0e (patch) | |
tree | ae2b10c3b6ce3fab4c516c6710d4fa0adafedb77 | |
parent | Removed old trunk code (diff) | |
download | opensim-SC-09dd4bd6834861791008e66652826a66724efa0e.zip opensim-SC-09dd4bd6834861791008e66652826a66724efa0e.tar.gz opensim-SC-09dd4bd6834861791008e66652826a66724efa0e.tar.bz2 opensim-SC-09dd4bd6834861791008e66652826a66724efa0e.tar.xz |
Brought in code from branches/gareth
Diffstat (limited to '')
38 files changed, 5350 insertions, 0 deletions
@@ -0,0 +1,22 @@ | |||
1 | Some basic instructions on how to use OpenSim/OGS for hackers and geeks | ||
2 | ------------------------------------------------- | ||
3 | |||
4 | 1.First, either get in touch with a grid owner or install the OGS server components on your own server. | ||
5 | 2.Ask the grid owner to send you keys over a secure channel (encrypted email, paper mail, phone, encrypted IM/IRC). If you and the grid owner are not concerned about security (YOU SHOULD BE!!!) then this exchange can be done over any communications channel. | ||
6 | 3.Edit src/Config.cs to reflect your changes or if the grid owner has provided you with a template/custom database, drop opensim.yap into bin/ | ||
7 | 4.If you edited src/Config.cs then run "nant build" at the root directory | ||
8 | 5.With mono on Linux/BSD cd into bin/ and run "mono OpenSim.exe", On win32 just run OpenSim.exe | ||
9 | 5.Login to the grid with a standard viewer and find your sim (note that at certain times the SVN version does not allow logins) | ||
10 | |||
11 | Some basic instructions on how to use OpenSim/OGS for the laymen | ||
12 | ------------------------------------------------- | ||
13 | |||
14 | 1.Ensure you either have mono or the .NET framework runtime installed | ||
15 | 2.Find a grid owner | ||
16 | 3.Ask the grid owner to send you connection instructions | ||
17 | 4.Either install the grid owner's opensim.yap by placing it into the same directory as OpenSim.exe or follow their instructions | ||
18 | 5.On Linux/BSD, go to a command prompt and type: | ||
19 | cd /path/to/where/you/downloaded/ | ||
20 | cd bin/ | ||
21 | mono OpenSim.exe | ||
22 | 6.Login to the grid in the normal way | ||
diff --git a/bin/Axiom.MathLib.dll b/bin/Axiom.MathLib.dll new file mode 100644 index 0000000..21ce3a8 --- /dev/null +++ b/bin/Axiom.MathLib.dll | |||
Binary files differ | |||
diff --git a/bin/Db4objects.Db4o.dll b/bin/Db4objects.Db4o.dll new file mode 100755 index 0000000..be976a1 --- /dev/null +++ b/bin/Db4objects.Db4o.dll | |||
Binary files differ | |||
diff --git a/bin/libsecondlife.dll b/bin/libsecondlife.dll new file mode 100755 index 0000000..90189a2 --- /dev/null +++ b/bin/libsecondlife.dll | |||
Binary files differ | |||
diff --git a/bin/log4net.dll b/bin/log4net.dll new file mode 100644 index 0000000..ffc57e1 --- /dev/null +++ b/bin/log4net.dll | |||
Binary files differ | |||
diff --git a/genvers.sh b/genvers.sh new file mode 100755 index 0000000..3da91d7 --- /dev/null +++ b/genvers.sh | |||
@@ -0,0 +1,9 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | MAJOR=0 | ||
4 | MINOR=1 | ||
5 | BUILD=`date +%s` | ||
6 | REVISION=`svnversion | sed s/:// | sed s/M//` | ||
7 | REALREVISION=`svnversion` | ||
8 | cat src/VersionInfo.cs.template | sed s/@@VERSION/"$MAJOR.$MINOR, Build $BUILD, Revision $REALREVISION"/g >src/VersionInfo.cs | ||
9 | echo -n $MAJOR.$MINOR.*.$REVISION >VERSION | ||
diff --git a/opensim.build b/opensim.build new file mode 100644 index 0000000..d91e748 --- /dev/null +++ b/opensim.build | |||
@@ -0,0 +1,62 @@ | |||
1 | <?xml version="1.0"?> | ||
2 | <project name="OpenSim" default="build" basedir="."> | ||
3 | <description>First nant buildfile for OpenSim</description> | ||
4 | <property name="debug" value="true" overwrite="false" /> | ||
5 | <target name="clean" description="remove all generated files"> | ||
6 | <delete file="bin/OpenSim.exe" failonerror="false" /> | ||
7 | <delete file="bin/OpenSim.pdb" failonerror="false" /> | ||
8 | </target> | ||
9 | |||
10 | <target name="svnupdate" description="updates to latest SVN"> | ||
11 | <exec program="svn"> | ||
12 | <arg value="update" /> | ||
13 | </exec> | ||
14 | </target> | ||
15 | |||
16 | <target name="upgrade" description="updates from SVN and then builds" depends="clean,svnupdate,build"> | ||
17 | |||
18 | </target> | ||
19 | |||
20 | <target name="build" description="compiles the source code"> | ||
21 | |||
22 | <exec program="genvers.sh" /> | ||
23 | <loadfile file="VERSION" property="svnver"/> | ||
24 | |||
25 | <asminfo output="src/AssemblyInfo.cs" language="CSharp"> | ||
26 | <imports> | ||
27 | <import namespace="System" /> | ||
28 | <import namespace="System.Reflection" /> | ||
29 | <import namespace="System.Runtime.InteropServices" /> | ||
30 | </imports> | ||
31 | <attributes> | ||
32 | <attribute type="ComVisibleAttribute" value="false" /> | ||
33 | <attribute type="CLSCompliantAttribute" value="false" /> | ||
34 | <attribute type="AssemblyVersionAttribute" value="${svnver}" /> | ||
35 | <attribute type="AssemblyTitleAttribute" value="opensim" /> | ||
36 | <attribute type="AssemblyDescriptionAttribute" value="The C# implementation of the simulator portion of OGS" /> | ||
37 | <attribute type="AssemblyCopyrightAttribute" value="Copyright © OGS development team 2007"/> | ||
38 | </attributes> | ||
39 | </asminfo> | ||
40 | <csc target="exe" output="bin/OpenSim.exe" debug="${debug}" verbose="true"> | ||
41 | <references basedir="bin/" failonempty="true"> | ||
42 | <include name="System" /> | ||
43 | <include name="System.Data" /> | ||
44 | <include name="System.Xml" /> | ||
45 | <include name="Axiom.MathLib.dll" /> | ||
46 | <include name="libsecondlife.dll" /> | ||
47 | <include name="log4net.dll" /> | ||
48 | <include name="Db4objects.Db4o.dll" /> | ||
49 | </references> | ||
50 | <sources basedir="src/"> | ||
51 | <include name="AssemblyInfo.cs" /> | ||
52 | <include name="Config.cs" /> | ||
53 | <include name="VersionInfo.cs" /> | ||
54 | <include name="Util.cs" /> | ||
55 | <include name="types/*.cs" /> | ||
56 | <include name="world/*.cs" /> | ||
57 | <include name="OpenSimClient.cs" /> | ||
58 | <include name="Main.cs" /> | ||
59 | </sources> | ||
60 | </csc> | ||
61 | </target> | ||
62 | </project> | ||
diff --git a/src/Agent_Manager.cs b/src/Agent_Manager.cs new file mode 100644 index 0000000..195065e --- /dev/null +++ b/src/Agent_Manager.cs | |||
@@ -0,0 +1,879 @@ | |||
1 | /* | ||
2 | Copyright (c) OpenSim project, http://osgrid.org/ | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions are met: | ||
6 | * * Redistributions of source code must retain the above copyright | ||
7 | * notice, this list of conditions and the following disclaimer. | ||
8 | * * Redistributions in binary form must reproduce the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer in the | ||
10 | * documentation and/or other materials provided with the distribution. | ||
11 | * * Neither the name of the <organization> nor the | ||
12 | * names of its contributors may be used to endorse or promote products | ||
13 | * derived from this software without specific prior written permission. | ||
14 | * | ||
15 | * THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY | ||
16 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
18 | * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY | ||
19 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
22 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
25 | */ | ||
26 | |||
27 | using System; | ||
28 | using System.Collections.Generic; | ||
29 | using libsecondlife; | ||
30 | using libsecondlife.Packets; | ||
31 | using libsecondlife.AssetSystem; | ||
32 | using System.IO; | ||
33 | using Axiom.MathLib; | ||
34 | |||
35 | namespace OpenSim | ||
36 | { | ||
37 | /// <summary> | ||
38 | /// Description of Agent_Manager. | ||
39 | /// </summary> | ||
40 | public class AgentManager | ||
41 | { | ||
42 | public Dictionary<libsecondlife.LLUUID,AvatarData> AgentList; | ||
43 | public static Dictionary<string, LLUUID> AnimsLLUUID = new Dictionary<string, LLUUID>(); | ||
44 | public static Dictionary<LLUUID, string> AnimsNames = new Dictionary<LLUUID, string>(); | ||
45 | |||
46 | private uint _localNumber=0; | ||
47 | private Server _server; | ||
48 | public PrimManager Prim_Manager; | ||
49 | public AssetManagement assetManager; | ||
50 | |||
51 | private libsecondlife.Packets.RegionHandshakePacket RegionPacket; | ||
52 | private System.Text.Encoding _enc = System.Text.Encoding.ASCII; | ||
53 | private libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock AvatarTemplate; | ||
54 | |||
55 | /// <summary> | ||
56 | /// | ||
57 | /// </summary> | ||
58 | /// <param name="serve"></param> | ||
59 | public AgentManager(Server server) | ||
60 | { | ||
61 | AgentList = new Dictionary<libsecondlife.LLUUID,AvatarData>(); | ||
62 | _server = server; | ||
63 | this.initialise(); | ||
64 | } | ||
65 | |||
66 | /// <summary> | ||
67 | /// | ||
68 | /// </summary> | ||
69 | /// <param name="id"></param> | ||
70 | /// <returns></returns> | ||
71 | public AvatarData GetAgent(LLUUID id) | ||
72 | { | ||
73 | if(!this.AgentList.ContainsKey(id)) | ||
74 | { | ||
75 | return null; | ||
76 | } | ||
77 | else | ||
78 | { | ||
79 | AvatarData avatar = this.AgentList[id]; | ||
80 | return avatar; | ||
81 | } | ||
82 | } | ||
83 | /// <summary> | ||
84 | /// | ||
85 | /// </summary> | ||
86 | /// <param name="agent"></param> | ||
87 | public void AddAgent(AvatarData agent) | ||
88 | { | ||
89 | this.AgentList.Add(agent.FullID, agent); | ||
90 | } | ||
91 | /// <summary> | ||
92 | /// | ||
93 | /// </summary> | ||
94 | /// <param name="User_info"></param> | ||
95 | /// <param name="first"></param> | ||
96 | /// <param name="last"></param> | ||
97 | /// <returns></returns> | ||
98 | /// | ||
99 | |||
100 | /// <summary> | ||
101 | /// | ||
102 | /// </summary> | ||
103 | /// <param name="User_info"></param> | ||
104 | /// <param name="first"></param> | ||
105 | /// <param name="last"></param> | ||
106 | /// <returns></returns> | ||
107 | public bool NewAgent(UserAgentInfo userInfo, string first, string last, LLUUID baseFolder, LLUUID inventoryFolder) | ||
108 | { | ||
109 | AvatarData agent = new AvatarData(); | ||
110 | agent.FullID = userInfo.AgentID; | ||
111 | agent.NetInfo = userInfo; | ||
112 | agent.NetInfo.first_name =first; | ||
113 | agent.NetInfo.last_name = last; | ||
114 | agent.Position = new LLVector3(100, 100, 22); | ||
115 | agent.BaseFolder = baseFolder; | ||
116 | agent.InventoryFolder = inventoryFolder; | ||
117 | agent.AnimID = AnimsLLUUID["ANIM_AGENT_STAND"]; | ||
118 | agent.AnimSequenceID = 1; | ||
119 | |||
120 | this.AgentList.Add(agent.FullID, agent); | ||
121 | |||
122 | //Create new Wearable Assets and place in Inventory | ||
123 | this.assetManager.CreateNewInventorySet(ref agent, userInfo); | ||
124 | |||
125 | return(true); | ||
126 | } | ||
127 | |||
128 | /// <summary> | ||
129 | /// | ||
130 | /// </summary> | ||
131 | /// <param name="UserInfo"></param> | ||
132 | public void RemoveAgent(UserAgentInfo userInfo) | ||
133 | { | ||
134 | this.AgentList.Remove(userInfo.AgentID); | ||
135 | |||
136 | //tell other clients to delete this avatar | ||
137 | } | ||
138 | |||
139 | /// <summary> | ||
140 | /// | ||
141 | /// </summary> | ||
142 | /// <param name="User_info"></param> | ||
143 | public void AgentJoin(UserAgentInfo userInfo) | ||
144 | { | ||
145 | //send region data | ||
146 | _server.SendPacket(RegionPacket,true, userInfo); | ||
147 | |||
148 | //inform client of join comlete | ||
149 | libsecondlife.Packets.AgentMovementCompletePacket mov = new AgentMovementCompletePacket(); | ||
150 | mov.AgentData.SessionID = userInfo.SessionID; | ||
151 | mov.AgentData.AgentID = userInfo.AgentID; | ||
152 | mov.Data.RegionHandle = Globals.Instance.RegionHandle; | ||
153 | mov.Data.Timestamp = 1169838966; | ||
154 | mov.Data.Position = new LLVector3(100f, 100f, 22f); | ||
155 | mov.Data.LookAt = new LLVector3(0.99f, 0.042f, 0); | ||
156 | _server.SendPacket(mov, true, userInfo); | ||
157 | |||
158 | } | ||
159 | |||
160 | /// <summary> | ||
161 | /// | ||
162 | /// </summary> | ||
163 | public void UpdatePositions() | ||
164 | { | ||
165 | //update positions | ||
166 | foreach (KeyValuePair<libsecondlife.LLUUID, AvatarData> kp in this.AgentList) | ||
167 | { | ||
168 | |||
169 | kp.Value.Position.X += (kp.Value.Velocity.X * 0.2f); | ||
170 | kp.Value.Position.Y += (kp.Value.Velocity.Y * 0.2f); | ||
171 | kp.Value.Position.Z += (kp.Value.Velocity.Z * 0.2f); | ||
172 | } | ||
173 | |||
174 | } | ||
175 | |||
176 | public void UpdateAnim(UserAgentInfo userInfo, LLUUID AnimID, int AnimSeq) | ||
177 | { | ||
178 | AgentList[userInfo.AgentID].AnimID = AnimID; | ||
179 | AgentList[userInfo.AgentID].AnimSequenceID = AnimSeq; | ||
180 | UpdateAnim(userInfo); | ||
181 | } | ||
182 | |||
183 | public void UpdateAnim(UserAgentInfo userInfo) | ||
184 | { | ||
185 | Console.WriteLine("Agent_Manager.cs: UpdateAnim(UserAgentInfo userInfo): called for Agent " + userInfo.AgentID.ToString()); | ||
186 | AvatarAnimationPacket ani = new AvatarAnimationPacket(); | ||
187 | ani.AnimationSourceList = new AvatarAnimationPacket.AnimationSourceListBlock[1]; | ||
188 | ani.AnimationSourceList[0] = new AvatarAnimationPacket.AnimationSourceListBlock(); | ||
189 | ani.AnimationSourceList[0].ObjectID = new LLUUID("00000000000000000000000000000000"); | ||
190 | ani.Sender = new AvatarAnimationPacket.SenderBlock(); | ||
191 | ani.Sender.ID = userInfo.AgentID; | ||
192 | ani.AnimationList = new AvatarAnimationPacket.AnimationListBlock[1]; | ||
193 | ani.AnimationList[0] = new AvatarAnimationPacket.AnimationListBlock(); | ||
194 | ani.AnimationList[0].AnimID = AgentList[userInfo.AgentID].AnimID; | ||
195 | ani.AnimationList[0].AnimSequenceID = AgentList[userInfo.AgentID].AnimSequenceID; | ||
196 | Console.WriteLine("Agenct_Manager.cs: UpdateAnim(UserAgentInfo userInfo): Sent Animation to client - " + AgentManager.AnimsNames[ani.AnimationList[0].AnimID]); | ||
197 | _server.SendPacket(ani, true, userInfo); | ||
198 | |||
199 | // update other agents as appropiate | ||
200 | Axiom.MathLib.Sphere BoundingSphere; | ||
201 | foreach (KeyValuePair<libsecondlife.LLUUID, AvatarData> kp in this.AgentList) | ||
202 | { | ||
203 | if(kp.Key!=userInfo.AgentID) { | ||
204 | // Make a bounding sphere for the other avatar | ||
205 | BoundingSphere = new Sphere(new Vector3(kp.Value.Position.X,kp.Value.Position.Y,kp.Value.Position.Z), kp.Value.far); | ||
206 | |||
207 | // If it intersects with our position, send an update packet | ||
208 | if(BoundingSphere.Intersects(new Vector3(this.AgentList[userInfo.AgentID].Position.X,this.AgentList[userInfo.AgentID].Position.Y,this.AgentList[userInfo.AgentID].Position.Z))) { | ||
209 | ani.AnimationSourceList[0].ObjectID = userInfo.AgentID; | ||
210 | ani.Sender = new AvatarAnimationPacket.SenderBlock(); | ||
211 | ani.Sender.ID = userInfo.AgentID; | ||
212 | ani.AnimationList = new AvatarAnimationPacket.AnimationListBlock[1]; | ||
213 | ani.AnimationList[0] = new AvatarAnimationPacket.AnimationListBlock(); | ||
214 | ani.AnimationList[0].AnimID = AgentList[userInfo.AgentID].AnimID; | ||
215 | ani.AnimationList[0].AnimSequenceID = AgentList[userInfo.AgentID].AnimSequenceID; | ||
216 | _server.SendPacket(ani, true, kp.Value.NetInfo); | ||
217 | } | ||
218 | } | ||
219 | } | ||
220 | } | ||
221 | /// <summary> | ||
222 | /// | ||
223 | /// </summary> | ||
224 | private void initialise() | ||
225 | { | ||
226 | //Region data | ||
227 | RegionPacket = new RegionHandshakePacket(); | ||
228 | RegionPacket.RegionInfo.BillableFactor = 0; | ||
229 | RegionPacket.RegionInfo.IsEstateManager = false; | ||
230 | RegionPacket.RegionInfo.TerrainHeightRange00 = 60; | ||
231 | RegionPacket.RegionInfo.TerrainHeightRange01 = 60; | ||
232 | RegionPacket.RegionInfo.TerrainHeightRange10 = 60; | ||
233 | RegionPacket.RegionInfo.TerrainHeightRange11 = 60; | ||
234 | RegionPacket.RegionInfo.TerrainStartHeight00 = 20; | ||
235 | RegionPacket.RegionInfo.TerrainStartHeight01 = 20; | ||
236 | RegionPacket.RegionInfo.TerrainStartHeight10 = 20; | ||
237 | RegionPacket.RegionInfo.TerrainStartHeight11 = 20; | ||
238 | RegionPacket.RegionInfo.SimAccess = 13; | ||
239 | RegionPacket.RegionInfo.WaterHeight = 5; | ||
240 | RegionPacket.RegionInfo.RegionFlags = 72458694; | ||
241 | RegionPacket.RegionInfo.SimName = _enc.GetBytes( Globals.Instance.RegionName); | ||
242 | RegionPacket.RegionInfo.SimOwner = new LLUUID("00000000-0000-0000-0000-000000000000"); | ||
243 | RegionPacket.RegionInfo.TerrainBase0 = new LLUUID("b8d3965a-ad78-bf43-699b-bff8eca6c975"); | ||
244 | RegionPacket.RegionInfo.TerrainBase1 = new LLUUID("abb783e6-3e93-26c0-248a-247666855da3"); | ||
245 | RegionPacket.RegionInfo.TerrainBase2 = new LLUUID("179cdabd-398a-9b6b-1391-4dc333ba321f"); | ||
246 | RegionPacket.RegionInfo.TerrainBase3 = new LLUUID("beb169c7-11ea-fff2-efe5-0f24dc881df2"); | ||
247 | RegionPacket.RegionInfo.TerrainDetail0 = new LLUUID("00000000-0000-0000-0000-000000000000"); | ||
248 | RegionPacket.RegionInfo.TerrainDetail1 = new LLUUID("00000000-0000-0000-0000-000000000000"); | ||
249 | RegionPacket.RegionInfo.TerrainDetail2 = new LLUUID("00000000-0000-0000-0000-000000000000"); | ||
250 | RegionPacket.RegionInfo.TerrainDetail3 = new LLUUID("00000000-0000-0000-0000-000000000000"); | ||
251 | RegionPacket.RegionInfo.CacheID = new LLUUID("545ec0a5-5751-1026-8a0b-216e38a7ab37"); | ||
252 | |||
253 | //this.SetupTemplate("objectupate168.dat"); | ||
254 | this.LoadAnims(); | ||
255 | } | ||
256 | |||
257 | /// <summary> | ||
258 | /// | ||
259 | /// </summary> | ||
260 | /// <param name="name"></param> | ||
261 | private void SetupTemplate(string name) | ||
262 | { | ||
263 | |||
264 | int i = 0; | ||
265 | FileInfo fInfo = new FileInfo(name); | ||
266 | long numBytes = fInfo.Length; | ||
267 | FileStream fStream = new FileStream(name, FileMode.Open, FileAccess.Read); | ||
268 | BinaryReader br = new BinaryReader(fStream); | ||
269 | byte [] data1 = br.ReadBytes((int)numBytes); | ||
270 | br.Close(); | ||
271 | fStream.Close(); | ||
272 | |||
273 | libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock objdata = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock(data1, ref i); | ||
274 | |||
275 | System.Text.Encoding enc = System.Text.Encoding.ASCII; | ||
276 | libsecondlife.LLVector3 pos = new LLVector3(objdata.ObjectData, 16); | ||
277 | pos.X = 100f; | ||
278 | objdata.ID = 8880000; | ||
279 | objdata.NameValue = enc.GetBytes("FirstName STRING RW SV Test \nLastName STRING RW SV User \0"); | ||
280 | libsecondlife.LLVector3 pos2 = new LLVector3(13.981f,100.0f,20.0f); | ||
281 | //objdata.FullID=user.AgentID; | ||
282 | byte[] pb = pos.GetBytes(); | ||
283 | Array.Copy(pb, 0, objdata.ObjectData, 16, pb.Length); | ||
284 | |||
285 | AvatarTemplate = objdata; | ||
286 | |||
287 | } | ||
288 | |||
289 | private void LoadAnims() | ||
290 | { | ||
291 | AnimsLLUUID.Add("ANIM_AGENT_AFRAID", new LLUUID("6b61c8e8-4747-0d75-12d7-e49ff207a4ca")); | ||
292 | AnimsLLUUID.Add("ANIM_AGENT_AIM_BAZOOKA_R", new LLUUID("b5b4a67d-0aee-30d2-72cd-77b333e932ef")); | ||
293 | AnimsLLUUID.Add("ANIM_AGENT_AIM_BOW_L", new LLUUID("46bb4359-de38-4ed8-6a22-f1f52fe8f506")); | ||
294 | AnimsLLUUID.Add("ANIM_AGENT_AIM_HANDGUN_R", new LLUUID("3147d815-6338-b932-f011-16b56d9ac18b")); | ||
295 | AnimsLLUUID.Add("ANIM_AGENT_AIM_RIFLE_R", new LLUUID("ea633413-8006-180a-c3ba-96dd1d756720")); | ||
296 | AnimsLLUUID.Add("ANIM_AGENT_ANGRY", new LLUUID("5747a48e-073e-c331-f6f3-7c2149613d3e")); | ||
297 | AnimsLLUUID.Add("ANIM_AGENT_AWAY", new LLUUID("fd037134-85d4-f241-72c6-4f42164fedee")); | ||
298 | AnimsLLUUID.Add("ANIM_AGENT_BACKFLIP", new LLUUID("c4ca6188-9127-4f31-0158-23c4e2f93304")); | ||
299 | AnimsLLUUID.Add("ANIM_AGENT_BELLY_LAUGH", new LLUUID("18b3a4b5-b463-bd48-e4b6-71eaac76c515")); | ||
300 | AnimsLLUUID.Add("ANIM_AGENT_BLOW_KISS", new LLUUID("db84829b-462c-ee83-1e27-9bbee66bd624")); | ||
301 | AnimsLLUUID.Add("ANIM_AGENT_BORED", new LLUUID("b906c4ba-703b-1940-32a3-0c7f7d791510")); | ||
302 | AnimsLLUUID.Add("ANIM_AGENT_BOW", new LLUUID("82e99230-c906-1403-4d9c-3889dd98daba")); | ||
303 | AnimsLLUUID.Add("ANIM_AGENT_BRUSH", new LLUUID("349a3801-54f9-bf2c-3bd0-1ac89772af01")); | ||
304 | AnimsLLUUID.Add("ANIM_AGENT_BUSY", new LLUUID("efcf670c-2d18-8128-973a-034ebc806b67")); | ||
305 | AnimsLLUUID.Add("ANIM_AGENT_CLAP", new LLUUID("9b0c1c4e-8ac7-7969-1494-28c874c4f668")); | ||
306 | AnimsLLUUID.Add("ANIM_AGENT_COURTBOW", new LLUUID("9ba1c942-08be-e43a-fb29-16ad440efc50")); | ||
307 | AnimsLLUUID.Add("ANIM_AGENT_CROUCH", new LLUUID("201f3fdf-cb1f-dbec-201f-7333e328ae7c")); | ||
308 | AnimsLLUUID.Add("ANIM_AGENT_CROUCHWALK", new LLUUID("47f5f6fb-22e5-ae44-f871-73aaaf4a6022")); | ||
309 | AnimsLLUUID.Add("ANIM_AGENT_CRY", new LLUUID("92624d3e-1068-f1aa-a5ec-8244585193ed")); | ||
310 | AnimsLLUUID.Add("ANIM_AGENT_CUSTOMIZE", new LLUUID("038fcec9-5ebd-8a8e-0e2e-6e71a0a1ac53")); | ||
311 | AnimsLLUUID.Add("ANIM_AGENT_CUSTOMIZE_DONE", new LLUUID("6883a61a-b27b-5914-a61e-dda118a9ee2c")); | ||
312 | AnimsLLUUID.Add("ANIM_AGENT_DANCE1", new LLUUID("b68a3d7c-de9e-fc87-eec8-543d787e5b0d")); | ||
313 | AnimsLLUUID.Add("ANIM_AGENT_DANCE2", new LLUUID("928cae18-e31d-76fd-9cc9-2f55160ff818")); | ||
314 | AnimsLLUUID.Add("ANIM_AGENT_DANCE3", new LLUUID("30047778-10ea-1af7-6881-4db7a3a5a114")); | ||
315 | AnimsLLUUID.Add("ANIM_AGENT_DANCE4", new LLUUID("951469f4-c7b2-c818-9dee-ad7eea8c30b7")); | ||
316 | AnimsLLUUID.Add("ANIM_AGENT_DANCE5", new LLUUID("4bd69a1d-1114-a0b4-625f-84e0a5237155")); | ||
317 | AnimsLLUUID.Add("ANIM_AGENT_DANCE6", new LLUUID("cd28b69b-9c95-bb78-3f94-8d605ff1bb12")); | ||
318 | AnimsLLUUID.Add("ANIM_AGENT_DANCE7", new LLUUID("a54d8ee2-28bb-80a9-7f0c-7afbbe24a5d6")); | ||
319 | AnimsLLUUID.Add("ANIM_AGENT_DANCE8", new LLUUID("b0dc417c-1f11-af36-2e80-7e7489fa7cdc")); | ||
320 | AnimsLLUUID.Add("ANIM_AGENT_DEAD", new LLUUID("57abaae6-1d17-7b1b-5f98-6d11a6411276")); | ||
321 | AnimsLLUUID.Add("ANIM_AGENT_DRINK", new LLUUID("0f86e355-dd31-a61c-fdb0-3a96b9aad05f")); | ||
322 | AnimsLLUUID.Add("ANIM_AGENT_EMBARRASSED", new LLUUID("514af488-9051-044a-b3fc-d4dbf76377c6")); | ||
323 | AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_AFRAID", new LLUUID("aa2df84d-cf8f-7218-527b-424a52de766e")); | ||
324 | AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_ANGER", new LLUUID("1a03b575-9634-b62a-5767-3a679e81f4de")); | ||
325 | AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_BORED", new LLUUID("214aa6c1-ba6a-4578-f27c-ce7688f61d0d")); | ||
326 | AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_CRY", new LLUUID("d535471b-85bf-3b4d-a542-93bea4f59d33")); | ||
327 | AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_DISDAIN", new LLUUID("d4416ff1-09d3-300f-4183-1b68a19b9fc1")); | ||
328 | AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_EMBARRASSED", new LLUUID("0b8c8211-d78c-33e8-fa28-c51a9594e424")); | ||
329 | AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_FROWN", new LLUUID("fee3df48-fa3d-1015-1e26-a205810e3001")); | ||
330 | AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_KISS", new LLUUID("1e8d90cc-a84e-e135-884c-7c82c8b03a14")); | ||
331 | AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_LAUGH", new LLUUID("62570842-0950-96f8-341c-809e65110823")); | ||
332 | AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_OPEN_MOUTH", new LLUUID("d63bc1f9-fc81-9625-a0c6-007176d82eb7")); | ||
333 | AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_REPULSED", new LLUUID("f76cda94-41d4-a229-2872-e0296e58afe1")); | ||
334 | AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_SAD", new LLUUID("eb6ebfb2-a4b3-a19c-d388-4dd5c03823f7")); | ||
335 | AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_SHRUG", new LLUUID("a351b1bc-cc94-aac2-7bea-a7e6ebad15ef")); | ||
336 | AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_SMILE", new LLUUID("b7c7c833-e3d3-c4e3-9fc0-131237446312")); | ||
337 | AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_SURPRISE", new LLUUID("728646d9-cc79-08b2-32d6-937f0a835c24")); | ||
338 | AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_TONGUE_OUT", new LLUUID("835965c6-7f2f-bda2-5deb-2478737f91bf")); | ||
339 | AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_TOOTHSMILE", new LLUUID("b92ec1a5-e7ce-a76b-2b05-bcdb9311417e")); | ||
340 | AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_WINK", new LLUUID("da020525-4d94-59d6-23d7-81fdebf33148")); | ||
341 | AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_WORRY", new LLUUID("9c05e5c7-6f07-6ca4-ed5a-b230390c3950")); | ||
342 | AnimsLLUUID.Add("ANIM_AGENT_FALLDOWN", new LLUUID("666307d9-a860-572d-6fd4-c3ab8865c094")); | ||
343 | AnimsLLUUID.Add("ANIM_AGENT_FEMALE_WALK", new LLUUID("f5fc7433-043d-e819-8298-f519a119b688")); | ||
344 | AnimsLLUUID.Add("ANIM_AGENT_FINGER_WAG", new LLUUID("c1bc7f36-3ba0-d844-f93c-93be945d644f")); | ||
345 | AnimsLLUUID.Add("ANIM_AGENT_FIST_PUMP", new LLUUID("7db00ccd-f380-f3ee-439d-61968ec69c8a")); | ||
346 | AnimsLLUUID.Add("ANIM_AGENT_FLY", new LLUUID("aec4610c-757f-bc4e-c092-c6e9caf18daf")); | ||
347 | AnimsLLUUID.Add("ANIM_AGENT_FLYSLOW", new LLUUID("2b5a38b2-5e00-3a97-a495-4c826bc443e6")); | ||
348 | AnimsLLUUID.Add("ANIM_AGENT_HELLO", new LLUUID("9b29cd61-c45b-5689-ded2-91756b8d76a9")); | ||
349 | AnimsLLUUID.Add("ANIM_AGENT_HOLD_BAZOOKA_R", new LLUUID("ef62d355-c815-4816-2474-b1acc21094a6")); | ||
350 | AnimsLLUUID.Add("ANIM_AGENT_HOLD_BOW_L", new LLUUID("8b102617-bcba-037b-86c1-b76219f90c88")); | ||
351 | AnimsLLUUID.Add("ANIM_AGENT_HOLD_HANDGUN_R", new LLUUID("efdc1727-8b8a-c800-4077-975fc27ee2f2")); | ||
352 | AnimsLLUUID.Add("ANIM_AGENT_HOLD_RIFLE_R", new LLUUID("3d94bad0-c55b-7dcc-8763-033c59405d33")); | ||
353 | AnimsLLUUID.Add("ANIM_AGENT_HOLD_THROW_R", new LLUUID("7570c7b5-1f22-56dd-56ef-a9168241bbb6")); | ||
354 | AnimsLLUUID.Add("ANIM_AGENT_HOVER", new LLUUID("4ae8016b-31b9-03bb-c401-b1ea941db41d")); | ||
355 | AnimsLLUUID.Add("ANIM_AGENT_HOVER_DOWN", new LLUUID("20f063ea-8306-2562-0b07-5c853b37b31e")); | ||
356 | AnimsLLUUID.Add("ANIM_AGENT_HOVER_UP", new LLUUID("62c5de58-cb33-5743-3d07-9e4cd4352864")); | ||
357 | AnimsLLUUID.Add("ANIM_AGENT_IMPATIENT", new LLUUID("5ea3991f-c293-392e-6860-91dfa01278a3")); | ||
358 | AnimsLLUUID.Add("ANIM_AGENT_JUMP", new LLUUID("2305bd75-1ca9-b03b-1faa-b176b8a8c49e")); | ||
359 | AnimsLLUUID.Add("ANIM_AGENT_JUMP_FOR_JOY", new LLUUID("709ea28e-1573-c023-8bf8-520c8bc637fa")); | ||
360 | AnimsLLUUID.Add("ANIM_AGENT_KISS_MY_BUTT", new LLUUID("19999406-3a3a-d58c-a2ac-d72e555dcf51")); | ||
361 | AnimsLLUUID.Add("ANIM_AGENT_LAND", new LLUUID("7a17b059-12b2-41b1-570a-186368b6aa6f")); | ||
362 | AnimsLLUUID.Add("ANIM_AGENT_LAUGH_SHORT", new LLUUID("ca5b3f14-3194-7a2b-c894-aa699b718d1f")); | ||
363 | AnimsLLUUID.Add("ANIM_AGENT_MEDIUM_LAND", new LLUUID("f4f00d6e-b9fe-9292-f4cb-0ae06ea58d57")); | ||
364 | AnimsLLUUID.Add("ANIM_AGENT_MOTORCYCLE_SIT", new LLUUID("08464f78-3a8e-2944-cba5-0c94aff3af29")); | ||
365 | AnimsLLUUID.Add("ANIM_AGENT_MUSCLE_BEACH", new LLUUID("315c3a41-a5f3-0ba4-27da-f893f769e69b")); | ||
366 | AnimsLLUUID.Add("ANIM_AGENT_NO", new LLUUID("5a977ed9-7f72-44e9-4c4c-6e913df8ae74")); | ||
367 | AnimsLLUUID.Add("ANIM_AGENT_NO_UNHAPPY", new LLUUID("d83fa0e5-97ed-7eb2-e798-7bd006215cb4")); | ||
368 | AnimsLLUUID.Add("ANIM_AGENT_NYAH_NYAH", new LLUUID("f061723d-0a18-754f-66ee-29a44795a32f")); | ||
369 | AnimsLLUUID.Add("ANIM_AGENT_ONETWO_PUNCH", new LLUUID("eefc79be-daae-a239-8c04-890f5d23654a")); | ||
370 | AnimsLLUUID.Add("ANIM_AGENT_PEACE", new LLUUID("b312b10e-65ab-a0a4-8b3c-1326ea8e3ed9")); | ||
371 | AnimsLLUUID.Add("ANIM_AGENT_POINT_ME", new LLUUID("17c024cc-eef2-f6a0-3527-9869876d7752")); | ||
372 | AnimsLLUUID.Add("ANIM_AGENT_POINT_YOU", new LLUUID("ec952cca-61ef-aa3b-2789-4d1344f016de")); | ||
373 | AnimsLLUUID.Add("ANIM_AGENT_PRE_JUMP", new LLUUID("7a4e87fe-de39-6fcb-6223-024b00893244")); | ||
374 | AnimsLLUUID.Add("ANIM_AGENT_PUNCH_LEFT", new LLUUID("f3300ad9-3462-1d07-2044-0fef80062da0")); | ||
375 | AnimsLLUUID.Add("ANIM_AGENT_PUNCH_RIGHT", new LLUUID("c8e42d32-7310-6906-c903-cab5d4a34656")); | ||
376 | AnimsLLUUID.Add("ANIM_AGENT_REPULSED", new LLUUID("36f81a92-f076-5893-dc4b-7c3795e487cf")); | ||
377 | AnimsLLUUID.Add("ANIM_AGENT_ROUNDHOUSE_KICK", new LLUUID("49aea43b-5ac3-8a44-b595-96100af0beda")); | ||
378 | AnimsLLUUID.Add("ANIM_AGENT_RPS_COUNTDOWN", new LLUUID("35db4f7e-28c2-6679-cea9-3ee108f7fc7f")); | ||
379 | AnimsLLUUID.Add("ANIM_AGENT_RPS_PAPER", new LLUUID("0836b67f-7f7b-f37b-c00a-460dc1521f5a")); | ||
380 | AnimsLLUUID.Add("ANIM_AGENT_RPS_ROCK", new LLUUID("42dd95d5-0bc6-6392-f650-777304946c0f")); | ||
381 | AnimsLLUUID.Add("ANIM_AGENT_RPS_SCISSORS", new LLUUID("16803a9f-5140-e042-4d7b-d28ba247c325")); | ||
382 | AnimsLLUUID.Add("ANIM_AGENT_RUN", new LLUUID("05ddbff8-aaa9-92a1-2b74-8fe77a29b445")); | ||
383 | AnimsLLUUID.Add("ANIM_AGENT_SAD", new LLUUID("0eb702e2-cc5a-9a88-56a5-661a55c0676a")); | ||
384 | AnimsLLUUID.Add("ANIM_AGENT_SALUTE", new LLUUID("cd7668a6-7011-d7e2-ead8-fc69eff1a104")); | ||
385 | AnimsLLUUID.Add("ANIM_AGENT_SHOOT_BOW_L", new LLUUID("e04d450d-fdb5-0432-fd68-818aaf5935f8")); | ||
386 | AnimsLLUUID.Add("ANIM_AGENT_SHOUT", new LLUUID("6bd01860-4ebd-127a-bb3d-d1427e8e0c42")); | ||
387 | AnimsLLUUID.Add("ANIM_AGENT_SHRUG", new LLUUID("70ea714f-3a97-d742-1b01-590a8fcd1db5")); | ||
388 | AnimsLLUUID.Add("ANIM_AGENT_SIT", new LLUUID("1a5fe8ac-a804-8a5d-7cbd-56bd83184568")); | ||
389 | AnimsLLUUID.Add("ANIM_AGENT_SIT_FEMALE", new LLUUID("b1709c8d-ecd3-54a1-4f28-d55ac0840782")); | ||
390 | AnimsLLUUID.Add("ANIM_AGENT_SIT_GENERIC", new LLUUID("245f3c54-f1c0-bf2e-811f-46d8eeb386e7")); | ||
391 | AnimsLLUUID.Add("ANIM_AGENT_SIT_GROUND", new LLUUID("1c7600d6-661f-b87b-efe2-d7421eb93c86")); | ||
392 | AnimsLLUUID.Add("ANIM_AGENT_SIT_GROUND_CONSTRAINED", new LLUUID("1a2bd58e-87ff-0df8-0b4c-53e047b0bb6e")); | ||
393 | AnimsLLUUID.Add("ANIM_AGENT_SIT_TO_STAND", new LLUUID("a8dee56f-2eae-9e7a-05a2-6fb92b97e21e")); | ||
394 | AnimsLLUUID.Add("ANIM_AGENT_SLEEP", new LLUUID("f2bed5f9-9d44-39af-b0cd-257b2a17fe40")); | ||
395 | AnimsLLUUID.Add("ANIM_AGENT_SMOKE_IDLE", new LLUUID("d2f2ee58-8ad1-06c9-d8d3-3827ba31567a")); | ||
396 | AnimsLLUUID.Add("ANIM_AGENT_SMOKE_INHALE", new LLUUID("6802d553-49da-0778-9f85-1599a2266526")); | ||
397 | AnimsLLUUID.Add("ANIM_AGENT_SMOKE_THROW_DOWN", new LLUUID("0a9fb970-8b44-9114-d3a9-bf69cfe804d6")); | ||
398 | AnimsLLUUID.Add("ANIM_AGENT_SNAPSHOT", new LLUUID("eae8905b-271a-99e2-4c0e-31106afd100c")); | ||
399 | AnimsLLUUID.Add("ANIM_AGENT_STAND", new LLUUID("2408fe9e-df1d-1d7d-f4ff-1384fa7b350f")); | ||
400 | AnimsLLUUID.Add("ANIM_AGENT_STANDUP", new LLUUID("3da1d753-028a-5446-24f3-9c9b856d9422")); | ||
401 | AnimsLLUUID.Add("ANIM_AGENT_STAND_1", new LLUUID("15468e00-3400-bb66-cecc-646d7c14458e")); | ||
402 | AnimsLLUUID.Add("ANIM_AGENT_STAND_2", new LLUUID("370f3a20-6ca6-9971-848c-9a01bc42ae3c")); | ||
403 | AnimsLLUUID.Add("ANIM_AGENT_STAND_3", new LLUUID("42b46214-4b44-79ae-deb8-0df61424ff4b")); | ||
404 | AnimsLLUUID.Add("ANIM_AGENT_STAND_4", new LLUUID("f22fed8b-a5ed-2c93-64d5-bdd8b93c889f")); | ||
405 | AnimsLLUUID.Add("ANIM_AGENT_STRETCH", new LLUUID("80700431-74ec-a008-14f8-77575e73693f")); | ||
406 | AnimsLLUUID.Add("ANIM_AGENT_STRIDE", new LLUUID("1cb562b0-ba21-2202-efb3-30f82cdf9595")); | ||
407 | AnimsLLUUID.Add("ANIM_AGENT_SURF", new LLUUID("41426836-7437-7e89-025d-0aa4d10f1d69")); | ||
408 | AnimsLLUUID.Add("ANIM_AGENT_SURPRISE", new LLUUID("313b9881-4302-73c0-c7d0-0e7a36b6c224")); | ||
409 | AnimsLLUUID.Add("ANIM_AGENT_SWORD_STRIKE", new LLUUID("85428680-6bf9-3e64-b489-6f81087c24bd")); | ||
410 | AnimsLLUUID.Add("ANIM_AGENT_TALK", new LLUUID("5c682a95-6da4-a463-0bf6-0f5b7be129d1")); | ||
411 | AnimsLLUUID.Add("ANIM_AGENT_TANTRUM", new LLUUID("11000694-3f41-adc2-606b-eee1d66f3724")); | ||
412 | AnimsLLUUID.Add("ANIM_AGENT_THROW_R", new LLUUID("aa134404-7dac-7aca-2cba-435f9db875ca")); | ||
413 | AnimsLLUUID.Add("ANIM_AGENT_TRYON_SHIRT", new LLUUID("83ff59fe-2346-f236-9009-4e3608af64c1")); | ||
414 | AnimsLLUUID.Add("ANIM_AGENT_TURNLEFT", new LLUUID("56e0ba0d-4a9f-7f27-6117-32f2ebbf6135")); | ||
415 | AnimsLLUUID.Add("ANIM_AGENT_TURNRIGHT", new LLUUID("2d6daa51-3192-6794-8e2e-a15f8338ec30")); | ||
416 | AnimsLLUUID.Add("ANIM_AGENT_TYPE", new LLUUID("c541c47f-e0c0-058b-ad1a-d6ae3a4584d9")); | ||
417 | AnimsLLUUID.Add("ANIM_AGENT_WALK", new LLUUID("6ed24bd8-91aa-4b12-ccc7-c97c857ab4e0")); | ||
418 | AnimsLLUUID.Add("ANIM_AGENT_WHISPER", new LLUUID("7693f268-06c7-ea71-fa21-2b30d6533f8f")); | ||
419 | AnimsLLUUID.Add("ANIM_AGENT_WHISTLE", new LLUUID("b1ed7982-c68e-a982-7561-52a88a5298c0")); | ||
420 | AnimsLLUUID.Add("ANIM_AGENT_WINK", new LLUUID("869ecdad-a44b-671e-3266-56aef2e3ac2e")); | ||
421 | AnimsLLUUID.Add("ANIM_AGENT_WINK_HOLLYWOOD", new LLUUID("c0c4030f-c02b-49de-24ba-2331f43fe41c")); | ||
422 | AnimsLLUUID.Add("ANIM_AGENT_WORRY", new LLUUID("9f496bd2-589a-709f-16cc-69bf7df1d36c")); | ||
423 | AnimsLLUUID.Add("ANIM_AGENT_YES", new LLUUID("15dd911d-be82-2856-26db-27659b142875")); | ||
424 | AnimsLLUUID.Add("ANIM_AGENT_YES_HAPPY", new LLUUID("b8c8b2a3-9008-1771-3bfc-90924955ab2d")); | ||
425 | AnimsLLUUID.Add("ANIM_AGENT_YOGA_FLOAT", new LLUUID("42ecd00b-9947-a97c-400a-bbc9174c7aeb")); | ||
426 | |||
427 | |||
428 | foreach (KeyValuePair<string, LLUUID> kp in AgentManager.AnimsLLUUID) | ||
429 | { | ||
430 | AnimsNames.Add(kp.Value, kp.Key); | ||
431 | } | ||
432 | } | ||
433 | |||
434 | /// <summary> | ||
435 | /// | ||
436 | /// </summary> | ||
437 | /// <param name="User_info"></param> | ||
438 | public void SendInitialData(UserAgentInfo userInfo) | ||
439 | { | ||
440 | |||
441 | //shouldn't have to read all this in from disk for every new client | ||
442 | string data_path = System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, @"layer_data"); | ||
443 | |||
444 | //send layerdata | ||
445 | LayerDataPacket layerpack = new LayerDataPacket(); | ||
446 | layerpack.LayerID.Type = 76; | ||
447 | this.SendLayerData(userInfo,ref layerpack, System.IO.Path.Combine(data_path, @"layerdata0.dat")); | ||
448 | |||
449 | LayerDataPacket layerpack1 = new LayerDataPacket(); | ||
450 | layerpack1.LayerID.Type = 76; | ||
451 | this.SendLayerData(userInfo, ref layerpack, System.IO.Path.Combine(data_path, @"layerdata1.dat")); | ||
452 | |||
453 | LayerDataPacket layerpack2 = new LayerDataPacket(); | ||
454 | layerpack2.LayerID.Type = 56; | ||
455 | this.SendLayerData(userInfo, ref layerpack, System.IO.Path.Combine(data_path, @"layerdata2.dat")); | ||
456 | |||
457 | LayerDataPacket layerpack3 = new LayerDataPacket(); | ||
458 | layerpack3.LayerID.Type = 55; | ||
459 | this.SendLayerData(userInfo, ref layerpack, System.IO.Path.Combine(data_path, @"layerdata3.dat")); | ||
460 | |||
461 | LayerDataPacket layerpack4 = new LayerDataPacket(); | ||
462 | layerpack4.LayerID.Type = 56; | ||
463 | this.SendLayerData(userInfo, ref layerpack, System.IO.Path.Combine(data_path, @"layerdata4.dat")); | ||
464 | |||
465 | LayerDataPacket layerpack5 = new LayerDataPacket(); | ||
466 | layerpack5.LayerID.Type = 55; | ||
467 | this.SendLayerData(userInfo, ref layerpack, System.IO.Path.Combine(data_path, @"layerdata5.dat")); | ||
468 | |||
469 | //send intial set of captured prims data? | ||
470 | this.Prim_Manager.ReadPrimDatabase( "objectdatabase.ini", userInfo); | ||
471 | |||
472 | //send prims that have been created by users | ||
473 | //prim_man.send_existing_prims(User_info); | ||
474 | |||
475 | //send update about clients avatar | ||
476 | this.SendInitialAvatarPosition(userInfo); | ||
477 | |||
478 | //send updates about all other users | ||
479 | foreach (KeyValuePair<libsecondlife.LLUUID, AvatarData> kp in this.AgentList) | ||
480 | { | ||
481 | if(kp.Value.NetInfo.AgentID != userInfo.AgentID) | ||
482 | { | ||
483 | this.SendOtherAvatarPosition(userInfo, kp.Value); | ||
484 | } | ||
485 | } | ||
486 | } | ||
487 | |||
488 | /// <summary> | ||
489 | /// | ||
490 | /// </summary> | ||
491 | /// <param name="User_info"></param> | ||
492 | public void SendInitialAvatarPosition(UserAgentInfo userInfo) | ||
493 | { | ||
494 | //send a objectupdate packet with information about the clients avatar | ||
495 | ObjectUpdatePacket objupdate = new ObjectUpdatePacket(); | ||
496 | objupdate.RegionData.RegionHandle = Globals.Instance.RegionHandle; | ||
497 | objupdate.RegionData.TimeDilation = 64096; | ||
498 | objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1]; | ||
499 | |||
500 | objupdate.ObjectData[0] = AvatarTemplate; | ||
501 | //give this avatar object a local id and assign the user a name | ||
502 | objupdate.ObjectData[0].ID = 8880000 + this._localNumber; | ||
503 | userInfo.localID = objupdate.ObjectData[0].ID; | ||
504 | //User_info.name="Test"+this.local_numer+" User"; | ||
505 | this.GetAgent(userInfo.AgentID).Started = true; | ||
506 | objupdate.ObjectData[0].FullID = userInfo.AgentID; | ||
507 | objupdate.ObjectData[0].NameValue = _enc.GetBytes("FirstName STRING RW SV " + userInfo.first_name + "\nLastName STRING RW SV " + userInfo.last_name + " \0"); | ||
508 | userInfo.name = "FirstName STRING RW SV " + userInfo.first_name + "\nLastName STRING RW SV " + userInfo.last_name + " \0"; | ||
509 | |||
510 | libsecondlife.LLVector3 pos2 = new LLVector3(100f, 100.0f, 22.0f); | ||
511 | |||
512 | byte[] pb = pos2.GetBytes(); | ||
513 | |||
514 | Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length); | ||
515 | this._localNumber++; | ||
516 | |||
517 | _server.SendPacket(objupdate, true, userInfo); | ||
518 | |||
519 | //send this info to other existing clients | ||
520 | foreach (KeyValuePair<libsecondlife.LLUUID, AvatarData> kp in this.AgentList) | ||
521 | { | ||
522 | if(kp.Value.NetInfo.AgentID != userInfo.AgentID) | ||
523 | { | ||
524 | _server.SendPacket(objupdate, true, kp.Value.NetInfo); | ||
525 | this.SendOtherAppearance(kp.Value.NetInfo, objupdate.ObjectData[0].FullID); | ||
526 | } | ||
527 | } | ||
528 | |||
529 | } | ||
530 | |||
531 | /// <summary> | ||
532 | /// | ||
533 | /// </summary> | ||
534 | /// <param name="user"></param> | ||
535 | public void SendIntialAvatarAppearance(UserAgentInfo userInfo) | ||
536 | { | ||
537 | AvatarData Agent = this.AgentList[userInfo.AgentID]; | ||
538 | AgentWearablesUpdatePacket aw = new AgentWearablesUpdatePacket(); | ||
539 | aw.AgentData.AgentID = userInfo.AgentID; | ||
540 | aw.AgentData.SerialNum = 0; | ||
541 | aw.AgentData.SessionID = userInfo.SessionID; | ||
542 | |||
543 | aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[13]; | ||
544 | AgentWearablesUpdatePacket.WearableDataBlock awb = null; | ||
545 | awb = new AgentWearablesUpdatePacket.WearableDataBlock(); | ||
546 | awb.WearableType = (byte)0; | ||
547 | awb.AssetID = Agent.Wearables[0].AssetID; | ||
548 | awb.ItemID = Agent.Wearables[0].ItemID; | ||
549 | aw.WearableData[0] = awb; | ||
550 | |||
551 | awb = new AgentWearablesUpdatePacket.WearableDataBlock(); | ||
552 | awb.WearableType =(byte)1; | ||
553 | awb.AssetID = Agent.Wearables[1].AssetID; | ||
554 | awb.ItemID = Agent.Wearables[1].ItemID; | ||
555 | aw.WearableData[1] = awb; | ||
556 | |||
557 | for(int i=2; i<13; i++) | ||
558 | { | ||
559 | awb = new AgentWearablesUpdatePacket.WearableDataBlock(); | ||
560 | awb.WearableType = (byte)i; | ||
561 | awb.AssetID = new LLUUID("00000000-0000-0000-0000-000000000000"); | ||
562 | awb.ItemID = new LLUUID("00000000-0000-0000-0000-000000000000"); | ||
563 | aw.WearableData[i] = awb; | ||
564 | } | ||
565 | |||
566 | _server.SendPacket(aw, true, userInfo); | ||
567 | } | ||
568 | |||
569 | /// <summary> | ||
570 | /// | ||
571 | /// </summary> | ||
572 | /// <param name="user"></param> | ||
573 | /// <param name="id"></param> | ||
574 | public void SendOtherAppearance(UserAgentInfo userInfo, LLUUID id) | ||
575 | { | ||
576 | AvatarAppearancePacket avp = new AvatarAppearancePacket(); | ||
577 | |||
578 | |||
579 | avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218]; | ||
580 | //avp.ObjectData.TextureEntry=this.avatar_template.TextureEntry;// br.ReadBytes((int)numBytes); | ||
581 | |||
582 | FileInfo fInfo = new FileInfo("Avatar_texture3.dat"); | ||
583 | long numBytes = fInfo.Length; | ||
584 | FileStream fStream = new FileStream("Avatar_texture3.dat", FileMode.Open, FileAccess.Read); | ||
585 | BinaryReader br = new BinaryReader(fStream); | ||
586 | avp.ObjectData.TextureEntry = br.ReadBytes((int)numBytes); | ||
587 | br.Close(); | ||
588 | fStream.Close(); | ||
589 | |||
590 | AvatarAppearancePacket.VisualParamBlock avblock = null; | ||
591 | for(int i = 0; i < 218; i++) | ||
592 | { | ||
593 | avblock = new AvatarAppearancePacket.VisualParamBlock(); | ||
594 | avblock.ParamValue = (byte)100; | ||
595 | avp.VisualParam[i] = avblock; | ||
596 | } | ||
597 | |||
598 | avp.Sender.IsTrial = false; | ||
599 | avp.Sender.ID = id; | ||
600 | _server.SendPacket(avp, true, userInfo); | ||
601 | |||
602 | } | ||
603 | |||
604 | /// <summary> | ||
605 | /// | ||
606 | /// </summary> | ||
607 | /// <param name="User_info"></param> | ||
608 | /// <param name="avd"></param> | ||
609 | public void SendOtherAvatarPosition(UserAgentInfo userInfo, AvatarData avatar) | ||
610 | { | ||
611 | //send a objectupdate packet with information about the clients avatar | ||
612 | ObjectUpdatePacket objupdate = new ObjectUpdatePacket(); | ||
613 | objupdate.RegionData.RegionHandle = Globals.Instance.RegionHandle; | ||
614 | objupdate.RegionData.TimeDilation = 64500; | ||
615 | objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1]; | ||
616 | |||
617 | objupdate.ObjectData[0] = AvatarTemplate; | ||
618 | //give this avatar object a local id and assign the user a name | ||
619 | objupdate.ObjectData[0].ID = avatar.NetInfo.localID; | ||
620 | objupdate.ObjectData[0].FullID = avatar.NetInfo.AgentID; | ||
621 | objupdate.ObjectData[0].NameValue = _enc.GetBytes(avatar.NetInfo.name); | ||
622 | libsecondlife.LLVector3 pos2 = new LLVector3(avatar.Position.X, avatar.Position.Y, avatar.Position.Z); | ||
623 | |||
624 | byte[] pb = pos2.GetBytes(); | ||
625 | Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length); | ||
626 | this._localNumber++; | ||
627 | |||
628 | _server.SendPacket(objupdate, true, userInfo); | ||
629 | this.SendOtherAppearance(userInfo, avatar.NetInfo.AgentID); | ||
630 | |||
631 | } | ||
632 | |||
633 | /// <summary> | ||
634 | /// | ||
635 | /// </summary> | ||
636 | /// <param name="User_info"></param> | ||
637 | /// <param name="line"></param> | ||
638 | public void SendChatMessage(UserAgentInfo userInfo, string line) | ||
639 | { | ||
640 | libsecondlife.Packets.ChatFromSimulatorPacket reply = new ChatFromSimulatorPacket(); | ||
641 | reply.ChatData.Audible = 1; | ||
642 | reply.ChatData.Message = _enc.GetBytes(line); | ||
643 | reply.ChatData.ChatType = 1; | ||
644 | reply.ChatData.SourceType = 1; | ||
645 | reply.ChatData.Position = new LLVector3(120, 100, 21); //should set to actual position | ||
646 | reply.ChatData.FromName = _enc.GetBytes(userInfo.first_name + " " + userInfo.last_name + "\0"); | ||
647 | reply.ChatData.OwnerID = userInfo.AgentID; | ||
648 | reply.ChatData.SourceID = userInfo.AgentID; | ||
649 | //echo to sender | ||
650 | _server.SendPacket(reply, true, userInfo); | ||
651 | |||
652 | //send to all users | ||
653 | foreach (KeyValuePair<libsecondlife.LLUUID, AvatarData> kp in this.AgentList) | ||
654 | { | ||
655 | if(kp.Value.NetInfo.AgentID!=userInfo.AgentID) | ||
656 | { | ||
657 | _server.SendPacket(reply, true, kp.Value.NetInfo); | ||
658 | } | ||
659 | } | ||
660 | } | ||
661 | |||
662 | /// <summary> | ||
663 | /// | ||
664 | /// </summary> | ||
665 | /// <param name="user"></param> | ||
666 | /// <param name="stop"></param> | ||
667 | /// <param name="x"></param> | ||
668 | /// <param name="y"></param> | ||
669 | /// <param name="z"></param> | ||
670 | /// <param name="av_id"></param> | ||
671 | /// <param name="body"></param> | ||
672 | public void SendMoveCommand(UserAgentInfo userInfo, bool stop, float x, float y, float z, uint avatarID, libsecondlife.LLQuaternion body) | ||
673 | { | ||
674 | Console.WriteLine("sending move"); | ||
675 | uint ID = userInfo.localID; | ||
676 | byte[] bytes = new byte[60]; | ||
677 | int i=0; | ||
678 | |||
679 | ImprovedTerseObjectUpdatePacket im = new ImprovedTerseObjectUpdatePacket(); | ||
680 | im.RegionData.RegionHandle = Globals.Instance.RegionHandle;; | ||
681 | im.RegionData.TimeDilation = 64096; | ||
682 | |||
683 | im.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1]; | ||
684 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock dat = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock(); | ||
685 | |||
686 | im.ObjectData[0] = dat; | ||
687 | |||
688 | dat.TextureEntry = AvatarTemplate.TextureEntry; | ||
689 | libsecondlife.LLVector3 pos2 = new LLVector3(x, y, z); | ||
690 | |||
691 | bytes[i++] = (byte)(ID % 256); | ||
692 | bytes[i++] = (byte)((ID >> 8) % 256); | ||
693 | bytes[i++] = (byte)((ID >> 16) % 256); | ||
694 | bytes[i++] = (byte)((ID >> 24) % 256); | ||
695 | |||
696 | bytes[i++] = 0; | ||
697 | bytes[i++] = 1; | ||
698 | |||
699 | i += 14; | ||
700 | bytes[i++] = 128; | ||
701 | bytes[i++] = 63; | ||
702 | byte[] pb = pos2.GetBytes(); | ||
703 | |||
704 | Array.Copy(pb, 0, bytes, i, pb.Length); | ||
705 | i += 12; | ||
706 | ushort ac = 32767; | ||
707 | Axiom.MathLib.Vector3 v3 = new Axiom.MathLib.Vector3(1, 0, 0); | ||
708 | Axiom.MathLib.Quaternion q = new Axiom.MathLib.Quaternion(body.W, body.X, body.Y, body.Z); | ||
709 | Axiom.MathLib.Vector3 direc = q * v3; | ||
710 | direc.Normalize(); | ||
711 | |||
712 | direc = direc * (0.03f); | ||
713 | direc.x += 1; | ||
714 | direc.y += 1; | ||
715 | direc.z += 1; | ||
716 | ushort dx, dy, dz; | ||
717 | dx = (ushort)(32768 * direc.x); | ||
718 | dy = (ushort)(32768 * direc.y); | ||
719 | dz = (ushort)(32768 * direc.z); | ||
720 | |||
721 | //vel | ||
722 | if(!stop) | ||
723 | { | ||
724 | bytes[i++] = (byte)(dx % 256); | ||
725 | bytes[i++] = (byte)((dx >> 8) % 256); | ||
726 | |||
727 | bytes[i++] = (byte)(dy % 256); | ||
728 | bytes[i++] = (byte)((dy >> 8) % 256); | ||
729 | |||
730 | bytes[i++] = (byte)(dz % 256); | ||
731 | bytes[i++] = (byte)((dz >> 8) % 256); | ||
732 | } | ||
733 | else | ||
734 | { | ||
735 | bytes[i++] = (byte)(ac % 256); | ||
736 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
737 | |||
738 | bytes[i++] = (byte)(ac % 256); | ||
739 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
740 | |||
741 | bytes[i++] = (byte)(ac % 256); | ||
742 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
743 | } | ||
744 | //accel | ||
745 | bytes[i++] = (byte)(ac % 256); | ||
746 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
747 | |||
748 | bytes[i++] = (byte)(ac % 256); | ||
749 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
750 | |||
751 | bytes[i++] = (byte)(ac % 256); | ||
752 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
753 | |||
754 | //rot | ||
755 | bytes[i++] = (byte)(ac % 256); | ||
756 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
757 | |||
758 | bytes[i++] = (byte)(ac % 256); | ||
759 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
760 | |||
761 | bytes[i++] = (byte)(ac % 256); | ||
762 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
763 | |||
764 | bytes[i++] = (byte)(ac % 256); | ||
765 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
766 | |||
767 | //rotation vel | ||
768 | bytes[i++] = (byte)(ac % 256); | ||
769 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
770 | |||
771 | bytes[i++] = (byte)(ac % 256); | ||
772 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
773 | |||
774 | bytes[i++] = (byte)(ac % 256); | ||
775 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
776 | |||
777 | dat.Data=bytes; | ||
778 | |||
779 | _server.SendPacket(im, true, userInfo); | ||
780 | |||
781 | //should send to all users. | ||
782 | foreach (KeyValuePair<libsecondlife.LLUUID, AvatarData> kp in this.AgentList) | ||
783 | { | ||
784 | if(kp.Value.NetInfo.AgentID != userInfo.AgentID) | ||
785 | { | ||
786 | _server.SendPacket(im, true, kp.Value.NetInfo); | ||
787 | } | ||
788 | } | ||
789 | |||
790 | //check if we should be standing or walking | ||
791 | if (this.AgentList[userInfo.AgentID].Walk) | ||
792 | { | ||
793 | this.AgentList[userInfo.AgentID].AnimID = AgentManager.AnimsLLUUID["ANIM_AGENT_WALK"]; | ||
794 | this.AgentList[userInfo.AgentID].AnimSequenceID = 1; | ||
795 | this.UpdateAnim(userInfo); | ||
796 | } | ||
797 | else | ||
798 | { | ||
799 | this.AgentList[userInfo.AgentID].AnimID = AgentManager.AnimsLLUUID["ANIM_AGENT_STAND"]; | ||
800 | this.AgentList[userInfo.AgentID].AnimSequenceID = 1; | ||
801 | this.UpdateAnim(userInfo); | ||
802 | } | ||
803 | } | ||
804 | |||
805 | /// <summary> | ||
806 | /// | ||
807 | /// </summary> | ||
808 | /// <param name="User_info"></param> | ||
809 | /// <param name="lay"></param> | ||
810 | /// <param name="name"></param> | ||
811 | public void SendLayerData(UserAgentInfo userInfo, ref LayerDataPacket layer, string name) | ||
812 | { | ||
813 | FileInfo fInfo = new FileInfo(name); | ||
814 | long numBytes = fInfo.Length; | ||
815 | FileStream fStream = new FileStream(name, FileMode.Open, FileAccess.Read); | ||
816 | BinaryReader br = new BinaryReader(fStream); | ||
817 | byte [] data1 = br.ReadBytes((int)numBytes); | ||
818 | br.Close(); | ||
819 | fStream.Close(); | ||
820 | layer.LayerData.Data = data1; | ||
821 | _server.SendPacket(layer, true, userInfo); | ||
822 | |||
823 | } | ||
824 | } | ||
825 | |||
826 | public class AvatarData | ||
827 | { | ||
828 | public UserAgentInfo NetInfo; | ||
829 | public LLUUID FullID; | ||
830 | public LLVector3 Position; | ||
831 | public LLVector3 Velocity = new LLVector3(0,0,0); | ||
832 | //public LLQuaternion Rotation; | ||
833 | public bool Walk = false; | ||
834 | public bool Started = false; | ||
835 | //public TextureEntry TextureEntry; | ||
836 | public AvatarWearable[] Wearables; | ||
837 | public LLUUID InventoryFolder; | ||
838 | public LLUUID BaseFolder; | ||
839 | public LLUUID AnimID; | ||
840 | public int AnimSequenceID; | ||
841 | public float far; | ||
842 | public libsecondlife.LLVector3 CameraAtAxis; | ||
843 | public libsecondlife.LLVector3 CameraCenter; | ||
844 | public libsecondlife.LLVector3 CameraLeftAxis; | ||
845 | public libsecondlife.LLVector3 CameraUpAxis; | ||
846 | |||
847 | public AvatarData() | ||
848 | { | ||
849 | Wearables=new AvatarWearable[2]; //should be 13 | ||
850 | for(int i = 0; i < 2; i++) | ||
851 | { | ||
852 | Wearables[i] = new AvatarWearable(); | ||
853 | } | ||
854 | } | ||
855 | } | ||
856 | |||
857 | public class AvatarWearable | ||
858 | { | ||
859 | public LLUUID AssetID; | ||
860 | public LLUUID ItemID; | ||
861 | |||
862 | public AvatarWearable() | ||
863 | { | ||
864 | |||
865 | } | ||
866 | } | ||
867 | /* | ||
868 | public class AvatarParams | ||
869 | { | ||
870 | public byte[] Params; | ||
871 | |||
872 | public AvatarParams() | ||
873 | { | ||
874 | |||
875 | } | ||
876 | |||
877 | } | ||
878 | */ | ||
879 | } | ||
diff --git a/src/AssetManagement.cs b/src/AssetManagement.cs new file mode 100644 index 0000000..f919476 --- /dev/null +++ b/src/AssetManagement.cs | |||
@@ -0,0 +1,455 @@ | |||
1 | /* | ||
2 | * | ||
3 | Copyright (c) OpenSim project, http://osgrid.org/ | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the <organization> nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | * | ||
27 | */ | ||
28 | |||
29 | using System; | ||
30 | using System.Net; | ||
31 | using System.Collections.Generic; | ||
32 | using libsecondlife; | ||
33 | using System.Collections; | ||
34 | using libsecondlife.Packets; | ||
35 | using libsecondlife.AssetSystem; | ||
36 | using System.IO; | ||
37 | |||
38 | namespace OpenSim | ||
39 | { | ||
40 | /// <summary> | ||
41 | /// Asset and Image management | ||
42 | /// </summary> | ||
43 | public class AssetManagement | ||
44 | { | ||
45 | public Dictionary<libsecondlife.LLUUID,AssetInfo> Assets; | ||
46 | public Dictionary<libsecondlife.LLUUID,TextureImage> Textures; | ||
47 | |||
48 | public ArrayList AssetRequests = new ArrayList(); //should change to a generic | ||
49 | public ArrayList TextureRequests = new ArrayList(); | ||
50 | //public ArrayList uploads=new ArrayList(); | ||
51 | private Server _server; | ||
52 | private InventoryManager _inventoryManager; | ||
53 | private System.Text.Encoding _enc = System.Text.Encoding.ASCII; | ||
54 | |||
55 | /// <summary> | ||
56 | /// | ||
57 | /// </summary> | ||
58 | /// <param name="_server"></param> | ||
59 | public AssetManagement(Server server, InventoryManager inventoryManager) | ||
60 | { | ||
61 | this._server = server; | ||
62 | this._inventoryManager = inventoryManager; | ||
63 | Textures = new Dictionary<libsecondlife.LLUUID,TextureImage> (); | ||
64 | Assets = new Dictionary<libsecondlife.LLUUID,AssetInfo> (); | ||
65 | this.initialise(); | ||
66 | } | ||
67 | |||
68 | /// <summary> | ||
69 | /// | ||
70 | /// </summary> | ||
71 | private void initialise() | ||
72 | { | ||
73 | //Shape and skin base assets | ||
74 | AssetInfo Asset = new AssetInfo(); | ||
75 | Asset.filename = "base_shape.dat"; | ||
76 | Asset.FullID = new LLUUID("66c41e39-38f9-f75a-024e-585989bfab73"); | ||
77 | this.LoadAsset(Asset, false); | ||
78 | this.Assets.Add(Asset.FullID, Asset); | ||
79 | |||
80 | Asset = new AssetInfo(); | ||
81 | Asset.filename = "base_skin.dat"; | ||
82 | Asset.FullID = new LLUUID("e0ee49b5a4184df8d3c9a65361fe7f49"); | ||
83 | this.LoadAsset(Asset, false); | ||
84 | this.Assets.Add(Asset.FullID, Asset); | ||
85 | |||
86 | //our test images | ||
87 | //Change these filenames to images you want to use. | ||
88 | TextureImage Image = new TextureImage(); | ||
89 | Image.filename = "testpic2.jp2"; | ||
90 | Image.FullID = new LLUUID("00000000-0000-0000-5005-000000000005"); | ||
91 | Image.Name = "test Texture"; | ||
92 | this.LoadAsset(Image, true); | ||
93 | this.Textures.Add(Image.FullID, Image); | ||
94 | |||
95 | Image = new TextureImage(); | ||
96 | Image.filename = "map_base.jp2"; | ||
97 | Image.FullID = new LLUUID("00000000-0000-0000-7007-000000000006"); | ||
98 | this.LoadAsset(Image, true); | ||
99 | this.Textures.Add(Image.FullID, Image); | ||
100 | |||
101 | Image = new TextureImage(); | ||
102 | Image.filename = "map1.jp2"; | ||
103 | Image.FullID = new LLUUID("00000000-0000-0000-7009-000000000008"); | ||
104 | this.LoadAsset(Image, true); | ||
105 | this.Textures.Add(Image.FullID, Image); | ||
106 | } | ||
107 | |||
108 | /// <summary> | ||
109 | /// | ||
110 | /// </summary> | ||
111 | /// <param name="UserInfo"></param> | ||
112 | /// <param name="AssetID"></param> | ||
113 | /// <param name="TransferRequest"></param> | ||
114 | #region AssetRegion | ||
115 | |||
116 | public void AddAssetRequest(UserAgentInfo userInfo, LLUUID assetID, TransferRequestPacket transferRequest) | ||
117 | { | ||
118 | |||
119 | if(!this.Assets.ContainsKey(assetID)) | ||
120 | { | ||
121 | //not found asset | ||
122 | return; | ||
123 | } | ||
124 | AssetInfo info = this.Assets[assetID]; | ||
125 | //for now as it will be only skin or shape request just send back the asset | ||
126 | TransferInfoPacket Transfer = new TransferInfoPacket(); | ||
127 | Transfer.TransferInfo.ChannelType = 2; | ||
128 | Transfer.TransferInfo.Status = 0; | ||
129 | Transfer.TransferInfo.TargetType = 0; | ||
130 | Transfer.TransferInfo.Params = transferRequest.TransferInfo.Params; | ||
131 | Transfer.TransferInfo.Size = info.data.Length; | ||
132 | Transfer.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID; | ||
133 | |||
134 | _server.SendPacket(Transfer, true, userInfo); | ||
135 | |||
136 | TransferPacketPacket TransferPacket = new TransferPacketPacket(); | ||
137 | TransferPacket.TransferData.Packet = 0; | ||
138 | TransferPacket.TransferData.ChannelType = 2; | ||
139 | TransferPacket.TransferData.TransferID=transferRequest.TransferInfo.TransferID; | ||
140 | if(info.data.Length>1000) //but needs to be less than 2000 at the moment | ||
141 | { | ||
142 | byte[] chunk = new byte[1000]; | ||
143 | Array.Copy(info.data,chunk,1000); | ||
144 | TransferPacket.TransferData.Data = chunk; | ||
145 | TransferPacket.TransferData.Status = 0; | ||
146 | _server.SendPacket(TransferPacket,true,userInfo); | ||
147 | |||
148 | TransferPacket = new TransferPacketPacket(); | ||
149 | TransferPacket.TransferData.Packet = 1; | ||
150 | TransferPacket.TransferData.ChannelType = 2; | ||
151 | TransferPacket.TransferData.TransferID = transferRequest.TransferInfo.TransferID; | ||
152 | byte[] chunk1 = new byte[(info.data.Length-1000)]; | ||
153 | Array.Copy(info.data, 1000, chunk1, 0, chunk1.Length); | ||
154 | TransferPacket.TransferData.Data = chunk1; | ||
155 | TransferPacket.TransferData.Status = 1; | ||
156 | _server.SendPacket(TransferPacket, true, userInfo); | ||
157 | } | ||
158 | else | ||
159 | { | ||
160 | TransferPacket.TransferData.Status = 1; //last packet? so set to 1 | ||
161 | TransferPacket.TransferData.Data = info.data; | ||
162 | _server.SendPacket(TransferPacket, true, userInfo); | ||
163 | } | ||
164 | |||
165 | } | ||
166 | |||
167 | public void CreateNewInventorySet(ref AvatarData Avata,UserAgentInfo UserInfo) | ||
168 | { | ||
169 | //Create Folders | ||
170 | LLUUID BaseFolder = Avata.BaseFolder; | ||
171 | _inventoryManager.CreateNewFolder(UserInfo, Avata.InventoryFolder); | ||
172 | _inventoryManager.CreateNewFolder(UserInfo, BaseFolder); | ||
173 | |||
174 | //Give a copy of default shape | ||
175 | AssetInfo Base = this.Assets[new LLUUID("66c41e39-38f9-f75a-024e-585989bfab73")]; | ||
176 | AssetInfo Shape = this.CloneAsset(UserInfo.AgentID, Base); | ||
177 | |||
178 | Shape.filename = ""; | ||
179 | Shape.Name = "Default Shape"; | ||
180 | Shape.Description = "Default Shape"; | ||
181 | Shape.InvType = 18; | ||
182 | Shape.Type=13; | ||
183 | //Shape.Type = libsecondlife.AssetSystem.Asset.ASSET_TYPE_WEARABLE_BODY; | ||
184 | |||
185 | byte[] Agentid = _enc.GetBytes(UserInfo.AgentID.ToStringHyphenated()); | ||
186 | Array.Copy(Agentid, 0, Shape.data, 294, Agentid.Length); | ||
187 | this.Assets.Add(Shape.FullID, Shape); | ||
188 | |||
189 | Avata.Wearables[0].ItemID = _inventoryManager.AddToInventory(UserInfo, BaseFolder, Shape); | ||
190 | Avata.Wearables[0].AssetID = Shape.FullID; | ||
191 | |||
192 | //Give copy of default skin | ||
193 | Base = this.Assets[new LLUUID("e0ee49b5a4184df8d3c9a65361fe7f49")]; | ||
194 | AssetInfo Skin=this.CloneAsset(UserInfo.AgentID, Base); | ||
195 | |||
196 | Skin.filename = ""; | ||
197 | Skin.Name = "Default Skin"; | ||
198 | Skin.Description = "Default Skin"; | ||
199 | Skin.InvType = 18; | ||
200 | Skin.Type=13; | ||
201 | //Skin.Type = libsecondlife.AssetSystem.Asset.ASSET_TYPE_WEARABLE_BODY; | ||
202 | |||
203 | Array.Copy(Agentid,0,Skin.data,238,Agentid.Length); | ||
204 | this.Assets.Add(Skin.FullID, Skin); | ||
205 | |||
206 | Avata.Wearables[1].ItemID = _inventoryManager.AddToInventory(UserInfo, BaseFolder, Skin); | ||
207 | Avata.Wearables[1].AssetID = Skin.FullID; | ||
208 | |||
209 | //give a copy of test texture | ||
210 | TextureImage Texture = this.CloneImage(UserInfo.AgentID, Textures[new LLUUID("00000000-0000-0000-5005-000000000005")]); | ||
211 | this.Textures.Add(Texture.FullID, Texture); | ||
212 | _inventoryManager.AddToInventory(UserInfo, BaseFolder, Texture); | ||
213 | |||
214 | } | ||
215 | |||
216 | |||
217 | private void LoadAsset(AssetBase info, bool Image) | ||
218 | { | ||
219 | WebRequest AssetLoad = WebRequest.Create(Globals.Instance.AssetURL + "getasset/" + Globals.Instance.AssetSendKey + "/" + info.FullID + "/data"); | ||
220 | WebResponse AssetResponse = AssetLoad.GetResponse(); | ||
221 | byte[] idata = new byte[(int)AssetResponse.ContentLength]; | ||
222 | BinaryReader br = new BinaryReader(AssetResponse.GetResponseStream()); | ||
223 | idata = br.ReadBytes((int)AssetResponse.ContentLength); | ||
224 | br.Close(); | ||
225 | AssetResponse.Close(); | ||
226 | info.data = idata; | ||
227 | } | ||
228 | |||
229 | public AssetInfo CloneAsset(LLUUID NewOwner, AssetInfo SourceAsset) | ||
230 | { | ||
231 | AssetInfo NewAsset = new AssetInfo(); | ||
232 | NewAsset.data = new byte[SourceAsset.data.Length]; | ||
233 | Array.Copy(SourceAsset.data, NewAsset.data, SourceAsset.data.Length); | ||
234 | NewAsset.FullID = LLUUID.Random(); | ||
235 | NewAsset.Type = SourceAsset.Type; | ||
236 | NewAsset.InvType = SourceAsset.InvType; | ||
237 | return(NewAsset); | ||
238 | } | ||
239 | #endregion | ||
240 | |||
241 | #region TextureRegion | ||
242 | public void AddTextureRequest(UserAgentInfo userInfo, LLUUID imageID) | ||
243 | { | ||
244 | |||
245 | if(!this.Textures.ContainsKey(imageID)) | ||
246 | { | ||
247 | //not found image so send back image not in data base message | ||
248 | ImageNotInDatabasePacket im_not = new ImageNotInDatabasePacket(); | ||
249 | im_not.ImageID.ID=imageID; | ||
250 | _server.SendPacket(im_not, true, userInfo); | ||
251 | return; | ||
252 | } | ||
253 | TextureImage imag = this.Textures[imageID]; | ||
254 | TextureRequest req = new TextureRequest(); | ||
255 | req.RequestUser = userInfo; | ||
256 | req.RequestImage = imageID; | ||
257 | req.ImageInfo = imag; | ||
258 | |||
259 | if(imag.data.LongLength>600) //should be bigger or smaller? | ||
260 | { | ||
261 | //over 600 bytes so split up file | ||
262 | req.NumPackets = 1 + (int)(imag.data.Length-600+999)/1000; | ||
263 | } | ||
264 | else | ||
265 | { | ||
266 | req.NumPackets = 1; | ||
267 | } | ||
268 | |||
269 | this.TextureRequests.Add(req); | ||
270 | |||
271 | } | ||
272 | |||
273 | public void AddTexture(LLUUID imageID, string name, byte[] data) | ||
274 | { | ||
275 | |||
276 | } | ||
277 | public void DoWork(ulong time) | ||
278 | { | ||
279 | if(this.TextureRequests.Count == 0) | ||
280 | { | ||
281 | //no requests waiting | ||
282 | return; | ||
283 | } | ||
284 | int num; | ||
285 | //should be running in its own thread but for now is called by timer | ||
286 | if(this.TextureRequests.Count < 5) | ||
287 | { | ||
288 | //lower than 5 so do all of them | ||
289 | num = this.TextureRequests.Count; | ||
290 | } | ||
291 | else | ||
292 | { | ||
293 | num=5; | ||
294 | } | ||
295 | TextureRequest req; | ||
296 | for(int i = 0; i < num; i++) | ||
297 | { | ||
298 | req=(TextureRequest)this.TextureRequests[i]; | ||
299 | |||
300 | if(req.PacketCounter == 0) | ||
301 | { | ||
302 | //first time for this request so send imagedata packet | ||
303 | if(req.NumPackets == 1) | ||
304 | { | ||
305 | //only one packet so send whole file | ||
306 | ImageDataPacket im = new ImageDataPacket(); | ||
307 | im.ImageID.Packets = 1; | ||
308 | im.ImageID.ID = req.ImageInfo.FullID; | ||
309 | im.ImageID.Size = (uint)req.ImageInfo.data.Length; | ||
310 | im.ImageData.Data = req.ImageInfo.data; | ||
311 | im.ImageID.Codec = 2; | ||
312 | _server.SendPacket(im, true, req.RequestUser); | ||
313 | req.PacketCounter++; | ||
314 | req.ImageInfo.last_used = time; | ||
315 | //System.Console.WriteLine("sent texture: "+req.image_info.FullID); | ||
316 | } | ||
317 | else | ||
318 | { | ||
319 | //more than one packet so split file up | ||
320 | ImageDataPacket im = new ImageDataPacket(); | ||
321 | im.ImageID.Packets = (ushort)req.NumPackets; | ||
322 | im.ImageID.ID = req.ImageInfo.FullID; | ||
323 | im.ImageID.Size = (uint)req.ImageInfo.data.Length; | ||
324 | im.ImageData.Data = new byte[600]; | ||
325 | Array.Copy(req.ImageInfo.data, 0, im.ImageData.Data, 0, 600); | ||
326 | im.ImageID.Codec = 2; | ||
327 | _server.SendPacket(im, true, req.RequestUser); | ||
328 | req.PacketCounter++; | ||
329 | req.ImageInfo.last_used = time; | ||
330 | //System.Console.WriteLine("sent first packet of texture: | ||
331 | } | ||
332 | } | ||
333 | else | ||
334 | { | ||
335 | //send imagepacket | ||
336 | //more than one packet so split file up | ||
337 | ImagePacketPacket im = new ImagePacketPacket(); | ||
338 | im.ImageID.Packet = (ushort)req.PacketCounter; | ||
339 | im.ImageID.ID = req.ImageInfo.FullID; | ||
340 | int size = req.ImageInfo.data.Length - 600 - 1000*(req.PacketCounter - 1); | ||
341 | if(size > 1000) size = 1000; | ||
342 | im.ImageData.Data = new byte[size]; | ||
343 | Array.Copy(req.ImageInfo.data, 600 + 1000*(req.PacketCounter - 1), im.ImageData.Data, 0, size); | ||
344 | _server.SendPacket(im, true, req.RequestUser); | ||
345 | req.PacketCounter++; | ||
346 | req.ImageInfo.last_used = time; | ||
347 | //System.Console.WriteLine("sent a packet of texture: "+req.image_info.FullID); | ||
348 | } | ||
349 | } | ||
350 | |||
351 | //remove requests that have been completed | ||
352 | for(int i = 0; i < num; i++) | ||
353 | { | ||
354 | req=(TextureRequest)this.TextureRequests[i]; | ||
355 | if(req.PacketCounter == req.NumPackets) | ||
356 | { | ||
357 | this.TextureRequests.Remove(req); | ||
358 | } | ||
359 | } | ||
360 | } | ||
361 | |||
362 | public void RecieveTexture(Packet pack) | ||
363 | { | ||
364 | |||
365 | } | ||
366 | |||
367 | public TextureImage CloneImage(LLUUID newOwner, TextureImage source) | ||
368 | { | ||
369 | TextureImage newImage = new TextureImage(); | ||
370 | newImage.data = new byte[source.data.Length]; | ||
371 | Array.Copy(source.data,newImage.data,source.data.Length); | ||
372 | newImage.filename = source.filename; | ||
373 | newImage.FullID = LLUUID.Random(); | ||
374 | newImage.Name = source.Name; | ||
375 | return(newImage); | ||
376 | } | ||
377 | |||
378 | #endregion | ||
379 | } | ||
380 | |||
381 | public class AssetRequest | ||
382 | { | ||
383 | public UserAgentInfo RequestUser; | ||
384 | public LLUUID RequestImage; | ||
385 | public AssetInfo asset_inf; | ||
386 | public long data_pointer = 0; | ||
387 | public int num_packets = 0; | ||
388 | public int packet_counter = 0; | ||
389 | |||
390 | public AssetRequest() | ||
391 | { | ||
392 | |||
393 | } | ||
394 | } | ||
395 | public class AssetInfo:AssetBase | ||
396 | { | ||
397 | //public byte[] data; | ||
398 | //public LLUUID Full_ID; | ||
399 | public bool loaded; | ||
400 | public ulong last_used; //need to add a tick/time counter and keep record | ||
401 | // of how often images are requested to unload unused ones. | ||
402 | |||
403 | public AssetInfo() | ||
404 | { | ||
405 | |||
406 | } | ||
407 | } | ||
408 | |||
409 | public class AssetBase | ||
410 | { | ||
411 | public byte[] data; | ||
412 | public LLUUID FullID; | ||
413 | public sbyte Type; | ||
414 | public sbyte InvType; | ||
415 | public string Name; | ||
416 | public string Description; | ||
417 | public string filename; | ||
418 | |||
419 | public AssetBase() | ||
420 | { | ||
421 | |||
422 | } | ||
423 | } | ||
424 | public class TextureRequest | ||
425 | { | ||
426 | public UserAgentInfo RequestUser; | ||
427 | public LLUUID RequestImage; | ||
428 | public TextureImage ImageInfo; | ||
429 | public long DataPointer = 0; | ||
430 | public int NumPackets = 0; | ||
431 | public int PacketCounter = 0; | ||
432 | |||
433 | public TextureRequest() | ||
434 | { | ||
435 | |||
436 | } | ||
437 | } | ||
438 | public class TextureImage: AssetBase | ||
439 | { | ||
440 | //any need for this class now most has been moved into AssetBase? | ||
441 | //public byte[] data; | ||
442 | //public LLUUID Full_ID; | ||
443 | //public string name; | ||
444 | public bool loaded; | ||
445 | public ulong last_used; //need to add a tick/time counter and keep record | ||
446 | // of how often images are requested to unload unused ones. | ||
447 | |||
448 | public TextureImage() | ||
449 | { | ||
450 | |||
451 | } | ||
452 | } | ||
453 | |||
454 | |||
455 | } | ||
diff --git a/src/Asset_manager.cs b/src/Asset_manager.cs new file mode 100644 index 0000000..60f8945 --- /dev/null +++ b/src/Asset_manager.cs | |||
@@ -0,0 +1,231 @@ | |||
1 | /* | ||
2 | Copyright (c) OpenSim project, http://osgrid.org/ | ||
3 | |||
4 | * Copyright (c) <year>, <copyright holder> | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Redistribution and use in source and binary forms, with or without | ||
8 | * modification, are permitted provided that the following conditions are met: | ||
9 | * * Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * * Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * * Neither the name of the <organization> nor the | ||
15 | * names of its contributors may be used to endorse or promote products | ||
16 | * derived from this software without specific prior written permission. | ||
17 | * | ||
18 | * THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY | ||
19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
21 | * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY | ||
22 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
24 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
25 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | ||
28 | |||
29 | using System; | ||
30 | using System.Collections.Generic; | ||
31 | using libsecondlife; | ||
32 | using System.Collections; | ||
33 | using libsecondlife.Packets; | ||
34 | using libsecondlife.AssetSystem; | ||
35 | using System.IO; | ||
36 | |||
37 | namespace OpenSim | ||
38 | { | ||
39 | /// <summary> | ||
40 | /// Description of Asset_manager. | ||
41 | /// </summary> | ||
42 | public class AssetManager | ||
43 | { | ||
44 | public Dictionary<libsecondlife.LLUUID,AssetInfo> Assets; | ||
45 | public ArrayList requests=new ArrayList(); //should change to a generic | ||
46 | // public ArrayList uploads=new ArrayList(); | ||
47 | private Server server; | ||
48 | public TextureManager TextureMan; | ||
49 | public InventoryManager InventoryManager; | ||
50 | private System.Text.Encoding enc = System.Text.Encoding.ASCII; | ||
51 | |||
52 | public AssetManager(Server serve) | ||
53 | { | ||
54 | server=serve; | ||
55 | Assets=new Dictionary<libsecondlife.LLUUID,AssetInfo> (); | ||
56 | this.initialise(); | ||
57 | } | ||
58 | |||
59 | public void AddRequest(User_Agent_info user, LLUUID asset_id, TransferRequestPacket tran_req) | ||
60 | { | ||
61 | Console.WriteLine("Asset Request "+ asset_id); | ||
62 | if(!this.Assets.ContainsKey(asset_id)) | ||
63 | { | ||
64 | //not found asset | ||
65 | return; | ||
66 | } | ||
67 | AssetInfo info=this.Assets[asset_id]; | ||
68 | System.Console.WriteLine("send asset : "+asset_id); | ||
69 | //for now as it will be only skin or shape request just send back the asset | ||
70 | TransferInfoPacket Transfer=new TransferInfoPacket(); | ||
71 | Transfer.TransferInfo.ChannelType=2; | ||
72 | Transfer.TransferInfo.Status=0; | ||
73 | Transfer.TransferInfo.TargetType=0; | ||
74 | Transfer.TransferInfo.Params=tran_req.TransferInfo.Params; | ||
75 | Transfer.TransferInfo.Size=info.data.Length; | ||
76 | Transfer.TransferInfo.TransferID=tran_req.TransferInfo.TransferID; | ||
77 | |||
78 | server.SendPacket(Transfer,true,user); | ||
79 | |||
80 | TransferPacketPacket tran_p=new TransferPacketPacket(); | ||
81 | tran_p.TransferData.Packet=0; | ||
82 | tran_p.TransferData.ChannelType=2; | ||
83 | tran_p.TransferData.TransferID=tran_req.TransferInfo.TransferID; | ||
84 | if(info.data.Length>1000) //but needs to be less than 2000 at the moment | ||
85 | { | ||
86 | byte[] chunk=new byte[1000]; | ||
87 | Array.Copy(info.data,chunk,1000); | ||
88 | tran_p.TransferData.Data=chunk; | ||
89 | tran_p.TransferData.Status=0; | ||
90 | server.SendPacket(tran_p,true,user); | ||
91 | |||
92 | tran_p=new TransferPacketPacket(); | ||
93 | tran_p.TransferData.Packet=1; | ||
94 | tran_p.TransferData.ChannelType=2; | ||
95 | tran_p.TransferData.TransferID=tran_req.TransferInfo.TransferID; | ||
96 | byte[] chunk1=new byte[(info.data.Length-1000)]; | ||
97 | Array.Copy(info.data,1000,chunk1,0,chunk1.Length); | ||
98 | tran_p.TransferData.Data=chunk1; | ||
99 | tran_p.TransferData.Status=1; | ||
100 | server.SendPacket(tran_p,true,user); | ||
101 | } | ||
102 | else | ||
103 | { | ||
104 | tran_p.TransferData.Status=1; //last packet? so set to 1 | ||
105 | tran_p.TransferData.Data=info.data; | ||
106 | server.SendPacket(tran_p,true,user); | ||
107 | } | ||
108 | |||
109 | } | ||
110 | public void CreateNewBaseSet(ref AvatarData Avata,User_Agent_info UserInfo) | ||
111 | { | ||
112 | //LLUUID BaseFolder=new LLUUID("4f5f559e-77a0-a4b9-84f9-8c74c07f7cfc");//*/"4fb2dab6-a987-da66-05ee-96ca82bccbf1"); | ||
113 | //LLUUID BaseFolder=new LLUUID("480e2d92-61f6-9f16-f4f5-0f77cfa4f8f9"); | ||
114 | LLUUID BaseFolder=Avata.BaseFolder; | ||
115 | InventoryManager.CreateNewFolder(UserInfo,Avata.InventoryFolder); | ||
116 | InventoryManager.CreateNewFolder(UserInfo, BaseFolder); | ||
117 | |||
118 | AssetInfo Base=this.Assets[new LLUUID("66c41e39-38f9-f75a-024e-585989bfab73")]; | ||
119 | AssetInfo Shape=new AssetInfo(); | ||
120 | |||
121 | Shape.filename=""; | ||
122 | Shape.data=new byte[Base.data.Length]; | ||
123 | Array.Copy(Base.data,Shape.data,Base.data.Length); | ||
124 | Shape.Full_ID=LLUUID.Random(); | ||
125 | Shape.Name="Default Skin"; | ||
126 | Shape.Description="Default"; | ||
127 | Shape.InvType=18; | ||
128 | |||
129 | Shape.Type=libsecondlife.AssetSystem.ASSET_TYPE_WEARABLE_BODY; | ||
130 | byte[] Agentid=enc.GetBytes(UserInfo.AgentID.ToStringHyphenated()); | ||
131 | Array.Copy(Agentid,0,Shape.data,294,Agentid.Length); | ||
132 | this.Assets.Add(Shape.Full_ID,Shape); | ||
133 | /*FileStream fStream = new FileStream("Assetshape.dat", FileMode.CreateNew); | ||
134 | BinaryWriter bw = new BinaryWriter(fStream); | ||
135 | bw.Write(Shape.data); | ||
136 | bw.Close(); | ||
137 | fStream.Close();*/ | ||
138 | |||
139 | Avata.Wearables[0].ItemID=InventoryManager.AddToInventory(UserInfo,BaseFolder,Shape); | ||
140 | Avata.Wearables[0].AssetID=Shape.Full_ID; | ||
141 | //Avata.RootFolder=BaseFolder; | ||
142 | |||
143 | //give test texture | ||
144 | |||
145 | TextureImage Texture=TextureMan.textures[new LLUUID("00000000-0000-0000-5005-000000000005")]; | ||
146 | InventoryManager.AddToInventory(UserInfo,BaseFolder,Texture); | ||
147 | |||
148 | } | ||
149 | |||
150 | private void initialise() | ||
151 | { | ||
152 | //for now read in our test image | ||
153 | AssetInfo im=new AssetInfo(); | ||
154 | im.filename="base_shape.dat"; | ||
155 | im.Full_ID=new LLUUID("66c41e39-38f9-f75a-024e-585989bfab73"); | ||
156 | this.loadAsset(im); | ||
157 | this.Assets.Add(im.Full_ID,im); | ||
158 | |||
159 | |||
160 | im=new AssetInfo(); | ||
161 | im.filename="base_skin.dat"; | ||
162 | im.Full_ID=new LLUUID("e0ee49b5a4184df8d3c9a65361fe7f49"); | ||
163 | this.loadAsset(im); | ||
164 | this.Assets.Add(im.Full_ID,im); | ||
165 | } | ||
166 | private void loadAsset(AssetInfo info) | ||
167 | { | ||
168 | //should request Asset from storage manager | ||
169 | //but for now read from file | ||
170 | |||
171 | string data_path = System.AppDomain.CurrentDomain.BaseDirectory + @"\assets\"; | ||
172 | string filename=data_path+@info.filename; | ||
173 | FileInfo fInfo = new FileInfo(filename); | ||
174 | |||
175 | long numBytes = fInfo.Length; | ||
176 | |||
177 | FileStream fStream = new FileStream(filename, FileMode.Open, FileAccess.Read); | ||
178 | byte[] idata=new byte[numBytes]; | ||
179 | BinaryReader br = new BinaryReader(fStream); | ||
180 | idata= br.ReadBytes((int)numBytes); | ||
181 | br.Close(); | ||
182 | fStream.Close(); | ||
183 | info.data=idata; | ||
184 | info.loaded=true; | ||
185 | } | ||
186 | } | ||
187 | |||
188 | public class AssetRequest | ||
189 | { | ||
190 | public User_Agent_info RequestUser; | ||
191 | public LLUUID RequestImage; | ||
192 | public AssetInfo asset_inf; | ||
193 | public long data_pointer=0; | ||
194 | public int num_packets=0; | ||
195 | public int packet_counter=0; | ||
196 | |||
197 | public AssetRequest() | ||
198 | { | ||
199 | |||
200 | } | ||
201 | } | ||
202 | public class AssetInfo:AssetBase | ||
203 | { | ||
204 | //public byte[] data; | ||
205 | //public LLUUID Full_ID; | ||
206 | public string filename; | ||
207 | public bool loaded; | ||
208 | public ulong last_used; //need to add a tick/time counter and keep record | ||
209 | // of how often images are requested to unload unused ones. | ||
210 | |||
211 | public AssetInfo() | ||
212 | { | ||
213 | |||
214 | } | ||
215 | } | ||
216 | |||
217 | public class AssetBase | ||
218 | { | ||
219 | public byte[] data; | ||
220 | public LLUUID Full_ID; | ||
221 | public sbyte Type; | ||
222 | public sbyte InvType; | ||
223 | public string Name; | ||
224 | public string Description; | ||
225 | |||
226 | public AssetBase() | ||
227 | { | ||
228 | |||
229 | } | ||
230 | } | ||
231 | } | ||
diff --git a/src/Config.cs b/src/Config.cs new file mode 100644 index 0000000..44e0689 --- /dev/null +++ b/src/Config.cs | |||
@@ -0,0 +1,140 @@ | |||
1 | /* | ||
2 | Copyright (c) OpenSim project, http://osgrid.org/ | ||
3 | |||
4 | * Copyright (c) <year>, <copyright holder> | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Redistribution and use in source and binary forms, with or without | ||
8 | * modification, are permitted provided that the following conditions are met: | ||
9 | * * Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * * Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * * Neither the name of the <organization> nor the | ||
15 | * names of its contributors may be used to endorse or promote products | ||
16 | * derived from this software without specific prior written permission. | ||
17 | * | ||
18 | * THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY | ||
19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
21 | * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY | ||
22 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
24 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
25 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
28 | */ | ||
29 | |||
30 | using System; | ||
31 | using System.Collections.Generic; | ||
32 | using System.IO; | ||
33 | using Db4objects.Db4o; | ||
34 | using libsecondlife; | ||
35 | using OpenSim.world; | ||
36 | |||
37 | namespace OpenSim | ||
38 | { | ||
39 | /// <summary> | ||
40 | /// This class handles connection to the underlying database used for configuration of the region. | ||
41 | /// Region content is also stored by this class. The main entry point is InitConfig() which attempts to locate | ||
42 | /// opensim.yap in the current working directory. If opensim.yap can not be found, default settings are loaded from | ||
43 | /// what is hardcoded here and then saved into opensim.yap for future startups. | ||
44 | /// </summary> | ||
45 | public class SimConfig | ||
46 | { | ||
47 | public string RegionName; | ||
48 | |||
49 | public uint RegionLocX; | ||
50 | public uint RegionLocY; | ||
51 | public ulong RegionHandle; | ||
52 | |||
53 | public int IPListenPort; | ||
54 | public string IPListenAddr; | ||
55 | |||
56 | public string AssetURL; | ||
57 | public string AssetSendKey; | ||
58 | |||
59 | public string GridURL; | ||
60 | public string GridSendKey; | ||
61 | |||
62 | private IObjectContainer db; | ||
63 | |||
64 | public void LoadDefaults() { | ||
65 | this.RegionName = "OpenSim test\0"; | ||
66 | this.RegionLocX = 997; | ||
67 | this.RegionLocY = 996; | ||
68 | this.RegionHandle = Helpers.UIntsToLong((RegionLocX*256), (RegionLocY*256)); | ||
69 | this.IPListenPort = 9000; | ||
70 | this.IPListenAddr = "4.78.190.75"; | ||
71 | this.AssetURL = "http://osgrid.org/ogs/assetserver/"; | ||
72 | this.AssetSendKey = "1234"; | ||
73 | this.GridURL = "http://osgrid.org/ogs/gridserver/"; | ||
74 | this.GridSendKey = "1234"; | ||
75 | } | ||
76 | |||
77 | public void InitConfig() { | ||
78 | try { | ||
79 | db = Db4oFactory.OpenFile("opensim.yap"); | ||
80 | IObjectSet result = db.Get(typeof(SimConfig)); | ||
81 | if(result.Count==1) { | ||
82 | Console.WriteLine("Config.cs:InitConfig() - Found a SimConfig object in the local database, loading"); | ||
83 | foreach (SimConfig cfg in result) { | ||
84 | this.RegionName = cfg.RegionName; | ||
85 | this.RegionLocX = cfg.RegionLocX; | ||
86 | this.RegionLocY = cfg.RegionLocY; | ||
87 | this.RegionHandle = Helpers.UIntsToLong((RegionLocX*256), (RegionLocY*256)); | ||
88 | this.IPListenPort = cfg.IPListenPort; | ||
89 | this.IPListenAddr = cfg.IPListenAddr; | ||
90 | this.AssetURL = cfg.AssetURL; | ||
91 | this.AssetSendKey = cfg.AssetSendKey; | ||
92 | this.GridURL = cfg.GridURL; | ||
93 | this.GridSendKey = cfg.GridSendKey; | ||
94 | } | ||
95 | } else { | ||
96 | Console.WriteLine("Config.cs:InitConfig() - Could not find object in database, loading precompiled defaults"); | ||
97 | LoadDefaults(); | ||
98 | Console.WriteLine("Writing out default settings to local database"); | ||
99 | db.Set(this); | ||
100 | } | ||
101 | } catch(Exception e) { | ||
102 | db.Close(); | ||
103 | Console.WriteLine("Config.cs:InitConfig() - Exception occured"); | ||
104 | Console.WriteLine(e.ToString()); | ||
105 | } | ||
106 | } | ||
107 | |||
108 | public World LoadWorld() { | ||
109 | IObjectSet world_result = db.Get(typeof(OpenSim.world.World)); | ||
110 | if(world_result.Count==1) { | ||
111 | Console.WriteLine("Config.cs:LoadWorld() - Found an OpenSim.world.World object in local database, loading"); | ||
112 | return (World)world_result.Next(); | ||
113 | } else { | ||
114 | Console.WriteLine("Config.cs:LoadWorld() - Could not find the world or too many worlds! Constructing blank one"); | ||
115 | World blank = new World(); | ||
116 | Console.WriteLine("Config.cs:LoadWorld() - Saving initial world state to disk"); | ||
117 | db.Set(blank); | ||
118 | db.Commit(); | ||
119 | return blank; | ||
120 | } | ||
121 | } | ||
122 | |||
123 | public void LoadFromGrid() { | ||
124 | Console.WriteLine("Config.cs:LoadFromGrid() - dummy function, DOING ABSOLUTELY NOTHING AT ALL!!!"); | ||
125 | // TODO: Make this crap work | ||
126 | /* WebRequest GridLogin = WebRequest.Create(this.GridURL + "regions/" + this.RegionHandle.ToString() + "/login"); | ||
127 | WebResponse GridResponse = GridLogin.GetResponse(); | ||
128 | byte[] idata = new byte[(int)GridResponse.ContentLength]; | ||
129 | BinaryReader br = new BinaryReader(GridResponse.GetResponseStream()); | ||
130 | |||
131 | br.Close(); | ||
132 | GridResponse.Close(); | ||
133 | */ | ||
134 | } | ||
135 | |||
136 | public void Shutdown() { | ||
137 | db.Close(); | ||
138 | } | ||
139 | } | ||
140 | } | ||
diff --git a/src/GridManager.cs b/src/GridManager.cs new file mode 100644 index 0000000..3d3b35d --- /dev/null +++ b/src/GridManager.cs | |||
@@ -0,0 +1,372 @@ | |||
1 | /* | ||
2 | Copyright (c) OpenSim project, http://osgrid.org/ | ||
3 | |||
4 | * Copyright (c) <year>, <copyright holder> | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Redistribution and use in source and binary forms, with or without | ||
8 | * modification, are permitted provided that the following conditions are met: | ||
9 | * * Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * * Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * * Neither the name of the <organization> nor the | ||
15 | * names of its contributors may be used to endorse or promote products | ||
16 | * derived from this software without specific prior written permission. | ||
17 | * | ||
18 | * THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY | ||
19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
21 | * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY | ||
22 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
24 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
25 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
28 | */ | ||
29 | |||
30 | using System; | ||
31 | using System.Collections.Generic; | ||
32 | using libsecondlife; | ||
33 | using System.Collections; | ||
34 | using libsecondlife.Packets; | ||
35 | using libsecondlife.AssetSystem; | ||
36 | using System.IO; | ||
37 | using System.Xml; | ||
38 | |||
39 | |||
40 | namespace OpenSim | ||
41 | { | ||
42 | /// <summary> | ||
43 | /// Description of GridManager. | ||
44 | /// </summary> | ||
45 | public class GridManager | ||
46 | { | ||
47 | private Server _server; | ||
48 | private System.Text.Encoding _enc = System.Text.Encoding.ASCII; | ||
49 | private AgentManager _agentManager; | ||
50 | public Dictionary<ulong,RegionInfo> Grid; | ||
51 | |||
52 | /// <summary> | ||
53 | /// | ||
54 | /// </summary> | ||
55 | /// <param name="serve"></param> | ||
56 | /// <param name="agentManager"></param> | ||
57 | public GridManager(Server server, AgentManager agentManager) | ||
58 | { | ||
59 | Grid = new Dictionary<ulong, RegionInfo>(); | ||
60 | _server = server; | ||
61 | _agentManager = agentManager; | ||
62 | LoadGrid(); | ||
63 | } | ||
64 | |||
65 | /// <summary> | ||
66 | /// | ||
67 | /// </summary> | ||
68 | /// <param name="UserInfo"></param> | ||
69 | public void RequestMapLayer(UserAgentInfo userInfo) | ||
70 | { | ||
71 | //send a layer covering the 800,800 - 1200,1200 area | ||
72 | MapLayerReplyPacket MapReply = new MapLayerReplyPacket(); | ||
73 | MapReply.AgentData.AgentID = userInfo.AgentID; | ||
74 | MapReply.AgentData.Flags = 0; | ||
75 | MapReply.LayerData = new MapLayerReplyPacket.LayerDataBlock[1]; | ||
76 | MapReply.LayerData[0] = new MapLayerReplyPacket.LayerDataBlock(); | ||
77 | MapReply.LayerData[0].Bottom = 800; | ||
78 | MapReply.LayerData[0].Left = 800; | ||
79 | MapReply.LayerData[0].Top = 1200; | ||
80 | MapReply.LayerData[0].Right = 1200; | ||
81 | MapReply.LayerData[0].ImageID = new LLUUID("00000000-0000-0000-7007-000000000006"); | ||
82 | _server.SendPacket(MapReply, true, userInfo); | ||
83 | } | ||
84 | |||
85 | /// <summary> | ||
86 | /// | ||
87 | /// </summary> | ||
88 | /// <param name="UserInfo"></param> | ||
89 | /// <param name="MinX"></param> | ||
90 | /// <param name="MinY"></param> | ||
91 | /// <param name="MaxX"></param> | ||
92 | /// <param name="MaxY"></param> | ||
93 | public void RequestMapBlock(UserAgentInfo userInfo, int minX, int minY,int maxX,int maxY) | ||
94 | { | ||
95 | foreach (KeyValuePair<ulong, RegionInfo> RegionPair in this.Grid) | ||
96 | { | ||
97 | //check Region is inside the requested area | ||
98 | RegionInfo Region = RegionPair.Value; | ||
99 | if(((Region.X > minX) && (Region.X < maxX)) && ((Region.Y > minY) && (Region.Y < maxY))) | ||
100 | { | ||
101 | MapBlockReplyPacket MapReply = new MapBlockReplyPacket(); | ||
102 | MapReply.AgentData.AgentID = userInfo.AgentID; | ||
103 | MapReply.AgentData.Flags = 0; | ||
104 | MapReply.Data = new MapBlockReplyPacket.DataBlock[1]; | ||
105 | MapReply.Data[0] = new MapBlockReplyPacket.DataBlock(); | ||
106 | MapReply.Data[0].MapImageID = Region.ImageID; | ||
107 | MapReply.Data[0].X = Region.X; | ||
108 | MapReply.Data[0].Y = Region.Y; | ||
109 | MapReply.Data[0].WaterHeight = Region.WaterHeight; | ||
110 | MapReply.Data[0].Name = _enc.GetBytes( Region.Name); | ||
111 | MapReply.Data[0].RegionFlags = 72458694; | ||
112 | MapReply.Data[0].Access = 13; | ||
113 | MapReply.Data[0].Agents = 1; | ||
114 | _server.SendPacket(MapReply, true, userInfo); | ||
115 | } | ||
116 | } | ||
117 | |||
118 | } | ||
119 | |||
120 | /// <summary> | ||
121 | /// | ||
122 | /// </summary> | ||
123 | /// <param name="UserInfo"></param> | ||
124 | /// <param name="Request"></param> | ||
125 | public void RequestTeleport(UserAgentInfo userInfo, TeleportLocationRequestPacket request) | ||
126 | { | ||
127 | if(Grid.ContainsKey(request.Info.RegionHandle)) | ||
128 | { | ||
129 | RegionInfo Region = Grid[request.Info.RegionHandle]; | ||
130 | libsecondlife.Packets.TeleportStartPacket TeleportStart = new TeleportStartPacket(); | ||
131 | TeleportStart.Info.TeleportFlags = 16; | ||
132 | _server.SendPacket(TeleportStart, true, userInfo); | ||
133 | |||
134 | libsecondlife.Packets.TeleportFinishPacket Teleport = new TeleportFinishPacket(); | ||
135 | Teleport.Info.AgentID = userInfo.AgentID; | ||
136 | Teleport.Info.RegionHandle = request.Info.RegionHandle; | ||
137 | Teleport.Info.SimAccess = 13; | ||
138 | Teleport.Info.SeedCapability = new byte[0]; | ||
139 | |||
140 | System.Net.IPAddress oIP = System.Net.IPAddress.Parse(Region.IPAddress.Address); | ||
141 | byte[] byteIP = oIP.GetAddressBytes(); | ||
142 | uint ip=(uint)byteIP[3]<<24; | ||
143 | ip+=(uint)byteIP[2]<<16; | ||
144 | ip+=(uint)byteIP[1]<<8; | ||
145 | ip+=(uint)byteIP[0]; | ||
146 | |||
147 | Teleport.Info.SimIP = ip; | ||
148 | Teleport.Info.SimPort = Region.IPAddress.Port; | ||
149 | Teleport.Info.LocationID = 4; | ||
150 | Teleport.Info.TeleportFlags = 1 << 4;; | ||
151 | _server.SendPacket(Teleport, true, userInfo); | ||
152 | |||
153 | this._agentManager.RemoveAgent(userInfo); | ||
154 | } | ||
155 | |||
156 | } | ||
157 | |||
158 | /// <summary> | ||
159 | /// | ||
160 | /// </summary> | ||
161 | private void LoadGrid() | ||
162 | { | ||
163 | //should connect to a space server to see what grids there are | ||
164 | //but for now we read static xml files | ||
165 | ulong CurrentHandle = 0; | ||
166 | bool Login = true; | ||
167 | |||
168 | XmlDocument doc = new XmlDocument(); | ||
169 | |||
170 | try { | ||
171 | doc.Load(Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "Grid.ini" )); | ||
172 | } | ||
173 | catch ( Exception e) | ||
174 | { | ||
175 | Console.WriteLine(e.Message); | ||
176 | return; | ||
177 | } | ||
178 | |||
179 | try | ||
180 | { | ||
181 | XmlNode root = doc.FirstChild; | ||
182 | if (root.Name != "Root") | ||
183 | throw new Exception("Error: Invalid File. Missing <Root>"); | ||
184 | |||
185 | XmlNode nodes = root.FirstChild; | ||
186 | if (nodes.Name != "Grid") | ||
187 | throw new Exception("Error: Invalid File. <project> first child should be <Grid>"); | ||
188 | |||
189 | if (nodes.HasChildNodes) { | ||
190 | foreach( XmlNode xmlnc in nodes.ChildNodes) | ||
191 | { | ||
192 | if(xmlnc.Name == "Region") | ||
193 | { | ||
194 | string xmlAttri; | ||
195 | RegionInfo Region = new RegionInfo(); | ||
196 | if(xmlnc.Attributes["Name"] != null) | ||
197 | { | ||
198 | xmlAttri = ((XmlAttribute)xmlnc.Attributes.GetNamedItem("Name")).Value; | ||
199 | Region.Name = xmlAttri+" \0"; | ||
200 | } | ||
201 | if(xmlnc.Attributes["ImageID"] != null) | ||
202 | { | ||
203 | xmlAttri = ((XmlAttribute)xmlnc.Attributes.GetNamedItem("ImageID")).Value; | ||
204 | Region.ImageID = new LLUUID(xmlAttri); | ||
205 | } | ||
206 | if(xmlnc.Attributes["IP_Address"] != null) | ||
207 | { | ||
208 | xmlAttri = ((XmlAttribute)xmlnc.Attributes.GetNamedItem("IP_Address")).Value; | ||
209 | Region.IPAddress.Address = xmlAttri; | ||
210 | } | ||
211 | if(xmlnc.Attributes["IP_Port"] != null) | ||
212 | { | ||
213 | xmlAttri = ((XmlAttribute)xmlnc.Attributes.GetNamedItem("IP_Port")).Value; | ||
214 | Region.IPAddress.Port = Convert.ToUInt16(xmlAttri); | ||
215 | } | ||
216 | if(xmlnc.Attributes["Location_X"] != null) | ||
217 | { | ||
218 | xmlAttri = ((XmlAttribute)xmlnc.Attributes.GetNamedItem("Location_X")).Value; | ||
219 | Region.X = Convert.ToUInt16(xmlAttri); | ||
220 | } | ||
221 | if(xmlnc.Attributes["Location_Y"] != null) | ||
222 | { | ||
223 | xmlAttri = ((XmlAttribute)xmlnc.Attributes.GetNamedItem("Location_Y")).Value; | ||
224 | Region.Y = Convert.ToUInt16(xmlAttri); | ||
225 | } | ||
226 | |||
227 | this.Grid.Add(Region.Handle, Region); | ||
228 | |||
229 | } | ||
230 | if(xmlnc.Name == "CurrentRegion") | ||
231 | { | ||
232 | |||
233 | string xmlAttri; | ||
234 | uint Rx = 0, Ry = 0; | ||
235 | if(xmlnc.Attributes["RegionHandle"] != null) | ||
236 | { | ||
237 | xmlAttri = ((XmlAttribute)xmlnc.Attributes.GetNamedItem("RegionHandle")).Value; | ||
238 | CurrentHandle = Convert.ToUInt64(xmlAttri); | ||
239 | |||
240 | } | ||
241 | else | ||
242 | { | ||
243 | if(xmlnc.Attributes["Region_X"] != null) | ||
244 | { | ||
245 | xmlAttri = ((XmlAttribute)xmlnc.Attributes.GetNamedItem("Region_X")).Value; | ||
246 | Rx = Convert.ToUInt32(xmlAttri); | ||
247 | } | ||
248 | if(xmlnc.Attributes["Region_Y"] != null) | ||
249 | { | ||
250 | xmlAttri = ((XmlAttribute)xmlnc.Attributes.GetNamedItem("Region_Y")).Value; | ||
251 | Ry = Convert.ToUInt32(xmlAttri); | ||
252 | } | ||
253 | } | ||
254 | if(xmlnc.Attributes["LoginServer"] != null) | ||
255 | { | ||
256 | xmlAttri = ((XmlAttribute)xmlnc.Attributes.GetNamedItem("LoginServer")).Value; | ||
257 | Login = Convert.ToBoolean(xmlAttri); | ||
258 | |||
259 | } | ||
260 | if(CurrentHandle == 0) | ||
261 | { | ||
262 | //no RegionHandle set | ||
263 | //so check for Region X and Y | ||
264 | if((Rx > 0) && (Ry > 0)) | ||
265 | { | ||
266 | CurrentHandle = Helpers.UIntsToLong((Rx*256), (Ry*256)); | ||
267 | } | ||
268 | else | ||
269 | { | ||
270 | //seems to be no Region location set | ||
271 | // so set default | ||
272 | CurrentHandle = 1096213093147648; | ||
273 | } | ||
274 | } | ||
275 | } | ||
276 | } | ||
277 | |||
278 | //finished loading grid, now set Globals to current region | ||
279 | if(CurrentHandle != 0) | ||
280 | { | ||
281 | if(Grid.ContainsKey(CurrentHandle)) | ||
282 | { | ||
283 | RegionInfo Region = Grid[CurrentHandle]; | ||
284 | Globals.Instance.RegionHandle = Region.Handle; | ||
285 | Globals.Instance.RegionName = Region.Name; | ||
286 | Globals.Instance.IpPort = Region.IPAddress.Port; | ||
287 | Globals.Instance.LoginSever = Login; | ||
288 | } | ||
289 | } | ||
290 | |||
291 | } | ||
292 | } | ||
293 | catch ( Exception e) | ||
294 | { | ||
295 | Console.WriteLine(e.Message); | ||
296 | return; | ||
297 | } | ||
298 | } | ||
299 | } | ||
300 | |||
301 | public class RegionInfo | ||
302 | { | ||
303 | public RegionIP IPAddress; | ||
304 | public string Name; | ||
305 | public ushort x; | ||
306 | public ushort y; | ||
307 | public ulong handle; | ||
308 | public LLUUID ImageID; | ||
309 | public uint Flags; | ||
310 | public byte WaterHeight; | ||
311 | |||
312 | public ushort X | ||
313 | { | ||
314 | get | ||
315 | { | ||
316 | return(x); | ||
317 | } | ||
318 | set | ||
319 | { | ||
320 | x = value; | ||
321 | Handle = Helpers.UIntsToLong((((uint)x)*256), (((uint)y)*256)); | ||
322 | } | ||
323 | } | ||
324 | public ushort Y | ||
325 | { | ||
326 | get | ||
327 | { | ||
328 | return(y); | ||
329 | } | ||
330 | set | ||
331 | { | ||
332 | y = value; | ||
333 | Handle = Helpers.UIntsToLong((((uint)x)*256), (((uint)y)*256)); | ||
334 | } | ||
335 | } | ||
336 | public ulong Handle | ||
337 | { | ||
338 | get | ||
339 | { | ||
340 | if(handle > 0) | ||
341 | { | ||
342 | return(handle); | ||
343 | } | ||
344 | else | ||
345 | { | ||
346 | return(Helpers.UIntsToLong((((uint)x)*256), (((uint)y)*256))); | ||
347 | } | ||
348 | } | ||
349 | set | ||
350 | { | ||
351 | handle = value; | ||
352 | } | ||
353 | |||
354 | } | ||
355 | |||
356 | public RegionInfo() | ||
357 | { | ||
358 | this.IPAddress = new RegionIP(); | ||
359 | } | ||
360 | } | ||
361 | public class RegionIP | ||
362 | { | ||
363 | public string Address; | ||
364 | public ushort Port; | ||
365 | |||
366 | public RegionIP() | ||
367 | { | ||
368 | |||
369 | } | ||
370 | |||
371 | } | ||
372 | } | ||
diff --git a/src/InventoryManager.cs b/src/InventoryManager.cs new file mode 100644 index 0000000..1df55a3 --- /dev/null +++ b/src/InventoryManager.cs | |||
@@ -0,0 +1,242 @@ | |||
1 | /* | ||
2 | Copyright (c) OpenSim project, http://osgrid.org/ | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions are met: | ||
6 | * * Redistributions of source code must retain the above copyright | ||
7 | * notice, this list of conditions and the following disclaimer. | ||
8 | * * Redistributions in binary form must reproduce the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer in the | ||
10 | * documentation and/or other materials provided with the distribution. | ||
11 | * * Neither the name of the <organization> nor the | ||
12 | * names of its contributors may be used to endorse or promote products | ||
13 | * derived from this software without specific prior written permission. | ||
14 | * | ||
15 | * THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY | ||
16 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
18 | * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY | ||
19 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
22 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
25 | */ | ||
26 | |||
27 | using System; | ||
28 | using System.Collections.Generic; | ||
29 | using libsecondlife; | ||
30 | using libsecondlife.Packets; | ||
31 | using libsecondlife.AssetSystem; | ||
32 | using System.IO; | ||
33 | |||
34 | namespace OpenSim | ||
35 | { | ||
36 | /// <summary> | ||
37 | /// Description of InventoryManager. | ||
38 | /// </summary> | ||
39 | public class InventoryManager | ||
40 | { | ||
41 | |||
42 | public Dictionary<LLUUID, InventoryFolder> Folders; | ||
43 | public Dictionary<LLUUID, InventoryItem> Items; | ||
44 | private Server _server; | ||
45 | private System.Text.Encoding _enc = System.Text.Encoding.ASCII; | ||
46 | private const uint FULL_MASK_PERMISSIONS = 2147483647; | ||
47 | |||
48 | /// <summary> | ||
49 | /// | ||
50 | /// </summary> | ||
51 | /// <param name="serve"></param> | ||
52 | public InventoryManager(Server server) | ||
53 | { | ||
54 | _server = server; | ||
55 | Folders=new Dictionary<LLUUID, InventoryFolder>(); | ||
56 | Items=new Dictionary<LLUUID, InventoryItem>(); | ||
57 | } | ||
58 | |||
59 | /// <summary> | ||
60 | /// | ||
61 | /// </summary> | ||
62 | /// <param name="UserInfo"></param> | ||
63 | /// <param name="FolderID"></param> | ||
64 | /// <param name="Asset"></param> | ||
65 | /// <returns></returns> | ||
66 | public LLUUID AddToInventory(UserAgentInfo userInfo, LLUUID folderID, AssetBase asset) | ||
67 | { | ||
68 | if(this.Folders.ContainsKey(folderID)) | ||
69 | { | ||
70 | LLUUID NewItemID = LLUUID.Random(); | ||
71 | |||
72 | InventoryItem Item = new InventoryItem(); | ||
73 | Item.FolderID = folderID; | ||
74 | Item.OwnerID = userInfo.AgentID; | ||
75 | Item.AssetID = asset.FullID; | ||
76 | Item.ItemID = NewItemID; | ||
77 | Item.Type = asset.Type; | ||
78 | Item.Name = asset.Name; | ||
79 | Item.Description = asset.Description; | ||
80 | Item.InvType = asset.InvType; | ||
81 | this.Items.Add(Item.ItemID, Item); | ||
82 | InventoryFolder Folder = Folders[Item.FolderID]; | ||
83 | Folder.Items.Add(Item); | ||
84 | return(Item.ItemID); | ||
85 | } | ||
86 | else | ||
87 | { | ||
88 | return(null); | ||
89 | } | ||
90 | } | ||
91 | |||
92 | /// <summary> | ||
93 | /// | ||
94 | /// </summary> | ||
95 | /// <param name="UserInfo"></param> | ||
96 | /// <param name="NewFolder"></param> | ||
97 | /// <returns></returns> | ||
98 | public bool CreateNewFolder(UserAgentInfo userInfo, LLUUID newFolder) | ||
99 | { | ||
100 | InventoryFolder Folder = new InventoryFolder(); | ||
101 | Folder.FolderID = newFolder; | ||
102 | Folder.OwnerID = userInfo.AgentID; | ||
103 | this.Folders.Add(Folder.FolderID, Folder); | ||
104 | |||
105 | return(true); | ||
106 | } | ||
107 | |||
108 | /// <summary> | ||
109 | /// | ||
110 | /// </summary> | ||
111 | /// <param name="User_info"></param> | ||
112 | /// <param name="FetchDescend"></param> | ||
113 | public void FetchInventoryDescendents(UserAgentInfo userInfo, FetchInventoryDescendentsPacket FetchDescend) | ||
114 | { | ||
115 | if(FetchDescend.InventoryData.FetchItems) | ||
116 | { | ||
117 | if(this.Folders.ContainsKey(FetchDescend.InventoryData.FolderID)) | ||
118 | { | ||
119 | |||
120 | InventoryFolder Folder = this.Folders[FetchDescend.InventoryData.FolderID]; | ||
121 | InventoryDescendentsPacket Descend = new InventoryDescendentsPacket(); | ||
122 | Descend.AgentData.AgentID = userInfo.AgentID; | ||
123 | Descend.AgentData.OwnerID = Folder.OwnerID; | ||
124 | Descend.AgentData.FolderID = FetchDescend.InventoryData.FolderID; | ||
125 | Descend.AgentData.Descendents = Folder.Items.Count; | ||
126 | Descend.AgentData.Version = Folder.Items.Count; | ||
127 | |||
128 | Descend.ItemData = new InventoryDescendentsPacket.ItemDataBlock[Folder.Items.Count]; | ||
129 | for(int i = 0; i < Folder.Items.Count ; i++) | ||
130 | { | ||
131 | |||
132 | InventoryItem Item=Folder.Items[i]; | ||
133 | Descend.ItemData[i] = new InventoryDescendentsPacket.ItemDataBlock(); | ||
134 | Descend.ItemData[i].ItemID = Item.ItemID; | ||
135 | Descend.ItemData[i].AssetID = Item.AssetID; | ||
136 | Descend.ItemData[i].CreatorID = Item.CreatorID; | ||
137 | Descend.ItemData[i].BaseMask = FULL_MASK_PERMISSIONS; | ||
138 | Descend.ItemData[i].CreationDate = 1000; | ||
139 | Descend.ItemData[i].Description = _enc.GetBytes(Item.Description+"\0"); | ||
140 | Descend.ItemData[i].EveryoneMask = FULL_MASK_PERMISSIONS; | ||
141 | Descend.ItemData[i].Flags = 1; | ||
142 | Descend.ItemData[i].FolderID = Item.FolderID; | ||
143 | Descend.ItemData[i].GroupID = new LLUUID("00000000-0000-0000-0000-000000000000"); | ||
144 | Descend.ItemData[i].GroupMask = FULL_MASK_PERMISSIONS; | ||
145 | Descend.ItemData[i].InvType = Item.InvType; | ||
146 | Descend.ItemData[i].Name = _enc.GetBytes(Item.Name+"\0"); | ||
147 | Descend.ItemData[i].NextOwnerMask = FULL_MASK_PERMISSIONS; | ||
148 | Descend.ItemData[i].OwnerID = Item.OwnerID; | ||
149 | Descend.ItemData[i].OwnerMask = FULL_MASK_PERMISSIONS; | ||
150 | Descend.ItemData[i].SalePrice = 100; | ||
151 | Descend.ItemData[i].SaleType = 0; | ||
152 | Descend.ItemData[i].Type = Item.Type; | ||
153 | Descend.ItemData[i].CRC=libsecondlife.Helpers.InventoryCRC(1000, 0, Descend.ItemData[i].InvType, Descend.ItemData[i].Type, Descend.ItemData[i].AssetID, Descend.ItemData[i].GroupID, 100, Descend.ItemData[i].OwnerID, Descend.ItemData[i].CreatorID, Descend.ItemData[i].ItemID, Descend.ItemData[i].FolderID, FULL_MASK_PERMISSIONS, 1, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS); | ||
154 | } | ||
155 | _server.SendPacket(Descend, true, userInfo); | ||
156 | |||
157 | } | ||
158 | } | ||
159 | else | ||
160 | { | ||
161 | Console.WriteLine("fetch subfolders"); | ||
162 | } | ||
163 | } | ||
164 | |||
165 | /// <summary> | ||
166 | /// | ||
167 | /// </summary> | ||
168 | /// <param name="User_info"></param> | ||
169 | public void FetchInventory(UserAgentInfo userInfo, FetchInventoryPacket FetchItems) | ||
170 | { | ||
171 | |||
172 | for(int i = 0; i < FetchItems.InventoryData.Length; i++) | ||
173 | { | ||
174 | if(this.Items.ContainsKey(FetchItems.InventoryData[i].ItemID)) | ||
175 | { | ||
176 | |||
177 | InventoryItem Item = Items[FetchItems.InventoryData[i].ItemID]; | ||
178 | FetchInventoryReplyPacket InventoryReply = new FetchInventoryReplyPacket(); | ||
179 | InventoryReply.AgentData.AgentID = userInfo.AgentID; | ||
180 | InventoryReply.InventoryData = new FetchInventoryReplyPacket.InventoryDataBlock[1]; | ||
181 | InventoryReply.InventoryData[0] = new FetchInventoryReplyPacket.InventoryDataBlock(); | ||
182 | InventoryReply.InventoryData[0].ItemID = Item.ItemID; | ||
183 | InventoryReply.InventoryData[0].AssetID = Item.AssetID; | ||
184 | InventoryReply.InventoryData[0].CreatorID = Item.CreatorID; | ||
185 | InventoryReply.InventoryData[0].BaseMask = FULL_MASK_PERMISSIONS; | ||
186 | InventoryReply.InventoryData[0].CreationDate = 1000; | ||
187 | InventoryReply.InventoryData[0].Description = _enc.GetBytes( Item.Description+"\0"); | ||
188 | InventoryReply.InventoryData[0].EveryoneMask = FULL_MASK_PERMISSIONS; | ||
189 | InventoryReply.InventoryData[0].Flags = 1; | ||
190 | InventoryReply.InventoryData[0].FolderID = Item.FolderID; | ||
191 | InventoryReply.InventoryData[0].GroupID = new LLUUID("00000000-0000-0000-0000-000000000000"); | ||
192 | InventoryReply.InventoryData[0].GroupMask = FULL_MASK_PERMISSIONS; | ||
193 | InventoryReply.InventoryData[0].InvType = Item.InvType; | ||
194 | InventoryReply.InventoryData[0].Name = _enc.GetBytes(Item.Name+"\0"); | ||
195 | InventoryReply.InventoryData[0].NextOwnerMask = FULL_MASK_PERMISSIONS; | ||
196 | InventoryReply.InventoryData[0].OwnerID = Item.OwnerID; | ||
197 | InventoryReply.InventoryData[0].OwnerMask = FULL_MASK_PERMISSIONS; | ||
198 | InventoryReply.InventoryData[0].SalePrice = 100; | ||
199 | InventoryReply.InventoryData[0].SaleType = 0; | ||
200 | InventoryReply.InventoryData[0].Type = Item.Type; | ||
201 | InventoryReply.InventoryData[0].CRC = libsecondlife.Helpers.InventoryCRC(1000, 0, InventoryReply.InventoryData[0].InvType, InventoryReply.InventoryData[0].Type, InventoryReply.InventoryData[0].AssetID, InventoryReply.InventoryData[0].GroupID, 100, InventoryReply.InventoryData[0].OwnerID, InventoryReply.InventoryData[0].CreatorID, InventoryReply.InventoryData[0].ItemID, InventoryReply.InventoryData[0].FolderID, FULL_MASK_PERMISSIONS, 1, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS); | ||
202 | _server.SendPacket(InventoryReply, true, userInfo); | ||
203 | } | ||
204 | } | ||
205 | } | ||
206 | } | ||
207 | |||
208 | public class InventoryFolder | ||
209 | { | ||
210 | public List<InventoryItem> Items; | ||
211 | //public List<InventoryFolder> Subfolders; | ||
212 | |||
213 | public LLUUID FolderID; | ||
214 | public LLUUID OwnerID; | ||
215 | public LLUUID ParentID; | ||
216 | |||
217 | |||
218 | public InventoryFolder() | ||
219 | { | ||
220 | Items = new List<InventoryItem>(); | ||
221 | } | ||
222 | |||
223 | } | ||
224 | |||
225 | public class InventoryItem | ||
226 | { | ||
227 | public LLUUID FolderID; | ||
228 | public LLUUID OwnerID; | ||
229 | public LLUUID ItemID; | ||
230 | public LLUUID AssetID; | ||
231 | public LLUUID CreatorID = LLUUID.Zero; | ||
232 | public sbyte InvType; | ||
233 | public sbyte Type; | ||
234 | public string Name; | ||
235 | public string Description; | ||
236 | |||
237 | public InventoryItem() | ||
238 | { | ||
239 | |||
240 | } | ||
241 | } | ||
242 | } | ||
diff --git a/src/Login_manager.cs b/src/Login_manager.cs new file mode 100644 index 0000000..dd741f5 --- /dev/null +++ b/src/Login_manager.cs | |||
@@ -0,0 +1,228 @@ | |||
1 | /* | ||
2 | * Copyright (c) OpenSim project, http://osgrid.org/> | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the <organization> nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | using Nwc.XmlRpc; | ||
28 | using System; | ||
29 | using System.IO; | ||
30 | using System.Net; | ||
31 | using System.Net.Sockets; | ||
32 | using System.Text; | ||
33 | using System.Text.RegularExpressions; | ||
34 | using System.Threading; | ||
35 | using System.Collections; | ||
36 | using System.Xml; | ||
37 | using libsecondlife; | ||
38 | |||
39 | namespace OpenSim | ||
40 | { | ||
41 | /// <summary> | ||
42 | /// Description of Login_manager. | ||
43 | /// </summary> | ||
44 | public class LoginManager | ||
45 | { | ||
46 | public LoginManager(Logon login) | ||
47 | { | ||
48 | Login=login; | ||
49 | } | ||
50 | public Logon Login; | ||
51 | public ushort loginPort = Globals.Instance.LoginServerPort; | ||
52 | public IPAddress clientAddress = IPAddress.Loopback; | ||
53 | public IPAddress remoteAddress = IPAddress.Any; | ||
54 | private Socket loginServer; | ||
55 | private Random RandomClass = new Random(); | ||
56 | private int NumClients; | ||
57 | |||
58 | // InitializeLoginProxy: initialize the login proxy | ||
59 | private void InitializeLoginProxy() { | ||
60 | loginServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); | ||
61 | loginServer.Bind(new IPEndPoint(remoteAddress, loginPort)); | ||
62 | loginServer.Listen(1); | ||
63 | } | ||
64 | |||
65 | public void Startup() | ||
66 | { | ||
67 | this.InitializeLoginProxy(); | ||
68 | Thread runLoginProxy = new Thread(new ThreadStart(RunLoginProxy)); | ||
69 | runLoginProxy.IsBackground = true; | ||
70 | runLoginProxy.Start(); | ||
71 | } | ||
72 | |||
73 | private void RunLoginProxy() | ||
74 | { | ||
75 | try | ||
76 | { | ||
77 | for (;;) | ||
78 | { | ||
79 | Socket client = loginServer.Accept(); | ||
80 | IPEndPoint clientEndPoint = (IPEndPoint)client.RemoteEndPoint; | ||
81 | |||
82 | |||
83 | NetworkStream networkStream = new NetworkStream(client); | ||
84 | StreamReader networkReader = new StreamReader(networkStream); | ||
85 | StreamWriter networkWriter = new StreamWriter(networkStream); | ||
86 | |||
87 | try | ||
88 | { | ||
89 | ProxyLogin(networkReader, networkWriter); | ||
90 | } | ||
91 | catch (Exception e) | ||
92 | { | ||
93 | Console.WriteLine(e.Message); | ||
94 | } | ||
95 | |||
96 | networkWriter.Close(); | ||
97 | networkReader.Close(); | ||
98 | networkStream.Close(); | ||
99 | |||
100 | client.Close(); | ||
101 | |||
102 | // send any packets queued for injection | ||
103 | |||
104 | } | ||
105 | } | ||
106 | catch (Exception e) | ||
107 | { | ||
108 | Console.WriteLine(e.Message); | ||
109 | Console.WriteLine(e.StackTrace); | ||
110 | } | ||
111 | } | ||
112 | |||
113 | // ProxyLogin: proxy a login request | ||
114 | private void ProxyLogin(StreamReader reader, StreamWriter writer) { lock(this) { | ||
115 | string line; | ||
116 | int contentLength = 0; | ||
117 | |||
118 | // read HTTP header | ||
119 | do | ||
120 | { | ||
121 | // read one line of the header | ||
122 | line = reader.ReadLine(); | ||
123 | |||
124 | // check for premature EOF | ||
125 | if (line == null) | ||
126 | throw new Exception("EOF in client HTTP header"); | ||
127 | |||
128 | // look for Content-Length | ||
129 | Match match = (new Regex(@"Content-Length: (\d+)$")).Match(line); | ||
130 | if (match.Success) | ||
131 | contentLength = Convert.ToInt32(match.Groups[1].Captures[0].ToString()); | ||
132 | } while (line != ""); | ||
133 | |||
134 | // read the HTTP body into a buffer | ||
135 | char[] content = new char[contentLength]; | ||
136 | reader.Read(content, 0, contentLength); | ||
137 | //System.Text.Encoding enc = System.Text.Encoding.ASCII; | ||
138 | XmlRpcRequest request = (XmlRpcRequest)(new XmlRpcRequestDeserializer()).Deserialize(new String(content)); | ||
139 | Hashtable requestData = (Hashtable)request.Params[0]; | ||
140 | |||
141 | string first; | ||
142 | string last; | ||
143 | LLUUID Agent; | ||
144 | LLUUID Session; | ||
145 | |||
146 | //get login name | ||
147 | if(requestData.Contains("first")) | ||
148 | { | ||
149 | first = (string)requestData["first"]; | ||
150 | } | ||
151 | else | ||
152 | { | ||
153 | first = "test"; | ||
154 | } | ||
155 | if(requestData.Contains("last")) | ||
156 | { | ||
157 | last = (string)requestData["last"]; | ||
158 | } | ||
159 | else | ||
160 | { | ||
161 | last = "User"+NumClients.ToString(); | ||
162 | } | ||
163 | NumClients++; | ||
164 | |||
165 | //create a agent and session LLUUID | ||
166 | int AgentRand = this.RandomClass.Next(1,9999); | ||
167 | Agent = new LLUUID("99998888-"+AgentRand.ToString("0000")+"-4f52-8ec1-0b1d5cd6aead"); | ||
168 | int SessionRand = this.RandomClass.Next(1,999); | ||
169 | Session = new LLUUID("aaaabbbb-8932-"+SessionRand.ToString("0000")+"-8664-58f53e442797"); | ||
170 | |||
171 | |||
172 | StreamReader SR; | ||
173 | string ResponseString = ""; | ||
174 | string lines; | ||
175 | SR=File.OpenText("new-login.dat"); | ||
176 | |||
177 | lines=SR.ReadLine(); | ||
178 | |||
179 | while(lines != "end-mfile") | ||
180 | { | ||
181 | |||
182 | ResponseString += lines; | ||
183 | lines = SR.ReadLine(); | ||
184 | } | ||
185 | SR.Close(); | ||
186 | |||
187 | XmlRpcResponse response =(XmlRpcResponse)(new XmlRpcResponseDeserializer()).Deserialize(ResponseString); | ||
188 | Hashtable responseData = (Hashtable)response.Value; | ||
189 | |||
190 | responseData["agent_id"] = Agent.ToStringHyphenated(); | ||
191 | responseData["session_id"] = Session.ToStringHyphenated(); | ||
192 | ArrayList InventoryList = (ArrayList) responseData["inventory-skeleton"]; | ||
193 | Hashtable Inventory1 = (Hashtable)InventoryList[0]; | ||
194 | Hashtable Inventory2 = (Hashtable)InventoryList[1]; | ||
195 | LLUUID BaseFolderID = LLUUID.Random(); | ||
196 | LLUUID InventoryFolderID = LLUUID.Random(); | ||
197 | Inventory2["name"] = "Base"; | ||
198 | Inventory2["folder_id"] = BaseFolderID.ToStringHyphenated(); | ||
199 | Inventory1["folder_id"] = InventoryFolderID.ToStringHyphenated(); | ||
200 | |||
201 | ArrayList InventoryRoot = (ArrayList) responseData["inventory-root"]; | ||
202 | Hashtable Inventoryroot = (Hashtable)InventoryRoot[0]; | ||
203 | Inventoryroot["folder_id"] = InventoryFolderID.ToStringHyphenated(); | ||
204 | |||
205 | |||
206 | //copy data to login object | ||
207 | lock(Login) | ||
208 | { | ||
209 | Login.First = first; | ||
210 | Login.Last = last; | ||
211 | Login.Agent = Agent; | ||
212 | Login.Session = Session; | ||
213 | Login.BaseFolder = BaseFolderID; | ||
214 | Login.InventoryFolder = InventoryFolderID; | ||
215 | } | ||
216 | |||
217 | // forward the XML-RPC response to the client | ||
218 | writer.WriteLine("HTTP/1.0 200 OK"); | ||
219 | writer.WriteLine("Content-type: text/xml"); | ||
220 | writer.WriteLine(); | ||
221 | |||
222 | XmlTextWriter responseWriter = new XmlTextWriter(writer); | ||
223 | XmlRpcResponseSerializer.Singleton.Serialize(responseWriter, response); | ||
224 | responseWriter.Close(); | ||
225 | } | ||
226 | } | ||
227 | } | ||
228 | } | ||
diff --git a/src/Main.cs b/src/Main.cs new file mode 100644 index 0000000..da926db --- /dev/null +++ b/src/Main.cs | |||
@@ -0,0 +1,138 @@ | |||
1 | /* | ||
2 | Copyright (c) OpenSim project, http://osgrid.org/ | ||
3 | |||
4 | |||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Redistribution and use in source and binary forms, with or without | ||
8 | * modification, are permitted provided that the following conditions are met: | ||
9 | * * Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * * Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * * Neither the name of the <organization> nor the | ||
15 | * names of its contributors may be used to endorse or promote products | ||
16 | * derived from this software without specific prior written permission. | ||
17 | * | ||
18 | * THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY | ||
19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
21 | * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY | ||
22 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
24 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
25 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
28 | */ | ||
29 | |||
30 | using System; | ||
31 | using System.Text; | ||
32 | using System.IO; | ||
33 | using System.Threading; | ||
34 | using System.Net; | ||
35 | using System.Net.Sockets; | ||
36 | using System.Collections; | ||
37 | using System.Collections.Generic; | ||
38 | using libsecondlife; | ||
39 | using libsecondlife.Packets; | ||
40 | using OpenSim.world; | ||
41 | |||
42 | namespace OpenSim | ||
43 | { | ||
44 | /// <summary> | ||
45 | /// Description of MainForm. | ||
46 | /// </summary> | ||
47 | public class OpenSim_Main | ||
48 | { | ||
49 | private static OpenSim_Main sim; | ||
50 | public static SimConfig cfg; | ||
51 | public static World local_world; | ||
52 | private static Thread MainListener; | ||
53 | private static Thread PingRespponder; | ||
54 | public static Socket Server; | ||
55 | private static IPEndPoint ServerIncoming; | ||
56 | private static byte[] RecvBuffer = new byte[4096]; | ||
57 | private byte[] ZeroBuffer = new byte[8192]; | ||
58 | private static IPEndPoint ipeSender; | ||
59 | private static EndPoint epSender; | ||
60 | private static AsyncCallback ReceivedData; | ||
61 | public Dictionary<EndPoint, OpenSimClient> ClientThreads = new Dictionary<EndPoint, OpenSimClient>(); | ||
62 | |||
63 | [STAThread] | ||
64 | public static void Main( string[] args ) | ||
65 | { | ||
66 | Console.WriteLine("OpenSim " + VersionInfo.Version + "\n"); | ||
67 | Console.WriteLine("Starting...\n"); | ||
68 | sim = new OpenSim_Main(); | ||
69 | sim.Startup(); | ||
70 | while(true) { | ||
71 | Thread.Sleep(1000); | ||
72 | } | ||
73 | } | ||
74 | |||
75 | private OpenSim_Main() { | ||
76 | } | ||
77 | |||
78 | private void Startup() { | ||
79 | // We check our local database first, then the grid for config options | ||
80 | Console.WriteLine("Main.cs:Startup() - Loading configuration"); | ||
81 | cfg = new SimConfig(); | ||
82 | cfg.InitConfig(); | ||
83 | Console.WriteLine("Main.cs:Startup() - Contacting gridserver"); | ||
84 | cfg.LoadFromGrid(); | ||
85 | |||
86 | Console.WriteLine("Main.cs:Startup() - We are " + cfg.RegionName + " at " + cfg.RegionLocX.ToString() + "," + cfg.RegionLocY.ToString()); | ||
87 | Console.WriteLine("Initialising world"); | ||
88 | local_world = cfg.LoadWorld(); | ||
89 | |||
90 | Console.WriteLine("Main.cs:Startup() - Starting up messaging system"); | ||
91 | MainListener = new Thread(new ThreadStart(MainServerListener)); | ||
92 | MainListener.Start(); | ||
93 | |||
94 | } | ||
95 | |||
96 | private void OnReceivedData(IAsyncResult result) { | ||
97 | ipeSender = new IPEndPoint(IPAddress.Any, 0); | ||
98 | epSender = (EndPoint)ipeSender; | ||
99 | Packet packet = null; | ||
100 | int numBytes = Server.EndReceiveFrom(result, ref epSender); | ||
101 | int packetEnd = numBytes - 1; | ||
102 | packet = Packet.BuildPacket(RecvBuffer, ref packetEnd, ZeroBuffer); | ||
103 | Console.Error.WriteLine(packet.ToString()); | ||
104 | |||
105 | // This is either a new client or a packet to send to an old one | ||
106 | if(ClientThreads.ContainsKey(epSender)) { | ||
107 | ClientThreads[epSender].InPacket(packet); | ||
108 | } else if( packet.Type == PacketType.UseCircuitCode ) { // new client | ||
109 | OpenSimClient newuser = new OpenSimClient(epSender,(UseCircuitCodePacket)packet); | ||
110 | ClientThreads.Add(epSender, newuser); | ||
111 | } else { // invalid client | ||
112 | Console.Error.WriteLine("Main.cs:OnReceivedData() - WARNING: Got a packet from an invalid client - " + epSender.ToString()); | ||
113 | } | ||
114 | Server.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null); | ||
115 | } | ||
116 | |||
117 | private void MainServerListener() { | ||
118 | Console.WriteLine("Main.cs:MainServerListener() - New thread started"); | ||
119 | Console.WriteLine("Main.cs:MainServerListener() - Opening UDP socket on " + cfg.IPListenAddr + ":" + cfg.IPListenPort); | ||
120 | |||
121 | ServerIncoming = new IPEndPoint(IPAddress.Parse(cfg.IPListenAddr),cfg.IPListenPort); | ||
122 | Server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); | ||
123 | Server.Bind(ServerIncoming); | ||
124 | |||
125 | Console.WriteLine("Main.cs:MainServerListener() - UDP socket bound, getting ready to listen"); | ||
126 | |||
127 | ipeSender = new IPEndPoint(IPAddress.Any, 0); | ||
128 | epSender = (EndPoint) ipeSender; | ||
129 | ReceivedData = new AsyncCallback(this.OnReceivedData); | ||
130 | Server.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null); | ||
131 | |||
132 | Console.WriteLine("Main.cs:MainServerListener() - Listening..."); | ||
133 | while(true) { | ||
134 | Thread.Sleep(1000); | ||
135 | } | ||
136 | } | ||
137 | } | ||
138 | } | ||
diff --git a/src/OpenSimClient.cs b/src/OpenSimClient.cs new file mode 100644 index 0000000..d3f90b7 --- /dev/null +++ b/src/OpenSimClient.cs | |||
@@ -0,0 +1,339 @@ | |||
1 | /* | ||
2 | Copyright (c) OpenSim project, http://osgrid.org/ | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions are met: | ||
6 | * * Redistributions of source code must retain the above copyright | ||
7 | * notice, this list of conditions and the following disclaimer. | ||
8 | * * Redistributions in binary form must reproduce the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer in the | ||
10 | * documentation and/or other materials provided with the distribution. | ||
11 | * * Neither the name of the <organization> nor the | ||
12 | * names of its contributors may be used to endorse or promote products | ||
13 | * derived from this software without specific prior written permission. | ||
14 | * | ||
15 | * THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY | ||
16 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
18 | * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY | ||
19 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
22 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
25 | */ | ||
26 | |||
27 | using System; | ||
28 | using System.Collections; | ||
29 | using System.Collections.Generic; | ||
30 | using libsecondlife; | ||
31 | using libsecondlife.Packets; | ||
32 | using System.Net; | ||
33 | using System.Net.Sockets; | ||
34 | using System.IO; | ||
35 | using System.Threading; | ||
36 | using System.Timers; | ||
37 | |||
38 | namespace OpenSim | ||
39 | { | ||
40 | /// <summary> | ||
41 | /// Handles new client connections | ||
42 | /// Constructor takes a single Packet and authenticates everything | ||
43 | /// </summary> | ||
44 | public class OpenSimClient { | ||
45 | |||
46 | public LLUUID AgentID; | ||
47 | public LLUUID SessionID; | ||
48 | public uint CircuitCode; | ||
49 | public world.Avatar ClientAvatar; | ||
50 | private UseCircuitCodePacket cirpack; | ||
51 | private Thread ClientThread; | ||
52 | private EndPoint userEP; | ||
53 | private BlockingQueue<QueItem> PacketQueue; | ||
54 | private Dictionary<uint, uint> PendingAcks = new Dictionary<uint, uint>(); | ||
55 | private Dictionary<uint, Packet> NeedAck = new Dictionary<uint, Packet>(); | ||
56 | private System.Timers.Timer AckTimer; | ||
57 | private uint Sequence = 0; | ||
58 | private object SequenceLock = new object(); | ||
59 | private const int MAX_APPENDED_ACKS = 10; | ||
60 | private const int RESEND_TIMEOUT = 4000; | ||
61 | private const int MAX_SEQUENCE = 0xFFFFFF; | ||
62 | |||
63 | public void ack_pack(Packet Pack) { | ||
64 | //libsecondlife.Packets.PacketAckPacket ack_it = new PacketAckPacket(); | ||
65 | //ack_it.Packets = new PacketAckPacket.PacketsBlock[1]; | ||
66 | //ack_it.Packets[0] = new PacketAckPacket.PacketsBlock(); | ||
67 | //ack_it.Packets[0].ID = Pack.Header.ID; | ||
68 | //ack_it.Header.Reliable = false; | ||
69 | |||
70 | //OutPacket(ack_it); | ||
71 | |||
72 | if (Pack.Header.Reliable) { | ||
73 | lock (PendingAcks) { | ||
74 | uint sequence = (uint)Pack.Header.Sequence; | ||
75 | if (!PendingAcks.ContainsKey(sequence)) { PendingAcks[sequence] = sequence; } | ||
76 | } | ||
77 | } | ||
78 | } | ||
79 | |||
80 | public void ProcessInPacket(Packet Pack) { | ||
81 | ack_pack(Pack); | ||
82 | switch(Pack.Type) { | ||
83 | case PacketType.CompleteAgentMovement: | ||
84 | ClientAvatar.CompleteMovement(OpenSim_Main.local_world); | ||
85 | break; | ||
86 | } | ||
87 | } | ||
88 | |||
89 | private void ResendUnacked() | ||
90 | { | ||
91 | int now = Environment.TickCount; | ||
92 | |||
93 | lock (NeedAck) | ||
94 | { | ||
95 | foreach (Packet packet in NeedAck.Values) | ||
96 | { | ||
97 | if (now - packet.TickCount > RESEND_TIMEOUT) | ||
98 | { | ||
99 | Console.WriteLine("Resending " + packet.Type.ToString() + " packet, " + | ||
100 | (now - packet.TickCount) + "ms have passed", Helpers.LogLevel.Info); | ||
101 | |||
102 | packet.Header.Resent = true; | ||
103 | OutPacket(packet); | ||
104 | } | ||
105 | } | ||
106 | } | ||
107 | } | ||
108 | |||
109 | private void SendAcks() | ||
110 | { | ||
111 | lock (PendingAcks) | ||
112 | { | ||
113 | if (PendingAcks.Count > 0) | ||
114 | { | ||
115 | if (PendingAcks.Count > 250) | ||
116 | { | ||
117 | // FIXME: Handle the odd case where we have too many pending ACKs queued up | ||
118 | Console.WriteLine("Too many ACKs queued up!", Helpers.LogLevel.Error); | ||
119 | return; | ||
120 | } | ||
121 | |||
122 | Console.WriteLine("Sending PacketAck"); | ||
123 | |||
124 | |||
125 | int i = 0; | ||
126 | PacketAckPacket acks = new PacketAckPacket(); | ||
127 | acks.Packets = new PacketAckPacket.PacketsBlock[PendingAcks.Count]; | ||
128 | |||
129 | foreach (uint ack in PendingAcks.Values) | ||
130 | { | ||
131 | acks.Packets[i] = new PacketAckPacket.PacketsBlock(); | ||
132 | acks.Packets[i].ID = ack; | ||
133 | i++; | ||
134 | } | ||
135 | |||
136 | acks.Header.Reliable = false; | ||
137 | OutPacket(acks); | ||
138 | |||
139 | PendingAcks.Clear(); | ||
140 | } | ||
141 | } | ||
142 | } | ||
143 | |||
144 | private void AckTimer_Elapsed(object sender, ElapsedEventArgs ea) | ||
145 | { | ||
146 | SendAcks(); ResendUnacked(); | ||
147 | } | ||
148 | |||
149 | public void ProcessOutPacket(Packet Pack) { | ||
150 | |||
151 | // Keep track of when this packet was sent out | ||
152 | Pack.TickCount = Environment.TickCount; | ||
153 | |||
154 | if (!Pack.Header.Resent) | ||
155 | { | ||
156 | // Set the sequence number | ||
157 | lock (SequenceLock) | ||
158 | { | ||
159 | if (Sequence >= MAX_SEQUENCE) | ||
160 | Sequence = 1; | ||
161 | else | ||
162 | Sequence++; | ||
163 | Pack.Header.Sequence = Sequence; | ||
164 | } | ||
165 | |||
166 | if (Pack.Header.Reliable) | ||
167 | { | ||
168 | lock (NeedAck) | ||
169 | { | ||
170 | if (!NeedAck.ContainsKey(Pack.Header.Sequence)) | ||
171 | { | ||
172 | NeedAck.Add(Pack.Header.Sequence, Pack); | ||
173 | } | ||
174 | else | ||
175 | { | ||
176 | // Client.Log("Attempted to add a duplicate sequence number (" + | ||
177 | // packet.Header.Sequence + ") to the NeedAck dictionary for packet type " + | ||
178 | // packet.Type.ToString(), Helpers.LogLevel.Warning); | ||
179 | } | ||
180 | } | ||
181 | |||
182 | // Don't append ACKs to resent packets, in case that's what was causing the | ||
183 | // delivery to fail | ||
184 | if (!Pack.Header.Resent) | ||
185 | { | ||
186 | // Append any ACKs that need to be sent out to this packet | ||
187 | lock (PendingAcks) | ||
188 | { | ||
189 | if (PendingAcks.Count > 0 && PendingAcks.Count < MAX_APPENDED_ACKS && | ||
190 | Pack.Type != PacketType.PacketAck && | ||
191 | Pack.Type != PacketType.LogoutRequest) | ||
192 | { | ||
193 | Pack.Header.AckList = new uint[PendingAcks.Count]; | ||
194 | int i = 0; | ||
195 | |||
196 | foreach (uint ack in PendingAcks.Values) | ||
197 | { | ||
198 | Pack.Header.AckList[i] = ack; | ||
199 | i++; | ||
200 | } | ||
201 | |||
202 | PendingAcks.Clear(); | ||
203 | Pack.Header.AppendedAcks = true; | ||
204 | } | ||
205 | } | ||
206 | } | ||
207 | } | ||
208 | } | ||
209 | |||
210 | Console.WriteLine("OUT: \n" + Pack.ToString()); | ||
211 | |||
212 | byte[] ZeroOutBuffer = new byte[4096]; | ||
213 | byte[] sendbuffer; | ||
214 | sendbuffer = Pack.ToBytes(); | ||
215 | |||
216 | try { | ||
217 | if (Pack.Header.Zerocoded) { | ||
218 | int packetsize = Helpers.ZeroEncode(sendbuffer, sendbuffer.Length, ZeroOutBuffer); | ||
219 | OpenSim_Main.Server.SendTo(ZeroOutBuffer, packetsize, SocketFlags.None,userEP); | ||
220 | } else { | ||
221 | OpenSim_Main.Server.SendTo(sendbuffer, sendbuffer.Length, SocketFlags.None,userEP); | ||
222 | } | ||
223 | } catch (Exception) { | ||
224 | Console.WriteLine("OpenSimClient.cs:ProcessOutPacket() - WARNING: Socket exception occurred on connection " + userEP.ToString() + " - killing thread"); | ||
225 | ClientThread.Abort(); | ||
226 | } | ||
227 | |||
228 | } | ||
229 | |||
230 | public void InPacket(Packet NewPack) { | ||
231 | // Handle appended ACKs | ||
232 | if (NewPack.Header.AppendedAcks) | ||
233 | { | ||
234 | lock (NeedAck) | ||
235 | { | ||
236 | foreach (uint ack in NewPack.Header.AckList) | ||
237 | { | ||
238 | NeedAck.Remove(ack); | ||
239 | } | ||
240 | } | ||
241 | } | ||
242 | |||
243 | // Handle PacketAck packets | ||
244 | if (NewPack.Type == PacketType.PacketAck) | ||
245 | { | ||
246 | PacketAckPacket ackPacket = (PacketAckPacket)NewPack; | ||
247 | |||
248 | lock (NeedAck) | ||
249 | { | ||
250 | foreach (PacketAckPacket.PacketsBlock block in ackPacket.Packets) | ||
251 | { | ||
252 | NeedAck.Remove(block.ID); | ||
253 | } | ||
254 | } | ||
255 | } else if( ( NewPack.Type == PacketType.StartPingCheck ) ) { | ||
256 | //reply to pingcheck | ||
257 | libsecondlife.Packets.StartPingCheckPacket startPing = (libsecondlife.Packets.StartPingCheckPacket)NewPack; | ||
258 | libsecondlife.Packets.CompletePingCheckPacket endPing = new CompletePingCheckPacket(); | ||
259 | endPing.PingID.PingID = startPing.PingID.PingID; | ||
260 | OutPacket(endPing); | ||
261 | } | ||
262 | else | ||
263 | { | ||
264 | QueItem item = new QueItem(); | ||
265 | item.Packet = NewPack; | ||
266 | item.Incoming = true; | ||
267 | this.PacketQueue.Enqueue(item); | ||
268 | } | ||
269 | |||
270 | } | ||
271 | |||
272 | public void OutPacket(Packet NewPack) { | ||
273 | QueItem item = new QueItem(); | ||
274 | item.Packet = NewPack; | ||
275 | item.Incoming = false; | ||
276 | this.PacketQueue.Enqueue(item); | ||
277 | } | ||
278 | |||
279 | public OpenSimClient(EndPoint remoteEP, UseCircuitCodePacket initialcirpack) { | ||
280 | Console.WriteLine("OpenSimClient.cs - Started up new client thread to handle incoming request"); | ||
281 | cirpack = initialcirpack; | ||
282 | userEP = remoteEP; | ||
283 | PacketQueue = new BlockingQueue<QueItem>(); | ||
284 | AckTimer = new System.Timers.Timer(500); | ||
285 | AckTimer.Elapsed += new ElapsedEventHandler(AckTimer_Elapsed); | ||
286 | AckTimer.Start(); | ||
287 | |||
288 | Thread ClientThread = new Thread(new ThreadStart(AuthUser)); | ||
289 | ClientThread.IsBackground = true; | ||
290 | ClientThread.Start(); | ||
291 | } | ||
292 | |||
293 | private void ClientLoop() { | ||
294 | Console.WriteLine("OpenSimClient.cs:ClientLoop() - Entered loop"); | ||
295 | while(true) { | ||
296 | QueItem nextPacket = PacketQueue.Dequeue(); | ||
297 | if(nextPacket.Incoming) | ||
298 | { | ||
299 | //is a incoming packet | ||
300 | ProcessInPacket(nextPacket.Packet); | ||
301 | } | ||
302 | else | ||
303 | { | ||
304 | //is a out going packet | ||
305 | ProcessOutPacket(nextPacket.Packet); | ||
306 | } | ||
307 | } | ||
308 | } | ||
309 | |||
310 | private void InitNewClient() { | ||
311 | Console.WriteLine("OpenSimClient.cs:InitNewClient() - Adding viewer agent to world"); | ||
312 | OpenSim_Main.local_world.AddViewerAgent(this); | ||
313 | world.Entity tempent=OpenSim_Main.local_world.Entities[this.AgentID]; | ||
314 | this.ClientAvatar=(world.Avatar)tempent; | ||
315 | } | ||
316 | |||
317 | private void AuthUser() { | ||
318 | Console.WriteLine("OpenSimClient.cs:AuthUser() - Authenticating new user request with grid"); | ||
319 | WebRequest CheckSession = WebRequest.Create(OpenSim_Main.cfg.GridURL + "/usersessions/" + OpenSim_Main.cfg.GridSendKey + "/" + cirpack.CircuitCode.ID.ToString() + "/" + cirpack.CircuitCode.Code.ToString() + "/exists"); | ||
320 | WebResponse GridResponse = CheckSession.GetResponse(); | ||
321 | StreamReader sr = new StreamReader(GridResponse.GetResponseStream()); | ||
322 | String grTest = sr.ReadLine(); | ||
323 | sr.Close(); | ||
324 | GridResponse.Close(); | ||
325 | if(grTest.Equals("1")) { // YAY! Valid login | ||
326 | Console.WriteLine("OpenSimClient.cs:AuthUser() - Got authenticated connection from " + userEP.ToString()); | ||
327 | this.AgentID=cirpack.CircuitCode.ID; | ||
328 | this.SessionID=cirpack.CircuitCode.SessionID; | ||
329 | this.CircuitCode=cirpack.CircuitCode.Code; | ||
330 | InitNewClient(); | ||
331 | ClientLoop(); | ||
332 | } else { // Invalid | ||
333 | Console.WriteLine("OpenSimClient.cs:AuthUser() - New user request denied to " + userEP.ToString()); | ||
334 | ClientThread.Abort(); | ||
335 | } | ||
336 | } | ||
337 | } | ||
338 | |||
339 | } | ||
diff --git a/src/Physics_manager.cs b/src/Physics_manager.cs new file mode 100644 index 0000000..a813deb --- /dev/null +++ b/src/Physics_manager.cs | |||
@@ -0,0 +1,41 @@ | |||
1 | /* | ||
2 | Copyright (c) OpenSim project, http://osgrid.org/ | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the <organization> nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | |||
30 | namespace OpenSim | ||
31 | { | ||
32 | /// <summary> | ||
33 | /// Description of Physics_manager. | ||
34 | /// </summary> | ||
35 | public class PhysicsManager | ||
36 | { | ||
37 | public PhysicsManager() | ||
38 | { | ||
39 | } | ||
40 | } | ||
41 | } | ||
diff --git a/src/Prim_manager.cs b/src/Prim_manager.cs new file mode 100644 index 0000000..72eae35 --- /dev/null +++ b/src/Prim_manager.cs | |||
@@ -0,0 +1,382 @@ | |||
1 | /* | ||
2 | Copyright (c) OpenSim project, http://osgrid.org/ | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the <organization> nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using libsecondlife; | ||
31 | using libsecondlife.Packets; | ||
32 | using libsecondlife.AssetSystem; | ||
33 | using System.IO; | ||
34 | using Axiom.MathLib; | ||
35 | |||
36 | namespace OpenSim | ||
37 | { | ||
38 | /// <summary> | ||
39 | /// Description of Prim_manager. | ||
40 | /// </summary> | ||
41 | public class PrimManager | ||
42 | { | ||
43 | private Server _server; | ||
44 | private uint _primCount; | ||
45 | |||
46 | public AgentManager AgentManagement; | ||
47 | public libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock PrimTemplate; | ||
48 | public Dictionary<libsecondlife.LLUUID,PrimInfo> PrimList; | ||
49 | |||
50 | /// <summary> | ||
51 | /// | ||
52 | /// </summary> | ||
53 | /// <param name="serve"></param> | ||
54 | public PrimManager(Server server) | ||
55 | { | ||
56 | _server = server; | ||
57 | PrimList = new Dictionary<libsecondlife.LLUUID,PrimInfo> (); | ||
58 | //this.SetupTemplates("objectupate164.dat"); | ||
59 | |||
60 | } | ||
61 | |||
62 | /// <summary> | ||
63 | /// | ||
64 | /// </summary> | ||
65 | /// <param name="User_info"></param> | ||
66 | /// <param name="p1"></param> | ||
67 | /// <param name="add_pack"></param> | ||
68 | public void CreatePrim(UserAgentInfo userInfo, libsecondlife.LLVector3 pos1, ObjectAddPacket addPacket) | ||
69 | { | ||
70 | ObjectUpdatePacket objupdate = new ObjectUpdatePacket(); | ||
71 | objupdate.RegionData.RegionHandle = Globals.Instance.RegionHandle; | ||
72 | objupdate.RegionData.TimeDilation = 64096; | ||
73 | |||
74 | objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1]; | ||
75 | PrimData PData = new PrimData(); | ||
76 | objupdate.ObjectData[0] = this.PrimTemplate; | ||
77 | PData.OwnerID=objupdate.ObjectData[0].OwnerID = userInfo.AgentID; | ||
78 | PData.PCode=objupdate.ObjectData[0].PCode = addPacket.ObjectData.PCode; | ||
79 | PData.PathBegin=objupdate.ObjectData[0].PathBegin = addPacket.ObjectData.PathBegin; | ||
80 | PData.PathEnd=objupdate.ObjectData[0].PathEnd = addPacket.ObjectData.PathEnd; | ||
81 | PData.PathScaleX=objupdate.ObjectData[0].PathScaleX = addPacket.ObjectData.PathScaleX; | ||
82 | PData.PathScaleY=objupdate.ObjectData[0].PathScaleY = addPacket.ObjectData.PathScaleY; | ||
83 | PData.PathShearX=objupdate.ObjectData[0].PathShearX = addPacket.ObjectData.PathShearX; | ||
84 | PData.PathShearY=objupdate.ObjectData[0].PathShearY = addPacket.ObjectData.PathShearY; | ||
85 | PData.PathSkew=objupdate.ObjectData[0].PathSkew = addPacket.ObjectData.PathSkew; | ||
86 | PData.ProfileBegin=objupdate.ObjectData[0].ProfileBegin = addPacket.ObjectData.ProfileBegin; | ||
87 | PData.ProfileEnd=objupdate.ObjectData[0].ProfileEnd = addPacket.ObjectData.ProfileEnd; | ||
88 | PData.Scale=objupdate.ObjectData[0].Scale = addPacket.ObjectData.Scale; | ||
89 | PData.PathCurve=objupdate.ObjectData[0].PathCurve = addPacket.ObjectData.PathCurve; | ||
90 | PData.ProfileCurve=objupdate.ObjectData[0].ProfileCurve = addPacket.ObjectData.ProfileCurve; | ||
91 | PData.ParentID=objupdate.ObjectData[0].ParentID = 0; | ||
92 | PData.ProfileHollow=objupdate.ObjectData[0].ProfileHollow = addPacket.ObjectData.ProfileHollow; | ||
93 | //finish off copying rest of shape data | ||
94 | |||
95 | objupdate.ObjectData[0].ID = (uint)(702000 + _primCount); | ||
96 | objupdate.ObjectData[0].FullID = new LLUUID("edba7151-5857-acc5-b30b-f01efefda"+_primCount.ToString("000")); | ||
97 | |||
98 | //update position | ||
99 | byte[] pb = pos1.GetBytes(); | ||
100 | Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 0, pb.Length); | ||
101 | |||
102 | _primCount++; | ||
103 | _server.SendPacket(objupdate, true, userInfo); | ||
104 | |||
105 | //should send to all users | ||
106 | foreach (KeyValuePair<libsecondlife.LLUUID, AvatarData> kp in AgentManagement.AgentList) | ||
107 | { | ||
108 | if(kp.Value.NetInfo.AgentID != userInfo.AgentID) | ||
109 | { | ||
110 | _server.SendPacket(objupdate, true, kp.Value.NetInfo); | ||
111 | } | ||
112 | } | ||
113 | //should store this infomation | ||
114 | PrimInfo NewPrim = new PrimInfo(); | ||
115 | NewPrim.FullID = objupdate.ObjectData[0].FullID; | ||
116 | NewPrim.LocalID = objupdate.ObjectData[0].ID; | ||
117 | NewPrim.Position = pos1; | ||
118 | NewPrim.Data = PData; | ||
119 | |||
120 | this.PrimList.Add(NewPrim.FullID, NewPrim); | ||
121 | |||
122 | //store rest of data | ||
123 | |||
124 | } | ||
125 | |||
126 | /// <summary> | ||
127 | /// | ||
128 | /// </summary> | ||
129 | /// <param name="User"></param> | ||
130 | /// <param name="position"></param> | ||
131 | /// <param name="LocalID"></param> | ||
132 | /// <param name="setRotation"></param> | ||
133 | /// <param name="rotation"></param> | ||
134 | public void UpdatePrimPosition(UserAgentInfo userInfo, LLVector3 position, uint localID, bool setRotation, LLQuaternion rotation) | ||
135 | { | ||
136 | PrimInfo pri = null; | ||
137 | foreach (KeyValuePair<libsecondlife.LLUUID,PrimInfo> kp in this.PrimList) | ||
138 | { | ||
139 | if(kp.Value.LocalID == localID) | ||
140 | { | ||
141 | pri = kp.Value; | ||
142 | } | ||
143 | } | ||
144 | if(pri == null) | ||
145 | { | ||
146 | return; | ||
147 | } | ||
148 | uint ID = pri.LocalID; | ||
149 | libsecondlife.LLVector3 pos2 = new LLVector3(position.X, position.Y, position.Z); | ||
150 | libsecondlife.LLQuaternion rotation2; | ||
151 | if(!setRotation) | ||
152 | { | ||
153 | pri.Position = pos2; | ||
154 | rotation2 = new LLQuaternion(pri.Rotation.X, pri.Rotation.Y, pri.Rotation.Z, pri.Rotation.W); | ||
155 | } | ||
156 | else | ||
157 | { | ||
158 | rotation2=new LLQuaternion(rotation.X, rotation.Y, rotation.Z, rotation.W); | ||
159 | pos2 = pri.Position; | ||
160 | pri.Rotation = rotation; | ||
161 | } | ||
162 | rotation2.W += 1; | ||
163 | rotation2.X += 1; | ||
164 | rotation2.Y += 1; | ||
165 | rotation2.Z += 1; | ||
166 | |||
167 | byte[] bytes = new byte[60]; | ||
168 | |||
169 | ImprovedTerseObjectUpdatePacket im = new ImprovedTerseObjectUpdatePacket(); | ||
170 | im.RegionData.RegionHandle = Globals.Instance.RegionHandle; | ||
171 | im.RegionData.TimeDilation = 64096; | ||
172 | im.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1]; | ||
173 | int i = 0; | ||
174 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock dat = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock(); | ||
175 | im.ObjectData[0] = dat; | ||
176 | dat.TextureEntry = PrimTemplate.TextureEntry; | ||
177 | |||
178 | bytes[i++] = (byte)(ID % 256); | ||
179 | bytes[i++] = (byte)((ID >> 8) % 256); | ||
180 | bytes[i++] = (byte)((ID >> 16) % 256); | ||
181 | bytes[i++] = (byte)((ID >> 24) % 256); | ||
182 | bytes[i++]= 0; | ||
183 | bytes[i++]= 0; | ||
184 | |||
185 | byte[] pb = pos2.GetBytes(); | ||
186 | pri.Position = pos2; | ||
187 | Array.Copy(pb, 0, bytes, i, pb.Length); | ||
188 | i += 12; | ||
189 | ushort ac = 32767; | ||
190 | |||
191 | //vel | ||
192 | bytes[i++] = (byte)(ac % 256); | ||
193 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
194 | bytes[i++] = (byte)(ac % 256); | ||
195 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
196 | bytes[i++] = (byte)(ac % 256); | ||
197 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
198 | |||
199 | //accel | ||
200 | bytes[i++] = (byte)(ac % 256); | ||
201 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
202 | bytes[i++] = (byte)(ac % 256); | ||
203 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
204 | bytes[i++] = (byte)(ac % 256); | ||
205 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
206 | |||
207 | ushort rw, rx,ry,rz; | ||
208 | rw = (ushort)(32768 * rotation2.W); | ||
209 | rx = (ushort)(32768 * rotation2.X); | ||
210 | ry = (ushort)(32768 * rotation2.Y); | ||
211 | rz = (ushort)(32768 * rotation2.Z); | ||
212 | |||
213 | //rot | ||
214 | bytes[i++] = (byte)(rx % 256); | ||
215 | bytes[i++] = (byte)((rx >> 8) % 256); | ||
216 | bytes[i++] = (byte)(ry % 256); | ||
217 | bytes[i++] = (byte)((ry >> 8) % 256); | ||
218 | bytes[i++] = (byte)(rz % 256); | ||
219 | bytes[i++] = (byte)((rz >> 8) % 256); | ||
220 | bytes[i++] = (byte)(rw % 256); | ||
221 | bytes[i++] = (byte)((rw >> 8) % 256); | ||
222 | |||
223 | //rotation vel | ||
224 | bytes[i++] = (byte)(ac % 256); | ||
225 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
226 | bytes[i++] = (byte)(ac % 256); | ||
227 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
228 | bytes[i++] = (byte)(ac % 256); | ||
229 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
230 | |||
231 | dat.Data=bytes; | ||
232 | |||
233 | foreach (KeyValuePair<libsecondlife.LLUUID,AvatarData> kp in AgentManagement.AgentList) | ||
234 | { | ||
235 | if(kp.Value.NetInfo.AgentID!=userInfo.AgentID) | ||
236 | { | ||
237 | _server.SendPacket(im, true, kp.Value.NetInfo); | ||
238 | } | ||
239 | } | ||
240 | } | ||
241 | |||
242 | /// <summary> | ||
243 | /// | ||
244 | /// </summary> | ||
245 | /// <param name="user"></param> | ||
246 | public void SendExistingPrims(UserAgentInfo userInfo) | ||
247 | { | ||
248 | //send data for already created prims to a new joining user | ||
249 | } | ||
250 | |||
251 | /// <summary> | ||
252 | /// | ||
253 | /// </summary> | ||
254 | /// <param name="name"></param> | ||
255 | public void SetupTemplates(string name) | ||
256 | { | ||
257 | ObjectUpdatePacket objupdate = new ObjectUpdatePacket(); | ||
258 | objupdate.RegionData.RegionHandle = Globals.Instance.RegionHandle; | ||
259 | objupdate.RegionData.TimeDilation = 64096; | ||
260 | objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1]; | ||
261 | |||
262 | int i = 0; | ||
263 | FileInfo fInfo = new FileInfo(name); | ||
264 | long numBytes = fInfo.Length; | ||
265 | FileStream fStream = new FileStream(name, FileMode.Open, FileAccess.Read); | ||
266 | BinaryReader br = new BinaryReader(fStream); | ||
267 | byte [] data1 = br.ReadBytes((int)numBytes); | ||
268 | br.Close(); | ||
269 | fStream.Close(); | ||
270 | |||
271 | libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock objdata = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock(data1,ref i); | ||
272 | objupdate.ObjectData[0] = objdata; | ||
273 | this.PrimTemplate = objdata; | ||
274 | objdata.UpdateFlags = objdata.UpdateFlags + 12 - 16 + 32 + 256; | ||
275 | objdata.OwnerID = new LLUUID("00000000-0000-0000-0000-000000000000"); | ||
276 | //test adding a new texture to object , to test image downloading | ||
277 | LLObject.TextureEntry te = new LLObject.TextureEntry(objdata.TextureEntry, 0, objdata.TextureEntry.Length); | ||
278 | te.DefaultTexture.TextureID = new LLUUID("00000000-0000-0000-5005-000000000005"); | ||
279 | |||
280 | LLObject.TextureEntry ntex = new LLObject.TextureEntry(new LLUUID("00000000-0000-0000-5005-000000000005")); | ||
281 | |||
282 | objdata.TextureEntry = ntex.ToBytes(); | ||
283 | } | ||
284 | |||
285 | /// <summary> | ||
286 | /// | ||
287 | /// </summary> | ||
288 | /// <param name="name"></param> | ||
289 | /// <param name="user"></param> | ||
290 | public void ReadPrimDatabase(string name, UserAgentInfo userInfo) | ||
291 | { | ||
292 | StreamReader SR; | ||
293 | string line; | ||
294 | SR=File.OpenText(name); | ||
295 | string [] comp = new string[10]; | ||
296 | string delimStr = " , "; | ||
297 | char [] delimiter = delimStr.ToCharArray(); | ||
298 | |||
299 | line=SR.ReadLine(); | ||
300 | while(line != "end") | ||
301 | { | ||
302 | comp = line.Split(delimiter); | ||
303 | if(comp[0] == "ObjPack") | ||
304 | { | ||
305 | int num = Convert.ToInt32(comp[2]); | ||
306 | int start = Convert.ToInt32(comp[1]); | ||
307 | ObjectUpdatePacket objupdate = new ObjectUpdatePacket(); | ||
308 | objupdate.RegionData.RegionHandle = Globals.Instance.RegionHandle; | ||
309 | objupdate.RegionData.TimeDilation = 64096; | ||
310 | objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[num]; | ||
311 | |||
312 | // int count=0; | ||
313 | string data_path = System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, @"data"); | ||
314 | for(int cc = 0; cc < num; cc++) | ||
315 | { | ||
316 | string filenam = System.IO.Path.Combine(data_path, @"prim_updates"+start+".dat"); | ||
317 | int i = 0; | ||
318 | //FileInfo fInfo = new FileInfo("objectupate"+start+".dat"); | ||
319 | FileInfo fInfo = new FileInfo(filenam); | ||
320 | long numBytes = fInfo.Length; | ||
321 | //FileStream fStream = new FileStream("objectupate"+start+".dat", FileMode.Open, FileAccess.Read); | ||
322 | FileStream fStream = new FileStream(filenam, FileMode.Open, FileAccess.Read); | ||
323 | BinaryReader br = new BinaryReader(fStream); | ||
324 | byte [] data1 = br.ReadBytes((int)numBytes); | ||
325 | br.Close(); | ||
326 | fStream.Close(); | ||
327 | |||
328 | libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock objdata = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock(data1, ref i); | ||
329 | objupdate.ObjectData[cc] = objdata; | ||
330 | start++; | ||
331 | } | ||
332 | _server.SendPacket(objupdate, true, userInfo); | ||
333 | line = SR.ReadLine(); | ||
334 | } | ||
335 | } | ||
336 | SR.Close(); | ||
337 | } | ||
338 | } | ||
339 | |||
340 | public class PrimInfo | ||
341 | { | ||
342 | public LLVector3 Position; | ||
343 | public LLVector3 Velocity; | ||
344 | public LLQuaternion Rotation=LLQuaternion.Identity; | ||
345 | public uint LocalID; | ||
346 | public LLUUID FullID; | ||
347 | public PrimData Data; | ||
348 | |||
349 | public PrimInfo() | ||
350 | { | ||
351 | Position=new LLVector3(0,0,0); | ||
352 | Velocity=new LLVector3(0,0,0); | ||
353 | //data=new PrimData(); | ||
354 | } | ||
355 | } | ||
356 | public class PrimData | ||
357 | { | ||
358 | public LLUUID OwnerID; | ||
359 | public byte PCode; | ||
360 | public byte PathBegin; | ||
361 | public byte PathEnd; | ||
362 | public byte PathScaleX; | ||
363 | public byte PathScaleY; | ||
364 | public byte PathShearX; | ||
365 | public byte PathShearY; | ||
366 | public sbyte PathSkew; | ||
367 | public byte ProfileBegin; | ||
368 | public byte ProfileEnd; | ||
369 | public LLVector3 Scale; | ||
370 | public byte PathCurve; | ||
371 | public byte ProfileCurve; | ||
372 | public uint ParentID=0; | ||
373 | public byte ProfileHollow; | ||
374 | |||
375 | public bool DataBaseStorage=false; | ||
376 | |||
377 | public PrimData() | ||
378 | { | ||
379 | |||
380 | } | ||
381 | } | ||
382 | } | ||
diff --git a/src/SceneGraphManager.cs b/src/SceneGraphManager.cs new file mode 100644 index 0000000..c71ad54 --- /dev/null +++ b/src/SceneGraphManager.cs | |||
@@ -0,0 +1,40 @@ | |||
1 | /* | ||
2 | Copyright (c) OpenSim project, http://osgrid.org/ | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions are met: | ||
6 | * * Redistributions of source code must retain the above copyright | ||
7 | * notice, this list of conditions and the following disclaimer. | ||
8 | * * Redistributions in binary form must reproduce the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer in the | ||
10 | * documentation and/or other materials provided with the distribution. | ||
11 | * * Neither the name of the <organization> nor the | ||
12 | * names of its contributors may be used to endorse or promote products | ||
13 | * derived from this software without specific prior written permission. | ||
14 | * | ||
15 | * THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY | ||
16 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
18 | * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY | ||
19 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
22 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
25 | */ | ||
26 | |||
27 | using System; | ||
28 | |||
29 | namespace OpenSim | ||
30 | { | ||
31 | /// <summary> | ||
32 | /// Description of SceneGraphManager. | ||
33 | /// </summary> | ||
34 | public class SceneGraphManager | ||
35 | { | ||
36 | public SceneGraphManager() | ||
37 | { | ||
38 | } | ||
39 | } | ||
40 | } | ||
diff --git a/src/Script_manager.cs b/src/Script_manager.cs new file mode 100644 index 0000000..1de1d22 --- /dev/null +++ b/src/Script_manager.cs | |||
@@ -0,0 +1,103 @@ | |||
1 | /* | ||
2 | Copyright (c) OpenSim project, http://osgrid.org/ | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the <organization> nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | |||
27 | */ | ||
28 | |||
29 | using System; | ||
30 | using System.Collections; | ||
31 | //using LuaInterface; | ||
32 | using libsecondlife; | ||
33 | |||
34 | namespace OpenSim | ||
35 | { | ||
36 | /// <summary> | ||
37 | /// Description of Script_manager. | ||
38 | /// </summary> | ||
39 | public class ScriptManager | ||
40 | { | ||
41 | //public LuaInterface.Lua Lu; | ||
42 | //private ArrayList scripts; | ||
43 | //private prim_info current_prim; | ||
44 | |||
45 | public ScriptManager() | ||
46 | { | ||
47 | } | ||
48 | |||
49 | /*public void start_up (Lua lua, App ap) | ||
50 | { | ||
51 | this.Lu=lua; | ||
52 | //register any lua routines , like check finish script one | ||
53 | Lu.OpenMathLib(); | ||
54 | }*/ | ||
55 | |||
56 | private void RegisterFunctions() | ||
57 | { | ||
58 | //lu.RegisterFunction( "RegisterScript",this,this.GetType().GetMethod("ScriptRegister")); | ||
59 | //lu.RegisterFunction( "MoveObject",this,this.GetType().GetMethod("MoveObject")); | ||
60 | //lu.RegisterFunction( "Say",this,this.GetType().GetMethod("Say")); | ||
61 | |||
62 | } | ||
63 | |||
64 | public void Call_tick(PrimInfo prim) | ||
65 | { | ||
66 | //set current prim and then call tick function in linked script | ||
67 | } | ||
68 | public void Call_touch(PrimInfo prim) | ||
69 | { | ||
70 | //set current prim and then call clicked function in linked script | ||
71 | |||
72 | } | ||
73 | public void Call_on_rex(PrimInfo prim) | ||
74 | { | ||
75 | //set current prim and then call clicked function in linked script | ||
76 | |||
77 | } | ||
78 | |||
79 | #region Lua Functions | ||
80 | |||
81 | public void ScriptRegister(script_object_interface script) | ||
82 | { | ||
83 | //called by scripts to register themselves | ||
84 | } | ||
85 | public void MoveObject(float x , float y, float z) | ||
86 | { | ||
87 | |||
88 | } | ||
89 | public void Say(string message) | ||
90 | { | ||
91 | |||
92 | } | ||
93 | #endregion | ||
94 | |||
95 | } | ||
96 | |||
97 | public interface script_object_interface | ||
98 | { | ||
99 | void frame_tick(); | ||
100 | void touch(int num); | ||
101 | void on_rex(int num); | ||
102 | } | ||
103 | } | ||
diff --git a/src/Second-server.csproj b/src/Second-server.csproj new file mode 100644 index 0000000..6d049ce --- /dev/null +++ b/src/Second-server.csproj | |||
@@ -0,0 +1,60 @@ | |||
1 | <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||
2 | <PropertyGroup> | ||
3 | <OutputType>Exe</OutputType> | ||
4 | <RootNamespace>OpenSim</RootNamespace> | ||
5 | <AssemblyName>OpenSim</AssemblyName> | ||
6 | <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | ||
7 | <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | ||
8 | <ProjectGuid>{132A6E3E-8F2D-4BF5-BDFB-8555F53F334E}</ProjectGuid> | ||
9 | <StartupObject>OpenSim.Controller</StartupObject> | ||
10 | </PropertyGroup> | ||
11 | <PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> | ||
12 | <OutputPath>bin\Debug\</OutputPath> | ||
13 | <Optimize>False</Optimize> | ||
14 | <DefineConstants>DEBUG;TRACE</DefineConstants> | ||
15 | <DebugSymbols>True</DebugSymbols> | ||
16 | <DebugType>Full</DebugType> | ||
17 | <CheckForOverflowUnderflow>True</CheckForOverflowUnderflow> | ||
18 | </PropertyGroup> | ||
19 | <PropertyGroup Condition=" '$(Configuration)' == 'Release' "> | ||
20 | <OutputPath>bin\Release\</OutputPath> | ||
21 | <Optimize>True</Optimize> | ||
22 | <DefineConstants>TRACE</DefineConstants> | ||
23 | <DebugSymbols>False</DebugSymbols> | ||
24 | <DebugType>None</DebugType> | ||
25 | <CheckForOverflowUnderflow>False</CheckForOverflowUnderflow> | ||
26 | </PropertyGroup> | ||
27 | <ItemGroup> | ||
28 | <Reference Include="Axiom.MathLib, Version=0.7.0.25497, Culture=neutral"> | ||
29 | <SpecificVersion>False</SpecificVersion> | ||
30 | <HintPath>..\bin\Axiom.MathLib.dll</HintPath> | ||
31 | </Reference> | ||
32 | <Reference Include="libsecondlife, Version=0.9.0.0, Culture=neutral, processorArchitecture=MSIL"> | ||
33 | <SpecificVersion>False</SpecificVersion> | ||
34 | <HintPath>..\bin\libsecondlife.dll</HintPath> | ||
35 | </Reference> | ||
36 | <Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821, processorArchitecture=MSIL"> | ||
37 | <SpecificVersion>False</SpecificVersion> | ||
38 | <HintPath>..\bin\log4net.dll</HintPath> | ||
39 | </Reference> | ||
40 | <Reference Include="System" /> | ||
41 | <Reference Include="System.Data" /> | ||
42 | <Reference Include="System.Xml" /> | ||
43 | </ItemGroup> | ||
44 | <ItemGroup> | ||
45 | <Compile Include="Agent_Manager.cs" /> | ||
46 | <Compile Include="Controller.cs" /> | ||
47 | <Compile Include="Prim_manager.cs" /> | ||
48 | <Compile Include="Login_manager.cs" /> | ||
49 | <Compile Include="Physics_manager.cs" /> | ||
50 | <Compile Include="Script_manager.cs" /> | ||
51 | <Compile Include="Server.cs" /> | ||
52 | <Compile Include="StorageManager.cs" /> | ||
53 | <Compile Include="GridManager.cs" /> | ||
54 | <Compile Include="Globals.cs" /> | ||
55 | <Compile Include="InventoryManager.cs" /> | ||
56 | <Compile Include="SceneGraphManager.cs" /> | ||
57 | <Compile Include="AssetManagement.cs" /> | ||
58 | </ItemGroup> | ||
59 | <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" /> | ||
60 | </Project> \ No newline at end of file | ||
diff --git a/src/Second-server.sln b/src/Second-server.sln new file mode 100644 index 0000000..44be1db --- /dev/null +++ b/src/Second-server.sln | |||
@@ -0,0 +1,34 @@ | |||
1 | | ||
2 | Microsoft Visual Studio Solution File, Format Version 9.00 | ||
3 | # SharpDevelop 2.1.0.2017 | ||
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Second-server", "Second-server.csproj", "{132A6E3E-8F2D-4BF5-BDFB-8555F53F334E}" | ||
5 | EndProject | ||
6 | Global | ||
7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
8 | Debug|.NET 1.1 = Debug|.NET 1.1 | ||
9 | Debug|Any CPU = Debug|Any CPU | ||
10 | Release|.NET 1.1 = Release|.NET 1.1 | ||
11 | Release|Any CPU = Release|Any CPU | ||
12 | EndGlobalSection | ||
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
14 | {132A6E3E-8F2D-4BF5-BDFB-8555F53F334E}.Debug|.NET 1.1.ActiveCfg = Debug|Any CPU | ||
15 | {132A6E3E-8F2D-4BF5-BDFB-8555F53F334E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
16 | {132A6E3E-8F2D-4BF5-BDFB-8555F53F334E}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
17 | {132A6E3E-8F2D-4BF5-BDFB-8555F53F334E}.Release|.NET 1.1.ActiveCfg = Release|Any CPU | ||
18 | {132A6E3E-8F2D-4BF5-BDFB-8555F53F334E}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
19 | {132A6E3E-8F2D-4BF5-BDFB-8555F53F334E}.Release|Any CPU.Build.0 = Release|Any CPU | ||
20 | {D9CDEDFB-8169-4B03-B57F-0DF638F044EC}.Debug|.NET 1.1.ActiveCfg = Debug|.NET 1.1 | ||
21 | {D9CDEDFB-8169-4B03-B57F-0DF638F044EC}.Debug|.NET 1.1.Build.0 = Debug|.NET 1.1 | ||
22 | {D9CDEDFB-8169-4B03-B57F-0DF638F044EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
23 | {D9CDEDFB-8169-4B03-B57F-0DF638F044EC}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
24 | {D9CDEDFB-8169-4B03-B57F-0DF638F044EC}.Release|.NET 1.1.ActiveCfg = Release|.NET 1.1 | ||
25 | {D9CDEDFB-8169-4B03-B57F-0DF638F044EC}.Release|.NET 1.1.Build.0 = Release|.NET 1.1 | ||
26 | {D9CDEDFB-8169-4B03-B57F-0DF638F044EC}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
27 | {D9CDEDFB-8169-4B03-B57F-0DF638F044EC}.Release|Any CPU.Build.0 = Release|Any CPU | ||
28 | {132A6E3E-8F2D-4BF5-BDFB-8555F53F334E}.Debug|.NET 1.1.Build.0 = Debug|.NET 1.1 | ||
29 | {132A6E3E-8F2D-4BF5-BDFB-8555F53F334E}.Release|.NET 1.1.Build.0 = Release|.NET 1.1 | ||
30 | EndGlobalSection | ||
31 | GlobalSection(SolutionProperties) = preSolution | ||
32 | HideSolutionNode = FALSE | ||
33 | EndGlobalSection | ||
34 | EndGlobal | ||
diff --git a/src/Second-server.suo b/src/Second-server.suo new file mode 100644 index 0000000..4ed1adc --- /dev/null +++ b/src/Second-server.suo | |||
Binary files differ | |||
diff --git a/src/Server.cs b/src/Server.cs new file mode 100644 index 0000000..1f19bf9 --- /dev/null +++ b/src/Server.cs | |||
@@ -0,0 +1,707 @@ | |||
1 | /* | ||
2 | * Copyright (c) OpenSim project, http://osgrid.org/ | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the <organization> nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using libsecondlife; | ||
31 | using System.Collections; | ||
32 | using libsecondlife.Packets; | ||
33 | using libsecondlife.AssetSystem; | ||
34 | using System.Net; | ||
35 | using System.Net.Sockets; | ||
36 | using System.Timers; | ||
37 | |||
38 | //really hacked , messy code | ||
39 | |||
40 | namespace OpenSim | ||
41 | { | ||
42 | /// <summary> | ||
43 | /// Description of Server. | ||
44 | /// </summary> | ||
45 | public interface ServerCallback | ||
46 | { | ||
47 | //should replace with delegates | ||
48 | void MainCallback(Packet pack, UserAgentInfo User_info); | ||
49 | void NewUserCallback(UserAgentInfo User_info); | ||
50 | void ErrorCallback(string text); | ||
51 | } | ||
52 | public class Server | ||
53 | { | ||
54 | /// <summary>A public reference to the client that this Simulator object | ||
55 | /// is attached to</summary> | ||
56 | //public SecondLife Client; | ||
57 | |||
58 | /// <summary>The Region class that this Simulator wraps</summary> | ||
59 | // public Region Region; | ||
60 | |||
61 | /// <summary> | ||
62 | /// Used internally to track sim disconnections, do not modify this | ||
63 | /// variable | ||
64 | /// </summary> | ||
65 | public bool DisconnectCandidate = false; | ||
66 | |||
67 | /// <summary> | ||
68 | /// The ID number associated with this particular connection to the | ||
69 | /// simulator, used to emulate TCP connections. This is used | ||
70 | /// internally for packets that have a CircuitCode field | ||
71 | /// </summary> | ||
72 | public uint CircuitCode | ||
73 | { | ||
74 | get { return circuitCode; } | ||
75 | set { circuitCode = value; } | ||
76 | } | ||
77 | |||
78 | /// <summary> | ||
79 | /// The IP address and port of the server | ||
80 | /// </summary> | ||
81 | public IPEndPoint IPEndPoint | ||
82 | { | ||
83 | get { return ipEndPoint; } | ||
84 | } | ||
85 | |||
86 | /// <summary> | ||
87 | /// A boolean representing whether there is a working connection to the | ||
88 | /// simulator or not | ||
89 | /// </summary> | ||
90 | public bool Connected | ||
91 | { | ||
92 | get { return connected; } | ||
93 | } | ||
94 | |||
95 | private ServerCallback CallbackObject; | ||
96 | private uint Sequence = 0; | ||
97 | private object SequenceLock = new object(); | ||
98 | private byte[] RecvBuffer = new byte[4096]; | ||
99 | private byte[] ZeroBuffer = new byte[8192]; | ||
100 | private byte[] ZeroOutBuffer = new byte[4096]; | ||
101 | private Socket Connection = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); | ||
102 | private AsyncCallback ReceivedData; | ||
103 | private bool connected = false; | ||
104 | private uint circuitCode; | ||
105 | private IPEndPoint ipEndPoint; | ||
106 | private EndPoint endPoint; | ||
107 | private IPEndPoint ipeSender; | ||
108 | private EndPoint epSender; | ||
109 | private System.Timers.Timer AckTimer; | ||
110 | private Server_Settings Settings=new Server_Settings(); | ||
111 | public ArrayList User_agents=new ArrayList(); | ||
112 | |||
113 | /// <summary> | ||
114 | /// Constructor for Simulator | ||
115 | /// </summary> | ||
116 | /// <param name="client"></param> | ||
117 | /// <param name="callbacks"></param> | ||
118 | /// <param name="circuit"></param> | ||
119 | /// <param name="ip"></param> | ||
120 | /// <param name="port"></param> | ||
121 | public Server(ServerCallback s_callback) | ||
122 | { | ||
123 | |||
124 | this.CallbackObject=s_callback; //should be using delegate | ||
125 | AckTimer = new System.Timers.Timer(Settings.NETWORK_TICK_LENGTH); | ||
126 | AckTimer.Elapsed += new ElapsedEventHandler(AckTimer_Elapsed); | ||
127 | |||
128 | // Initialize the callback for receiving a new packet | ||
129 | ReceivedData = new AsyncCallback(this.OnReceivedData); | ||
130 | |||
131 | // Client.Log("Connecting to " + ip.ToString() + ":" + port, Helpers.LogLevel.Info); | ||
132 | |||
133 | try | ||
134 | { | ||
135 | // Create an endpoint that we will be communicating with (need it in two | ||
136 | // types due to .NET weirdness) | ||
137 | // ipEndPoint = new IPEndPoint(ip, port); | ||
138 | ipEndPoint = new IPEndPoint(IPAddress.Any, Globals.Instance.IpPort); | ||
139 | endPoint = (EndPoint)ipEndPoint; | ||
140 | |||
141 | // Associate this simulator's socket with the given ip/port and start listening | ||
142 | Connection.Bind(endPoint); | ||
143 | ipeSender = new IPEndPoint(IPAddress.Any, 0); | ||
144 | //The epSender identifies the incoming clients | ||
145 | epSender = (EndPoint) ipeSender; | ||
146 | Connection.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null); | ||
147 | |||
148 | // Start the ACK timer | ||
149 | AckTimer.Start(); | ||
150 | } | ||
151 | catch (Exception e) | ||
152 | { | ||
153 | |||
154 | System.Console.WriteLine(e.Message); | ||
155 | } | ||
156 | } | ||
157 | |||
158 | /// <summary> | ||
159 | /// Disconnect a Simulator | ||
160 | /// </summary> | ||
161 | public void Disconnect() | ||
162 | { | ||
163 | if (connected) | ||
164 | { | ||
165 | connected = false; | ||
166 | AckTimer.Stop(); | ||
167 | |||
168 | // Send the CloseCircuit notice | ||
169 | CloseCircuitPacket close = new CloseCircuitPacket(); | ||
170 | |||
171 | if (Connection.Connected) | ||
172 | { | ||
173 | try | ||
174 | { | ||
175 | // Connection.Send(close.ToBytes()); | ||
176 | } | ||
177 | catch (SocketException) | ||
178 | { | ||
179 | // There's a high probability of this failing if the network is | ||
180 | // disconnecting, so don't even bother logging the error | ||
181 | } | ||
182 | } | ||
183 | |||
184 | try | ||
185 | { | ||
186 | // Shut the socket communication down | ||
187 | // Connection.Shutdown(SocketShutdown.Both); | ||
188 | } | ||
189 | catch (SocketException) | ||
190 | { | ||
191 | } | ||
192 | } | ||
193 | } | ||
194 | |||
195 | /// <summary> | ||
196 | /// Sends a packet | ||
197 | /// </summary> | ||
198 | /// <param name="packet">Packet to be sent</param> | ||
199 | /// <param name="incrementSequence">Increment sequence number?</param> | ||
200 | public void SendPacket(Packet packet, bool incrementSequence, UserAgentInfo User_info) | ||
201 | { | ||
202 | Console.WriteLine("OUTGOING"); | ||
203 | Console.WriteLine(packet.ToString()); | ||
204 | byte[] buffer; | ||
205 | int bytes; | ||
206 | |||
207 | if (!connected && packet.Type != PacketType.UseCircuitCode) | ||
208 | { | ||
209 | Console.WriteLine("Trying to send a " + packet.Type.ToString() + " packet when the socket is closed"); | ||
210 | |||
211 | |||
212 | return; | ||
213 | } | ||
214 | |||
215 | /*if (packet.Header.AckList.Length > 0) | ||
216 | { | ||
217 | // Scrub any appended ACKs since all of the ACK handling is done here | ||
218 | packet.Header.AckList = new uint[0]; | ||
219 | } | ||
220 | packet.Header.AppendedAcks = false; | ||
221 | |||
222 | // Keep track of when this packet was sent out | ||
223 | packet.TickCount = Environment.TickCount; | ||
224 | */ | ||
225 | if (incrementSequence) | ||
226 | { | ||
227 | // Set the sequence number | ||
228 | lock (SequenceLock) | ||
229 | { | ||
230 | if (Sequence > Settings.MAX_SEQUENCE) | ||
231 | Sequence = 1; | ||
232 | else | ||
233 | Sequence++; | ||
234 | packet.Header.Sequence = Sequence; | ||
235 | } | ||
236 | |||
237 | if (packet.Header.Reliable) | ||
238 | { | ||
239 | lock (User_info.NeedAck) | ||
240 | { | ||
241 | if (!User_info.NeedAck.ContainsKey(packet.Header.Sequence)) | ||
242 | { | ||
243 | User_info.NeedAck.Add(packet.Header.Sequence, packet); | ||
244 | } | ||
245 | else | ||
246 | { | ||
247 | // Client.Log("Attempted to add a duplicate sequence number (" + | ||
248 | // packet.Header.Sequence + ") to the NeedAck dictionary for packet type " + | ||
249 | // packet.Type.ToString(), Helpers.LogLevel.Warning); | ||
250 | } | ||
251 | } | ||
252 | |||
253 | // Don't append ACKs to resent packets, in case that's what was causing the | ||
254 | // delivery to fail | ||
255 | if (!packet.Header.Resent) | ||
256 | { | ||
257 | // Append any ACKs that need to be sent out to this packet | ||
258 | lock (User_info.PendingAcks) | ||
259 | { | ||
260 | if (User_info.PendingAcks.Count > 0 && User_info.PendingAcks.Count < Settings.MAX_APPENDED_ACKS && | ||
261 | packet.Type != PacketType.PacketAck && | ||
262 | packet.Type != PacketType.LogoutRequest) | ||
263 | { | ||
264 | packet.Header.AckList = new uint[User_info.PendingAcks.Count]; | ||
265 | int i = 0; | ||
266 | |||
267 | foreach (uint ack in User_info.PendingAcks.Values) | ||
268 | { | ||
269 | packet.Header.AckList[i] = ack; | ||
270 | i++; | ||
271 | } | ||
272 | |||
273 | User_info.PendingAcks.Clear(); | ||
274 | packet.Header.AppendedAcks = true; | ||
275 | } | ||
276 | } | ||
277 | } | ||
278 | } | ||
279 | } | ||
280 | |||
281 | // Serialize the packet | ||
282 | buffer = packet.ToBytes(); | ||
283 | bytes = buffer.Length; | ||
284 | |||
285 | try | ||
286 | { | ||
287 | // Zerocode if needed | ||
288 | if (packet.Header.Zerocoded) | ||
289 | { | ||
290 | lock (ZeroOutBuffer) | ||
291 | { | ||
292 | bytes = Helpers.ZeroEncode(buffer, bytes, ZeroOutBuffer); | ||
293 | Connection.SendTo(ZeroOutBuffer, bytes, SocketFlags.None,User_info.endpoint); | ||
294 | } | ||
295 | } | ||
296 | else | ||
297 | { | ||
298 | |||
299 | Connection.SendTo(buffer, bytes, SocketFlags.None,User_info.endpoint); | ||
300 | } | ||
301 | } | ||
302 | catch (SocketException) | ||
303 | { | ||
304 | //Client.Log("Tried to send a " + packet.Type.ToString() + " on a closed socket", | ||
305 | // Helpers.LogLevel.Warning); | ||
306 | |||
307 | Disconnect(); | ||
308 | } | ||
309 | } | ||
310 | |||
311 | /// <summary> | ||
312 | /// Send a raw byte array payload as a packet | ||
313 | /// </summary> | ||
314 | /// <param name="payload">The packet payload</param> | ||
315 | /// <param name="setSequence">Whether the second, third, and fourth bytes | ||
316 | /// should be modified to the current stream sequence number</param> | ||
317 | /// <summary> | ||
318 | /// Returns Simulator Name as a String | ||
319 | /// </summary> | ||
320 | /// <returns></returns> | ||
321 | public override string ToString() | ||
322 | { | ||
323 | return( " (" + ipEndPoint.ToString() + ")"); | ||
324 | } | ||
325 | |||
326 | /// <summary> | ||
327 | /// Sends out pending acknowledgements | ||
328 | /// </summary> | ||
329 | private void SendAcks(UserAgentInfo User_info) | ||
330 | { | ||
331 | lock (User_info.PendingAcks) | ||
332 | { | ||
333 | if (connected && User_info.PendingAcks.Count > 0) | ||
334 | { | ||
335 | if (User_info.PendingAcks.Count > 250) | ||
336 | { | ||
337 | // FIXME: Handle the odd case where we have too many pending ACKs queued up | ||
338 | //Client.Log("Too many ACKs queued up!", Helpers.LogLevel.Error); | ||
339 | return; | ||
340 | } | ||
341 | |||
342 | int i = 0; | ||
343 | PacketAckPacket acks = new PacketAckPacket(); | ||
344 | acks.Packets = new PacketAckPacket.PacketsBlock[User_info.PendingAcks.Count]; | ||
345 | |||
346 | foreach (uint ack in User_info.PendingAcks.Values) | ||
347 | { | ||
348 | acks.Packets[i] = new PacketAckPacket.PacketsBlock(); | ||
349 | acks.Packets[i].ID = ack; | ||
350 | i++; | ||
351 | } | ||
352 | |||
353 | acks.Header.Reliable = false; | ||
354 | //SendPacket(acks, true,User_info); | ||
355 | |||
356 | User_info.PendingAcks.Clear(); | ||
357 | } | ||
358 | } | ||
359 | } | ||
360 | /// <summary> | ||
361 | /// Resend unacknowledged packets | ||
362 | /// </summary> | ||
363 | private void ResendUnacked(UserAgentInfo User_info) | ||
364 | { | ||
365 | if (connected) | ||
366 | { | ||
367 | int now = Environment.TickCount; | ||
368 | |||
369 | lock (User_info.NeedAck) | ||
370 | { | ||
371 | foreach (Packet packet in User_info.NeedAck.Values) | ||
372 | { | ||
373 | if (now - packet.TickCount > Settings.RESEND_TIMEOUT) | ||
374 | { | ||
375 | // Client.Log("Resending " + packet.Type.ToString() + " packet, " + | ||
376 | // (now - packet.TickCount) + "ms have passed", Helpers.LogLevel.Info); | ||
377 | |||
378 | //packet.Header.Resent = true; | ||
379 | // SendPacket(packet, false,User_info); | ||
380 | } | ||
381 | } | ||
382 | } | ||
383 | } | ||
384 | } | ||
385 | /// <summary> | ||
386 | /// Callback handler for incomming data | ||
387 | /// </summary> | ||
388 | /// <param name="result"></param> | ||
389 | private void OnReceivedData(IAsyncResult result) | ||
390 | { | ||
391 | ipeSender = new IPEndPoint(IPAddress.Any, 0); | ||
392 | epSender = (EndPoint)ipeSender; | ||
393 | Packet packet = null; | ||
394 | int numBytes; | ||
395 | UserAgentInfo tempinfo; | ||
396 | |||
397 | // If we're receiving data the sim connection is open | ||
398 | connected = true; | ||
399 | |||
400 | // Update the disconnect flag so this sim doesn't time out | ||
401 | DisconnectCandidate = false; | ||
402 | UserAgentInfo User_info=null; | ||
403 | |||
404 | lock (RecvBuffer) | ||
405 | { | ||
406 | // Retrieve the incoming packet | ||
407 | try | ||
408 | { | ||
409 | numBytes = Connection.EndReceiveFrom(result, ref epSender); | ||
410 | |||
411 | //find user_agent_info | ||
412 | |||
413 | int packetEnd = numBytes - 1; | ||
414 | packet = Packet.BuildPacket(RecvBuffer, ref packetEnd, ZeroBuffer); | ||
415 | |||
416 | Console.WriteLine("INCOMING PACKET" + packet.TickCount.ToString() + " " + packet.Header.Sequence.ToString()); | ||
417 | Console.WriteLine(packet.ToString()); | ||
418 | libsecondlife.Packets.PacketAckPacket ack_it = new PacketAckPacket(); | ||
419 | ack_it.Packets = new PacketAckPacket.PacketsBlock[1]; | ||
420 | ack_it.Packets[0] = new PacketAckPacket.PacketsBlock(); | ||
421 | ack_it.Packets[0].ID = packet.Header.ID; | ||
422 | ack_it.Header.Reliable = false; | ||
423 | |||
424 | tempinfo = new UserAgentInfo(); | ||
425 | tempinfo.endpoint = epSender; | ||
426 | this.SendPacket(ack_it, false, tempinfo); | ||
427 | if (packet.Header.Resent) | ||
428 | { | ||
429 | this.CallbackObject.ErrorCallback("resent"); | ||
430 | } | ||
431 | |||
432 | if ((packet.Type == PacketType.StartPingCheck) && (packet.Header.Resent == false)) | ||
433 | { | ||
434 | //reply to pingcheck | ||
435 | libsecondlife.Packets.StartPingCheckPacket startping = (libsecondlife.Packets.StartPingCheckPacket)packet; | ||
436 | libsecondlife.Packets.CompletePingCheckPacket endping = new CompletePingCheckPacket(); | ||
437 | endping.PingID.PingID = startping.PingID.PingID; | ||
438 | endping.Header.Reliable = false; | ||
439 | tempinfo = new UserAgentInfo(); | ||
440 | tempinfo.endpoint = epSender; | ||
441 | this.SendPacket(endping, true, tempinfo); | ||
442 | } | ||
443 | |||
444 | //should check if login/useconnection packet first | ||
445 | if ((packet.Type == PacketType.UseCircuitCode) && (packet.Header.Resent == false)) | ||
446 | { | ||
447 | Console.WriteLine("Got UseCircuitCode, confirming with grid..."); | ||
448 | UseCircuitCodePacket cir_pack=(UseCircuitCodePacket)packet; | ||
449 | |||
450 | ArrayList requestParams = new ArrayList(); | ||
451 | requestParams.Add(Globals.Instance.GridSendKey); | ||
452 | requestParams.Add(cir_pack.CircuitCode.SessionID.ToString()); | ||
453 | requestParams.Add(cir_pack.CircuitCode.ID.ToString()); | ||
454 | |||
455 | |||
456 | Nwc.XmlRpc.XmlRpcRequest GridSessionInfo = new Nwc.XmlRpc.XmlRpcRequest("get_session_info",requestParams); | ||
457 | |||
458 | Nwc.XmlRpc.XmlRpcResponse gridresponse = GridSessionInfo.Send(Globals.Instance.GridURL, 5000); | ||
459 | |||
460 | Console.WriteLine("Processing response from grid server..."); | ||
461 | Hashtable gridreply = (Hashtable)gridresponse.Value; | ||
462 | if (gridresponse.IsFault) | ||
463 | { | ||
464 | Console.WriteLine("XML-RPC error when talking to grid: " + gridresponse.FaultString); | ||
465 | Connection.Disconnect(false); | ||
466 | } | ||
467 | if (((string)gridreply["agent_id"]).ToLower().Equals(cir_pack.CircuitCode.ID.ToString()) == false) | ||
468 | { | ||
469 | Console.WriteLine("Bad agent ID!"); | ||
470 | Connection.Disconnect(false); | ||
471 | } | ||
472 | else if (((string)gridreply["session_id"]).ToLower().Equals(cir_pack.CircuitCode.SessionID.ToString()) == false) | ||
473 | { | ||
474 | Console.WriteLine("Bad session ID!"); | ||
475 | Connection.Disconnect(false); | ||
476 | } | ||
477 | UserAgentInfo new_user = new UserAgentInfo(); | ||
478 | |||
479 | new_user.AgentID = cir_pack.CircuitCode.ID; | ||
480 | new_user.circuitCode=cir_pack.CircuitCode.Code; | ||
481 | new_user.AgentID=cir_pack.CircuitCode.ID; | ||
482 | new_user.SessionID=cir_pack.CircuitCode.SessionID; | ||
483 | new_user.endpoint=epSender; | ||
484 | new_user.Inbox = new Queue<uint>(Settings.INBOX_SIZE); | ||
485 | new_user.first_name = (string)gridreply["firstname"]; | ||
486 | new_user.first_name = (string)gridreply["lastname"]; | ||
487 | |||
488 | |||
489 | this.CallbackObject.NewUserCallback(new_user); | ||
490 | this.User_agents.Add(new_user); | ||
491 | |||
492 | } | ||
493 | |||
494 | |||
495 | UserAgentInfo temp_agent=null; | ||
496 | IPEndPoint send_ip=(IPEndPoint)epSender; | ||
497 | Console.WriteLine("incoming: address is "+send_ip.Address +"port number is: "+send_ip.Port.ToString()); | ||
498 | |||
499 | for(int ii=0; ii<this.User_agents.Count ; ii++) | ||
500 | { | ||
501 | temp_agent=(UserAgentInfo)this.User_agents[ii]; | ||
502 | IPEndPoint ag_ip=(IPEndPoint)temp_agent.endpoint; | ||
503 | Console.WriteLine("searching: address is "+ag_ip.Address +"port number is: "+ag_ip.Port.ToString()); | ||
504 | |||
505 | if((ag_ip.Address.ToString()==send_ip.Address.ToString()) && (ag_ip.Port.ToString()==send_ip.Port.ToString())) | ||
506 | { | ||
507 | Console.WriteLine("found user"); | ||
508 | User_info=temp_agent; | ||
509 | break; | ||
510 | } | ||
511 | } | ||
512 | |||
513 | Connection.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null); | ||
514 | } | ||
515 | catch (SocketException) | ||
516 | { | ||
517 | // Client.Log(endPoint.ToString() + " socket is closed, shutting down " + this.Region.Name, | ||
518 | // Helpers.LogLevel.Info); | ||
519 | |||
520 | connected = false; | ||
521 | //Network.DisconnectSim(this); | ||
522 | return; | ||
523 | } | ||
524 | } | ||
525 | if(User_info==null) | ||
526 | { | ||
527 | this.CallbackObject.ErrorCallback("no user found"); | ||
528 | return; | ||
529 | } | ||
530 | |||
531 | // Fail-safe check | ||
532 | if (packet == null) | ||
533 | { | ||
534 | this.CallbackObject.ErrorCallback("couldn't build packet"); | ||
535 | // Client.Log("Couldn't build a message from the incoming data", Helpers.LogLevel.Warning); | ||
536 | return; | ||
537 | } | ||
538 | //this.callback_object.error("past tests"); | ||
539 | // Track the sequence number for this packet if it's marked as reliable | ||
540 | if (packet.Header.Reliable) | ||
541 | { | ||
542 | if (User_info.PendingAcks.Count > Settings.MAX_PENDING_ACKS) | ||
543 | { | ||
544 | SendAcks(User_info); | ||
545 | } | ||
546 | |||
547 | // Check if we already received this packet | ||
548 | if (User_info.Inbox.Contains(packet.Header.Sequence)) | ||
549 | { | ||
550 | //Client.Log("Received a duplicate " + packet.Type.ToString() + ", sequence=" + | ||
551 | // packet.Header.Sequence + ", resent=" + ((packet.Header.Resent) ? "Yes" : "No") + | ||
552 | // ", Inbox.Count=" + Inbox.Count + ", NeedAck.Count=" + NeedAck.Count, | ||
553 | // Helpers.LogLevel.Info); | ||
554 | |||
555 | // Send an ACK for this packet immediately | ||
556 | |||
557 | |||
558 | // TESTING: Try just queuing up ACKs for resent packets instead of immediately triggering an ACK | ||
559 | /* lock (User_info.PendingAcks) | ||
560 | { | ||
561 | uint sequence = (uint)packet.Header.Sequence; | ||
562 | if (!User_info.PendingAcks.ContainsKey(sequence)) { User_info.PendingAcks[sequence] = sequence; } | ||
563 | }*/ | ||
564 | |||
565 | // Avoid firing a callback twice for the same packet | ||
566 | this.CallbackObject.ErrorCallback("Avoiding callback"); | ||
567 | // this.callback_object.error("avoiding callback"); | ||
568 | return; | ||
569 | } | ||
570 | else | ||
571 | { | ||
572 | lock (User_info.PendingAcks) | ||
573 | { | ||
574 | uint sequence = (uint)packet.Header.Sequence; | ||
575 | // if (!User_info.PendingAcks.ContainsKey(sequence)) { User_info.PendingAcks[sequence] = sequence; } | ||
576 | } | ||
577 | } | ||
578 | } | ||
579 | |||
580 | // Add this packet to our inbox | ||
581 | lock (User_info.Inbox) | ||
582 | { | ||
583 | while (User_info.Inbox.Count >= Settings.INBOX_SIZE) | ||
584 | { | ||
585 | User_info.Inbox.Dequeue(); | ||
586 | } | ||
587 | User_info.Inbox.Enqueue(packet.Header.Sequence); | ||
588 | } | ||
589 | |||
590 | // Handle appended ACKs | ||
591 | if (packet.Header.AppendedAcks) | ||
592 | { | ||
593 | lock (User_info.NeedAck) | ||
594 | { | ||
595 | foreach (uint ack in packet.Header.AckList) | ||
596 | { | ||
597 | User_info.NeedAck.Remove(ack); | ||
598 | } | ||
599 | } | ||
600 | } | ||
601 | |||
602 | // Handle PacketAck packets | ||
603 | if (packet.Type == PacketType.PacketAck) | ||
604 | { | ||
605 | PacketAckPacket ackPacket = (PacketAckPacket)packet; | ||
606 | |||
607 | lock (User_info.NeedAck) | ||
608 | { | ||
609 | foreach (PacketAckPacket.PacketsBlock block in ackPacket.Packets) | ||
610 | { | ||
611 | User_info.NeedAck.Remove(block.ID); | ||
612 | } | ||
613 | } | ||
614 | } | ||
615 | |||
616 | this.CallbackObject.MainCallback(packet,User_info); | ||
617 | |||
618 | } | ||
619 | |||
620 | private void AckTimer_Elapsed(object sender, ElapsedEventArgs ea) | ||
621 | { | ||
622 | if (connected) | ||
623 | { | ||
624 | |||
625 | //TODO for each user_agent_info | ||
626 | for(int i=0; i<this.User_agents.Count; i++) | ||
627 | { | ||
628 | UserAgentInfo user=(UserAgentInfo)this.User_agents[i]; | ||
629 | |||
630 | SendAcks(user); | ||
631 | ResendUnacked(user); | ||
632 | } | ||
633 | } | ||
634 | } | ||
635 | } | ||
636 | |||
637 | public class Server_Settings | ||
638 | { | ||
639 | /// <summary>The version of libsecondlife (not the SL protocol itself)</summary> | ||
640 | public string VERSION = "libsecondlife 0.0.9"; | ||
641 | /// <summary>XML-RPC login server to connect to</summary> | ||
642 | public string LOGIN_SERVER = "http://www.garethnelson.com/ogs/login/"; | ||
643 | |||
644 | /// <summary>Millisecond interval between ticks, where all ACKs are | ||
645 | /// sent out and the age of unACKed packets is checked</summary> | ||
646 | public readonly int NETWORK_TICK_LENGTH = 500; | ||
647 | /// <summary>The maximum value of a packet sequence number. After that | ||
648 | /// we assume the sequence number just rolls over? Or maybe the | ||
649 | /// protocol isn't able to sustain a connection past that</summary> | ||
650 | public readonly int MAX_SEQUENCE = 0xFFFFFF; | ||
651 | /// <summary>Number of milliseconds before a teleport attempt will time | ||
652 | /// out</summary> | ||
653 | public readonly int TELEPORT_TIMEOUT = 18 * 1000; | ||
654 | |||
655 | /// <summary>Number of milliseconds before NetworkManager.Logout() will time out</summary> | ||
656 | public int LOGOUT_TIMEOUT = 5 * 1000; | ||
657 | /// <summary>Number of milliseconds for xml-rpc to timeout</summary> | ||
658 | public int LOGIN_TIMEOUT = 30 * 1000; | ||
659 | /// <summary>The maximum size of the sequence number inbox, used to | ||
660 | /// check for resent and/or duplicate packets</summary> | ||
661 | public int INBOX_SIZE = 100; | ||
662 | /// <summary>Milliseconds before a packet is assumed lost and resent</summary> | ||
663 | public int RESEND_TIMEOUT = 4000; | ||
664 | /// <summary>Milliseconds before the connection to a simulator is | ||
665 | /// assumed lost</summary> | ||
666 | public int SIMULATOR_TIMEOUT = 15000; | ||
667 | /// <summary>Maximum number of queued ACKs to be sent before SendAcks() | ||
668 | /// is forced</summary> | ||
669 | public int MAX_PENDING_ACKS = 10; | ||
670 | /// <summary>Maximum number of ACKs to append to a packet</summary> | ||
671 | public int MAX_APPENDED_ACKS = 10; | ||
672 | /// <summary>Cost of uploading an asset</summary> | ||
673 | public int UPLOAD_COST { get { return priceUpload; } } | ||
674 | |||
675 | |||
676 | private int priceUpload = 0; | ||
677 | |||
678 | public Server_Settings() | ||
679 | { | ||
680 | |||
681 | } | ||
682 | } | ||
683 | |||
684 | public class UserAgentInfo | ||
685 | { | ||
686 | public EndPoint endpoint; | ||
687 | public LLUUID AgentID; | ||
688 | public LLUUID SessionID; | ||
689 | public uint circuitCode; | ||
690 | public string name; | ||
691 | public uint localID; | ||
692 | public string first_name; | ||
693 | public string last_name; | ||
694 | |||
695 | public Dictionary<uint, Packet> NeedAck = new Dictionary<uint, Packet>(); | ||
696 | // Sequence numbers of packets we've received from the simulator | ||
697 | public Queue<uint> Inbox; | ||
698 | // ACKs that are queued up to be sent to the simulator | ||
699 | public Dictionary<uint, uint> PendingAcks = new Dictionary<uint, uint>(); | ||
700 | |||
701 | public UserAgentInfo() | ||
702 | { | ||
703 | |||
704 | } | ||
705 | } | ||
706 | |||
707 | } | ||
diff --git a/src/StorageManager.cs b/src/StorageManager.cs new file mode 100644 index 0000000..05ef782 --- /dev/null +++ b/src/StorageManager.cs | |||
@@ -0,0 +1,53 @@ | |||
1 | /* | ||
2 | Copyright (c) OpenSim project, http://osgrid.org/ | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the <organization> nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using libsecondlife; | ||
31 | using System.Collections; | ||
32 | using libsecondlife.Packets; | ||
33 | using libsecondlife.AssetSystem; | ||
34 | using System.IO; | ||
35 | |||
36 | namespace OpenSim | ||
37 | { | ||
38 | /// <summary> | ||
39 | /// Description of StorageManager. | ||
40 | /// </summary> | ||
41 | public class StorageManager | ||
42 | { | ||
43 | public StorageManager() | ||
44 | { | ||
45 | } | ||
46 | } | ||
47 | |||
48 | public class AssetStorage | ||
49 | { | ||
50 | public LLUUID Full_ID; | ||
51 | public byte Type; | ||
52 | } | ||
53 | } | ||
diff --git a/src/Texture_manager.cs b/src/Texture_manager.cs new file mode 100644 index 0000000..6d3f1db --- /dev/null +++ b/src/Texture_manager.cs | |||
@@ -0,0 +1,238 @@ | |||
1 | /* | ||
2 | Copyright (c) OpenSim project, http://osgrid.org/ | ||
3 | |||
4 | * Copyright (c) <year>, <copyright holder> | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Redistribution and use in source and binary forms, with or without | ||
8 | * modification, are permitted provided that the following conditions are met: | ||
9 | * * Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * * Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * * Neither the name of the <organization> nor the | ||
15 | * names of its contributors may be used to endorse or promote products | ||
16 | * derived from this software without specific prior written permission. | ||
17 | * | ||
18 | * THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY | ||
19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
21 | * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY | ||
22 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
24 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
25 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
28 | */ | ||
29 | |||
30 | using System; | ||
31 | using System.Collections.Generic; | ||
32 | using libsecondlife; | ||
33 | using System.Collections; | ||
34 | using libsecondlife.Packets; | ||
35 | using libsecondlife.AssetSystem; | ||
36 | using System.IO; | ||
37 | |||
38 | |||
39 | namespace OpenSim | ||
40 | { | ||
41 | /// <summary> | ||
42 | /// Description of Texture_manager. | ||
43 | /// </summary> | ||
44 | public class TextureManager | ||
45 | { | ||
46 | public Dictionary<libsecondlife.LLUUID,TextureImage> textures; | ||
47 | public ArrayList requests=new ArrayList(); //should change to a generic | ||
48 | public ArrayList uploads=new ArrayList(); | ||
49 | private Server server; | ||
50 | |||
51 | public TextureManager(Server serve) | ||
52 | { | ||
53 | server=serve; | ||
54 | textures=new Dictionary<libsecondlife.LLUUID,TextureImage> (); | ||
55 | this.initialise(); | ||
56 | } | ||
57 | |||
58 | public void AddRequest(User_Agent_info user, LLUUID image_id) | ||
59 | { | ||
60 | |||
61 | if(!this.textures.ContainsKey(image_id)) | ||
62 | { | ||
63 | //not found image so send back image not in data base message | ||
64 | ImageNotInDatabasePacket im_not=new ImageNotInDatabasePacket(); | ||
65 | im_not.ImageID.ID=image_id; | ||
66 | server.SendPacket(im_not,true,user); | ||
67 | return; | ||
68 | } | ||
69 | TextureImage imag=this.textures[image_id]; | ||
70 | TextureRequest req=new TextureRequest(); | ||
71 | req.RequestUser=user; | ||
72 | req.RequestImage=image_id; | ||
73 | req.image_info=imag; | ||
74 | |||
75 | if(imag.data.LongLength>1000) //should be bigger or smaller? | ||
76 | { | ||
77 | //over 1000 bytes so split up file | ||
78 | req.num_packets=(int)imag.data.LongLength/1000; | ||
79 | req.num_packets++; | ||
80 | } | ||
81 | else | ||
82 | { | ||
83 | req.num_packets=1; | ||
84 | } | ||
85 | |||
86 | this.requests.Add(req); | ||
87 | |||
88 | } | ||
89 | |||
90 | public void AddTexture(LLUUID image_id, string name, byte[] data) | ||
91 | { | ||
92 | |||
93 | } | ||
94 | public void DoWork(ulong time) | ||
95 | { | ||
96 | if(this.requests.Count==0) | ||
97 | { | ||
98 | //no requests waiting | ||
99 | return; | ||
100 | } | ||
101 | int num; | ||
102 | //should be running in its own thread but for now is called by timer | ||
103 | if(this.requests.Count<5) | ||
104 | { | ||
105 | //lower than 5 so do all of them | ||
106 | num=this.requests.Count; | ||
107 | } | ||
108 | else | ||
109 | { | ||
110 | num=5; | ||
111 | } | ||
112 | TextureRequest req; | ||
113 | for(int i=0; i<num; i++) | ||
114 | { | ||
115 | req=(TextureRequest)this.requests[i]; | ||
116 | |||
117 | if(req.packet_counter==0) | ||
118 | { | ||
119 | //first time for this request so send imagedata packet | ||
120 | if(req.num_packets==1) | ||
121 | { | ||
122 | //only one packet so send whole file | ||
123 | ImageDataPacket im=new ImageDataPacket(); | ||
124 | im.ImageID.Packets=1; | ||
125 | im.ImageID.ID=req.image_info.Full_ID; | ||
126 | im.ImageID.Size=(uint)req.image_info.data.Length; | ||
127 | im.ImageData.Data=req.image_info.data; | ||
128 | im.ImageID.Codec=2; | ||
129 | server.SendPacket(im,true,req.RequestUser); | ||
130 | req.packet_counter++; | ||
131 | req.image_info.last_used=time; | ||
132 | System.Console.WriteLine("sent texture: "+req.image_info.Full_ID); | ||
133 | } | ||
134 | else | ||
135 | { | ||
136 | //more than one packet so split file up | ||
137 | } | ||
138 | } | ||
139 | else | ||
140 | { | ||
141 | //send imagepacket | ||
142 | |||
143 | } | ||
144 | } | ||
145 | |||
146 | //remove requests that have been completed | ||
147 | for(int i=0; i<num; i++) | ||
148 | { | ||
149 | req=(TextureRequest)this.requests[i]; | ||
150 | if(req.packet_counter==req.num_packets) | ||
151 | { | ||
152 | this.requests.Remove(req); | ||
153 | } | ||
154 | } | ||
155 | } | ||
156 | |||
157 | public void RecieveTexture(Packet pack) | ||
158 | { | ||
159 | |||
160 | } | ||
161 | |||
162 | private void initialise() | ||
163 | { | ||
164 | |||
165 | TextureImage im=new TextureImage(); | ||
166 | im.filename="testpic2.jp2"; | ||
167 | im.Full_ID=new LLUUID("00000000-0000-0000-5005-000000000005"); | ||
168 | im.Name="test Texture"; | ||
169 | this.LoadImage(im); | ||
170 | this.textures.Add(im.Full_ID,im); | ||
171 | |||
172 | //Change these filenames to images you want to use. | ||
173 | im=new TextureImage(); | ||
174 | im.filename="map_base.jp2"; | ||
175 | im.Full_ID=new LLUUID("00000000-0000-0000-7007-000000000006"); | ||
176 | this.LoadImage(im); | ||
177 | this.textures.Add(im.Full_ID,im); | ||
178 | |||
179 | im=new TextureImage(); | ||
180 | im.filename="map1.jp2"; | ||
181 | im.Full_ID=new LLUUID("00000000-0000-0000-7009-000000000008"); | ||
182 | this.LoadImage(im); | ||
183 | this.textures.Add(im.Full_ID,im); | ||
184 | |||
185 | } | ||
186 | private void LoadImage(TextureImage im) | ||
187 | { | ||
188 | //should request Image from StorageManager | ||
189 | //but for now read from file | ||
190 | |||
191 | string data_path=System.AppDomain.CurrentDomain.BaseDirectory + @"\textures\"; | ||
192 | string filename=data_path+@im.filename; | ||
193 | FileInfo fInfo = new FileInfo(filename); | ||
194 | |||
195 | long numBytes = fInfo.Length; | ||
196 | |||
197 | FileStream fStream = new FileStream(filename, FileMode.Open, FileAccess.Read); | ||
198 | byte[] idata=new byte[numBytes]; | ||
199 | BinaryReader br = new BinaryReader(fStream); | ||
200 | idata= br.ReadBytes((int)numBytes); | ||
201 | br.Close(); | ||
202 | fStream.Close(); | ||
203 | im.data=idata; | ||
204 | im.loaded=true; | ||
205 | } | ||
206 | |||
207 | } | ||
208 | |||
209 | public class TextureRequest | ||
210 | { | ||
211 | public User_Agent_info RequestUser; | ||
212 | public LLUUID RequestImage; | ||
213 | public TextureImage image_info; | ||
214 | public long data_pointer=0; | ||
215 | public int num_packets=0; | ||
216 | public int packet_counter=0; | ||
217 | |||
218 | public TextureRequest() | ||
219 | { | ||
220 | |||
221 | } | ||
222 | } | ||
223 | public class TextureImage: AssetBase | ||
224 | { | ||
225 | //public byte[] data; | ||
226 | //public LLUUID Full_ID; | ||
227 | //public string name; | ||
228 | public string filename; | ||
229 | public bool loaded; | ||
230 | public ulong last_used; //need to add a tick/time counter and keep record | ||
231 | // of how often images are requested to unload unused ones. | ||
232 | |||
233 | public TextureImage() | ||
234 | { | ||
235 | |||
236 | } | ||
237 | } | ||
238 | } | ||
diff --git a/src/Util.cs b/src/Util.cs new file mode 100644 index 0000000..3b89b25 --- /dev/null +++ b/src/Util.cs | |||
@@ -0,0 +1,75 @@ | |||
1 | /* | ||
2 | Copyright (c) OpenSim project, http://osgrid.org/ | ||
3 | |||
4 | * Copyright (c) <year>, <copyright holder> | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Redistribution and use in source and binary forms, with or without | ||
8 | * modification, are permitted provided that the following conditions are met: | ||
9 | * * Redistributions of source code must retain the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer. | ||
11 | * * Redistributions in binary form must reproduce the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer in the | ||
13 | * documentation and/or other materials provided with the distribution. | ||
14 | * * Neither the name of the <organization> nor the | ||
15 | * names of its contributors may be used to endorse or promote products | ||
16 | * derived from this software without specific prior written permission. | ||
17 | * | ||
18 | * THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY | ||
19 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
21 | * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY | ||
22 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
24 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
25 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
28 | */ | ||
29 | |||
30 | using System; | ||
31 | using System.Collections.Generic; | ||
32 | using System.Threading; | ||
33 | using libsecondlife; | ||
34 | using libsecondlife.Packets; | ||
35 | |||
36 | namespace OpenSim | ||
37 | { | ||
38 | /// <summary> | ||
39 | /// </summary> | ||
40 | public class QueItem { | ||
41 | public QueItem() | ||
42 | { | ||
43 | } | ||
44 | |||
45 | public Packet Packet; | ||
46 | public bool Incoming; | ||
47 | } | ||
48 | |||
49 | |||
50 | public class BlockingQueue< T > { | ||
51 | private Queue< T > _queue = new Queue< T >(); | ||
52 | private object _queueSync = new object(); | ||
53 | |||
54 | public void Enqueue(T value) | ||
55 | { | ||
56 | lock(_queueSync) | ||
57 | { | ||
58 | _queue.Enqueue(value); | ||
59 | Monitor.Pulse(_queueSync); | ||
60 | } | ||
61 | } | ||
62 | |||
63 | public T Dequeue() | ||
64 | { | ||
65 | lock(_queueSync) | ||
66 | { | ||
67 | if( _queue.Count < 1) | ||
68 | Monitor.Wait(_queueSync); | ||
69 | |||
70 | return _queue.Dequeue(); | ||
71 | } | ||
72 | } | ||
73 | } | ||
74 | |||
75 | } | ||
diff --git a/src/VersionInfo.cs.template b/src/VersionInfo.cs.template new file mode 100644 index 0000000..e4e1b95 --- /dev/null +++ b/src/VersionInfo.cs.template | |||
@@ -0,0 +1,37 @@ | |||
1 | /* | ||
2 | Copyright (c) OpenSim project, http://osgrid.org/ | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions are met: | ||
6 | * * Redistributions of source code must retain the above copyright | ||
7 | * notice, this list of conditions and the following disclaimer. | ||
8 | * * Redistributions in binary form must reproduce the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer in the | ||
10 | * documentation and/or other materials provided with the distribution. | ||
11 | * * Neither the name of the <organization> nor the | ||
12 | * names of its contributors may be used to endorse or promote products | ||
13 | * derived from this software without specific prior written permission. | ||
14 | * | ||
15 | * THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY | ||
16 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
18 | * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY | ||
19 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
22 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
25 | */ | ||
26 | |||
27 | using System; | ||
28 | |||
29 | namespace OpenSim | ||
30 | { | ||
31 | /// <summary> | ||
32 | /// </summary> | ||
33 | public class VersionInfo | ||
34 | { | ||
35 | public static string Version = "@@VERSION"; | ||
36 | } | ||
37 | } | ||
diff --git a/src/types/BitPack.cs b/src/types/BitPack.cs new file mode 100644 index 0000000..1abbcf0 --- /dev/null +++ b/src/types/BitPack.cs | |||
@@ -0,0 +1,138 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | using System.Text; | ||
4 | |||
5 | namespace OpenSim.types | ||
6 | { | ||
7 | /* New Method | ||
8 | * | ||
9 | * 1. Get all the individual bytes and their bitlength, put them in a dictionary | ||
10 | * 2. Mash together when wanted. | ||
11 | * | ||
12 | * */ | ||
13 | public class Bits { | ||
14 | public byte[] data; | ||
15 | public int len; | ||
16 | } | ||
17 | |||
18 | public class InverseBitPack | ||
19 | { | ||
20 | private List<Bits> bits; | ||
21 | |||
22 | public InverseBitPack() | ||
23 | { | ||
24 | bits = new List<Bits>(); | ||
25 | } | ||
26 | } | ||
27 | |||
28 | public class BitPack | ||
29 | { | ||
30 | private const int MAX_BITS = 8; | ||
31 | |||
32 | private byte[] Data; | ||
33 | private int bytePos; | ||
34 | private int bitPos; | ||
35 | |||
36 | public BitPack(byte[] data, int pos) // For libsl compatibility | ||
37 | { | ||
38 | Data = data; | ||
39 | bytePos = pos; | ||
40 | } | ||
41 | |||
42 | public BitPack() // Encoding version | ||
43 | { | ||
44 | |||
45 | } | ||
46 | |||
47 | public void LoadData(byte[] data, int pos) { | ||
48 | Data = data; | ||
49 | bytePos = pos; | ||
50 | bitPos = 0; | ||
51 | } | ||
52 | |||
53 | private void PackBitsArray(byte[] bits, int bitLen) | ||
54 | { | ||
55 | int offset = bitPos % MAX_BITS; | ||
56 | int i; | ||
57 | byte temp1; | ||
58 | byte temp2; | ||
59 | |||
60 | for (i = 0; i < bits.Length; i++) | ||
61 | { | ||
62 | int Byte = bits[i]; | ||
63 | Byte <<= offset; | ||
64 | temp1 = (byte)(Byte & 0xFF); | ||
65 | temp2 = (byte)((Byte >> 8) & 0xFF); | ||
66 | |||
67 | Data[Data.Length - 1] |= temp1; | ||
68 | // Data | ||
69 | |||
70 | bitPos += bitLen; | ||
71 | } | ||
72 | } | ||
73 | |||
74 | public float UnpackFloat() | ||
75 | { | ||
76 | byte[] output = UnpackBitsArray(32); | ||
77 | |||
78 | if (!BitConverter.IsLittleEndian) Array.Reverse(output); | ||
79 | return BitConverter.ToSingle(output, 0); | ||
80 | } | ||
81 | |||
82 | public int UnpackBits(int totalCount) | ||
83 | { | ||
84 | byte[] output = UnpackBitsArray(totalCount); | ||
85 | |||
86 | if (!BitConverter.IsLittleEndian) Array.Reverse(output); | ||
87 | return BitConverter.ToInt32(output, 0); | ||
88 | } | ||
89 | |||
90 | private byte[] UnpackBitsArray(int totalCount) | ||
91 | { | ||
92 | int count = 0; | ||
93 | byte[] output = new byte[4]; | ||
94 | int curBytePos = 0; | ||
95 | int curBitPos = 0; | ||
96 | |||
97 | while (totalCount > 0) | ||
98 | { | ||
99 | if (totalCount > MAX_BITS) | ||
100 | { | ||
101 | count = MAX_BITS; | ||
102 | totalCount -= MAX_BITS; | ||
103 | } | ||
104 | else | ||
105 | { | ||
106 | count = totalCount; | ||
107 | totalCount = 0; | ||
108 | } | ||
109 | |||
110 | while (count > 0) | ||
111 | { | ||
112 | // Shift the previous bits | ||
113 | output[curBytePos] <<= 1; | ||
114 | |||
115 | // Grab one bit | ||
116 | if ((Data[bytePos] & (0x80 >> bitPos++)) != 0) | ||
117 | ++output[curBytePos]; | ||
118 | |||
119 | --count; | ||
120 | ++curBitPos; | ||
121 | |||
122 | if (bitPos >= MAX_BITS) | ||
123 | { | ||
124 | bitPos = 0; | ||
125 | ++bytePos; | ||
126 | } | ||
127 | if (curBitPos >= MAX_BITS) | ||
128 | { | ||
129 | curBitPos = 0; | ||
130 | ++curBytePos; | ||
131 | } | ||
132 | } | ||
133 | } | ||
134 | |||
135 | return output; | ||
136 | } | ||
137 | } | ||
138 | } | ||
diff --git a/src/types/Mesh.cs b/src/types/Mesh.cs new file mode 100644 index 0000000..3e00c91 --- /dev/null +++ b/src/types/Mesh.cs | |||
@@ -0,0 +1,28 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | using System.Text; | ||
4 | |||
5 | namespace OpenSim.types | ||
6 | { | ||
7 | // TODO: This will need some performance tuning no doubt. | ||
8 | public class Mesh | ||
9 | { | ||
10 | public List<Triangle> mesh; | ||
11 | |||
12 | public Mesh() | ||
13 | { | ||
14 | mesh = new List<Triangle>(); | ||
15 | } | ||
16 | |||
17 | public void AddTri(Triangle tri) | ||
18 | { | ||
19 | mesh.Add(tri); | ||
20 | } | ||
21 | |||
22 | public static Mesh operator +(Mesh a, Mesh b) | ||
23 | { | ||
24 | a.mesh.AddRange(b.mesh); | ||
25 | return a; | ||
26 | } | ||
27 | } | ||
28 | } | ||
diff --git a/src/types/Triangle.cs b/src/types/Triangle.cs new file mode 100644 index 0000000..8dfea6e --- /dev/null +++ b/src/types/Triangle.cs | |||
@@ -0,0 +1,28 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | using System.Text; | ||
4 | using Axiom.MathLib; | ||
5 | |||
6 | namespace OpenSim.types | ||
7 | { | ||
8 | public class Triangle | ||
9 | { | ||
10 | Vector3 a; | ||
11 | Vector3 b; | ||
12 | Vector3 c; | ||
13 | |||
14 | public Triangle() | ||
15 | { | ||
16 | a = new Vector3(); | ||
17 | b = new Vector3(); | ||
18 | c = new Vector3(); | ||
19 | } | ||
20 | |||
21 | public Triangle(Vector3 A, Vector3 B, Vector3 C) | ||
22 | { | ||
23 | a = A; | ||
24 | b = B; | ||
25 | c = C; | ||
26 | } | ||
27 | } | ||
28 | } | ||
diff --git a/src/world/Avatar.cs b/src/world/Avatar.cs new file mode 100644 index 0000000..863ce29 --- /dev/null +++ b/src/world/Avatar.cs | |||
@@ -0,0 +1,70 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | using System.Text; | ||
4 | using libsecondlife; | ||
5 | using libsecondlife.Packets; | ||
6 | |||
7 | namespace OpenSim.world | ||
8 | { | ||
9 | public class Avatar : Entity | ||
10 | { | ||
11 | public string firstname; | ||
12 | public string lastname; | ||
13 | public OpenSimClient ControllingClient; | ||
14 | |||
15 | public Avatar(OpenSimClient TheClient) { | ||
16 | Console.WriteLine("Avatar.cs - Loading details from grid (DUMMY)"); | ||
17 | ControllingClient=TheClient; | ||
18 | } | ||
19 | |||
20 | public void CompleteMovement(World RegionInfo) { | ||
21 | Console.WriteLine("Avatar.cs:CompleteMovement() - Constructing AgentMovementComplete packet"); | ||
22 | AgentMovementCompletePacket mov = new AgentMovementCompletePacket(); | ||
23 | mov.AgentData.SessionID = this.ControllingClient.SessionID; | ||
24 | mov.AgentData.AgentID = this.ControllingClient.AgentID; | ||
25 | mov.Data.RegionHandle = OpenSim_Main.cfg.RegionHandle; | ||
26 | // TODO - dynamicalise this stuff | ||
27 | mov.Data.Timestamp = 1169838966; | ||
28 | mov.Data.Position = new LLVector3(100f, 100f, 22f); | ||
29 | mov.Data.LookAt = new LLVector3(0.99f, 0.042f, 0); | ||
30 | |||
31 | Console.WriteLine("Sending AgentMovementComplete packet"); | ||
32 | ControllingClient.OutPacket(mov); | ||
33 | } | ||
34 | |||
35 | public void SendRegionHandshake(World RegionInfo) { | ||
36 | Console.WriteLine("Avatar.cs:SendRegionHandshake() - Creating empty RegionHandshake packet"); | ||
37 | System.Text.Encoding _enc = System.Text.Encoding.ASCII; | ||
38 | RegionHandshakePacket handshake = new RegionHandshakePacket(); | ||
39 | |||
40 | Console.WriteLine("Avatar.cs:SendRegionhandshake() - Filling in RegionHandshake details"); | ||
41 | handshake.RegionInfo.BillableFactor = 0; | ||
42 | handshake.RegionInfo.IsEstateManager = false; | ||
43 | handshake.RegionInfo.TerrainHeightRange00 = 60; | ||
44 | handshake.RegionInfo.TerrainHeightRange01 = 60; | ||
45 | handshake.RegionInfo.TerrainHeightRange10 = 60; | ||
46 | handshake.RegionInfo.TerrainHeightRange11 = 60; | ||
47 | handshake.RegionInfo.TerrainStartHeight00 = 20; | ||
48 | handshake.RegionInfo.TerrainStartHeight01 = 20; | ||
49 | handshake.RegionInfo.TerrainStartHeight10 = 20; | ||
50 | handshake.RegionInfo.TerrainStartHeight11 = 20; | ||
51 | handshake.RegionInfo.SimAccess = 13; | ||
52 | handshake.RegionInfo.WaterHeight = 5; | ||
53 | handshake.RegionInfo.RegionFlags = 72458694; | ||
54 | handshake.RegionInfo.SimName = _enc.GetBytes(OpenSim_Main.cfg.RegionName + "\0"); | ||
55 | handshake.RegionInfo.SimOwner = new LLUUID("00000000-0000-0000-0000-000000000000"); | ||
56 | handshake.RegionInfo.TerrainBase0 = new LLUUID("b8d3965a-ad78-bf43-699b-bff8eca6c975"); | ||
57 | handshake.RegionInfo.TerrainBase1 = new LLUUID("abb783e6-3e93-26c0-248a-247666855da3"); | ||
58 | handshake.RegionInfo.TerrainBase2 = new LLUUID("179cdabd-398a-9b6b-1391-4dc333ba321f"); | ||
59 | handshake.RegionInfo.TerrainBase3 = new LLUUID("beb169c7-11ea-fff2-efe5-0f24dc881df2"); | ||
60 | handshake.RegionInfo.TerrainDetail0 = new LLUUID("00000000-0000-0000-0000-000000000000"); | ||
61 | handshake.RegionInfo.TerrainDetail1 = new LLUUID("00000000-0000-0000-0000-000000000000"); | ||
62 | handshake.RegionInfo.TerrainDetail2 = new LLUUID("00000000-0000-0000-0000-000000000000"); | ||
63 | handshake.RegionInfo.TerrainDetail3 = new LLUUID("00000000-0000-0000-0000-000000000000"); | ||
64 | handshake.RegionInfo.CacheID = new LLUUID("545ec0a5-5751-1026-8a0b-216e38a7ab37"); | ||
65 | |||
66 | Console.WriteLine("Avatar.cs:SendRegionHandshake() - Sending RegionHandshake packet"); | ||
67 | this.ControllingClient.OutPacket(handshake); | ||
68 | } | ||
69 | } | ||
70 | } | ||
diff --git a/src/world/Entity.cs b/src/world/Entity.cs new file mode 100644 index 0000000..ab07fd6 --- /dev/null +++ b/src/world/Entity.cs | |||
@@ -0,0 +1,53 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | using System.Text; | ||
4 | using Axiom.MathLib; | ||
5 | using OpenSim.types; | ||
6 | |||
7 | namespace OpenSim.world | ||
8 | { | ||
9 | public class Entity | ||
10 | { | ||
11 | protected libsecondlife.LLUUID uuid; | ||
12 | protected Vector3 position; | ||
13 | protected Vector3 velocity; | ||
14 | protected Quaternion rotation; | ||
15 | protected string name; | ||
16 | protected List<Entity> children; | ||
17 | |||
18 | public Entity() | ||
19 | { | ||
20 | uuid = new libsecondlife.LLUUID(); | ||
21 | position = new Vector3(); | ||
22 | velocity = new Vector3(); | ||
23 | rotation = new Quaternion(); | ||
24 | name = "(basic entity)"; | ||
25 | children = new List<Entity>(); | ||
26 | } | ||
27 | |||
28 | public virtual void update() { | ||
29 | // Do any per-frame updates needed that are applicable to every type of entity | ||
30 | foreach (Entity child in children) | ||
31 | { | ||
32 | child.update(); | ||
33 | } | ||
34 | } | ||
35 | |||
36 | public virtual string getName() | ||
37 | { | ||
38 | return name; | ||
39 | } | ||
40 | |||
41 | public virtual Mesh getMesh() | ||
42 | { | ||
43 | Mesh mesh = new Mesh(); | ||
44 | |||
45 | foreach (Entity child in children) | ||
46 | { | ||
47 | mesh += child.getMesh(); | ||
48 | } | ||
49 | |||
50 | return mesh; | ||
51 | } | ||
52 | } | ||
53 | } | ||
diff --git a/src/world/Primitive.cs b/src/world/Primitive.cs new file mode 100644 index 0000000..143fa55 --- /dev/null +++ b/src/world/Primitive.cs | |||
@@ -0,0 +1,33 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | using System.Text; | ||
4 | using OpenSim.types; | ||
5 | |||
6 | namespace OpenSim.world | ||
7 | { | ||
8 | public class Primitive : Entity | ||
9 | { | ||
10 | protected float mesh_cutbegin; | ||
11 | protected float mesh_cutend; | ||
12 | |||
13 | public Primitive() | ||
14 | { | ||
15 | mesh_cutbegin = 0.0f; | ||
16 | mesh_cutend = 1.0f; | ||
17 | } | ||
18 | |||
19 | public override Mesh getMesh() | ||
20 | { | ||
21 | Mesh mesh = new Mesh(); | ||
22 | Triangle tri = new Triangle( | ||
23 | new Axiom.MathLib.Vector3(0.0f, 1.0f, 1.0f), | ||
24 | new Axiom.MathLib.Vector3(1.0f, 0.0f, 1.0f), | ||
25 | new Axiom.MathLib.Vector3(1.0f, 1.0f, 0.0f)); | ||
26 | |||
27 | mesh.AddTri(tri); | ||
28 | mesh += base.getMesh(); | ||
29 | |||
30 | return mesh; | ||
31 | } | ||
32 | } | ||
33 | } | ||
diff --git a/src/world/ScriptEngine.cs b/src/world/ScriptEngine.cs new file mode 100644 index 0000000..f20a08e --- /dev/null +++ b/src/world/ScriptEngine.cs | |||
@@ -0,0 +1,18 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | using System.Text; | ||
4 | |||
5 | namespace OpenSim.world | ||
6 | { | ||
7 | public class ScriptEngine | ||
8 | { | ||
9 | public ScriptEngine(World env) | ||
10 | { | ||
11 | } | ||
12 | |||
13 | public void LoadScript() | ||
14 | { | ||
15 | |||
16 | } | ||
17 | } | ||
18 | } | ||
diff --git a/src/world/SurfacePatch.cs b/src/world/SurfacePatch.cs new file mode 100644 index 0000000..71e4116 --- /dev/null +++ b/src/world/SurfacePatch.cs | |||
@@ -0,0 +1,22 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | using System.Text; | ||
4 | |||
5 | namespace OpenSim.world | ||
6 | { | ||
7 | public class SurfacePatch | ||
8 | { | ||
9 | public float[] HeightMap; | ||
10 | |||
11 | public SurfacePatch() { | ||
12 | HeightMap = new float[16*16]; | ||
13 | |||
14 | int xinc; | ||
15 | int yinc; | ||
16 | for(xinc=0; xinc<16; xinc++) for(yinc=0; yinc<16; yinc++) { | ||
17 | HeightMap[xinc+(yinc*16)]=100.0f; | ||
18 | } | ||
19 | |||
20 | } | ||
21 | } | ||
22 | } | ||
diff --git a/src/world/World.cs b/src/world/World.cs new file mode 100644 index 0000000..cf337a8 --- /dev/null +++ b/src/world/World.cs | |||
@@ -0,0 +1,57 @@ | |||
1 | using System; | ||
2 | using libsecondlife; | ||
3 | using System.Collections.Generic; | ||
4 | using System.Text; | ||
5 | |||
6 | namespace OpenSim.world | ||
7 | { | ||
8 | public class World | ||
9 | { | ||
10 | public Dictionary<libsecondlife.LLUUID, Entity> Entities; | ||
11 | public SurfacePatch[] LandMap; | ||
12 | public ScriptEngine Scripts; | ||
13 | |||
14 | public World() | ||
15 | { | ||
16 | Console.WriteLine("World.cs - creating new entitities instance"); | ||
17 | Entities = new Dictionary<libsecondlife.LLUUID, Entity>(); | ||
18 | |||
19 | // We need a 16x16 array of 16m2 surface patches for a 256m2 sim | ||
20 | Console.WriteLine("World.cs - creating LandMap"); | ||
21 | LandMap = new SurfacePatch[16*16]; | ||
22 | int xinc; | ||
23 | int yinc; | ||
24 | for(xinc=0; xinc<16; xinc++) for(yinc=0; yinc<16; yinc++) { | ||
25 | LandMap[xinc+(yinc*16)]=new SurfacePatch(); | ||
26 | } | ||
27 | |||
28 | Console.WriteLine("World.cs - Creating script engine instance"); | ||
29 | // Initialise this only after the world has loaded | ||
30 | Scripts = new ScriptEngine(this); | ||
31 | } | ||
32 | |||
33 | public void Update() | ||
34 | { | ||
35 | foreach (libsecondlife.LLUUID UUID in Entities.Keys) | ||
36 | { | ||
37 | Entities[UUID].update(); | ||
38 | } | ||
39 | } | ||
40 | |||
41 | public void AddViewerAgent(OpenSimClient AgentClient) { | ||
42 | Console.WriteLine("World.cs:AddViewerAgent() - Creating new avatar for remote viewer agent"); | ||
43 | Avatar NewAvatar = new Avatar(AgentClient); | ||
44 | Console.WriteLine("World.cs:AddViewerAgent() - Adding new avatar to world"); | ||
45 | this.Entities.Add(AgentClient.AgentID, NewAvatar); | ||
46 | Console.WriteLine("World.cs:AddViewerAgent() - Starting RegionHandshake "); | ||
47 | NewAvatar.SendRegionHandshake(this); | ||
48 | this.Update(); // will work for now, but needs to be optimised so we don't update everything in the sim for each new user | ||
49 | } | ||
50 | |||
51 | public bool Backup() { | ||
52 | /* TODO: Save the current world entities state. */ | ||
53 | |||
54 | return false; | ||
55 | } | ||
56 | } | ||
57 | } | ||
diff --git a/src/world/scripting/IScript.cs b/src/world/scripting/IScript.cs new file mode 100644 index 0000000..550594d --- /dev/null +++ b/src/world/scripting/IScript.cs | |||
@@ -0,0 +1,16 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | using System.Text; | ||
4 | |||
5 | namespace OpenSim.world.scripting | ||
6 | { | ||
7 | public interface IScriptHost { | ||
8 | bool Register(IScript iscript); | ||
9 | } | ||
10 | public interface IScript | ||
11 | { | ||
12 | string Name{get;set;} | ||
13 | IScriptHost Host{get;set;} | ||
14 | void Show(); | ||
15 | } | ||
16 | } | ||