Esempio n. 1
0
        public static int Run([NotNull, ItemNotNull] string[] args, GraphicsBackend graphicsBackend, [NotNull] string loggerName = "theater-days")
        {
            GraphicsBackend = graphicsBackend;

            GameLog.Initialize(loggerName);
            GameLog.Enabled = true;

            var exitCode = -1;

            var parser = new Parser(settings => { settings.IgnoreUnknownArguments = true; });
            var optionsParsingResult = parser.ParseArguments <Options>(args);

#if ENABLE_GUI_CONSOLE
            GuiConsole.Initialize();
            GuiConsole.Error.WriteLine();
#endif
#if SAFE_STARTUP
            try {
#endif
            if (optionsParsingResult.Tag == ParserResultType.Parsed)
            {
                var options = ((Parsed <Options>)optionsParsingResult).Value;

                GameLog.Enabled = options.IsDebugEnabled;

                using (var pluginManager = new TheaterDaysPluginManager()) {
                    pluginManager.LoadPlugins();

                    var configurationStore  = ConfigurationHelper.CreateConfigurationStore(pluginManager);
                    var cultureSpecificInfo = CultureSpecificInfoHelper.CreateCultureSpecificInfo();

                    using (var game = new Theater(options, pluginManager, configurationStore, cultureSpecificInfo)) {
                        game.Run();
                    }

                    exitCode = 0;
                }
            }
            else
            {
                var helpText = CommandLine.Text.HelpText.AutoBuild(optionsParsingResult);

                GameLog.Info(helpText);
            }
#if SAFE_STARTUP
        }

        catch (Exception ex) {
            GameLog.Error(ex.Message);
            GameLog.Error(ex.StackTrace);
        }
#endif

#if ENABLE_GUI_CONSOLE
            GuiConsole.Uninitialize();
#endif

            return(exitCode);
        }
Esempio n. 2
0
        public void CallToTalk()
        {
            TelepathyBehaviour.CallToTalk(hero);
            var textObject = new TextObject("{=Telepathy_Hero_Will_Talk}{HeroName} will talk to you soon...", null);

            textObject.SetTextVariable("HeroName", hero.Name);
            GameLog.Info(textObject.ToString());
            base.OnPropertyChanged(nameof(WillNotTalk));
        }
Esempio n. 3
0
        private static int Main([NotNull, ItemNotNull] string[] args)
        {
            BaseGame.GraphicsBackend = GraphicsBackend.Direct3D11;

            GameLog.Initialize("arcaea-debug");
            GameLog.Enabled = true;

            var exitCode = -1;

            var parser = new Parser(settings => {
                settings.IgnoreUnknownArguments    = true;
                settings.CaseInsensitiveEnumValues = true;
            });

            var optionsParsingResult = parser.ParseArguments <Options>(args);

            try {
                if (optionsParsingResult.Tag == ParserResultType.Parsed)
                {
                    var options = ((Parsed <Options>)optionsParsingResult).Value;

                    // Enable game log if the app is launched with "--debug" switch.
                    GameLog.Enabled = options.IsDebugEnabled;

                    using (var pluginManager = new ArcaeaSimPluginManager()) {
                        pluginManager.LoadPlugins();

                        var configurationStore  = ConfigurationHelper.CreateConfigurationStore(pluginManager);
                        var cultureSpecificInfo = CultureSpecificInfoHelper.CreateCultureSpecificInfo();

                        using (var game = new ArcaeaSimApplication(pluginManager, configurationStore, cultureSpecificInfo)) {
                            game.Run();
                        }

                        exitCode = 0;
                    }
                }
                else
                {
                    var helpText = CommandLine.Text.HelpText.AutoBuild(optionsParsingResult);

                    GameLog.Info(helpText);
                }
            } catch (Exception ex) {
                GameLog.Error(ex.Message);
                GameLog.Error(ex.StackTrace);
                Debug.Print(ex.ToString());
            }

            return(exitCode);
        }
Esempio n. 4
0
 public bool RemoveGold(uint gold)
 {
     if (gold <= CurrentGold)
     {
         CurrentGold -= gold;
         GameLog.Info($"{gold} gold removed from vault {OwnerGuid}");
         return(true);
     }
     else
     {
         GameLog.Info($"Attempt to remove {gold} gold from vault {OwnerGuid}, but only {CurrentGold} available");
         return(false);
     }
 }
