Exemple #1
0
		/// <summary>
		/// Distribute Events to Registered objects
		/// </summary>
		/// <param name="notifiers">Enumerable of Registered Object</param>
		/// <param name="player">player who made the check</param>
		/// <param name="data">Check data for Args</param>
		private static void NotifyObjects(IList<IDOLEventHandler> notifiers, GamePlayer player, LosCheckData data) 
		{
			// Lock notifiers list.
			lock(((ICollection)notifiers).SyncRoot)
			{
				foreach(IDOLEventHandler notifier in notifiers)
				{
					notifier.Notify(GameObjectEvent.FinishedLosCheck, player, data);
				}
				
				// Clear at end, so a new list can be made for next call
				notifiers.Clear();
			}
		}
Exemple #2
0
		/// <summary>
		/// LoS Responses are handled through this method
		/// </summary>
		/// <param name="player">Player replying</param>
		/// <param name="response">Client response</param>
		/// <param name="targetOID">Target OID to which the Check was made</param>
		private void LosResponseHandler(GamePlayer player, ushort response, ushort sourceOID, ushort targetOID) 
		{
			if(player == null || sourceOID == 0 || targetOID == 0)
				return;
			
			// get time
			long sent = GameTimer.GetTickCount();
			long time = sent;
			
			// Check result
			bool losOK = (response & 0x100) == 0x100;
			
			// key for pending
			Tuple<GamePlayer, ushort, ushort> checkerKey = new Tuple<GamePlayer, ushort, ushort>(player, sourceOID, targetOID);			
			
			// Object from OID
			GameObject source = player.CurrentRegion.GetObject(sourceOID);
			GameObject target = player.CurrentRegion.GetObject(targetOID);
			
			// FIXME remove debug
			if(LOSMGR_DEBUG_LEVEL >= LOSMGR_DEBUG_WARN)
				log.Warn("LOSMGR_W : Los Check Finished - Player : "+player.Name+" Source : "+(source != null ? source.Name : "null")+"("+sourceOID+") Target : "+(target != null ? target.Name : "null")+"("+targetOID+") LoS : " + (losOK ? "OK" : "KO"));
			
			// we have a response, it should be in pending
			lock(((ICollection)PendingChecks).SyncRoot)
			{			
				// We have some data into pending cache
				if(PendingChecks.ContainsKey(checkerKey)) 
				{
					//We should remove it
					sent = PendingChecks[checkerKey];
					PendingChecks.Remove(checkerKey);
					// Update Client Stats

					if(ClientStats.ContainsKey(player)) 
					{
						long total = ClientStats[player].Item1 * ClientStats[player].Item2;
						total += (time - sent);
						int count = ClientStats[player].Item1+1;
						ClientStats[player] = new Tuple<int, int, int>(count, (int)total/count, (int)(time - sent));
						// FIXME debug
						if(LOSMGR_DEBUG_LEVEL >= LOSMGR_DEBUG_DEBUG)
							log.Warn("LOSMGR_D : Clients Stats Update : "+player.Name+", count : "+count+", average : "+((int)total/count)+", instant : "+((int)(time - sent)));
					}
					else
					{
						ClientStats[player] = new Tuple<int, int, int>(1, (int)(time - sent), (int)(time - sent));
					}
			
				}
				else
				{
					//No Pending Object, it's a wild one !
					// FIXME Display debug
					if(LOSMGR_DEBUG_LEVEL >= LOSMGR_DEBUG_INFO)
						log.Warn("LOSMGR_I : Los Check Without pending objects - Player : "+player.Name+" Source : "+(source != null ? source.Name : "null")+"("+sourceOID+") Target : "+(target != null ? target.Name : "null")+"("+targetOID+") LoS : " + (losOK ? "OK" : "KO") + " !");
				}
			}
			
			// Update all caches
			if(source != null && target != null) 
			{
				int timeout = GetDefaultTimeouts(source, target);
				lock(((ICollection)ResponsesCache).SyncRoot)
				{
					UpdateVincinityLosCache(source, target, losOK, time);
					UpdateVincinityLosCache(target, source, losOK, time);
					UpdateLosCacheItem(source, target, losOK, timeout, time);
				}
			}
			
			// key for registered
			Tuple<GameObject, GameObject> cachekey = new Tuple<GameObject, GameObject>(source, target);
			Tuple<GameObject, GameObject> rcachekey = new Tuple<GameObject, GameObject>(target, source);
			
			// We should Notify objects asking for this Check or the reverse one.
			lock(((ICollection)RegisteredLosEvents).SyncRoot)
			{
				LosCheckData losData = new LosCheckData(source, target, sent, losOK);
				if(RegisteredLosEvents.ContainsKey(cachekey))
				{
					NotifyObjects(RegisteredLosEvents[cachekey], player, losData);
				}
				if(RegisteredLosEvents.ContainsKey(rcachekey))
				{
					NotifyObjects(RegisteredLosEvents[rcachekey], player, losData);
				}
			}		
		}