public static async Task <List <Databases.personal.Challenge> > GetAsync(
     long playerId,
     Services.MasterData.IMasterData masterdata,
     PersonalDBContext db)
 {
     return(await UpdateAsync(playerId, masterdata, db));
 }
        public static async Task CountupAsync(
            long playerId,
            Services.MasterData.IMasterData masterdata,
            PersonalDBContext db,
            evolib.Challenge.OutgameServerChallengeType challengeType,
            string sessionId)
        {
            if (challengeType == evolib.Challenge.OutgameServerChallengeType.None)
            {
                return;
            }

            // 指定するカテゴリのチャレンジをリストアップする
            var countupInfos = masterdata.AllChallenge
                               .Where(master =>
                                      master.reporterType == evolib.Challenge.ReporterType.OutgameServer &&
                                      master.outgameServerChallengeType == challengeType)
                               .Select(master =>
                                       new CountupInfo()
            {
                id    = master.challengeId,
                value = 1,
            })
                               .ToList();

            await CountupAsync(playerId, masterdata, db, countupInfos, sessionId);
        }
        public static DateTime GetExpirationDate(Services.MasterData.IMasterData masterdata, evolib.Challenge.Type type, DateTime today)
        {
            var expirationMaster = masterdata.GetChallengeExpiration(type);

            if (expirationMaster == null)
            {
                return(DateTime.MaxValue);
            }

            var finishDate = new DateTime(today.Year, today.Month, today.Day);

            switch (type)
            {
            case Challenge.Type.Beginner:
                finishDate = DateTime.MaxValue;
                break;

            case Challenge.Type.Daily:
            {
                finishDate += expirationMaster.expirationOffsetTime;

                //終了日より未来なら、終了日に次の日を指定する
                if (finishDate <= today)
                {
                    finishDate = finishDate.AddHours(24);
                }
            }
            break;

            case Challenge.Type.Weekly:
            {
                // 終了曜日算出の為、一旦日曜日に設定する
                var sundayAddDays = (int)System.DayOfWeek.Sunday - (int)finishDate.DayOfWeek;
                finishDate = finishDate.AddDays(sundayAddDays);

                finishDate += expirationMaster.expirationOffsetTime;

                //終了曜日より未来なら、終了日に次週を指定する
                if (finishDate <= today)
                {
                    finishDate = finishDate.AddHours(7 * 24);
                }
            }
            break;
            }

            return(finishDate);
        }
Beispiel #4
0
        private static async Task <GiveAssetsResult> FirstOrDefaultAssetsAsync(
            Services.MasterData.IMasterData masterData,
            Databases.personal.PersonalDBContext db,
            long playerId,
            Model model
            )
        {
            var assetsInfo = masterData.GetAssetsInfo(model.assetsId);

            if (assetsInfo == null)
            {
                return(GiveAssetsResult.Err);
            }

            var result = GiveAssetsResult.Err;

            var rec = await db.AssetsInventories.FirstOrDefaultAsync(r =>
                                                                     r.playerId == playerId && r.assetsId == model.assetsId);

            if (rec == null)
            {
                rec = new Databases.personal.AssetsInventory
                {
                    playerId = playerId,
                    assetsId = model.assetsId,
                };
                await db.AssetsInventories.AddAsync(rec);

                result = GiveAssetsResult.Add;
            }
            else
            {
                result = GiveAssetsResult.Update;
            }

            rec.amount = Math.Clamp(rec.amount + model.amount, 0, assetsInfo.maxValue);

            if (rec.amount >= assetsInfo.maxValue)
            {
                result = GiveAssetsResult.MaxValue;
            }

            return(result);
        }
Beispiel #5
0
        public static async Task <BalanceList> BalanceAsync(
            Services.MasterData.IMasterData masterData,
            Databases.personal.PersonalDBContext db,
            string accountAccessToken,
            long playerId //playerIdの正当性は呼び出し元で保証してください
            )
        {
            var balanceList = new BalanceList();

            ////////////////////////
            // Coins
            var requester = new Multiplatform.Inky.GetAccountPlatinumBalance();
            var response  = await requester.GetAsync(accountAccessToken);

            if (response.StatusCode == System.Net.HttpStatusCode.OK)
            {
                var coinModel = new BalanceModel
                {
                    type     = Type.Coin,
                    assetsId = "",
                    amount   = response.Payload.data.total_platinum,
                };
                balanceList.Add(coinModel);
            }

            ////////////////////////
            // Assets
            var query = db.AssetsInventories.Where(a =>
                                                   a.playerId == playerId
                                                   );

            var inventorySrc = await query.ToListAsync();

            inventorySrc.ForEach(
                a => balanceList.Add(new BalanceModel
            {
                type     = Type.Assets,
                assetsId = a.assetsId,
                amount   = a.amount,
            })
                );

            return(balanceList);
        }