Esempio n. 5
0
    public bool AddGold(uint gold)
    {
        if (gold <= RemainingGold)
        {
            CurrentGold += gold;

            GameLog.Info($"{gold} gold added to vault {OwnerGuid}");
            return(true);
        }
        else
        {
            GameLog.Info($"Attempt to add {gold} gold to vault {OwnerGuid}, but only {RemainingGold} available");
            return(false);
        }
    }
Esempio n. 6
0
 IEnumerator InitializeLog()
 {
     if (isHeadless)
     {
         #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN
         ConsoleWindow.Instance.Initialize();
         ConsoleWindow.Instance.SetTitle("DedicatedServer");
         #endif
         yield return(StartCoroutine(Logging.Initialize("Config/headless_log.xml")));
     }
     else
     {
         yield return(StartCoroutine(Logging.Initialize("Config/log.xml")));
     }
     GameLog.Info("Log Initialize");
 }
Esempio n. 7
0
    /// <summary>
    /// Perform the exchange once confirmation from both sides is received.
    /// </summary>
    /// <returns></returns>
    public void PerformExchange()
    {
        GameLog.Info("Performing exchange");
        foreach (var item in _sourceItems)
        {
            _target.AddItem(item);
        }
        foreach (var item in _targetItems)
        {
            _source.AddItem(item);
        }
        _source.AddGold(_targetGold);
        _target.AddGold(_sourceGold);

        _source.ActiveExchange       = null;
        _target.ActiveExchange       = null;
        _source.Condition.InExchange = false;
        _target.Condition.InExchange = false;
    }
Esempio n. 8
0
 public bool RemoveItem(string itemName, ushort quantity = 1)
 {
     if (Items.ContainsKey(itemName))
     {
         if (Items[itemName] > quantity)
         {
             Items[itemName] -= quantity;
             GameLog.Info($"{itemName} [{quantity}] removed from existing item in vault {OwnerGuid}");
         }
         else
         {
             Items.Remove(itemName);
             GameLog.Info($"{itemName} removed from vault {OwnerGuid}");
         }
         return(true);
     }
     else
     {
         return(false);
     }
 }
Esempio n. 9
0
    public void Redirect(Redirect redirect, bool isLogoff = false, int transmitDelay = 0)
    {
        GameLog.InfoFormat("Processing redirect");
        GlobalConnectionManifest.RegisterRedirect(this, redirect);
        GameLog.InfoFormat("Redirect: cid {0}", this.ConnectionId);
        GameLog.Info($"Redirect EncryptionKey is {Encoding.ASCII.GetString(redirect.EncryptionKey)}");
        if (isLogoff)
        {
            GlobalConnectionManifest.DeregisterClient(this);
        }
        redirect.Destination.ExpectedConnections.TryAdd(redirect.Id, redirect);

        var endPoint = Socket.RemoteEndPoint as IPEndPoint;

        byte[] addressBytes;

        if (Game.RedirectTarget != null)
        {
            addressBytes = Game.RedirectTarget.GetAddressBytes();
        }
        else
        {
            addressBytes = IPAddress.IsLoopback(endPoint.Address) ? IPAddress.Loopback.GetAddressBytes() : Game.IpAddress.GetAddressBytes();
        }

        Array.Reverse(addressBytes);

        var x03 = new ServerPacket(0x03);

        x03.Write(addressBytes);
        x03.WriteUInt16((ushort)redirect.Destination.Port);
        x03.WriteByte((byte)(redirect.EncryptionKey.Length + Encoding.ASCII.GetBytes(redirect.Name).Length + 7));
        x03.WriteByte(redirect.EncryptionSeed);
        x03.WriteByte((byte)redirect.EncryptionKey.Length);
        x03.Write(redirect.EncryptionKey);
        x03.WriteString8(redirect.Name);
        x03.WriteUInt32(redirect.Id);
        x03.TransmitDelay = transmitDelay == 0 ? 250 : transmitDelay;
        Enqueue(x03);
    }
