示例#1
0
 public void AddEvent(ReactorEvent newEvent)
 {
     Monitor.Enter(_events);
     _events.Enqueue(newEvent);
     Monitor.Pulse(_events);
     Monitor.Exit(_events);
 }
示例#2
0
        /// <summary>
        ///     Return the next event or null if there are no events and the
        ///     timeout milliseconds have passed.
        /// </summary>
        /// <param name="timeout"></param>
        /// <returns></returns>
        private ReactorEvent GetNextEvent(int timeout)
        {
            if (timeout > 20)
            {
                timeout = 20;
            }

            ReactorEvent nextEvent = null;

            // If there's an event queued now, return the next immediately.
            Monitor.Enter(_events);
            if (_events.Count > 0)
            {
                nextEvent = _events.Dequeue();
            }
            Monitor.Exit(_events);

            if (nextEvent != null)
            {
                return(nextEvent);
            }

            // If no timeout because lot's of pending timers, return immediately.
            if (timeout == 0)
            {
                return(null);
            }

            // Wait for another event to be queued or for the timeout
            // to expire.
            Monitor.Enter(_events);
            if (timeout > 0)
            {
                Monitor.Wait(_events, timeout);
            }
            else
            {
                Monitor.Wait(_events);
            }
            if (_events.Count > 0)
            {
                nextEvent = _events.Dequeue();
            }
            Monitor.Exit(_events);

            return(nextEvent);
        }
示例#3
0
        /// <summary>
        ///     Start and run the simulation for this system.
        /// </summary>
        public void GameThreadRun()
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
            CurrentTime = Utilities.GetTime();

            AddTimer(new UpdateMonitoredObjs(this));
            AddTimer(new SpawnBackgroundNPCs(this));

            bool running = true;

            while (running)
            {
                // Calculate the delta time.
                double delta = Utilities.GetTime() - CurrentTime;
                CurrentTime += delta;

                // Call the reactor to return the next event the process
                // and run any timer functions.
                ReactorEvent next_event = Run(CurrentTime, delta);
                if (next_event is DPGameRunnerRxMsgEvent)
                {
                    var revent = next_event as DPGameRunnerRxMsgEvent;

                    // Process a message from this player. If the message isn't for this runner because
                    // the runner ownership changes, requeue in the right place.
                    if (revent.player.Runner != this)
                    {
                        Log.AddLog(LogType.FL_MSG, "Warning: requeued rx msg onto changed runner");
                        revent.player.Runner.AddEvent(revent);
                    }
                    else
                    {
                        revent.player.RxMsgFromClient(revent.msg);
                    }
                }
                else if (next_event is DPGameRunnerPlayerUpdateEvent)
                {
                    var revent = next_event as DPGameRunnerPlayerUpdateEvent;

                    // If the player is assigned to this runner, make sure we've got it in our
                    // owned player list
                    Player.Player player = revent.player;
                    if (revent.runner == this)
                    {
                        if (!Players.ContainsKey(player.FLPlayerID))
                        {
                            Log.AddLog(LogType.GENERAL, "Player control gained runner={0} flplayerid={1}",
                                       system.Nickname, player.FLPlayerID);
                            Players.Add(player.FLPlayerID, player);
                            if (player.Ship.Objid != 0)
                            {
                                AffObjects[player.Ship.Objid] = player.Ship;
                            }
                            Objects[player.Ship.Objid] = player.Ship;
                            player.Runner      = this;
                            player.Ship.Runner = this;
                            AddTimer(player.Ship);
                        }
                    }
                    // If the player is not assigned to this runner, make sure it's not in our
                    // owned player list.
                    else
                    {
                        if (Players.ContainsKey(player.FLPlayerID))
                        {
                            Log.AddLog(LogType.GENERAL, "Player control lost runner={0} flplayerid={1}", system.Nickname,
                                       player.FLPlayerID);
                            if (player.Ship.Objid != 0)
                            {
                                AffObjects.Remove(player.Ship.Objid);
                            }
                            Objects.Remove(player.Ship.Objid);
                            DelTimer(player.Ship);
                            Players.Remove(player.FLPlayerID);
                        }
                    }

                    PlayerListItem update;
                    update = !Playerlist.ContainsKey(revent.flplayerid) ? new PlayerListItem() : Playerlist[revent.flplayerid];

                    update.Player                 = revent.player;
                    update.FlPlayerID             = revent.flplayerid;
                    update.Name                   = revent.name;
                    update.Rank                   = revent.rank;
                    update.System                 = revent.system;
                    update.Group                  = revent.group;
                    update.GroupInvited           = revent.groupInvited;
                    Playerlist[revent.flplayerid] = update;

                    // Notify all owned players of the player list update
                    foreach (Player.Player p in Players.Values)
                    {
                        p.SendPlayerListUpdate(update);
                    }
                }
                else if (next_event is DPGameRunnerPlayerDeletedEvent)
                {
                    var revent = next_event as DPGameRunnerPlayerDeletedEvent;

                    // fixme: might crash if the player leaves
                    if (!Players.ContainsKey(revent.FlPlayerID))
                    {
                        continue;
                    }

                    var player = Players[revent.FlPlayerID];

                    Players.Remove(revent.FlPlayerID);
                    if (player.Ship.Objid != 0)
                    {
                        DelSimObject(player.Ship);
                    }

                    if (Playerlist.ContainsKey(revent.FlPlayerID))
                    {
                        Playerlist.Remove(revent.FlPlayerID);
                    }

                    foreach (PlayerListItem item in Playerlist.Values)
                    {
                        item.Player.SendPlayerListDepart(player);
                    }
                }
                else if (next_event is ReactorShutdownEvent)
                {
                    running = false;
                }
                else if (next_event is DPGRAddCash)
                {
                    var revent = next_event as DPGRAddCash;
                    if (revent.player.Runner != this)
                    {
                        Log.AddLog(LogType.FL_MSG, "Warning: requeued rx msg onto changed runner");
                        revent.player.Runner.AddEvent(revent);
                    }
                    else
                    {
                        revent.player.Money += revent.cash;
                        revent.player.SendSetMoney();
                    }
                }
                else if (next_event is DPGRSetCash)
                {
                    var revent = next_event as DPGRSetCash;
                    if (revent.player.Runner != this)
                    {
                        Log.AddLog(LogType.FL_MSG, "Warning: requeued rx msg onto changed runner");
                        revent.player.Runner.AddEvent(revent);
                    }
                    else
                    {
                        revent.player.Money = revent.cash;
                        revent.player.SendSetMoney();
                    }
                }
                else if (next_event is DPGRBeam)
                {
                    var revent = next_event as DPGRBeam;
                    if (revent.Player.Runner != this)
                    {
                        Log.AddLog(LogType.FL_MSG, "Warning: requeued rx msg onto changed runner");
                        revent.Player.Runner.AddEvent(revent);
                    }
                    else
                    {
                        revent.Player.MonitoredObjs.Clear();
                        revent.Player.Ship.Basedata        = revent.TargetBase;
                        revent.Player.Ship.RespawnBasedata = revent.TargetBase;
                        revent.Player.Ship.System          = UniverseDB.FindSystem(revent.TargetBase.SystemID);
                        revent.Player.Ship.IsDestroyed     = false;
                        revent.Player.SendServerLand(revent.Player.Ship, 0, revent.Player.Ship.Basedata.BaseID);
                        revent.Player.Runner.Server.AddEvent(new DPGameRunnerPlayerUpdateEvent(revent.Player));
                    }
                }
            }
        }