public static void Init() { watch = new Stopwatch(); watch.Start(); foreach (GameTimer.TimeManager mgr in WorldMgr.GetRegionTimeManagers()) { old_time.Add(mgr, 0); } m_timer = new Timer(new TimerCallback(Resynch), null, 0, UPDATE_INTERVAL); }
/// <summary> /// print out some periodic information on server statistics /// </summary> /// <param name="state"></param> public static void PrintStats(object state) { try { //Don't enable this line unless you have memory issues and //need more details in memory usage //GC.Collect(); long newTick = DateTime.Now.Ticks; long time = newTick - m_lastMeasureTick; m_lastMeasureTick = newTick; time /= 10000000L; if (time < 1) { log.Warn("Time has not changed since last call of PrintStats"); time = 1; // prevent division by zero? } long inRate = (Statistics.BytesIn - m_lastBytesIn) / time; long outRate = (Statistics.BytesOut - m_lastBytesOut) / time; long inPckRate = (Statistics.PacketsIn - m_lastPacketsIn) / time; long outPckRate = (Statistics.PacketsOut - m_lastPacketsOut) / time; m_lastBytesIn = Statistics.BytesIn; m_lastBytesOut = Statistics.BytesOut; m_lastPacketsIn = Statistics.PacketsIn; m_lastPacketsOut = Statistics.PacketsOut; // Get threadpool info int iocpCurrent, iocpMin, iocpMax; int poolCurrent, poolMin, poolMax; ThreadPool.GetAvailableThreads(out poolCurrent, out iocpCurrent); ThreadPool.GetMinThreads(out poolMin, out iocpMin); ThreadPool.GetMaxThreads(out poolMax, out iocpMax); int globalHandlers = GameEventMgr.NumGlobalHandlers; int objectHandlers = GameEventMgr.NumObjectHandlers; if (log.IsInfoEnabled) { StringBuilder stats = new StringBuilder(256) .Append("-stats- Mem=").Append(GC.GetTotalMemory(false) / 1024 / 1024).Append("MB") .Append(" Clients=").Append(GameServer.Instance.ClientCount) .Append(" Down=").Append(inRate / 1024).Append("kb/s (").Append(Statistics.BytesIn / 1024 / 1024).Append("MB)") .Append(" Up=").Append(outRate / 1024).Append("kb/s (").Append(Statistics.BytesOut / 1024 / 1024).Append("MB)") .Append(" In=").Append(inPckRate).Append("pck/s (").Append(Statistics.PacketsIn / 1000).Append("K)") .Append(" Out=").Append(outPckRate).Append("pck/s (").Append(Statistics.PacketsOut / 1000).Append("K)") .AppendFormat(" Pool={0}/{1}({2})", poolCurrent, poolMax, poolMin) .AppendFormat(" IOCP={0}/{1}({2})", iocpCurrent, iocpMax, iocpMin) .AppendFormat(" GH/OH={0}/{1}", globalHandlers, objectHandlers); lock (m_timerStatsByMgr.SyncRoot) { foreach (GameTimer.TimeManager mgr in WorldMgr.GetRegionTimeManagers()) { TimerStats ts = (TimerStats)m_timerStatsByMgr[mgr]; if (ts == null) { ts = new TimerStats(); m_timerStatsByMgr.Add(mgr, ts); } long curInvoked = mgr.InvokedCount; long invoked = curInvoked - ts.InvokedCount; stats.Append(" ").Append(mgr.Name).Append('=').Append(invoked / time).Append("t/s (") .Append(mgr.ActiveTimers).Append(')'); ts.InvokedCount = curInvoked; } } if (m_systemCpuUsedCounter != null) { stats.Append(" CPU=").Append(m_systemCpuUsedCounter.NextValue().ToString("0.0")).Append('%'); } if (m_processCpuUsedCounter != null) { stats.Append(" DOL=").Append(m_processCpuUsedCounter.NextValue().ToString("0.0")).Append('%'); } if (m_memoryPages != null) { stats.Append(" pg/s=").Append(m_memoryPages.NextValue().ToString("0.0")); } if (m_physycalDisk != null) { stats.Append(" dsk/s=").Append(m_physycalDisk.NextValue().ToString("0.0")); } log.Info(stats); } if (log.IsFatalEnabled) { lock (m_timerStatsByMgr.SyncRoot) { foreach (GameTimer.TimeManager mgr in WorldMgr.GetRegionTimeManagers()) { TimerStats ts = (TimerStats)m_timerStatsByMgr[mgr]; if (ts == null) { continue; } long curTick = mgr.CurrentTime; if (ts.Time == curTick) { log.FatalFormat("{0} stopped ticking; timer stacktrace:\n{1}\n", mgr.Name, Util.FormatStackTrace(mgr.GetStacktrace())); log.FatalFormat("NPC update stacktrace:\n{0}\n", Util.FormatStackTrace(WorldMgr.GetWorldUpdateStacktrace())); log.FatalFormat("Relocate() stacktrace:\n{0}\n", Util.FormatStackTrace(WorldMgr.GetRelocateRegionsStacktrace())); log.FatalFormat("Packethandlers stacktraces:\n{0}\n", PacketProcessor.GetConnectionThreadpoolStacks()); } ts.Time = curTick; } } } } catch (Exception e) { log.Error("stats Log callback", e); } finally { lock (typeof(StatPrint)) { if (m_timer != null) { m_timer.Change(ServerProperties.Properties.STATPRINT_FREQUENCY, 0); } } } }
private static void Resynch(object nullValue) { long syncTime = watch.ElapsedMilliseconds; //Check alive foreach (GameTimer.TimeManager mgr in WorldMgr.GetRegionTimeManagers()) { if (old_time.ContainsKey(mgr) && old_time[mgr] > 0 && old_time[mgr] == mgr.CurrentTime) { if (log.IsErrorEnabled) { // Tolakram: Can't do StackTrace call here. If thread is stopping will result in UAE app stop log.ErrorFormat("----- Found Frozen Region Timer -----\nName: {0} - Current Time: {1}", mgr.Name, mgr.CurrentTime); } //if(mgr.Running) try { if (!mgr.Stop()) { log.ErrorFormat("----- Failed to Stop the TimeManager: {0}", mgr.Name); } } catch (Exception mex) { log.ErrorFormat("----- Errors while trying to stop the TimeManager: {0}\n{1}", mgr.Name, mex); } foreach (GameClient clients in WorldMgr.GetAllClients()) { if (clients.Player == null || clients.ClientState == GameClient.eClientState.Linkdead) { if (log.IsErrorEnabled) { log.ErrorFormat("----- Disconnected Client: {0}", clients.Account.Name); } if (clients.Player != null) { clients.Player.SaveIntoDatabase(); clients.Player.Quit(true); } clients.Out.SendPlayerQuit(true); clients.Disconnect(); GameServer.Instance.Disconnect(clients); WorldMgr.RemoveClient(clients); } } if (!mgr.Start()) { log.ErrorFormat("----- Failed to (re)Start the TimeManager: {0}", mgr.Name); } foreach (Region reg in WorldMgr.GetAllRegions()) { if (reg.TimeManager == mgr) { foreach (GameObject obj in reg.Objects) { //Restart Player regen & remove PvP immunity if (obj is GamePlayer) { GamePlayer plr = obj as GamePlayer; if (plr.IsAlive) { plr.StopHealthRegeneration(); plr.StopPowerRegeneration(); plr.StopEnduranceRegeneration(); plr.StopCurrentSpellcast(); plr.StartHealthRegeneration(); plr.StartPowerRegeneration(); plr.StartEnduranceRegeneration(); plr.StartInvulnerabilityTimer(1000, null); try { foreach (IGameEffect effect in plr.EffectList) { var gsp = effect as GameSpellEffect; if (gsp != null) { gsp.RestartTimers(); } } } catch (Exception e) { log.Error("Can't cancel immunty effect : " + e); } } // Warn Player plr.Client.Out.SendMessage("[" + reg.Description + "] detected as frozen, restarting the zone.", eChatType.CT_Broadcast, eChatLoc.CL_ChatWindow); } //Restart Brains & Paths if (obj is GameNPC && (obj as GameNPC).Brain != null) { GameNPC npc = obj as GameNPC; if (npc.Brain is IControlledBrain) { npc.Die(null); } else if (!(npc.Brain is BlankBrain)) { npc.Brain.Stop(); DOL.AI.ABrain brain = npc.Brain; npc.RemoveBrain(npc.Brain); //npc.Brain.Stop(); if (npc.MaxSpeedBase > 0 && npc.PathID != null && npc.PathID != "" && npc.PathID != "NULL") { npc.StopMovingOnPath(); PathPoint path = MovementMgr.LoadPath(npc.PathID); if (path != null) { var p = path.GetNearestNextPoint(npc.Position); npc.CurrentWayPoint = p; npc.MoveOnPath((short)p.MaxSpeed); } } try { npc.SetOwnBrain(brain); npc.Brain.Start(); } catch (Exception e) { log.Error("Can't restart Brain in RegionTimerResynch, NPC Name = " + npc.Name + " Position=" + npc.Position.ToString("F0") + "/R=" + npc.CurrentRegion.ID + " " + e); try { npc.Die(null); } catch (Exception ee) { log.Error("Can't restart Brain and Kill NPC in RegionTimerResynch, NPC Name = " + npc.Name + " Position=" + npc.Position.ToString("F0") + "/R=" + npc.CurrentRegion.ID + " " + ee); } } } } } //Restart Respawn Timers List <GameNPC> respawnings = new List <GameNPC>(reg.MobsRespawning.Keys); foreach (GameNPC deadMob in respawnings) { GameNPC mob = deadMob; if (mob != null) { mob.StartRespawn(); } } } } //RegionTimerUnfrozen(mgr, syncTime); } if (old_time.ContainsKey(mgr)) { old_time[mgr] = mgr.CurrentTime; } else { old_time.Add(mgr, mgr.CurrentTime); } } }