Esempio n. 10
0
 public bool AddItem(string itemName, ushort quantity = 1)
 {
     if (CurrentItemCount < ItemLimit)
     {
         if (Items.ContainsKey(itemName))
         {
             Items[itemName] += quantity;
             GameLog.Info($"{itemName} [{quantity}] added to existing item in vault {OwnerGuid}");
         }
         else
         {
             Items.Add(itemName, quantity);
             GameLog.Info($"{itemName} [{quantity}] added as new item in vault {OwnerGuid}");
         }
         return(true);
     }
     else
     {
         GameLog.Info($"Attempt to add {itemName} [{quantity}] to vault {OwnerGuid}, but user doesn't have it?");
         return(false);
     }
 }
Esempio n. 11
0
 /// <summary>
 /// Confirm the exchange. Once both sides confirm, perform the exchange.
 /// </summary>
 /// <returns>Boolean indicating success.</returns>
 public void ConfirmExchange(User requestor)
 {
     if (_source == requestor)
     {
         GameLog.InfoFormat("Exchange: source ({0}) confirmed", _source.Name);
         _sourceConfirmed = true;
         _target.SendExchangeConfirmation(false);
     }
     if (_target == requestor)
     {
         GameLog.InfoFormat("Exchange: target ({0}) confirmed", _target.Name);
         _targetConfirmed = true;
         _source.SendExchangeConfirmation(false);
     }
     if (_sourceConfirmed && _targetConfirmed)
     {
         GameLog.Info("Exchange: Both sides confirmed");
         _source.SendExchangeConfirmation();
         _target.SendExchangeConfirmation();
         PerformExchange();
     }
 }
Esempio n. 12
0
        public IEnumerator Initialize()
        {
            yield return(GameInitializer.Instance.StartCoroutine(BytesReader.Read(mConfigFileName, bytes =>
            {
                if (null == bytes)
                {
                    #if UNITY_EDITOR_WIN || UNITY_STANDALONE
                    File.WriteAllText(
                        Path.Combine(Application.streamingAssetsPath, mConfigFileName),
                        JsonUtility.ToJson(Instance, true),
                        Encoding.UTF8);
                    #endif
                    GameLog.ErrorFormat("Read Config {0} Failed", mConfigFileName);
                }
                else
                {
                    // NOTE(llisper): detect BOM mark
                    // http://stackoverflow.com/questions/26101859/why-is-file-readallbytes-result-different-than-when-using-file-readalltext
                    string json;
                    if (bytes.Length > 3 &&
                        bytes[0] == 0xEF &&
                        bytes[1] == 0xBB &&
                        bytes[2] == 0xBF)
                    {
                        json = Encoding.UTF8.GetString(bytes, 3, bytes.Length - 3);
                    }
                    else
                    {
                        json = Encoding.UTF8.GetString(bytes);
                    }
                    JsonUtility.FromJsonOverwrite(json, Instance);
                }
            })));

            StringBuilder log = new StringBuilder("AppConfig:\n");
            LogConfig(log, "AppConfig", this);
            GameLog.Info(log.ToString());
        }
Esempio n. 13
0
 /// <summary>
 /// Write a message to the game (server) informational log.
 /// </summary>
 /// <param name="message">The message to be written</param>
 public void WriteLog(string message)
 {
     GameLog.Info(message);
 }
Esempio n. 14
0
 public static void Info(string message, string color = "#00ff00ff")
 {
     GameLog.Info(string.Format("<color={0}>{1}</color>", color, message));
 }