Beispiel #6
0
        public static ConvertModel GiveConvertModel(
            Services.MasterData.IMasterData masterData,
            string itemId)
        {
            var r = new ConvertModel();

            var item = masterData.GetItemFromItemId(itemId);

            if (item == null)
            {
                r.result = Result.Err;
                return(r);
            }
            var materialConversion = masterData.GetMaterialConversion(item.rankType);

            if (materialConversion == null)
            {
                r.result = Result.Err;
                return(r);
            }

            var assetsInfo = masterData.GetAssetsInfoByType(AssetsType);

            if (assetsInfo == null)
            {
                r.result = Result.Err;
                return(r);
            }

            r.result = Result.Ok;
            r.model  = new GiveAndTake.Model
            {
                type     = GiveAndTake.Type.Assets,
                assetsId = assetsInfo.assetsId,
                itemId   = "",
                amount   = materialConversion.value,
            };

            return(r);
        }
Beispiel #7
0
        public static async Task <GiveResult> GiveAsync(
            Services.MasterData.IMasterData masterData,
            Databases.personal.PersonalDBContext db,
            string accountAccessToken,
            long playerId, //playerIdの正当性は呼び出し元で保証してください
            GiveModel reward
            )
        {
            var rewards = new List <GiveModel>();

            rewards.Add(reward);

            var results = await GiveAsync(
                masterData, db, accountAccessToken,
                playerId, rewards);

            if (results.Count > 0)
            {
                return(results[0].result);
            }

            return(GiveResult.Err);
        }
