Fixed weather updates to be thread safe
This commit is contained in:
@@ -1276,10 +1276,7 @@ namespace Game.Chat
|
||||
Player player = handler.GetSession().GetPlayer();
|
||||
uint zoneid = player.GetZoneId();
|
||||
|
||||
Weather weather = Global.WeatherMgr.FindWeather(zoneid);
|
||||
|
||||
if (weather == null)
|
||||
weather = Global.WeatherMgr.AddWeather(zoneid);
|
||||
Weather weather = player.GetMap().GetOrGenerateZoneDefaultWeather(zoneid);
|
||||
if (weather == null)
|
||||
{
|
||||
handler.SendSysMessage(CypherStrings.NoWeather);
|
||||
|
||||
@@ -175,18 +175,10 @@ namespace Game.Entities
|
||||
if (zone == null)
|
||||
return;
|
||||
|
||||
if (WorldConfig.GetBoolValue(WorldCfg.Weather) && !HasAuraType(AuraType.ForceWeather))
|
||||
{
|
||||
Weather weather = Global.WeatherMgr.FindWeather(newZone);
|
||||
if (weather != null)
|
||||
weather.SendWeatherUpdateToPlayer(this);
|
||||
else if (Global.WeatherMgr.AddWeather(newZone) == null)
|
||||
{
|
||||
// send fine weather packet to remove old zone's weather
|
||||
Global.WeatherMgr.SendFineWeatherUpdateToPlayer(this);
|
||||
}
|
||||
}
|
||||
if (WorldConfig.GetBoolValue(WorldCfg.Weather))
|
||||
GetMap().GetOrGenerateZoneDefaultWeather(newZone);
|
||||
|
||||
GetMap().SendZoneDynamicInfo(newZone, this);
|
||||
|
||||
Global.ScriptMgr.OnPlayerUpdateZone(this, newZone, newArea);
|
||||
|
||||
|
||||
+73
-15
@@ -64,6 +64,8 @@ namespace Game.Maps
|
||||
|
||||
//lets initialize visibility distance for map
|
||||
InitVisibilityDistance();
|
||||
_weatherUpdateTimer = new IntervalTimer();
|
||||
_weatherUpdateTimer.SetInterval(1 * Time.InMilliseconds);
|
||||
|
||||
GetGuidSequenceGenerator(HighGuid.Transport).Set(Global.ObjectMgr.GetGenerator(HighGuid.Transport).GetNextAfterMaxUsed());
|
||||
|
||||
@@ -407,7 +409,6 @@ namespace Game.Maps
|
||||
SendInitSelf(player);
|
||||
|
||||
SendInitTransports(player);
|
||||
SendZoneDynamicInfo(player);
|
||||
|
||||
if (initPlayer)
|
||||
player.m_clientGUIDs.Clear();
|
||||
@@ -634,7 +635,18 @@ namespace Game.Maps
|
||||
ScriptsProcess();
|
||||
i_scriptLock = false;
|
||||
}
|
||||
|
||||
|
||||
if (_weatherUpdateTimer.Passed())
|
||||
{
|
||||
foreach (var zoneInfo in _zoneDynamicInfo)
|
||||
{
|
||||
if (zoneInfo.Value.DefaultWeather != null && !zoneInfo.Value.DefaultWeather.Update((uint)_weatherUpdateTimer.GetInterval()))
|
||||
zoneInfo.Value.DefaultWeather = null;
|
||||
}
|
||||
|
||||
_weatherUpdateTimer.Reset();
|
||||
}
|
||||
|
||||
MoveAllCreaturesInMoveList();
|
||||
MoveAllGameObjectsInMoveList();
|
||||
MoveAllAreaTriggersInMoveList();
|
||||
@@ -2611,9 +2623,8 @@ namespace Game.Maps
|
||||
}
|
||||
}
|
||||
|
||||
void SendZoneDynamicInfo(Player player)
|
||||
public void SendZoneDynamicInfo(uint zoneId, Player player)
|
||||
{
|
||||
uint zoneId = GetZoneId(player.GetPositionX(), player.GetPositionY(), player.GetPositionZ());
|
||||
var zoneInfo = _zoneDynamicInfo.LookupByKey(zoneId);
|
||||
if (zoneInfo == null)
|
||||
return;
|
||||
@@ -2622,12 +2633,7 @@ namespace Game.Maps
|
||||
if (music != 0)
|
||||
player.SendPacket(new PlayMusic(music));
|
||||
|
||||
WeatherState weatherId = zoneInfo.WeatherId;
|
||||
if (weatherId != 0)
|
||||
{
|
||||
WeatherPkt weather = new WeatherPkt(weatherId, zoneInfo.WeatherGrade);
|
||||
player.SendPacket(weather);
|
||||
}
|
||||
SendZoneWeather(zoneInfo, player);
|
||||
|
||||
uint overrideLightId = zoneInfo.OverrideLightId;
|
||||
if (overrideLightId != 0)
|
||||
@@ -2640,6 +2646,34 @@ namespace Game.Maps
|
||||
}
|
||||
}
|
||||
|
||||
public void SendZoneWeather(uint zoneId, Player player)
|
||||
{
|
||||
if (!player.HasAuraType(AuraType.ForceWeather))
|
||||
{
|
||||
var zoneInfo = _zoneDynamicInfo.LookupByKey(zoneId);
|
||||
if (zoneInfo == null)
|
||||
return;
|
||||
|
||||
SendZoneWeather(zoneInfo, player);
|
||||
}
|
||||
}
|
||||
|
||||
void SendZoneWeather(ZoneDynamicInfo zoneDynamicInfo, Player player)
|
||||
{
|
||||
WeatherState weatherId = zoneDynamicInfo.WeatherId;
|
||||
if (weatherId != 0)
|
||||
{
|
||||
WeatherPkt weather = new WeatherPkt(weatherId, zoneDynamicInfo.WeatherGrade);
|
||||
player.SendPacket(weather);
|
||||
}
|
||||
else if (zoneDynamicInfo.DefaultWeather != null)
|
||||
{
|
||||
zoneDynamicInfo.DefaultWeather.SendWeatherUpdateToPlayer(player);
|
||||
}
|
||||
else
|
||||
Weather.SendFineWeatherUpdateToPlayer(player);
|
||||
}
|
||||
|
||||
public void SetZoneMusic(uint zoneId, uint musicId)
|
||||
{
|
||||
if (!_zoneDynamicInfo.ContainsKey(zoneId))
|
||||
@@ -2650,14 +2684,34 @@ namespace Game.Maps
|
||||
var players = GetPlayers();
|
||||
if (!players.Empty())
|
||||
{
|
||||
PlayMusic data = new PlayMusic(musicId);
|
||||
PlayMusic playMusic = new PlayMusic(musicId);
|
||||
|
||||
foreach (var player in players)
|
||||
if (player.GetZoneId() == zoneId)
|
||||
player.SendPacket(data);
|
||||
if (player.GetZoneId() == zoneId && !player.HasAuraType(AuraType.ForceWeather))
|
||||
player.SendPacket(playMusic);
|
||||
}
|
||||
}
|
||||
|
||||
public Weather GetOrGenerateZoneDefaultWeather(uint zoneId)
|
||||
{
|
||||
WeatherData weatherData = Global.WeatherMgr.GetWeatherData(zoneId);
|
||||
if (weatherData == null)
|
||||
return null;
|
||||
|
||||
if (!_zoneDynamicInfo.ContainsKey(zoneId))
|
||||
_zoneDynamicInfo[zoneId] = new ZoneDynamicInfo();
|
||||
|
||||
ZoneDynamicInfo info = _zoneDynamicInfo[zoneId];
|
||||
if (info.DefaultWeather == null)
|
||||
{
|
||||
info.DefaultWeather = new Weather(zoneId, weatherData);
|
||||
info.DefaultWeather.ReGenerate();
|
||||
info.DefaultWeather.UpdateWeather();
|
||||
}
|
||||
|
||||
return info.DefaultWeather;
|
||||
}
|
||||
|
||||
void SetZoneWeather(uint zoneId, WeatherState weatherId, float weatherGrade)
|
||||
{
|
||||
if (!_zoneDynamicInfo.ContainsKey(zoneId))
|
||||
@@ -2666,15 +2720,17 @@ namespace Game.Maps
|
||||
ZoneDynamicInfo info = _zoneDynamicInfo[zoneId];
|
||||
info.WeatherId = weatherId;
|
||||
info.WeatherGrade = weatherGrade;
|
||||
var players = GetPlayers();
|
||||
|
||||
var players = GetPlayers();
|
||||
if (!players.Empty())
|
||||
{
|
||||
WeatherPkt weather = new WeatherPkt(weatherId, weatherGrade);
|
||||
|
||||
foreach (var player in players)
|
||||
{
|
||||
if (player.GetZoneId() == zoneId)
|
||||
player.SendPacket(weather);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4157,6 +4213,7 @@ namespace Game.Maps
|
||||
internal uint m_unloadTimer;
|
||||
|
||||
Dictionary<uint, ZoneDynamicInfo> _zoneDynamicInfo = new Dictionary<uint, ZoneDynamicInfo>();
|
||||
IntervalTimer _weatherUpdateTimer;
|
||||
uint _defaultLight;
|
||||
Dictionary<HighGuid, ObjectGuidGenerator> _guidGenerators = new Dictionary<HighGuid, ObjectGuidGenerator>();
|
||||
Dictionary<ObjectGuid, WorldObject> _objectsStore = new Dictionary<ObjectGuid, WorldObject>();
|
||||
@@ -4698,7 +4755,8 @@ namespace Game.Maps
|
||||
public class ZoneDynamicInfo
|
||||
{
|
||||
public uint MusicId;
|
||||
public WeatherState WeatherId = WeatherState.Fine;
|
||||
public Weather DefaultWeather;
|
||||
public WeatherState WeatherId;
|
||||
public float WeatherGrade;
|
||||
public uint OverrideLightId;
|
||||
public uint LightFadeInTime;
|
||||
|
||||
@@ -824,7 +824,6 @@ namespace Game
|
||||
|
||||
DB.Login.Execute("INSERT INTO uptime (realmid, starttime, uptime, revision) VALUES({0}, {1}, 0, '{2}')", _realm.Id.Realm, m_startTime, ""); // One-time query
|
||||
|
||||
m_timers[WorldTimers.Weathers].SetInterval(1 * Time.InMilliseconds);
|
||||
m_timers[WorldTimers.Auctions].SetInterval(Time.Minute * Time.InMilliseconds);
|
||||
m_timers[WorldTimers.AuctionsPending].SetInterval(250);
|
||||
|
||||
@@ -1222,13 +1221,6 @@ namespace Game
|
||||
UpdateSessions(diff);
|
||||
RecordTimeDiff("UpdateSessions");
|
||||
|
||||
//Handle weather updates when the timer has passed
|
||||
if (m_timers[WorldTimers.Weathers].Passed())
|
||||
{
|
||||
m_timers[WorldTimers.Weathers].Reset();
|
||||
Global.WeatherMgr.Update((uint)m_timers[WorldTimers.Weathers].GetInterval());
|
||||
}
|
||||
|
||||
/// <li> Update uptime table
|
||||
if (m_timers[WorldTimers.UpTime].Passed())
|
||||
{
|
||||
@@ -2446,7 +2438,6 @@ namespace Game
|
||||
{
|
||||
Auctions,
|
||||
AuctionsPending,
|
||||
Weathers,
|
||||
UpTime,
|
||||
Corpses,
|
||||
Events,
|
||||
|
||||
@@ -6093,25 +6093,9 @@ namespace Game.Spells
|
||||
return;
|
||||
|
||||
if (apply)
|
||||
{
|
||||
WeatherPkt weather = new WeatherPkt((WeatherState)GetMiscValue(), 1.0f);
|
||||
target.SendPacket(weather);
|
||||
}
|
||||
target.SendPacket(new WeatherPkt((WeatherState)GetMiscValue(), 1.0f));
|
||||
else
|
||||
{
|
||||
// send weather for current zone
|
||||
Weather weather = Global.WeatherMgr.FindWeather(target.GetZoneId());
|
||||
if (weather != null)
|
||||
weather.SendWeatherUpdateToPlayer(target);
|
||||
else
|
||||
{
|
||||
if (Global.WeatherMgr.AddWeather(target.GetZoneId()) == null)
|
||||
{
|
||||
// send fine weather packet to remove old weather
|
||||
Global.WeatherMgr.SendFineWeatherUpdateToPlayer(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
target.GetMap().SendZoneWeather(target.GetZoneId(), target);
|
||||
}
|
||||
|
||||
[AuraEffectHandler(AuraType.EnableAltPower)]
|
||||
|
||||
@@ -27,32 +27,6 @@ namespace Game
|
||||
{
|
||||
WeatherManager() { }
|
||||
|
||||
/// Find a Weather object by the given zoneid
|
||||
public Weather FindWeather(uint id)
|
||||
{
|
||||
return m_weathers.LookupByKey(id);
|
||||
}
|
||||
|
||||
void RemoveWeather(uint id)
|
||||
{
|
||||
m_weathers.Remove(id);
|
||||
}
|
||||
|
||||
public Weather AddWeather(uint zone_id)
|
||||
{
|
||||
WeatherData weatherChances = GetWeatherData(zone_id);
|
||||
|
||||
// zone does not have weather, ignore
|
||||
if (weatherChances == null)
|
||||
return null;
|
||||
|
||||
Weather w = new Weather(zone_id, weatherChances);
|
||||
w.ReGenerate();
|
||||
w.UpdateWeather();
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
public void LoadWeatherData()
|
||||
{
|
||||
uint oldMSTime = Time.GetMSTime();
|
||||
@@ -101,7 +75,7 @@ namespace Game
|
||||
}
|
||||
|
||||
wzc.ScriptId = Global.ObjectMgr.GetScriptId(result.Read<string>(13));
|
||||
mWeatherZoneMap[zone_id] = wzc;
|
||||
_weatherData[zone_id] = wzc;
|
||||
++count;
|
||||
}
|
||||
while (result.NextRow());
|
||||
@@ -109,28 +83,12 @@ namespace Game
|
||||
Log.outInfo(LogFilter.ServerLoading, "Loaded {0} weather definitions in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
|
||||
}
|
||||
|
||||
public void SendFineWeatherUpdateToPlayer(Player player)
|
||||
public WeatherData GetWeatherData(uint zone_id)
|
||||
{
|
||||
WeatherPkt weather = new WeatherPkt(WeatherState.Fine);
|
||||
player.SendPacket(weather);
|
||||
return _weatherData.LookupByKey(zone_id);
|
||||
}
|
||||
|
||||
public void Update(uint diff)
|
||||
{
|
||||
foreach (var pair in m_weathers.ToList())
|
||||
{
|
||||
if (!pair.Value.Update(diff))
|
||||
m_weathers.Remove(pair.Key);
|
||||
}
|
||||
}
|
||||
|
||||
WeatherData GetWeatherData(uint zone_id)
|
||||
{
|
||||
return mWeatherZoneMap.LookupByKey(zone_id);
|
||||
}
|
||||
|
||||
Dictionary<uint, Weather> m_weathers = new Dictionary<uint, Weather>();
|
||||
Dictionary<uint, WeatherData> mWeatherZoneMap = new Dictionary<uint, WeatherData>();
|
||||
Dictionary<uint, WeatherData> _weatherData = new Dictionary<uint, WeatherData>();
|
||||
}
|
||||
|
||||
public class Weather
|
||||
@@ -296,6 +254,11 @@ namespace Game
|
||||
player.SendPacket(weather);
|
||||
}
|
||||
|
||||
public static void SendFineWeatherUpdateToPlayer(Player player)
|
||||
{
|
||||
player.SendPacket(new WeatherPkt(WeatherState.Fine));
|
||||
}
|
||||
|
||||
public bool UpdateWeather()
|
||||
{
|
||||
Player player = Global.WorldMgr.FindPlayerInZone(m_zone);
|
||||
|
||||
Reference in New Issue
Block a user