Esempio n. 15
0
        public virtual List <Creature> GetTargets(Xml.Castable castable, Creature target = null)
        {
            List <Creature> actualTargets = new List <Creature>();

            /* INTENT HANDLING FOR TARGETING
             *
             * This is particularly confusing so it is documented here.
             * UseType=Target Radius=0 Direction=None -> exact clicked target
             * UseType=Target Radius=0 Direction=!None -> invalid
             * UseType=Target Radius=>0 Direction=None -> rect centered on target
             * UseType=Target Radius>0 Direction=(anything but none) -> directional rect target based on click x/y
             * UseType=NoTarget Radius=0 Direction=None -> self (wings of protection, maybe custom spells / mentoring / lore / etc)?
             * UseType=NoTarget Radius>0 Direction=None -> rect from self in all directions
             * UseType=NoTarget Radius>0 Direction=!None -> rect from self in specific direction
             */

            var intents = castable.Intents;

            foreach (var intent in intents)
            {
                var possibleTargets = new List <VisibleObject>();
                if (intent.UseType == Xml.SpellUseType.NoTarget && intent.Target.Contains(Xml.IntentTarget.Group))
                {
                    // Targeting group members
                    var user = this as User;
                    if (user != null && user.Group != null)
                    {
                        possibleTargets.AddRange(user.Group.Members.Where(m => m.Map.Id == Map.Id && m.Distance(this) < intent.Radius));
                    }
                }
                else if (intent.UseType == Xml.SpellUseType.Target && intent.Radius == 0 && intent.Direction == Xml.IntentDirection.None)
                {
                    // Targeting the exact clicked target
                    if (target == null)
                    {
                        GameLog.Error($"GetTargets: {castable.Name} - intent was for exact clicked target but no target was passed?");
                    }
                    else
                    // If we're doing damage, ensure the target is attackable
                    if (!castable.Effects.Damage.IsEmpty && target.Condition.IsAttackable)
                    {
                        possibleTargets.Add(target);
                    }
                    else if (castable.Effects.Damage.IsEmpty)
                    {
                        possibleTargets.Add(target);
                    }
                }
                else if (intent.UseType == Xml.SpellUseType.NoTarget && intent.Radius == 0 && intent.Direction == Xml.IntentDirection.None)
                {
                    // Targeting self - which, currently, is only allowed for non-damaging spells
                    if (castable.Effects.Damage.IsEmpty)
                    {
                        possibleTargets.Add(this);
                    }
                }
                else
                {
                    // Area targeting, directional or otherwise

                    Rectangle rect = new Rectangle(0, 0, 0, 0);
                    byte      X    = this.X;
                    byte      Y    = this.Y;

                    // Handle area targeting with click target as the source
                    if (intent.UseType == Xml.SpellUseType.Target)
                    {
                        X = target.X;
                        Y = target.Y;
                    }

                    switch (intent.Direction)
                    {
                    case Xml.IntentDirection.Front:
                    {
                        switch (Direction)
                        {
                        case Xml.Direction.North:
                        {
                            //facing north, attack north
                            rect = new Rectangle(X, Y - intent.Radius, 1, intent.Radius);
                        }
                        break;

                        case Xml.Direction.South:
                        {
                            //facing south, attack south
                            rect = new Rectangle(X, Y, 1, 1 + intent.Radius);
                        }
                        break;

                        case Xml.Direction.East:
                        {
                            //facing east, attack east
                            rect = new Rectangle(X, Y, 1 + intent.Radius, 1);
                        }
                        break;

                        case Xml.Direction.West:
                        {
                            //facing west, attack west
                            rect = new Rectangle(X - intent.Radius, Y, intent.Radius, 1);
                        }
                        break;
                        }
                    }
                    break;

                    case Xml.IntentDirection.Back:
                    {
                        switch (Direction)
                        {
                        case Xml.Direction.North:
                        {
                            //facing north, attack south
                            rect = new Rectangle(X, Y, 1, 1 + intent.Radius);
                        }
                        break;

                        case Xml.Direction.South:
                        {
                            //facing south, attack north
                            rect = new Rectangle(X, Y - intent.Radius, 1, intent.Radius);
                        }
                        break;

                        case Xml.Direction.East:
                        {
                            //facing east, attack west
                            rect = new Rectangle(X - intent.Radius, Y, intent.Radius, 1);
                        }
                        break;

                        case Xml.Direction.West:
                        {
                            //facing west, attack east
                            rect = new Rectangle(X, Y, 1 + intent.Radius, 1);
                        }
                        break;
                        }
                    }
                    break;

                    case Xml.IntentDirection.Left:
                    {
                        switch (Direction)
                        {
                        case Xml.Direction.North:
                        {
                            //facing north, attack west
                            rect = new Rectangle(X - intent.Radius, Y, intent.Radius, 1);
                        }
                        break;

                        case Xml.Direction.South:
                        {
                            //facing south, attack east
                            rect = new Rectangle(X, Y, 1 + intent.Radius, 1);
                        }
                        break;

                        case Xml.Direction.East:
                        {
                            //facing east, attack north
                            rect = new Rectangle(X, Y, 1, 1 + intent.Radius);
                        }
                        break;

                        case Xml.Direction.West:
                        {
                            //facing west, attack south
                            rect = new Rectangle(X, Y - intent.Radius, 1, intent.Radius);
                        }
                        break;
                        }
                    }
                    break;

                    case Xml.IntentDirection.Right:
                    {
                        switch (Direction)
                        {
                        case Xml.Direction.North:
                        {
                            //facing north, attack east
                            rect = new Rectangle(X, Y, 1 + intent.Radius, 1);
                        }
                        break;

                        case Xml.Direction.South:
                        {
                            //facing south, attack west
                            rect = new Rectangle(X - intent.Radius, Y, intent.Radius, 1);
                        }
                        break;

                        case Xml.Direction.East:
                        {
                            //facing east, attack south
                            rect = new Rectangle(X, Y - intent.Radius, 1, intent.Radius);
                        }
                        break;

                        case Xml.Direction.West:
                        {
                            //facing west, attack north
                            rect = new Rectangle(X, Y, 1, 1 + intent.Radius);
                        }
                        break;
                        }
                    }
                    break;

                    case Xml.IntentDirection.Nearby:
                    case Xml.IntentDirection.None:
                    {
                        //attack radius
                        rect = new Rectangle(X - intent.Radius, Y - intent.Radius, Math.Max(intent.Radius, (byte)1) * 2, Math.Max(intent.Radius, (byte)1) * 2);
                    }
                    break;
                    }
                    GameLog.Info($"Rectangle: x: {X - intent.Radius} y: {Y - intent.Radius}, radius: {intent.Radius} - LOCATION: {rect.Location} TOP: {rect.Top}, BOTTOM: {rect.Bottom}, RIGHT: {rect.Right}, LEFT: {rect.Left}");
                    if (rect.IsEmpty)
                    {
                        continue;
                    }

                    possibleTargets.AddRange(Map.EntityTree.GetObjects(rect).Where(obj => obj is Creature && obj != this));
                }

                // Remove merchants
                possibleTargets = possibleTargets.Where(e => !(e is Merchant)).ToList();

                // Handle intent flags
                if (this is Monster)
                {
                    // No hostile flag: remove users
                    // No friendly flag: remove monsters
                    // Group / pvp: do not apply here
                    if (!intent.Target.Contains(Xml.IntentTarget.Friendly))
                    {
                        possibleTargets = possibleTargets.Where(e => !(e is Monster)).ToList();
                    }
                    if (!intent.Target.Contains(Xml.IntentTarget.Hostile))
                    {
                        possibleTargets = possibleTargets.Where(e => !(e is User)).ToList();
                    }
                }
                else if (this is User && intent.UseType != Xml.SpellUseType.NoTarget)
                {
                    var user = this as User;
                    // No hostile flag: remove monsters
                    // No friendly flag: remove users with pvp disabled
                    // No pvp: remove
                    // If we aren't targeting friendlies or pvp, remove all users entirely
                    if (!intent.Target.Contains(Xml.IntentTarget.Pvp))
                    {
                        possibleTargets = possibleTargets.Where(e => !(e is User && (e as Creature).Condition.PvpEnabled == true)).ToList();
                    }
                    if (!intent.Target.Contains(Xml.IntentTarget.Friendly))
                    {
                        possibleTargets = possibleTargets.Where(e => !(e is User && (e as Creature).Condition.PvpEnabled == false)).ToList();
                    }
                    // If we aren't targeting hostiles, remove all monsters
                    if (!intent.Target.Contains(Xml.IntentTarget.Hostile))
                    {
                        possibleTargets = possibleTargets.Where(e => !(e is Monster)).ToList();
                    }
                }

                // Finally, add the targets to our list

                List <Creature> possible = intent.MaxTargets > 0 ? possibleTargets.Take(intent.MaxTargets).OfType <Creature>().ToList() : possibleTargets.OfType <Creature>().ToList();
                if (possible != null && possible.Count > 0)
                {
                    actualTargets.AddRange(possible);
                }
                else
                {
                    GameLog.Info("No targets found");
                }
            }
            return(actualTargets);
        }