Beispiel #8
0
        public static async Task <List <GiveResultModel> > GiveAsync(
            Services.MasterData.IMasterData masterData,
            Databases.personal.PersonalDBContext db,
            string accountAccessToken,
            long playerId, //playerIdの正当性は呼び出し元で保証してください
            long[] ids
            )
        {
            var results = new List <GiveResultModel>();

            var update = false;

            var list = await db.PresentBoxs.Where(r => r.playerId == playerId).ToListAsync();

            var now = DateTime.UtcNow;

            for (int i = 0; i < list.Count;)
            {
                var m = list[i];

                // 期限が切れたプレゼントを削除しておく(期限には少しだけ余裕を持たせる)
                if (m.endDate + TimeSpan.FromMinutes(1) <= now)
                {
                    Logger.Logging(
                        new LogObj().AddChild(new LogModels.GivePresent
                    {
                        PlayerId       = playerId,
                        Date           = now,
                        Type           = m.type,
                        Id             = m.presentId,
                        Amount         = m.amount,
                        ExpirationDate = m.endDate,
                        RouteType      = m.giveType,
                        Code           = Code.Expired,
                        GivenCode      = GiveAndTake.GiveResult.Ok,
                    })
                        );

                    db.PresentBoxs.Remove(m);
                    list.RemoveAt(i);
                    update = true;

                    continue;
                }

                i++;
            }

            var presentList = new List <Databases.personal.PresentBox>();

            foreach (var id in ids)
            {
                var present = list.Find(r => r.Id == id);

                if (present == null)
                {
                    var r = new GiveResultModel
                    {
                        id     = id,
                        result = GiveResult.Err,
                    };
                    results.Add(r);

                    Logger.Logging(
                        new LogObj().AddChild(new LogModels.GivePresent
                    {
                        PlayerId       = playerId,
                        Date           = now,
                        Type           = GiveAndTake.Type.Coin,
                        Id             = "",
                        Amount         = 0,
                        ExpirationDate = now,
                        RouteType      = Type.Management,
                        Code           = Code.Err,
                        GivenCode      = GiveAndTake.GiveResult.Ok,
                    })
                        );

                    continue;
                }

                presentList.Add(present);

                db.PresentBoxs.Remove(present);

                update = true;
            }

            if (update)
            {
                await db.SaveChangesAsync();
            }

            var rewards = new List <GiveAndTake.GiveModel>();

            foreach (var present in presentList)
            {
                var reward = new GiveAndTake.Model
                {
                    assetsId = "",
                    itemId   = "",
                    amount   = present.amount,
                };

                if (present.type == GiveAndTake.Type.Coin)
                {
                    reward.type = GiveAndTake.Type.Coin;
                }
                else if (present.type == GiveAndTake.Type.Assets)
                {
                    reward.type     = GiveAndTake.Type.Assets;
                    reward.assetsId = present.presentId;
                }
                else if (present.type == GiveAndTake.Type.Item)
                {
                    reward.type   = GiveAndTake.Type.Item;
                    reward.itemId = present.presentId;
                }

                rewards.Add(new GiveAndTake.GiveModel
                {
                    id           = present.Id,
                    model        = reward,
                    historyModel = new GiveAndTake.HistoryModel
                    {
                        giveType = present.giveType,
                        text     = present.text,
                    },
                });
            }

            // プレゼント獲得
            var giveModels = await GiveAndTake.GiveAsync(
                masterData,
                db,
                accountAccessToken,
                playerId,
                rewards);

            // 獲得結果集計
            foreach (var reward in rewards)
            {
                var giveModel = giveModels.Find(i => i.id == reward.id);
                if (giveModel == null)
                {
                    Logger.Logging(
                        new LogObj().AddChild(new LogModels.GivePresent
                    {
                        PlayerId       = playerId,
                        Date           = now,
                        Type           = GiveAndTake.Type.Coin,
                        Id             = "",
                        Amount         = 0,
                        ExpirationDate = now,
                        RouteType      = Type.Management,
                        Code           = Code.Err,
                        GivenCode      = GiveAndTake.GiveResult.Ok,
                    })
                        );
                    continue;
                }

                var r = new GiveResultModel
                {
                    id    = reward.id,
                    model = reward.model,
                };

                if (giveModel.result == GiveAndTake.GiveResult.Ok)
                {
                    r.result = GiveResult.Ok;
                }
                else if (giveModel.result == GiveAndTake.GiveResult.AlreadyOwned)
                {
                    r.result = GiveResult.Ok;

                    var convert = ItemConversion.GiveConvertModel(masterData, reward.model.itemId);
                    if (convert.result == ItemConversion.Result.Ok)
                    {
                        // 変換したモデルに差し替える
                        r.model = convert.model;
                    }
                }
                else if (giveModel.result == GiveAndTake.GiveResult.Err)
                {
                    r.result = GiveResult.Err;
                }

                var present = presentList.Find(i => i.Id == reward.id);
                Logger.Logging(
                    new LogObj().AddChild(new LogModels.GivePresent
                {
                    PlayerId       = playerId,
                    Date           = now,
                    Type           = reward.model.type,
                    Id             = (reward.model.type == GiveAndTake.Type.Item) ? reward.model.itemId : reward.model.assetsId,
                    Amount         = reward.model.amount,
                    ExpirationDate = (present != null) ? present.endDate: now,
                    RouteType      = (present != null) ? present.giveType : Type.Management,
                    Code           = Code.Ok,
                    GivenCode      = giveModel.result,
                })
                    );

                results.Add(r);
            }

            return(results);
        }
