Fixed weather updates to be thread safe

This commit is contained in:
hondacrx
2017-09-20 00:27:47 -04:00
parent 28e6d6870a
commit 1b9bf99d8c
6 changed files with 88 additions and 103 deletions
+1 -4
View File
@@ -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);
+3 -11
View File
@@ -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);
+72 -14
View File
@@ -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();
@@ -635,6 +636,17 @@ namespace Game.Maps
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,17 +2720,19 @@ 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);
}
}
}
void SetZoneOverrideLight(uint zoneId, uint lightId, uint fadeInTime)
{
@@ -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;
-9
View File
@@ -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,
+2 -18
View File
@@ -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)]
+9 -46
View File
@@ -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);