aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/ClientView.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/ClientView.cs')
-rw-r--r--OpenSim/Region/ClientStack/ClientView.cs293
1 files changed, 293 insertions, 0 deletions
diff --git a/OpenSim/Region/ClientStack/ClientView.cs b/OpenSim/Region/ClientStack/ClientView.cs
new file mode 100644
index 0000000..0fe3884
--- /dev/null
+++ b/OpenSim/Region/ClientStack/ClientView.cs
@@ -0,0 +1,293 @@
1/*
2* Copyright (c) Contributors, http://www.openmetaverse.org/
3* See CONTRIBUTORS.TXT for a full list of copyright holders.
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 OpenSim Project 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 THE DEVELOPERS ``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 THE CONTRIBUTORS 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*/
28using System;
29using System.Collections.Generic;
30using System.Net;
31using System.Text;
32using System.Threading;
33using System.Timers;
34using libsecondlife;
35using libsecondlife.Packets;
36using OpenSim.Assets;
37using OpenSim.Framework;
38using OpenSim.Framework.Console;
39using OpenSim.Framework.Interfaces;
40using OpenSim.Framework.Inventory;
41using OpenSim.Framework.Types;
42using OpenSim.Framework.Utilities;
43using OpenSim.Region.Caches;
44using Timer=System.Timers.Timer;
45
46namespace OpenSim.Region.ClientStack
47{
48 public delegate bool PacketMethod(ClientView simClient, Packet packet);
49
50 /// <summary>
51 /// Handles new client connections
52 /// Constructor takes a single Packet and authenticates everything
53 /// </summary>
54 public partial class ClientView : ClientViewBase, IClientAPI
55 {
56 public static TerrainManager TerrainManager;
57
58 protected static Dictionary<PacketType, PacketMethod> PacketHandlers = new Dictionary<PacketType, PacketMethod>(); //Global/static handlers for all clients
59 protected Dictionary<PacketType, PacketMethod> m_packetHandlers = new Dictionary<PacketType, PacketMethod>(); //local handlers for this instance
60
61 public LLUUID AgentID;
62 public LLUUID SessionID;
63 public LLUUID SecureSessionID = LLUUID.Zero;
64 public string firstName;
65 public string lastName;
66 public bool m_child = false;
67 private UseCircuitCodePacket cirpack;
68 public Thread ClientThread;
69 public LLVector3 startpos;
70
71 private AgentAssetUpload UploadAssets;
72 private LLUUID newAssetFolder = LLUUID.Zero;
73 private bool debug = false;
74 protected IWorld m_world;
75 private Dictionary<uint, ClientView> m_clientThreads;
76 private AssetCache m_assetCache;
77 private InventoryCache m_inventoryCache;
78 private int cachedtextureserial = 0;
79 protected AuthenticateSessionsBase m_authenticateSessionsHandler;
80 private Encoding enc = Encoding.ASCII;
81 // Dead client detection vars
82 private Timer clientPingTimer;
83 private int packetsReceived = 0;
84 private int probesWithNoIngressPackets = 0;
85 private int lastPacketsReceived = 0;
86
87 public ClientView(EndPoint remoteEP, UseCircuitCodePacket initialcirpack, Dictionary<uint, ClientView> clientThreads, IWorld world, AssetCache assetCache, PacketServer packServer, InventoryCache inventoryCache, AuthenticateSessionsBase authenSessions )
88 {
89 m_world = world;
90 m_clientThreads = clientThreads;
91 m_assetCache = assetCache;
92
93 m_networkServer = packServer;
94 m_inventoryCache = inventoryCache;
95 m_authenticateSessionsHandler = authenSessions;
96
97 MainLog.Instance.Verbose( "OpenSimClient.cs - Started up new client thread to handle incoming request");
98 cirpack = initialcirpack;
99 userEP = remoteEP;
100
101 this.startpos = m_authenticateSessionsHandler.GetPosition(initialcirpack.CircuitCode.Code);
102
103 PacketQueue = new BlockingQueue<QueItem>();
104
105 this.UploadAssets = new AgentAssetUpload(this, m_assetCache, m_inventoryCache);
106 AckTimer = new Timer(500);
107 AckTimer.Elapsed += new ElapsedEventHandler(AckTimer_Elapsed);
108 AckTimer.Start();
109
110 this.RegisterLocalPacketHandlers();
111
112 ClientThread = new Thread(new ThreadStart(AuthUser));
113 ClientThread.IsBackground = true;
114 ClientThread.Start();
115 }
116
117 # region Client Methods
118
119 public void KillClient()
120 {
121 clientPingTimer.Stop();
122 this.m_inventoryCache.ClientLeaving(this.AgentID, null);
123 m_world.RemoveClient(this.AgentId);
124
125 m_clientThreads.Remove(this.CircuitCode);
126 m_networkServer.RemoveClientCircuit(this.CircuitCode);
127 this.ClientThread.Abort();
128 }
129 #endregion
130
131 # region Packet Handling
132 public static bool AddPacketHandler(PacketType packetType, PacketMethod handler)
133 {
134 bool result = false;
135 lock (PacketHandlers)
136 {
137 if (!PacketHandlers.ContainsKey(packetType))
138 {
139 PacketHandlers.Add(packetType, handler);
140 result = true;
141 }
142 }
143 return result;
144 }
145
146 public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler)
147 {
148 bool result = false;
149 lock (m_packetHandlers)
150 {
151 if (!m_packetHandlers.ContainsKey(packetType))
152 {
153 m_packetHandlers.Add(packetType, handler);
154 result = true;
155 }
156 }
157 return result;
158 }
159
160 protected virtual bool ProcessPacketMethod(Packet packet)
161 {
162 bool result = false;
163 bool found = false;
164 PacketMethod method;
165 if (m_packetHandlers.TryGetValue(packet.Type, out method))
166 {
167 //there is a local handler for this packet type
168 result = method(this, packet);
169 }
170 else
171 {
172 //there is not a local handler so see if there is a Global handler
173 lock (PacketHandlers)
174 {
175 found = PacketHandlers.TryGetValue(packet.Type, out method);
176 }
177 if (found)
178 {
179 result = method(this, packet);
180 }
181 }
182 return result;
183 }
184
185 protected virtual void ClientLoop()
186 {
187 MainLog.Instance.Verbose( "OpenSimClient.cs:ClientLoop() - Entered loop");
188 while (true)
189 {
190 QueItem nextPacket = PacketQueue.Dequeue();
191 if (nextPacket.Incoming)
192 {
193 //is a incoming packet
194 if (nextPacket.Packet.Type != PacketType.AgentUpdate) {
195 packetsReceived++;
196 }
197 ProcessInPacket(nextPacket.Packet);
198 }
199 else
200 {
201 //is a out going packet
202 ProcessOutPacket(nextPacket.Packet);
203 }
204 }
205 }
206 # endregion
207
208 protected void CheckClientConnectivity(object sender, ElapsedEventArgs e)
209 {
210 if (packetsReceived == lastPacketsReceived) {
211 probesWithNoIngressPackets++;
212 if (probesWithNoIngressPackets > 30) {
213 this.KillClient();
214 } else {
215 // this will normally trigger at least one packet (ping response)
216 SendStartPingCheck(0);
217 }
218 } else {
219 // Something received in the meantime - we can reset the counters
220 probesWithNoIngressPackets = 0;
221 lastPacketsReceived = packetsReceived;
222 }
223 }
224
225 # region Setup
226
227 protected virtual void InitNewClient()
228 {
229 clientPingTimer = new Timer(1000);
230 clientPingTimer.Elapsed += new ElapsedEventHandler(CheckClientConnectivity);
231 clientPingTimer.Enabled = true;
232
233 MainLog.Instance.Verbose( "OpenSimClient.cs:InitNewClient() - Adding viewer agent to world");
234 this.m_world.AddNewClient(this, false);
235 }
236
237 protected virtual void AuthUser()
238 {
239 // AuthenticateResponse sessionInfo = m_gridServer.AuthenticateSession(cirpack.CircuitCode.SessionID, cirpack.CircuitCode.ID, cirpack.CircuitCode.Code);
240 AuthenticateResponse sessionInfo = this.m_authenticateSessionsHandler.AuthenticateSession(cirpack.CircuitCode.SessionID, cirpack.CircuitCode.ID, cirpack.CircuitCode.Code);
241 if (!sessionInfo.Authorised)
242 {
243 //session/circuit not authorised
244 MainLog.Instance.Notice("OpenSimClient.cs:AuthUser() - New user request denied to " + userEP.ToString());
245 ClientThread.Abort();
246 }
247 else
248 {
249 MainLog.Instance.Notice("OpenSimClient.cs:AuthUser() - Got authenticated connection from " + userEP.ToString());
250 //session is authorised
251 this.AgentID = cirpack.CircuitCode.ID;
252 this.SessionID = cirpack.CircuitCode.SessionID;
253 this.CircuitCode = cirpack.CircuitCode.Code;
254 this.firstName = sessionInfo.LoginInfo.First;
255 this.lastName = sessionInfo.LoginInfo.Last;
256
257 if (sessionInfo.LoginInfo.SecureSession != LLUUID.Zero)
258 {
259 this.SecureSessionID = sessionInfo.LoginInfo.SecureSession;
260 }
261 InitNewClient();
262
263 ClientLoop();
264 }
265 }
266 # endregion
267
268
269 protected override void KillThread()
270 {
271 this.ClientThread.Abort();
272 }
273
274 #region Inventory Creation
275 private void SetupInventory(AuthenticateResponse sessionInfo)
276 {
277
278 }
279 private AgentInventory CreateInventory(LLUUID baseFolder)
280 {
281 AgentInventory inventory = null;
282
283 return inventory;
284 }
285
286 private void CreateInventoryItem(CreateInventoryItemPacket packet)
287 {
288
289 }
290 #endregion
291
292 }
293}