Beispiel #9
0
        public static async Task <TakeResult> TakeAsync(
            Services.MasterData.IMasterData masterData,
            Databases.personal.PersonalDBContext db,
            long playerId, //playerIdの正当性は呼び出し元で保証してください
            Model present
            )
        {
            ////////////////////////
            // Assets
            if (present.type == GiveAndTake.Type.Assets)
            {
                var assetsInfo = masterData.GetAssetsInfo(present.id);
                if (assetsInfo == null)
                {
                    return(TakeResult.Err);
                }
            }

            ////////////////////////
            // Item
            if (present.type == GiveAndTake.Type.Item)
            {
                var itemInfo = masterData.GetItemFromItemId(present.id);

                if (itemInfo == null)
                {
                    return(TakeResult.Err);
                }

                if (masterData.CheckDefaultOwnedItem(present.id))
                {
                    return(TakeResult.Err);
                }
            }

            var addDate = TimeSpan.FromDays(10);

            var presentBoxInfo = masterData.GetPresentBox(present.presentType);

            if (presentBoxInfo != null)
            {
                addDate = TimeSpan.FromDays(presentBoxInfo.value);
            }

            var beginDate = DateTime.UtcNow;
            var endDate   = DateTime.UtcNow + addDate;
            var text      = "";

            if (present.presentType == Type.Management)
            {
                // Management = GMツール。以下を任意に設定できるようにする
                beginDate = present.setting.beginDate;
                endDate   = present.setting.endDate;
                text      = (present.setting.text != null) ? present.setting.text : "";
            }

            var record = new Databases.personal.PresentBox
            {
                playerId  = playerId,
                beginDate = beginDate,
                endDate   = endDate,
                type      = present.type,
                presentId = present.id,
                amount    = present.amount,
                giveType  = present.presentType,
                text      = text,
            };
            await db.PresentBoxs.AddAsync(record);

            await db.SaveChangesAsync();

            return(TakeResult.Ok);
        }
        static async Task <List <Databases.personal.Challenge> > UpdateAsync(
            long playerId,
            Services.MasterData.IMasterData masterdata,
            PersonalDBContext db)
        {
            var changed = false;

            var list = await db.Challenges.Where(r => r.playerId == playerId).ToListAsync();

            var now = DateTime.UtcNow;

            for (int i = 0; i < list.Count;)
            {
                var m = list[i];

                if (m.expirationDate <= now)
                {
                    db.Challenges.Remove(m);
                    list.RemoveAt(i);
                    changed = true;

                    continue;
                }

                i++;
            }

            var addedList = new List <Databases.personal.Challenge>();

            if (list.Find(r => r.type == Challenge.Type.Beginner) == null)
            {
                var expirationDate = GetExpirationDate(masterdata, Challenge.Type.Beginner, now);

                var allBeginners = masterdata.AllChallenge.Where(challenge => challenge.type == evolib.Challenge.Type.Beginner).ToList();

                var firstOrder = 0;
                if (0 < masterdata.AllBeginnerChallengeSheet.Count)
                {
                    firstOrder = masterdata.AllBeginnerChallengeSheet.Min(i => i.order);
                }

                foreach (var info in allBeginners)
                {
                    var sheetMaster = masterdata.GetBeginnerChallengeSheet(info.sheetId);

                    var r = new Databases.personal.Challenge
                    {
                        playerId       = playerId,
                        challengeId    = info.challengeId,
                        type           = evolib.Challenge.Type.Beginner,
                        order          = sheetMaster.order,
                        expirationDate = expirationDate,
                        unlocked       = firstOrder == sheetMaster.order ? true : false,
                    };
                    addedList.Add(r);
                }
                changed = true;
            }
            if (list.Find(r => r.type == Challenge.Type.Weekly) == null)
            {
                var allWeeklies = masterdata.AllChallenge.Where(challenge => challenge.type == evolib.Challenge.Type.Weekly).ToList();

                // TODO: 抽選ロジックは仮
                var indexList = Challenge.DrawLots(allWeeklies.Count, 3);

                var weeklyDrawLots = allWeeklies.Where((challenge, index) => indexList.Contains(index)).ToList();

                var expirationDate = GetExpirationDate(masterdata, Challenge.Type.Weekly, now);

                // TODO: 有償ならロックを掛ける
                var unlocked = true;

                foreach (var info in weeklyDrawLots)
                {
                    var r = new Databases.personal.Challenge
                    {
                        playerId       = playerId,
                        challengeId    = info.challengeId,
                        type           = evolib.Challenge.Type.Weekly,
                        order          = 0,
                        expirationDate = expirationDate,
                        unlocked       = unlocked,
                    };
                    addedList.Add(r);
                }
                changed = true;
            }
            if (list.Find(r => r.type == Challenge.Type.Daily) == null)
            {
                var allDailies = masterdata.AllChallenge.Where(challenge => challenge.type == evolib.Challenge.Type.Daily).ToList();

                // TODO: 抽選ロジックは仮
                var indexList = Challenge.DrawLots(allDailies.Count, 3);

                var dailyDrawLots = allDailies.Where((challenge, index) => indexList.Contains(index)).ToList();

                var expirationDate = GetExpirationDate(masterdata, Challenge.Type.Daily, now);

                // TODO: 有償ならロックを掛ける
                var unlocked = true;

                foreach (var info in dailyDrawLots)
                {
                    var r = new Databases.personal.Challenge
                    {
                        playerId       = playerId,
                        challengeId    = info.challengeId,
                        type           = evolib.Challenge.Type.Daily,
                        order          = 0,
                        expirationDate = expirationDate,
                        unlocked       = unlocked,
                    };
                    addedList.Add(r);
                }
                changed = true;
            }

            if (changed)
            {
                await db.Challenges.AddRangeAsync(addedList);

                await db.SaveChangesAsync();
            }

            list.AddRange(addedList);

            return(list);
        }
        public static async Task CountupAsync(
            long playerId,
            Services.MasterData.IMasterData masterdata,
            PersonalDBContext db,
            List <CountupInfo> countupInfos,
            string sessionId)
        {
            var challengeList = await UpdateAsync(playerId, masterdata, db);

            var clearList = new List <string>();

            var allBeginnerMaster = masterdata.AllChallenge.Where(challenge => challenge.type == evolib.Challenge.Type.Beginner).ToList();

            foreach (var countupInfo in countupInfos)
            {
                var challenge = challengeList.Find(r => r.challengeId == countupInfo.id);

                if (challenge == null)
                {
                    continue;
                }

                if (challenge.status == Challenge.Status.Clear)
                {
                    continue;
                }

                if (!challenge.unlocked)
                {
                    continue;
                }

                var challengeMaster = masterdata.GetChallenge(challenge.challengeId);

                if (challengeMaster == null)
                {
                    continue;
                }

                challenge.value += countupInfo.value;

                if (challengeMaster.requiredNum <= challenge.value)
                {
                    challenge.status = Challenge.Status.Clear;

                    // 最大値を超えないように設定
                    challenge.value = Math.Min(challenge.value, challengeMaster.requiredNum);

                    //報酬
                    //db.PresentBoxs.Add(new Databases.personal.PresentBox
                    //{

                    //});

                    // ビギナーチャレンジのシート達成確認
                    if (challenge.type == Challenge.Type.Beginner)
                    {
                        var notClearList = challengeList.FindAll(r => r.type == evolib.Challenge.Type.Beginner && r.status != evolib.Challenge.Status.Clear);

                        if (notClearList != null)
                        {
                            notClearList.Sort((a, b) => a.order - b.order);
                            var nextOrder = notClearList.First().order;

                            // シートが次のステップに変わったなら、シート達成
                            if (challenge.order != nextOrder)
                            {
                                // 次のシートのロックを解除する
                                var unlockedList = notClearList.Where(r => r.order == nextOrder)
                                                   .Select(r =>
                                {
                                    r.unlocked = true;
                                    return(r);
                                })
                                                   .ToList();
                            }
                        }
                    }

                    // アウトゲームでカウントする項目のみ通知 = ビギナーチャレンジ の為、
                    // ビギナーチャレンジの時には通知する
                    if (challenge.type == Challenge.Type.Beginner)
                    {
                        clearList.Add(countupInfo.id);
                    }
                }
            }

            await db.SaveChangesAsync();

            if (0 <= clearList.Count)
            {
                await new ConnectionQueue(sessionId).EnqueueAsync(new ClearChallenge
                {
                    challengeIds = clearList,
                });
            }
        }
