aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorTeravus Ovares (Dan Olivares)2010-12-23 13:17:55 -0500
committerTeravus Ovares (Dan Olivares)2010-12-23 13:17:55 -0500
commitd829580e5e3fa1db760dc764c0ca76e65dd9b4c8 (patch)
treea6b530c63a0f59ebf1c016f52fe511fd01fc438e
parent* Cleanup from a commit a while ago. (diff)
parentMerge branch 'master' of ssh://opensimulator.org/var/git/opensim (diff)
downloadopensim-SC_OLD-d829580e5e3fa1db760dc764c0ca76e65dd9b4c8.zip
opensim-SC_OLD-d829580e5e3fa1db760dc764c0ca76e65dd9b4c8.tar.gz
opensim-SC_OLD-d829580e5e3fa1db760dc764c0ca76e65dd9b4c8.tar.bz2
opensim-SC_OLD-d829580e5e3fa1db760dc764c0ca76e65dd9b4c8.tar.xz
Merge branch 'master' of ssh://MyConnection/var/git/opensim
-rw-r--r--OpenSim/Framework/IClientAPI.cs4
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs58
-rw-r--r--OpenSim/Region/CoreModules/Agent/TextureDownload/TextureDownloadModule.cs302
-rw-r--r--OpenSim/Region/CoreModules/Agent/TextureDownload/TextureNotFoundSender.cs87
-rw-r--r--OpenSim/Region/CoreModules/Agent/TextureDownload/UserTextureDownloadService.cs265
-rw-r--r--OpenSim/Region/CoreModules/Agent/TextureSender/TextureSender.cs212
-rw-r--r--OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs11
-rw-r--r--OpenSim/Region/Framework/Interfaces/ITextureSender.cs58
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdePlugin.cs19
9 files changed, 55 insertions, 961 deletions
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs
index 6bca6eb..21ffa9a 100644
--- a/OpenSim/Framework/IClientAPI.cs
+++ b/OpenSim/Framework/IClientAPI.cs
@@ -574,11 +574,13 @@ namespace OpenSim.Framework
574 { 574 {
575 public ISceneEntity Entity; 575 public ISceneEntity Entity;
576 public PrimUpdateFlags Flags; 576 public PrimUpdateFlags Flags;
577 public float TimeDilation;
577 578
578 public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags) 579 public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags, float timedilation)
579 { 580 {
580 Entity = entity; 581 Entity = entity;
581 Flags = flags; 582 Flags = flags;
583 TimeDilation = timedilation;
582 } 584 }
583 } 585 }
584 586
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 929f282..d63b719 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -3554,7 +3554,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3554 double priority = m_prioritizer.GetUpdatePriority(this, entity); 3554 double priority = m_prioritizer.GetUpdatePriority(this, entity);
3555 3555
3556 lock (m_entityUpdates.SyncRoot) 3556 lock (m_entityUpdates.SyncRoot)
3557 m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags), entity.LocalId); 3557 m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation), entity.LocalId);
3558 } 3558 }
3559 3559
3560 private void ProcessEntityUpdates(int maxUpdates) 3560 private void ProcessEntityUpdates(int maxUpdates)
@@ -3570,14 +3570,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3570 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3570 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3571 // condition where a kill can be processed before an out-of-date update for the same object. 3571 // condition where a kill can be processed before an out-of-date update for the same object.
3572 lock (m_killRecord) 3572 lock (m_killRecord)
3573 { 3573 {
3574 float avgTimeDilation = 1.0f;
3574 EntityUpdate update; 3575 EntityUpdate update;
3575 while (updatesThisCall < maxUpdates) 3576 while (updatesThisCall < maxUpdates)
3576 { 3577 {
3577 lock (m_entityUpdates.SyncRoot) 3578 lock (m_entityUpdates.SyncRoot)
3578 if (!m_entityUpdates.TryDequeue(out update)) 3579 if (!m_entityUpdates.TryDequeue(out update))
3579 break; 3580 break;
3580 3581 avgTimeDilation += update.TimeDilation;
3582 avgTimeDilation *= 0.5f;
3583
3581 if (update.Entity is SceneObjectPart) 3584 if (update.Entity is SceneObjectPart)
3582 { 3585 {
3583 SceneObjectPart part = (SceneObjectPart)update.Entity; 3586 SceneObjectPart part = (SceneObjectPart)update.Entity;
@@ -3725,8 +3728,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3725 3728
3726 #region Packet Sending 3729 #region Packet Sending
3727 3730
3728 const float TIME_DILATION = 1.0f; 3731 //const float TIME_DILATION = 1.0f;
3729 ushort timeDilation = Utils.FloatToUInt16(TIME_DILATION, 0.0f, 1.0f); 3732
3733
3734 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3730 3735
3731 if (terseAgentUpdateBlocks.IsValueCreated) 3736 if (terseAgentUpdateBlocks.IsValueCreated)
3732 { 3737 {
@@ -3739,7 +3744,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3739 3744
3740 for (int i = 0; i < blocks.Count; i++) 3745 for (int i = 0; i < blocks.Count; i++)
3741 packet.ObjectData[i] = blocks[i]; 3746 packet.ObjectData[i] = blocks[i];
3742 3747
3748
3743 OutPacket(packet, ThrottleOutPacketType.Unknown, true); 3749 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3744 } 3750 }
3745 3751
@@ -7189,34 +7195,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7189 //handlerTextureRequest = null; 7195 //handlerTextureRequest = null;
7190 for (int i = 0; i < imageRequest.RequestImage.Length; i++) 7196 for (int i = 0; i < imageRequest.RequestImage.Length; i++)
7191 { 7197 {
7192 if (OnRequestTexture != null) 7198 TextureRequestArgs args = new TextureRequestArgs();
7193 {
7194 TextureRequestArgs args = new TextureRequestArgs();
7195
7196 RequestImagePacket.RequestImageBlock block = imageRequest.RequestImage[i];
7197 7199
7198 args.RequestedAssetID = block.Image; 7200 RequestImagePacket.RequestImageBlock block = imageRequest.RequestImage[i];
7199 args.DiscardLevel = block.DiscardLevel;
7200 args.PacketNumber = block.Packet;
7201 args.Priority = block.DownloadPriority;
7202 args.requestSequence = imageRequest.Header.Sequence;
7203 7201
7204 // NOTE: This is not a built in part of the LLUDP protocol, but we double the 7202 args.RequestedAssetID = block.Image;
7205 // priority of avatar textures to get avatars rezzing in faster than the 7203 args.DiscardLevel = block.DiscardLevel;
7206 // surrounding scene 7204 args.PacketNumber = block.Packet;
7207 if ((ImageType)block.Type == ImageType.Baked) 7205 args.Priority = block.DownloadPriority;
7208 args.Priority *= 2.0f; 7206 args.requestSequence = imageRequest.Header.Sequence;
7209 7207
7210 //handlerTextureRequest = OnRequestTexture; 7208 // NOTE: This is not a built in part of the LLUDP protocol, but we double the
7209 // priority of avatar textures to get avatars rezzing in faster than the
7210 // surrounding scene
7211 if ((ImageType)block.Type == ImageType.Baked)
7212 args.Priority *= 2.0f;
7211 7213
7212 //if (handlerTextureRequest != null) 7214 // in the end, we null this, so we have to check if it's null
7213 //OnRequestTexture(this, args); 7215 if (m_imageManager != null)
7214 7216 {
7215 // in the end, we null this, so we have to check if it's null 7217 m_imageManager.EnqueueReq(args);
7216 if (m_imageManager != null)
7217 {
7218 m_imageManager.EnqueueReq(args);
7219 }
7220 } 7218 }
7221 } 7219 }
7222 return true; 7220 return true;
diff --git a/OpenSim/Region/CoreModules/Agent/TextureDownload/TextureDownloadModule.cs b/OpenSim/Region/CoreModules/Agent/TextureDownload/TextureDownloadModule.cs
deleted file mode 100644
index c7bf6c8..0000000
--- a/OpenSim/Region/CoreModules/Agent/TextureDownload/TextureDownloadModule.cs
+++ /dev/null
@@ -1,302 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.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 OpenSimulator 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.Reflection;
31using System.Threading;
32using log4net;
33using Nini.Config;
34using OpenMetaverse;
35using OpenSim.Framework;
36
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes;
39using BlockingQueue = OpenSim.Framework.BlockingQueue<OpenSim.Region.Framework.Interfaces.ITextureSender>;
40using OpenSim.Services.Interfaces;
41
42namespace OpenSim.Region.CoreModules.Agent.TextureDownload
43{
44 public class TextureDownloadModule : IRegionModule
45 {
46 private static readonly ILog m_log
47 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48
49 /// <summary>
50 /// There is one queue for all textures waiting to be sent, regardless of the requesting user.
51 /// </summary>
52 private readonly BlockingQueue m_queueSenders
53 = new BlockingQueue();
54
55 /// <summary>
56 /// Each user has their own texture download service.
57 /// </summary>
58 private readonly Dictionary<UUID, UserTextureDownloadService> m_userTextureServices =
59 new Dictionary<UUID, UserTextureDownloadService>();
60
61 private Scene m_scene;
62 private List<Scene> m_scenes = new List<Scene>();
63
64 public TextureDownloadModule()
65 {
66 }
67
68 #region IRegionModule Members
69
70 public void Initialise(Scene scene, IConfigSource config)
71 {
72
73 if (m_scene == null)
74 {
75 //m_log.Debug("Creating Texture download module");
76 m_scene = scene;
77 //m_thread = new Thread(new ThreadStart(ProcessTextureSenders));
78 //m_thread.Name = "ProcessTextureSenderThread";
79 //m_thread.IsBackground = true;
80 //m_thread.Start();
81 //ThreadTracker.Add(m_thread);
82 }
83
84 if (!m_scenes.Contains(scene))
85 {
86 m_scenes.Add(scene);
87 m_scene = scene;
88 m_scene.EventManager.OnNewClient += NewClient;
89 m_scene.EventManager.OnRemovePresence += EventManager_OnRemovePresence;
90 }
91 }
92
93 public void PostInitialise()
94 {
95 }
96
97 public void Close()
98 {
99 }
100
101 public string Name
102 {
103 get { return "TextureDownloadModule"; }
104 }
105
106 public bool IsSharedModule
107 {
108 get { return false; }
109 }
110
111 #endregion
112
113 /// <summary>
114 /// Cleanup the texture service related objects for the removed presence.
115 /// </summary>
116 /// <param name="agentId"> </param>
117 private void EventManager_OnRemovePresence(UUID agentId)
118 {
119 UserTextureDownloadService textureService;
120
121 lock (m_userTextureServices)
122 {
123 if (m_userTextureServices.TryGetValue(agentId, out textureService))
124 {
125 textureService.Close();
126 //m_log.DebugFormat("[TEXTURE MODULE]: Removing UserTextureServices from {0}", m_scene.RegionInfo.RegionName);
127 m_userTextureServices.Remove(agentId);
128 }
129 }
130 }
131
132 public void NewClient(IClientAPI client)
133 {
134 UserTextureDownloadService textureService;
135
136 lock (m_userTextureServices)
137 {
138 if (m_userTextureServices.TryGetValue(client.AgentId, out textureService))
139 {
140 textureService.Close();
141 //m_log.DebugFormat("[TEXTURE MODULE]: Removing outdated UserTextureServices from {0}", m_scene.RegionInfo.RegionName);
142 m_userTextureServices.Remove(client.AgentId);
143 }
144 m_userTextureServices.Add(client.AgentId, new UserTextureDownloadService(client, m_scene, m_queueSenders));
145 }
146
147 client.OnRequestTexture += TextureRequest;
148 }
149
150 /// I'm commenting this out, and replacing it with the implementation below, which
151 /// may return a null value. This is necessary for avoiding race conditions
152 /// recreating UserTextureServices for clients that have just been closed.
153 /// That behavior of always returning a UserTextureServices was causing the
154 /// A-B-A problem (mantis #2855).
155 ///
156 ///// <summary>
157 ///// Does this user have a registered texture download service?
158 ///// </summary>
159 ///// <param name="userID"></param>
160 ///// <param name="textureService"></param>
161 ///// <returns>Always returns true, since a service is created if one does not already exist</returns>
162 //private bool TryGetUserTextureService(
163 // IClientAPI client, out UserTextureDownloadService textureService)
164 //{
165 // lock (m_userTextureServices)
166 // {
167 // if (m_userTextureServices.TryGetValue(client.AgentId, out textureService))
168 // {
169 // //m_log.DebugFormat("[TEXTURE MODULE]: Found existing UserTextureServices in ", m_scene.RegionInfo.RegionName);
170 // return true;
171 // }
172
173 // m_log.DebugFormat("[TEXTURE MODULE]: Creating new UserTextureServices in ", m_scene.RegionInfo.RegionName);
174 // textureService = new UserTextureDownloadService(client, m_scene, m_queueSenders);
175 // m_userTextureServices.Add(client.AgentId, textureService);
176
177 // return true;
178 // }
179 //}
180
181 /// <summary>
182 /// Does this user have a registered texture download service?
183 /// </summary>
184 /// <param name="userID"></param>
185 /// <param name="textureService"></param>
186 /// <returns>A UserTextureDownloadService or null in the output parameter, and true or false accordingly.</returns>
187 private bool TryGetUserTextureService(IClientAPI client, out UserTextureDownloadService textureService)
188 {
189 lock (m_userTextureServices)
190 {
191 if (m_userTextureServices.TryGetValue(client.AgentId, out textureService))
192 {
193 //m_log.DebugFormat("[TEXTURE MODULE]: Found existing UserTextureServices in ", m_scene.RegionInfo.RegionName);
194 return true;
195 }
196
197 textureService = null;
198 return false;
199 }
200 }
201
202 /// <summary>
203 /// Start the process of requesting a given texture.
204 /// </summary>
205 /// <param name="sender"> </param>
206 /// <param name="e"></param>
207 public void TextureRequest(Object sender, TextureRequestArgs e)
208 {
209 IClientAPI client = (IClientAPI)sender;
210
211 if (e.Priority == 1016001f) // Preview
212 {
213 if (client.Scene is Scene)
214 {
215 Scene scene = (Scene)client.Scene;
216
217 ScenePresence sp = scene.GetScenePresence(client.AgentId);
218 if (sp == null) // Deny unknown user
219 return;
220
221 IInventoryService invService = scene.InventoryService;
222 if (invService.GetRootFolder(client.AgentId) == null) // Deny no inventory
223 return;
224
225 // Diva 2009-08-13: this test doesn't make any sense to many devs
226 //if (profile.UserProfile.GodLevel < 200 && profile.RootFolder.FindAsset(e.RequestedAssetID) == null) // Deny if not owned
227 //{
228 // m_log.WarnFormat("[TEXTURE]: user {0} doesn't have permissions to texture {1}");
229 // return;
230 //}
231
232 m_log.Debug("Texture preview");
233 }
234 }
235
236 UserTextureDownloadService textureService;
237
238 if (TryGetUserTextureService(client, out textureService))
239 {
240 textureService.HandleTextureRequest(e);
241 }
242 }
243
244 /// <summary>
245 /// Entry point for the thread dedicated to processing the texture queue.
246 /// </summary>
247 public void ProcessTextureSenders()
248 {
249 ITextureSender sender = null;
250
251 try
252 {
253 while (true)
254 {
255 sender = m_queueSenders.Dequeue();
256
257 if (sender.Cancel)
258 {
259 TextureSent(sender);
260
261 sender.Cancel = false;
262 }
263 else
264 {
265 bool finished = sender.SendTexturePacket();
266 if (finished)
267 {
268 TextureSent(sender);
269 }
270 else
271 {
272 m_queueSenders.Enqueue(sender);
273 }
274 }
275
276 // Make sure that any sender we currently have can get garbage collected
277 sender = null;
278
279 //m_log.InfoFormat("[TEXTURE] Texture sender queue size: {0}", m_queueSenders.Count());
280 }
281 }
282 catch (Exception e)
283 {
284 // TODO: Let users in the sim and those entering it and possibly an external watchdog know what has happened
285 m_log.ErrorFormat(
286 "[TEXTURE]: Texture send thread terminating with exception. PLEASE REBOOT YOUR SIM - TEXTURES WILL NOT BE AVAILABLE UNTIL YOU DO. Exception is {0}",
287 e);
288 }
289 }
290
291 /// <summary>
292 /// Called when the texture has finished sending.
293 /// </summary>
294 /// <param name="sender"></param>
295 private void TextureSent(ITextureSender sender)
296 {
297 sender.Sending = false;
298 //m_log.DebugFormat("[TEXTURE]: Removing download stat for {0}", sender.assetID);
299 m_scene.StatsReporter.AddPendingDownloads(-1);
300 }
301 }
302}
diff --git a/OpenSim/Region/CoreModules/Agent/TextureDownload/TextureNotFoundSender.cs b/OpenSim/Region/CoreModules/Agent/TextureDownload/TextureNotFoundSender.cs
deleted file mode 100644
index ba735a7..0000000
--- a/OpenSim/Region/CoreModules/Agent/TextureDownload/TextureNotFoundSender.cs
+++ /dev/null
@@ -1,87 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.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 OpenSimulator 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 OpenMetaverse;
29using OpenSim.Framework;
30using OpenSim.Region.Framework.Interfaces;
31
32namespace OpenSim.Region.CoreModules.Agent.TextureDownload
33{
34 /// <summary>
35 /// Sends a 'texture not found' packet back to the client
36 /// </summary>
37 public class TextureNotFoundSender : ITextureSender
38 {
39 // private static readonly log4net.ILog m_log
40 // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
41
42 // private IClientAPI m_client;
43 // private UUID m_textureId;
44
45 public TextureNotFoundSender(IClientAPI client, UUID textureID)
46 {
47 //m_client = client;
48 //m_textureId = textureID;
49 }
50
51 #region ITextureSender Members
52
53 public bool Sending
54 {
55 get { return false; }
56 set { }
57 }
58
59 public bool Cancel
60 {
61 get { return false; }
62 set { }
63 }
64
65 // See ITextureSender
66 public void UpdateRequest(int discardLevel, uint packetNumber)
67 {
68 // No need to implement since priority changes don't affect this operation
69 }
70
71 // See ITextureSender
72 public bool SendTexturePacket()
73 {
74 // m_log.DebugFormat(
75 // "[TEXTURE NOT FOUND SENDER]: Informing the client that texture {0} cannot be found",
76 // m_textureId);
77
78 // XXX Temporarily disabling as this appears to be causing client crashes on at least
79 // 1.19.0(5) of the Linden Second Life client.
80 // m_client.SendImageNotFound(m_textureId);
81
82 return true;
83 }
84
85 #endregion
86 }
87}
diff --git a/OpenSim/Region/CoreModules/Agent/TextureDownload/UserTextureDownloadService.cs b/OpenSim/Region/CoreModules/Agent/TextureDownload/UserTextureDownloadService.cs
deleted file mode 100644
index 19f0f90..0000000
--- a/OpenSim/Region/CoreModules/Agent/TextureDownload/UserTextureDownloadService.cs
+++ /dev/null
@@ -1,265 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.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 OpenSimulator 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.Reflection;
31using log4net;
32using OpenMetaverse;
33using OpenSim.Framework;
34using OpenSim.Framework.Communications.Limit;
35using OpenSim.Framework.Statistics;
36using OpenSim.Region.Framework.Interfaces;
37using OpenSim.Region.Framework.Scenes;
38
39namespace OpenSim.Region.CoreModules.Agent.TextureDownload
40{
41 /// <summary>
42 /// This module sets up texture senders in response to client texture requests, and places them on a
43 /// processing queue once those senders have the appropriate data (i.e. a texture retrieved from the
44 /// asset cache).
45 /// </summary>
46 public class UserTextureDownloadService
47 {
48// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49
50 /// <summary>
51 /// True if the service has been closed, probably because a user with texture requests still queued
52 /// logged out.
53 /// </summary>
54 private bool closed;
55
56 /// <summary>
57 /// We will allow the client to request the same texture n times before dropping further requests
58 ///
59 /// This number includes repeated requests for the same texture at different resolutions (which we don't
60 /// currently handle properly as far as I know). However, this situation should be handled in a more
61 /// sophisticated way.
62 /// </summary>
63// private static readonly int MAX_ALLOWED_TEXTURE_REQUESTS = 5;
64
65 /// <summary>
66 /// XXX Also going to limit requests for found textures.
67 /// </summary>
68// private readonly IRequestLimitStrategy<UUID> foundTextureLimitStrategy
69// = new RepeatLimitStrategy<UUID>(MAX_ALLOWED_TEXTURE_REQUESTS);
70
71// private readonly IClientAPI m_client;
72 private readonly Scene m_scene;
73
74 /// <summary>
75 /// Texture Senders are placed in this queue once they have received their texture from the asset
76 /// cache. Another module actually invokes the send.
77 /// </summary>
78// private readonly OpenSim.Framework.BlockingQueue<ITextureSender> m_sharedSendersQueue;
79
80 /// <summary>
81 /// Holds texture senders before they have received the appropriate texture from the asset cache.
82 /// </summary>
83 private readonly Dictionary<UUID, TextureSender.TextureSender> m_textureSenders = new Dictionary<UUID, TextureSender.TextureSender>();
84
85 /// <summary>
86 /// We're going to limit requests for the same missing texture.
87 /// XXX This is really a temporary solution to deal with the situation where a client continually requests
88 /// the same missing textures
89 /// </summary>
90// private readonly IRequestLimitStrategy<UUID> missingTextureLimitStrategy
91// = new RepeatLimitStrategy<UUID>(MAX_ALLOWED_TEXTURE_REQUESTS);
92
93 public UserTextureDownloadService(
94 IClientAPI client, Scene scene, OpenSim.Framework.BlockingQueue<ITextureSender> sharedQueue)
95 {
96// m_client = client;
97 m_scene = scene;
98// m_sharedSendersQueue = sharedQueue;
99 }
100
101 /// <summary>
102 /// Handle a texture request. This involves creating a texture sender and placing it on the
103 /// previously passed in shared queue.
104 /// </summary>
105 /// <param name="e"></param>
106 public void HandleTextureRequest(TextureRequestArgs e)
107 {
108
109 //TextureSender.TextureSender textureSender;
110
111 //TODO: should be working out the data size/ number of packets to be sent for each discard level
112 //if ((e.DiscardLevel >= 0) || (e.Priority != 0))
113 //{
114 //lock (m_textureSenders)
115 //{
116 //if (m_textureSenders.TryGetValue(e.RequestedAssetID, out textureSender))
117 //{
118 // If we've received new non UUID information for this request and it hasn't dispatched
119 // yet, then update the request accordingly.
120 // textureSender.UpdateRequest(e.DiscardLevel, e.PacketNumber);
121 //}
122 //else
123 //{
124 // m_log.DebugFormat("[TEXTURE]: Received a request for texture {0}", e.RequestedAssetID);
125
126 //if (!foundTextureLimitStrategy.AllowRequest(e.RequestedAssetID))
127 //{
128 // m_log.DebugFormat(
129 // "[TEXTURE]: Refusing request for {0} from client {1}",
130 // e.RequestedAssetID, m_client.AgentId);
131
132 //return;
133 //}
134 //else if (!missingTextureLimitStrategy.AllowRequest(e.RequestedAssetID))
135 //{
136 // if (missingTextureLimitStrategy.IsFirstRefusal(e.RequestedAssetID))
137 // {
138 // if (StatsManager.SimExtraStats != null)
139 // StatsManager.SimExtraStats.AddBlockedMissingTextureRequest();
140
141 // Commenting out this message for now as it causes too much noise with other
142 // debug messages.
143 // m_log.DebugFormat(
144 // "[TEXTURE]: Dropping requests for notified missing texture {0} for client {1} since we have received more than {2} requests",
145 // e.RequestedAssetID, m_client.AgentId, MAX_ALLOWED_TEXTURE_REQUESTS);
146 // }
147
148 // return;
149 //}
150
151 m_scene.StatsReporter.AddPendingDownloads(1);
152
153 //TextureSender.TextureSender requestHandler = new TextureSender.TextureSender(m_client, e.DiscardLevel, e.PacketNumber);
154 //m_textureSenders.Add(e.RequestedAssetID, null);
155
156 m_scene.AssetService.Get(e.RequestedAssetID.ToString(), this, TextureReceived);
157
158
159 }
160
161 protected void TextureReceived(string id, Object sender, AssetBase asset)
162 {
163 if (asset != null)
164 TextureCallback(asset.FullID, asset);
165 }
166
167 /// <summary>
168 /// The callback for the asset cache when a texture has been retrieved. This method queues the
169 /// texture sender for processing.
170 /// </summary>
171 /// <param name="textureID"></param>
172 /// <param name="texture"></param>
173 public void TextureCallback(UUID textureID, AssetBase texture)
174 {
175 //m_log.DebugFormat("[USER TEXTURE DOWNLOAD SERVICE]: Calling TextureCallback with {0}, texture == null is {1}", textureID, (texture == null ? true : false));
176
177 // There may still be texture requests pending for a logged out client
178 if (closed)
179 return;
180
181 /*
182 lock (m_textureSenders)
183 {
184 TextureSender.TextureSender textureSender;
185 if (m_textureSenders.TryGetValue(textureID, out textureSender))
186 {
187 // XXX It may be perfectly valid for a texture to have no data... but if we pass
188 // this on to the TextureSender it will blow up, so just discard for now.
189 // Needs investigation.
190 if (texture == null || texture.Data == null)
191 {
192 if (!missingTextureLimitStrategy.IsMonitoringRequests(textureID))
193 {
194 missingTextureLimitStrategy.MonitorRequests(textureID);
195
196 // m_log.DebugFormat(
197 // "[TEXTURE]: Queueing first TextureNotFoundSender for {0}, client {1}",
198 // textureID, m_client.AgentId);
199 }
200
201 ITextureSender textureNotFoundSender = new TextureNotFoundSender(m_client, textureID);
202 EnqueueTextureSender(textureNotFoundSender);
203 }
204 else
205 {
206 if (!textureSender.ImageLoaded)
207 {
208 textureSender.TextureReceived(texture);
209 EnqueueTextureSender(textureSender);
210
211 foundTextureLimitStrategy.MonitorRequests(textureID);
212 }
213 }
214
215 //m_log.InfoFormat("[TEXTURE] Removing texture sender with uuid {0}", textureID);
216 m_textureSenders.Remove(textureID);
217 //m_log.InfoFormat("[TEXTURE] Current texture senders in dictionary: {0}", m_textureSenders.Count);
218 }
219 else
220 {
221 m_log.WarnFormat(
222 "[TEXTURE]: Got a texture uuid {0} with no sender object to handle it, this shouldn't happen",
223 textureID);
224 }
225 }
226 */
227 }
228
229 /// <summary>
230 /// Place a ready texture sender on the processing queue.
231 /// </summary>
232 /// <param name="textureSender"></param>
233// private void EnqueueTextureSender(ITextureSender textureSender)
234// {
235// textureSender.Cancel = false;
236// textureSender.Sending = true;
237//
238// if (!m_sharedSendersQueue.Contains(textureSender))
239// {
240// m_sharedSendersQueue.Enqueue(textureSender);
241// }
242// }
243
244 /// <summary>
245 /// Close this module.
246 /// </summary>
247 internal void Close()
248 {
249 closed = true;
250
251 lock (m_textureSenders)
252 {
253 foreach (TextureSender.TextureSender textureSender in m_textureSenders.Values)
254 {
255 textureSender.Cancel = true;
256 }
257
258 m_textureSenders.Clear();
259 }
260
261 // XXX: It might be possible to also remove pending texture requests from the asset cache queues,
262 // though this might also be more trouble than it's worth.
263 }
264 }
265}
diff --git a/OpenSim/Region/CoreModules/Agent/TextureSender/TextureSender.cs b/OpenSim/Region/CoreModules/Agent/TextureSender/TextureSender.cs
deleted file mode 100644
index 62c5a32..0000000
--- a/OpenSim/Region/CoreModules/Agent/TextureSender/TextureSender.cs
+++ /dev/null
@@ -1,212 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.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 OpenSimulator 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.Reflection;
30using log4net;
31using OpenSim.Framework;
32using OpenSim.Region.Framework.Interfaces;
33
34namespace OpenSim.Region.CoreModules.Agent.TextureSender
35{
36 /// <summary>
37 /// A TextureSender handles the process of receiving a texture requested by the client from the
38 /// AssetCache, and then sending that texture back to the client.
39 /// </summary>
40 public class TextureSender : ITextureSender
41 {
42 private static readonly ILog m_log
43 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
44
45 /// <summary>
46 /// Records the number of times texture send has been called.
47 /// </summary>
48 public int counter = 0;
49
50 public bool ImageLoaded = false;
51
52 /// <summary>
53 /// Holds the texture asset to send.
54 /// </summary>
55 private AssetBase m_asset;
56
57 //public UUID assetID { get { return m_asset.FullID; } }
58
59 // private bool m_cancel = false;
60
61 // See ITextureSender
62
63 // private bool m_sending = false;
64
65 /// <summary>
66 /// This is actually the number of extra packets required to send the texture data! We always assume
67 /// at least one is required.
68 /// </summary>
69 private int NumPackets = 0;
70
71 /// <summary>
72 /// Holds the packet number to send next. In this case, each packet is 1000 bytes long and starts
73 /// at the 600th byte (0th indexed).
74 /// </summary>
75 private int PacketCounter = 0;
76
77 private int RequestedDiscardLevel = -1;
78 private IClientAPI RequestUser;
79 private uint StartPacketNumber = 0;
80
81 public TextureSender(IClientAPI client, int discardLevel, uint packetNumber)
82 {
83 RequestUser = client;
84 RequestedDiscardLevel = discardLevel;
85 StartPacketNumber = packetNumber;
86 }
87
88 #region ITextureSender Members
89
90 public bool Cancel
91 {
92 get { return false; }
93 set
94 {
95 // m_cancel = value;
96 }
97 }
98
99 public bool Sending
100 {
101 get { return false; }
102 set
103 {
104 // m_sending = value;
105 }
106 }
107
108 // See ITextureSender
109 public void UpdateRequest(int discardLevel, uint packetNumber)
110 {
111 RequestedDiscardLevel = discardLevel;
112 StartPacketNumber = packetNumber;
113 PacketCounter = (int)StartPacketNumber;
114 }
115
116 // See ITextureSender
117 public bool SendTexturePacket()
118 {
119 //m_log.DebugFormat("[TEXTURE SENDER]: Sending packet for {0}", m_asset.FullID);
120
121 SendPacket();
122 counter++;
123 if ((NumPackets == 0) || (RequestedDiscardLevel == -1) || (PacketCounter > NumPackets) ||
124 ((RequestedDiscardLevel > 0) && (counter > 50 + (NumPackets / (RequestedDiscardLevel + 1)))))
125 {
126 return true;
127 }
128 return false;
129 }
130
131 #endregion
132
133 /// <summary>
134 /// Load up the texture data to send.
135 /// </summary>
136 /// <param name="asset"></param>
137 public void TextureReceived(AssetBase asset)
138 {
139 m_asset = asset;
140 NumPackets = CalculateNumPackets(asset.Data.Length);
141 PacketCounter = (int)StartPacketNumber;
142 ImageLoaded = true;
143 }
144
145 /// <summary>
146 /// Sends a texture packet to the client.
147 /// </summary>
148 private void SendPacket()
149 {
150 if (PacketCounter <= NumPackets)
151 {
152 if (PacketCounter == 0)
153 {
154 if (NumPackets == 0)
155 {
156 RequestUser.SendImageFirstPart(1, m_asset.FullID, (uint)m_asset.Data.Length, m_asset.Data, 2);
157 PacketCounter++;
158 }
159 else
160 {
161 byte[] ImageData1 = new byte[600];
162 Array.Copy(m_asset.Data, 0, ImageData1, 0, 600);
163
164 RequestUser.SendImageFirstPart(
165 (ushort)(NumPackets), m_asset.FullID, (uint)m_asset.Data.Length, ImageData1, 2);
166 PacketCounter++;
167 }
168 }
169 else
170 {
171 int size = m_asset.Data.Length - 600 - (1000 * (PacketCounter - 1));
172 if (size > 1000) size = 1000;
173 byte[] imageData = new byte[size];
174 try
175 {
176 Array.Copy(m_asset.Data, 600 + (1000 * (PacketCounter - 1)), imageData, 0, size);
177 }
178 catch (ArgumentOutOfRangeException)
179 {
180 m_log.Error("[TEXTURE SENDER]: Unable to separate texture into multiple packets: Array bounds failure on asset:" +
181 m_asset.ID);
182 return;
183 }
184
185 RequestUser.SendImageNextPart((ushort)PacketCounter, m_asset.FullID, imageData);
186 PacketCounter++;
187 }
188 }
189 }
190
191 /// <summary>
192 /// Calculate the number of packets that will be required to send the texture loaded into this sender
193 /// This is actually the number of 1000 byte packets not including an initial 600 byte packet...
194 /// </summary>
195 /// <param name="length"></param>
196 /// <returns></returns>
197 private int CalculateNumPackets(int length)
198 {
199 int numPackets = 0;
200
201 if (length > 600)
202 {
203 //over 600 bytes so split up file
204 int restData = (length - 600);
205 int restPackets = ((restData + 999) / 1000);
206 numPackets = restPackets;
207 }
208
209 return numPackets;
210 }
211 }
212}
diff --git a/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs b/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs
index c5a6e62..4f9e32b 100644
--- a/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs
+++ b/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs
@@ -105,12 +105,11 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer
105 } 105 }
106 } 106 }
107 107
108 // This should not be here 108 if (Requests.ContainsKey(fileName))
109 //if (Requests.ContainsKey(fileName)) 109 {
110 //{ 110 RequestXfer(Requests[fileName].remoteClient, Requests[fileName].xferID, fileName);
111 // RequestXfer(Requests[fileName].remoteClient, Requests[fileName].xferID, fileName); 111 Requests.Remove(fileName);
112 // Requests.Remove(fileName); 112 }
113 //}
114 113
115 return true; 114 return true;
116 } 115 }
diff --git a/OpenSim/Region/Framework/Interfaces/ITextureSender.cs b/OpenSim/Region/Framework/Interfaces/ITextureSender.cs
deleted file mode 100644
index c469ae8..0000000
--- a/OpenSim/Region/Framework/Interfaces/ITextureSender.cs
+++ /dev/null
@@ -1,58 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.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 OpenSimulator 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
28namespace OpenSim.Region.Framework.Interfaces
29{
30 /// <summary>
31 /// Interface for an object which can send texture information to a client
32 /// </summary>
33 public interface ITextureSender
34 {
35 /// <summary>
36 /// Are we in the process of sending the texture?
37 /// </summary>
38 bool Sending { get; set; }
39
40 /// <summary>
41 /// Has the texture send been cancelled?
42 /// </summary>
43 bool Cancel { get; set; }
44
45 /// <summary>
46 /// Update the non data properties of a texture request
47 /// </summary>
48 /// <param name="discardLevel"></param>
49 /// <param name="packetNumber"></param>
50 void UpdateRequest(int discardLevel, uint packetNumber);
51
52 /// <summary>
53 /// Send a texture packet to the client.
54 /// </summary>
55 /// <returns>True if the last packet has been sent, false otherwise.</returns>
56 bool SendTexturePacket();
57 }
58}
diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
index 7fd59a0..eb97f41 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
@@ -287,6 +287,9 @@ namespace OpenSim.Region.Physics.OdePlugin
287 private OdePrim cp1; 287 private OdePrim cp1;
288 private OdeCharacter cc2; 288 private OdeCharacter cc2;
289 private OdePrim cp2; 289 private OdePrim cp2;
290 private int tickCountFrameRun;
291
292 private int latertickcount=0;
290 //private int cStartStop = 0; 293 //private int cStartStop = 0;
291 //private string cDictKey = ""; 294 //private string cDictKey = "";
292 295
@@ -3123,6 +3126,22 @@ namespace OpenSim.Region.Physics.OdePlugin
3123 } 3126 }
3124 d.WorldExportDIF(world, fname, physics_logging_append_existing_logfile, prefix); 3127 d.WorldExportDIF(world, fname, physics_logging_append_existing_logfile, prefix);
3125 } 3128 }
3129 latertickcount = Util.EnvironmentTickCount() - tickCountFrameRun;
3130
3131 // OpenSimulator above does 10 fps. 10 fps = means that the main thread loop and physics
3132 // has a max of 100 ms to run theoretically.
3133 // If the main loop stalls, it calls Simulate later which makes the tick count ms larger.
3134 // If Physics stalls, it takes longer which makes the tick count ms larger.
3135
3136 if (latertickcount < 100)
3137 m_timeDilation = 1.0f;
3138 else
3139 {
3140 m_timeDilation = 100f / latertickcount;
3141 //m_timeDilation = Math.Min((Math.Max(100 - (Util.EnvironmentTickCount() - tickCountFrameRun), 1) / 100f), 1.0f);
3142 }
3143
3144 tickCountFrameRun = Util.EnvironmentTickCount();
3126 } 3145 }
3127 3146
3128 return fps; 3147 return fps;