Пример #1
0
 /// <summary>
 /// ホストを追加する
 /// </summary>
 /// <param name="host">新しいホストデータ</param>
 public async Task AddAsync(EntryHost host)
 {
     try
     {
         await this.container.Context.EntryHosts.AddAsync(host);
     }
     catch (Exception ex)
     {
         this.container.Error(ex);
     }
 }
Пример #2
0
        public static async Task EntryAsync(MainRepository repo, string ipAddress, Character newChara, CharacterIcon newIcon, string password, Country newCountry, string invitationCode, bool isFreeCountry)
        {
            var town = await repo.Town.GetByIdAsync(newChara.TownId).GetOrErrorAsync(ErrorCode.TownNotFoundError);

            var system = await repo.System.GetAsync();

            CheckEntryStatus(system.GameDateTime, ipAddress, newChara, password, newIcon, town, newCountry, isFreeCountry);

            // 文字数チェックしてからエスケープ
            newChara.Name    = HtmlUtil.Escape(newChara.Name);
            newCountry.Name  = HtmlUtil.Escape(newCountry.Name);
            newChara.Message = HtmlUtil.Escape(newChara.Message);

            // 既存との重複チェック
            if (await repo.Character.IsAlreadyExistsAsync(newChara.Name, newChara.AliasId))
            {
                ErrorCode.DuplicateCharacterNameOrAliasIdError.Throw();
            }
            if ((system.IsDebug && (await repo.System.GetDebugDataAsync()).IsCheckDuplicateEntry || !system.IsDebug) &&
                await repo.EntryHost.ExistsAsync(ipAddress))
            {
                ErrorCode.DuplicateEntryError.Throw();
            }

            // 招待コードチェック
            Optional <InvitationCode> invitationCodeOptional = default;

            if (system.InvitationCodeRequestedAtEntry)
            {
                invitationCodeOptional = await repo.InvitationCode.GetByCodeAsync(invitationCode);

                if (!invitationCodeOptional.HasData || invitationCodeOptional.Data.HasUsed || invitationCodeOptional.Data.Aim != InvitationCodeAim.Entry)
                {
                    ErrorCode.InvitationCodeRequestedError.Throw();
                }
            }

            var    updateCountriesRequested = false;
            MapLog maplog = null;
            var    chara  = new Character
            {
                Name                = newChara.Name,
                AliasId             = newChara.AliasId,
                Strong              = newChara.Strong,
                StrongEx            = 0,
                Intellect           = newChara.Intellect,
                IntellectEx         = 0,
                Leadership          = newChara.Leadership,
                LeadershipEx        = 0,
                Popularity          = newChara.Popularity,
                PopularityEx        = 0,
                Contribution        = 0,
                Class               = 0,
                DeleteTurn          = (short)(Config.DeleteTurns - 10),
                LastUpdated         = DateTime.Now,
                LastUpdatedGameDate = system.GameDateTime,
                Message             = newChara.Message,
                Money               = 10_0000 + Math.Max(system.GameDateTime.ToInt() - (Config.StartYear + Config.UpdateStartYear + 4) * 12 - Config.StartMonth, 0) * 800,
                Rice                = 5_0000 + Math.Max(system.GameDateTime.ToInt() - (Config.StartYear + Config.UpdateStartYear + 4) * 12 - Config.StartMonth, 0) * 400,
                SkillPoint          = Math.Max(0, (int)((system.IntGameDateTime - Config.UpdateStartYear * 12) * 0.8f)),
                SoldierType         = SoldierType.Common,
                SoldierNumber       = 0,
                Proficiency         = 0,
                TownId              = newChara.TownId,
                From                = newChara.From,
                Religion            = ReligionType.Any,
                FormationType       = newChara.FormationType,
                IsBeginner          = newChara.IsBeginner,
            };

            chara.SetPassword(password);

            // 出身
            var skills = new List <CharacterSkillType>();
            var items  = new List <CharacterItemType>();

            if (chara.From == CharacterFrom.Warrior)
            {
                skills.Add(CharacterSkillType.Strong1);
                chara.Strong += 20;
            }
            else if (chara.From == CharacterFrom.Civilian)
            {
                skills.Add(CharacterSkillType.Intellect1);
                chara.Intellect += 20;
            }
            else if (chara.From == CharacterFrom.Merchant)
            {
                skills.Add(CharacterSkillType.Merchant1);
                chara.Money += 200000;
            }
            else if (chara.From == CharacterFrom.Engineer)
            {
                skills.Add(CharacterSkillType.Engineer1);
                chara.Strong += 10;
                chara.Money  += 100000;
            }
            else if (chara.From == CharacterFrom.Terrorist)
            {
                skills.Add(CharacterSkillType.Terrorist1);
                chara.Strong     += 15;
                chara.Leadership += 5;
            }
            else if (chara.From == CharacterFrom.People)
            {
                skills.Add(CharacterSkillType.People1);
                chara.Popularity += 20;
            }
            else if (chara.From == CharacterFrom.Tactician)
            {
                skills.Add(CharacterSkillType.Tactician1);
                chara.Strong     += 5;
                chara.Leadership += 15;
            }
            else if (chara.From == CharacterFrom.Scholar)
            {
                skills.Add(CharacterSkillType.Scholar1);
                chara.Intellect += 20;
            }
            else if (chara.From == CharacterFrom.Staff)
            {
                skills.Add(CharacterSkillType.Staff1);
                chara.Intellect += 20;
            }
            else if (chara.From == CharacterFrom.Buddhism)
            {
                if (system.RuleSet == GameRuleSet.SimpleBattle)
                {
                    ErrorCode.RuleSetError.Throw();
                }
                skills.Add(CharacterSkillType.Buddhism1);
                chara.Intellect += 15;
                chara.Religion   = ReligionType.Buddhism;
            }
            else if (chara.From == CharacterFrom.Confucianism)
            {
                if (system.RuleSet == GameRuleSet.SimpleBattle)
                {
                    ErrorCode.RuleSetError.Throw();
                }
                skills.Add(CharacterSkillType.Confucianism1);
                chara.Intellect += 15;
                chara.Religion   = ReligionType.Confucianism;
            }
            else if (chara.From == CharacterFrom.Taoism)
            {
                if (system.RuleSet == GameRuleSet.SimpleBattle)
                {
                    ErrorCode.RuleSetError.Throw();
                }
                skills.Add(CharacterSkillType.Taoism1);
                chara.Intellect += 15;
                chara.Religion   = ReligionType.Taoism;
            }
            else
            {
                ErrorCode.InvalidParameterError.Throw();
            }

            // 来月の更新がまだ終わってないタイミングで登録したときの、武将更新時刻の調整
            if (chara.LastUpdated - system.CurrentMonthStartDateTime > TimeSpan.FromSeconds(Config.UpdateTime))
            {
                chara.IntLastUpdatedGameDate++;
            }

            if (isFreeCountry)
            {
                // 無所属で開始
                chara.CountryId = 0;
                await repo.Character.AddAsync(chara);

                maplog = new MapLog
                {
                    Date            = DateTime.Now,
                    ApiGameDateTime = system.GameDateTime,
                    EventType       = EventType.CharacterEntryToFree,
                    IsImportant     = false,
                    Message         = $"<character>{chara.Name}</character> が無所属に出現しました",
                };
                await repo.MapLog.AddAsync(maplog);
            }
            else if (town.CountryId > 0)
            {
                // 武将総数チェック
                var country = await repo.Country.GetByIdAsync(town.CountryId).GetOrErrorAsync(ErrorCode.CountryNotFoundError);

                if (country.IntEstablished + Config.CountryBattleStopDuring > system.GameDateTime.ToInt())
                {
                    var countryCharaCount = await repo.Country.CountCharactersAsync(country.Id, true);

                    if (countryCharaCount >= Config.CountryJoinMaxOnLimited)
                    {
                        ErrorCode.CantJoinAtSuchCountryhError.Throw();
                    }
                    else if (countryCharaCount + 1 == Config.CountryJoinMaxOnLimited)
                    {
                        updateCountriesRequested = true;
                    }
                }

                // AI国家チェック
                if (country.AiType != CountryAiType.Human)
                {
                    ErrorCode.CantJoinAtSuchCountryhError.Throw();
                }

                // 金と米を仕官先国の武将の平均にあわせる
                if (system.GameDateTime.Year >= Config.UpdateStartYear + Config.CountryBattleStopDuring / 12)
                {
                    var countryCharacters = (await repo.Country.GetCharactersAsync(town.CountryId)).Where(c => c.AiType == CharacterAiType.Human || c.AiType == CharacterAiType.Administrator);
                    if (countryCharacters.Any())
                    {
                        chara.Money = Math.Min((int)countryCharacters.Average(c => c.Money) + 10_0000, chara.Money);
                        chara.Rice  = Math.Min((int)countryCharacters.Average(c => c.Rice) + 5_0000, chara.Rice);
                    }
                }

                chara.CountryId = town.CountryId;
                await repo.Character.AddAsync(chara);

                maplog = new MapLog
                {
                    Date            = DateTime.Now,
                    ApiGameDateTime = system.GameDateTime,
                    EventType       = EventType.CharacterEntry,
                    IsImportant     = false,
                    Message         = $"<character>{chara.Name}</character> が <country>{country.Name}</country> に仕官しました",
                };
                await repo.MapLog.AddAsync(maplog);
            }
            else
            {
                // 重複チェック
                if ((await repo.Country.GetAllAsync()).Any(c => c.Name == newCountry.Name || c.CountryColorId == newCountry.CountryColorId))
                {
                    ErrorCode.DuplicateCountryNameOrColorError.Throw();
                }

                if (system.RuleSet == GameRuleSet.SimpleBattle)
                {
                    newCountry.Civilization = CountryCivilization.None;
                }

                var country = new Country
                {
                    Name           = newCountry.Name,
                    CountryColorId = newCountry.CountryColorId,
                    CapitalTownId  = newChara.TownId,
                    IntEstablished = Math.Max(system.GameDateTime.ToInt(), new GameDateTime {
                        Year = Config.UpdateStartYear, Month = 1,
                    }.ToInt()),
                    HasOverthrown         = false,
                    IntOverthrownGameDate = 0,
                    LastMoneyIncomes      = 0,
                    LastRiceIncomes       = 0,
                    PolicyPoint           = 10000,
                    Religion     = RandomService.Next(new ReligionType[] { ReligionType.Buddhism, ReligionType.Confucianism, ReligionType.Taoism, }),
                    Civilization = newCountry.Civilization,
                };
                updateCountriesRequested = true;
                await repo.Country.AddAsync(country);

                var countries = await repo.Country.GetAllAsync();

                var point = 500;

                if (system.RuleSet != GameRuleSet.Wandering)
                {
                    // 大都市に変更
                    town.SubType = town.Type;
                    MapService.UpdateTownType(town, TownType.Large);

                    // 首都の宗教
                    if (system.RuleSet != GameRuleSet.SimpleBattle)
                    {
                        if (country.Religion == ReligionType.Buddhism)
                        {
                            town.Buddhism    += point;
                            town.Confucianism = Math.Min(town.Confucianism, 999);
                            town.Taoism       = Math.Min(town.Taoism, 999);
                        }
                        if (country.Religion == ReligionType.Confucianism)
                        {
                            town.Confucianism += point;
                            town.Buddhism      = Math.Min(town.Buddhism, 999);
                            town.Taoism        = Math.Min(town.Taoism, 999);
                        }
                        if (country.Religion == ReligionType.Taoism)
                        {
                            town.Taoism      += point;
                            town.Buddhism     = Math.Min(town.Buddhism, 999);
                            town.Confucianism = Math.Min(town.Confucianism, 999);
                        }
                    }
                }
                else
                {
                    country.CapitalTownId = 0;
                    items.Add(CharacterItemType.CastleBlueprint);
                    items.Add(CharacterItemType.CastleBlueprint);
                    items.Add(CharacterItemType.CastleBlueprint);
                    chara.Money += 50_0000 * 3;
                }

                await repo.SaveChangesAsync();

                chara.CountryId = country.Id;
                if (system.RuleSet != GameRuleSet.Wandering)
                {
                    town.CountryId = country.Id;
                }
                await repo.Character.AddAsync(chara);

                await repo.SaveChangesAsync();

                var countryPost = new CountryPost
                {
                    Type        = CountryPostType.Monarch,
                    CountryId   = country.Id,
                    CharacterId = chara.Id,
                };
                await repo.Country.AddPostAsync(countryPost);

                if (system.RuleSet == GameRuleSet.Wandering)
                {
                    maplog = new MapLog
                    {
                        Date            = DateTime.Now,
                        ApiGameDateTime = system.GameDateTime,
                        EventType       = EventType.StartWandering,
                        IsImportant     = true,
                        Message         = $"<character>{chara.Name}</character> は <country>{country.Name}</country> の頭領となり放浪を開始しました",
                    };
                }
                else
                {
                    maplog = new MapLog
                    {
                        Date            = DateTime.Now,
                        ApiGameDateTime = system.GameDateTime,
                        EventType       = EventType.Publish,
                        IsImportant     = true,
                        Message         = $"<character>{chara.Name}</character> が <town>{town.Name}</town> に <country>{country.Name}</country> を建国しました",
                    };
                }
                await repo.MapLog.AddAsync(maplog);
            }

            await repo.SaveChangesAsync();

            // 陣形
            var formation = new Formation
            {
                CharacterId = chara.Id,
                Type        = chara.FormationType,
                Level       = 1,
            };
            await repo.Character.AddFormationAsync(formation);

            if (invitationCodeOptional.HasData)
            {
                var code = invitationCodeOptional.Data;
                code.HasUsed     = true;
                code.Used        = DateTime.Now;
                code.CharacterId = chara.Id;
            }

            var icon = new CharacterIcon
            {
                Type        = newIcon.Type,
                IsAvailable = true,
                IsMain      = true,
                FileName    = newIcon.FileName,
                CharacterId = chara.Id,
            };
            await repo.Character.AddCharacterIconAsync(icon);

            var host = new EntryHost
            {
                CharacterId = chara.Id,
                IpAddress   = ipAddress,
            };
            await repo.EntryHost.AddAsync(host);

            var skillItems = skills.Select(s => new CharacterSkill
            {
                CharacterId = chara.Id,
                Type        = s,
                Status      = CharacterSkillStatus.Available,
            });

            foreach (var si in skillItems)
            {
                await SkillService.SetCharacterAndSaveAsync(repo, si, chara);
            }
            var itemData = items.Select(i => new CharacterItem
            {
                Type        = i,
                CharacterId = chara.Id,
                Status      = CharacterItemStatus.CharacterHold,
            });

            foreach (var id in itemData)
            {
                await ItemService.GenerateItemAndSaveAsync(repo, id);
            }

            await repo.SaveChangesAsync();

            if (updateCountriesRequested)
            {
                var countries = await repo.Country.GetAllForAnonymousAsync();

                await AnonymousStreaming.Default.SendAllAsync(countries.Select(c => ApiData.From(c)));

                await StatusStreaming.Default.SendAllAsync(countries.Select(c => ApiData.From(c)));
            }

            var townData   = ApiData.From(new TownForAnonymous(town));
            var maplogData = ApiData.From(maplog);
            await AnonymousStreaming.Default.SendAllAsync(maplogData);

            await StatusStreaming.Default.SendAllAsync(maplogData);

            await AnonymousStreaming.Default.SendAllAsync(townData);

            await StatusStreaming.Default.SendAllAsync(townData);

            await StatusStreaming.Default.SendCountryAsync(ApiData.From(town), town.CountryId);

            await CharacterService.StreamCharacterAsync(repo, chara);
        }