Beispiel #12
0
        public static async Task <TakeResult> TakeAsync(
            Services.MasterData.IMasterData masterData,
            Databases.personal.PersonalDBContext db,
            string accountAccessToken,
            long playerId,             //playerIdの正当性は呼び出し元で保証してください
            Model cost
            )
        {
            ////////////////////////
            // Coins
            if (cost.type == Type.Coin)
            {
                var requester = new Multiplatform.Inky.PurchaseItem();
                requester.request.items = new List <Multiplatform.Inky.PurchaseItem.Request.PurchasedProductItems>()
                {
                    new Multiplatform.Inky.PurchaseItem.Request.PurchasedProductItems
                    {
                        deduct_platinum = (int)cost.amount,
                        item_id         = "testItemId",
                        item_name       = "testItem",
                        item_qty        = 1,
                        item_type       = 1,
                    }
                };

                var response = await requester.PostAsync(accountAccessToken);

                if (response.StatusCode == System.Net.HttpStatusCode.OK)
                {
                    return(TakeResult.Ok);
                }

                return(TakeResult.Insufficient);
            }

            ////////////////////////
            // Assets
            if (cost.type == Type.Assets)
            {
                var assetsInfo = masterData.GetAssetsInfo(cost.assetsId);
                if (assetsInfo == null)
                {
                    return(TakeResult.Err);
                }

                var rec = await db.AssetsInventories.FirstOrDefaultAsync(r =>
                                                                         r.playerId == playerId && r.assetsId == cost.assetsId);

                if (rec == null)
                {
                    rec = new Databases.personal.AssetsInventory
                    {
                        playerId = playerId,
                        assetsId = cost.assetsId,
                    };
                    await db.AssetsInventories.AddAsync(rec);
                }

                if (rec.amount < cost.amount)
                {
                    return(TakeResult.Insufficient);
                }

                rec.amount = rec.amount - cost.amount;
                await db.SaveChangesAsync();

                return(TakeResult.Ok);
            }

            ////////////////////////
            // Item
            if (cost.type == Type.Item)
            {
                var itemInfo = masterData.GetItemFromItemId(cost.itemId);

                if (itemInfo == null)
                {
                    return(TakeResult.Err);
                }

                if (masterData.CheckDefaultOwnedItem(cost.itemId))
                {
                    return(TakeResult.Ok);
                }

                var rec = await db.ItemInventories.FirstOrDefaultAsync(r =>
                                                                       r.playerId == playerId && r.itemId == cost.itemId);

                if (rec != null)
                {
                    return(TakeResult.Ok);
                }

                return(TakeResult.Insufficient);
            }

            ////////////////////////
            // Unknown
            return(TakeResult.Err);
        }
