Ejemplo n.º 1
0
        private void WorkLoop()
        {
            try
            {
                Time = Stopwatch.ElapsedMilliseconds;

                long conTime = Time;
                long saveTime = Time + Settings.SaveDelay * Settings.Minute;
                long userTime = Time + Settings.Minute * 5;

                long processTime = Time + 1000;
                long StartTime = Time;
                int processCount = 0;
                int processRealCount = 0;

                LinkedListNode<MapObject> current = null;

                if (Settings.Multithreaded)
                {
                    for (int j = 0; j < MobThreads.Length; j++)
                    {
                        MobThreads[j] = new MobThread();
                        MobThreads[j].Id = j;
                    }
                }

                StartEnvir();
                string canstartserver = CanStartEnvir();
                if (canstartserver != "true")
                {
                    SMain.Enqueue(canstartserver);
                    StopEnvir();
                    _thread = null;
                    Stop();
                    return;
                }

                if (Settings.Multithreaded)
                {
                    for (int j = 0; j < MobThreads.Length; j++)
                    {
                        MobThread Info = MobThreads[j];
                        if (j > 0) //dont start up 0
                        {
                            MobThreading[j] = new Thread(() => ThreadLoop(Info));
                            MobThreading[j].IsBackground = true;
                            MobThreading[j].Start();
                        }
                    }
                }

                StartNetwork();

                try
                {

                    while (Running)
                    {
                        Time = Stopwatch.ElapsedMilliseconds;

                        if (Time >= processTime)
                        {
                            LastCount = processCount;
                            LastRealCount = processRealCount;
                            processCount = 0;
                            processRealCount = 0;
                            processTime = Time + 1000;
                        }

                        if (conTime != Time)
                        {
                            conTime = Time;

                            AdjustLights();

                            lock (Connections)
                            {
                                for (int i = Connections.Count - 1; i >= 0; i--)
                                {
                                    Connections[i].Process();
                                }
                            }
                            lock (StatusConnections)
                            {
                                for (int i = StatusConnections.Count - 1; i >= 0; i--)
                                {
                                    StatusConnections[i].Process();
                                }
                            }
                        }

                        if (current == null)
                            current = Objects.First;

                        if (current == Objects.First)
                        {
                            LastRunTime = Time - StartTime;
                            StartTime = Time;
                        }

                        if (Settings.Multithreaded)
                        {
                            for (int j = 1; j < MobThreads.Length; j++)
                            {
                                MobThread Info = MobThreads[j];

                                if (Info.Stop == true)
                                {
                                    Info.EndTime = Time + 20;
                                    Info.Stop = false;
                                }
                            }
                            lock (_locker)
                            {
                                Monitor.PulseAll(_locker);         // changing a blocking condition. (this makes the threads wake up!)
                            }
                            //run the first loop in the main thread so the main thread automaticaly 'halts' untill the other threads are finished
                            ThreadLoop(MobThreads[0]);
                        }

                        Boolean TheEnd = false;
                        long Start = Stopwatch.ElapsedMilliseconds;
                        while ((!TheEnd) && (Stopwatch.ElapsedMilliseconds - Start < 20))
                        {
                            if (current == null)
                            {
                                TheEnd = true;
                                break;
                            }
                            else
                            {
                                LinkedListNode<MapObject> next = current.Next;
                                if (!Settings.Multithreaded || ((current.Value.Race != ObjectType.Monster) || (current.Value.Master != null)))
                                {
                                    if (Time > current.Value.OperateTime)
                                    {

                                        current.Value.Process();
                                        current.Value.SetOperateTime();
                                    }
                                    processCount++;
                                }
                                current = next;
                            }
                        }
                        for (int i = 0; i < MapList.Count; i++)
                            MapList[i].Process();

                        if (DragonSystem != null) DragonSystem.Process();

                        Process();

                        if (Time >= saveTime)
                        {
                            saveTime = Time + Settings.SaveDelay * Settings.Minute;
                            BeginSaveAccounts();
                            SaveGuilds();
                            SaveGoods();
                        }

                        if (Time >= userTime)
                        {
                            userTime = Time + Settings.Minute * 5;
                            Broadcast(new S.Chat
                                {
                                    Message = string.Format("Online Players: {0}", Players.Count),
                                    Type = ChatType.Hint
                                });
                        }

                        //   if (Players.Count == 0) Thread.Sleep(1);
                        //   GC.Collect();

                    }

                }
                catch (Exception ex)
                {
                    SMain.Enqueue(ex);

                    lock (Connections)
                    {
                        for (int i = Connections.Count - 1; i >= 0; i--)
                            Connections[i].SendDisconnect(3);
                    }

                    File.AppendAllText(@".\Error.txt",
                                           string.Format("[{0}] {1}{2}", Now, ex, Environment.NewLine));
                }

                StopNetwork();
                StopEnvir();
                SaveAccounts();
                SaveGuilds(true);
            }
            catch (Exception ex)
            {
                SMain.Enqueue("[outer workloop error]" + ex);
                File.AppendAllText(@".\Error.txt",
                                       string.Format("[{0}] {1}{2}", Now, ex, Environment.NewLine));
            }
            _thread = null;
        }
Ejemplo n.º 2
0
        private void ThreadLoop(MobThread Info)
        {
            Info.Stop = false;
            long starttime = Time;
            try
            {

                bool stopping = false;
                if (Info.current == null)
                    Info.current = Info.ObjectsList.First;
                stopping = Info.current == null;
                //while (stopping == false)
                while (Running)
                {
                    if (Info.current == null)
                        Info.current = Info.ObjectsList.First;
                    else
                    {
                        LinkedListNode<MapObject> next = Info.current.Next;

                        //if we reach the end of our list > go back to the top (since we are running threaded, we dont want the system to sit there for xxms doing nothing)
                        if (Info.current == Info.ObjectsList.Last)
                        {
                            next = Info.ObjectsList.First;
                            Info.LastRunTime = (Info.LastRunTime + (Time - Info.StartTime)) / 2;
                            //Info.LastRunTime = (Time - Info.StartTime) /*> 0 ? (Time - Info.StartTime) : Info.LastRunTime */;
                            Info.StartTime = Time;
                        }
                        if (Time > Info.current.Value.OperateTime)
                        {
                            if (Info.current.Value.Master == null)//since we are running multithreaded, dont allow pets to be processed (unless you constantly move pets into their map appropriate thead)
                            {
                                Info.current.Value.Process();

                                Info.current.Value.SetOperateTime();
                            }
                        }
                        Info.current = next;
                    }
                    //if it's the main thread > make it loop till the subthreads are done, else make it stop after 'endtime'
                    if (Info.Id == 0)
                    {
                        stopping = true;
                        for (int x = 1; x < MobThreads.Length; x++)
                            if (MobThreads[x].Stop == false)
                                stopping = false;
                        if (stopping)
                        {
                            Info.Stop = stopping;
                            return;
                        }
                    }
                    else
                    {
                        if ((Stopwatch.ElapsedMilliseconds > Info.EndTime) && Running)
                        {
                            Info.Stop = true;
                            lock (_locker)
                            {
                                while (Info.Stop) Monitor.Wait(_locker);
                            }
                        }

                    }
                }
            }
            catch (Exception ex)
            {
                if (ex is ThreadInterruptedException) return;
                SMain.Enqueue(ex);

                File.AppendAllText(@".\Error.txt",
                                       string.Format("[{0}] {1}{2}", Now, ex, Environment.NewLine));
            }
            //Info.Stop = true;
        }