Beispiel #13
0
        public static async Task <List <GiveResultModel> > GiveAsync(
            Services.MasterData.IMasterData masterData,
            Databases.personal.PersonalDBContext db,
            string accountAccessToken,
            long playerId,             //playerIdの正当性は呼び出し元で保証してください
            List <GiveModel> rewards
            )
        {
            bool update = false;

            var results = new List <GiveResultModel>();

            // 獲得履歴
            var givenHistorys = new List <GivenHistory.Model>();
            // アイテム重複確認
            var alreadyOwnedItems = new List <string>();

            foreach (var reward in rewards)
            {
                ////////////////////////
                // Coins
                if (reward.model.type == Type.Coin)
                {
                    var requester = new Multiplatform.Inky.GiveFreePlatinum();
                    requester.request.amount = (int)reward.model.amount;

                    var response = await requester.PostAsync(accountAccessToken);

                    if (response.StatusCode == System.Net.HttpStatusCode.OK)
                    {
                        givenHistorys.Add(new GivenHistory.Model
                        {
                            type     = Type.Coin,
                            id       = "",
                            amount   = reward.model.amount,
                            giveType = reward.historyModel.giveType,
                            text     = reward.historyModel.text,
                        });

                        results.Add(new GiveResultModel
                        {
                            id     = reward.id,
                            result = GiveResult.Ok,
                        });
                        continue;
                    }
                    else
                    {
                        results.Add(new GiveResultModel
                        {
                            id     = reward.id,
                            result = GiveResult.Err,
                        });
                        continue;
                    }
                }

                ////////////////////////
                // Assets
                if (reward.model.type == Type.Assets)
                {
                    var assetsResult = await FirstOrDefaultAssetsAsync(masterData, db, playerId, reward.model);

                    if (assetsResult == GiveAssetsResult.Err || assetsResult == GiveAssetsResult.MaxValue)
                    {
                        results.Add(new GiveResultModel
                        {
                            id     = reward.id,
                            result = GiveResult.Err,
                        });
                        continue;
                    }

                    if (assetsResult == GiveAssetsResult.Add)
                    {
                        // サロゲートキーなテーブルにレコードaddした場合はSaveChangesAsyncする
                        await db.SaveChangesAsync();

                        // SaveChangesAsyncしたので更新フラグ解除
                        update = false;
                    }
                    else if (assetsResult == GiveAssetsResult.Update)
                    {
                        // 更新フラグを立てる
                        update = true;
                    }

                    givenHistorys.Add(new GivenHistory.Model
                    {
                        type     = Type.Assets,
                        id       = reward.model.assetsId,
                        amount   = reward.model.amount,
                        giveType = reward.historyModel.giveType,
                        text     = reward.historyModel.text,
                    });

                    results.Add(new GiveResultModel
                    {
                        id     = reward.id,
                        result = GiveResult.Ok,
                    });
                    continue;
                }

                ////////////////////////
                // Item
                if (reward.model.type == Type.Item)
                {
                    var itemInfo = masterData.GetItemFromItemId(reward.model.itemId);

                    if (itemInfo == null)
                    {
                        results.Add(new GiveResultModel
                        {
                            id     = reward.id,
                            result = GiveResult.Err,
                        });
                        continue;
                    }

                    var alreadyOwnedItem = false;

                    if (alreadyOwnedItems.Contains(reward.model.itemId))
                    {
                        alreadyOwnedItem = true;
                    }
                    else
                    {
                        alreadyOwnedItems.Add(reward.model.itemId);

                        if (masterData.CheckDefaultOwnedItem(reward.model.itemId))
                        {
                            alreadyOwnedItem = true;
                        }
                        else
                        {
                            var rec = await db.ItemInventories.FirstOrDefaultAsync(r =>
                                                                                   r.playerId == playerId && r.itemId == reward.model.itemId);

                            if (rec != null)
                            {
                                alreadyOwnedItem = true;
                            }
                        }
                    }

                    if (alreadyOwnedItem)
                    {
                        // マテリアル変換
                        var convert = ItemConversion.GiveConvertModel(masterData, reward.model.itemId);
                        if (convert.result == ItemConversion.Result.Err)
                        {
                            results.Add(new GiveResultModel
                            {
                                id     = reward.id,
                                result = GiveResult.Err,
                            });
                            continue;
                        }

                        var assetsResult = await FirstOrDefaultAssetsAsync(masterData, db, playerId, convert.model);

                        if (assetsResult == GiveAssetsResult.Err || assetsResult == GiveAssetsResult.MaxValue)
                        {
                            results.Add(new GiveResultModel
                            {
                                id     = reward.id,
                                result = GiveResult.Err,
                            });
                            continue;
                        }

                        if (assetsResult == GiveAssetsResult.Add)
                        {
                            // サロゲートキーなテーブルにレコードaddした場合はSaveChangesAsyncする
                            await db.SaveChangesAsync();

                            // SaveChangesAsyncしたので更新フラグ解除
                            update = false;
                        }
                        else if (assetsResult == GiveAssetsResult.Update)
                        {
                            // 更新フラグを立てる
                            update = true;
                        }

                        givenHistorys.Add(new GivenHistory.Model
                        {
                            type     = Type.Assets,
                            id       = convert.model.assetsId,
                            amount   = convert.model.amount,
                            giveType = reward.historyModel.giveType,
                            text     = reward.historyModel.text,
                        });

                        results.Add(new GiveResultModel
                        {
                            id     = reward.id,
                            result = GiveResult.AlreadyOwned,
                        });
                        continue;
                    }
                    else
                    {
                        // アイテム獲得
                        await db.ItemInventories.AddAsync(new Databases.personal.ItemInventory
                        {
                            playerId     = playerId,
                            itemId       = reward.model.itemId,
                            itemType     = itemInfo.itemType,
                            obtainedDate = DateTime.UtcNow,
                            obtainedWay  = Item.ObtainedWay.Game,
                            isNew        = true,
                        });

                        update = true;

                        givenHistorys.Add(new GivenHistory.Model
                        {
                            type     = Type.Item,
                            id       = reward.model.itemId,
                            amount   = 0,
                            giveType = reward.historyModel.giveType,
                            text     = reward.historyModel.text,
                        });

                        results.Add(new GiveResultModel
                        {
                            id     = reward.id,
                            result = GiveResult.Ok,
                        });
                        continue;
                    }
                }

                ////////////////////////
                // BattlePassExp
                if (reward.model.type == Type.BattlePassExp)
                {
                    // TODO
                    results.Add(new GiveResultModel
                    {
                        id     = reward.id,
                        result = GiveResult.Err,
                    });
                    continue;
                }

                ////////////////////////
                // Unknown
                results.Add(new GiveResultModel
                {
                    id     = reward.id,
                    result = GiveResult.Err,
                });
            }

            if (update)
            {
                await db.SaveChangesAsync();
            }

            ////////////////////////
            // 獲得履歴追加
            if (givenHistorys.Count > 0)
            {
                await GivenHistory.AddAsync(playerId, db, givenHistorys);
            }

            return(results);
        }