コード例 #1
0
 public static void WritePlayerBuildplateList(string playerId, PlayerBuildplateList list)
 => GenericUtils.WriteJsonFile(playerId, list, "buildplates");
コード例 #2
0
 public static bool WriteRubies(string playerId, SplitRubyResponse ruby)
 {
     return(GenericUtils.WriteJsonFile(playerId, ruby, "rubies"));
 }
コード例 #3
0
 public static PlayerBuildplateList ReadPlayerBuildplateList(string playerId)
 => GenericUtils.ParseJsonFile <PlayerBuildplateList>(playerId, "buildplates");
コード例 #4
0
 public static void WriteJournalForPlayer(string playerId, JournalResponse data)
 => GenericUtils.WriteJsonFile(playerId, data, "journal");
コード例 #5
0
 public static SplitRubyResponse ReadRubies(string playerId)
 {
     return(GenericUtils.ParseJsonFile <SplitRubyResponse>(playerId, "rubies"));
 }
コード例 #6
0
        public static CraftingUpdates ActivateBoost(string playerId, Guid boostId)
        {
            var updates = new CraftingUpdates {
                updates = new Updates()
            };

            List <DateTime> expirationTimes = new List <DateTime>();           // This looks bad (and it totally is), but we can optimize it at a later date
            var             currentTime     = DateTime.UtcNow;

            var baseBoosts   = ReadBoosts(playerId);
            var boostToApply = catalog.result.items.Find(match => match.id == boostId);


            var indexNum = 0;

            if (baseBoosts.result.scenarioBoosts.death != null)
            {
                indexNum = baseBoosts.result.scenarioBoosts.death.Count;                 // Only used if boost is scenario specific
            }
            var nextStreamId = GenericUtils.GetNextStreamVersion();

            var locOfEffect = baseBoosts.result.activeEffects.Find(match => match.effect == boostToApply.item.boostMetadata.effects[0]);             // null when not an active effect, e.g scenario boost

            ActiveBoost locOfBoost = null;


            if (baseBoosts.result.scenarioBoosts.death != null)
            {
                locOfBoost = baseBoosts.result.scenarioBoosts.death.Find(match =>
                                                                         match.effects.Any(pred => pred == boostToApply.item.boostMetadata.effects[0]));
            }

            if (locOfEffect != null && boostToApply.item.boostMetadata.additive && boostToApply.item.boostMetadata.scenario == null)
            {
                locOfEffect.effect.duration += boostToApply.item.boostMetadata.activeDuration.Value.TimeOfDay;
                baseBoosts.result.potions.Find(match => match.itemId == boostId).expiration +=
                    boostToApply.item.boostMetadata.activeDuration.Value.TimeOfDay;
            }
            else if (locOfBoost != null && boostToApply.item.boostMetadata.additive && boostToApply.item.boostMetadata.scenario == "Death")
            {
                indexNum = baseBoosts.result.scenarioBoosts.death.IndexOf(locOfBoost);
                locOfBoost.expiration += boostToApply.item.boostMetadata.activeDuration.Value.TimeOfDay;
                baseBoosts.result.potions.Find(match => match.itemId == boostId).expiration += boostToApply.item.boostMetadata.activeDuration.Value.TimeOfDay;
            }
            else
            {
                Dictionary <Guid, string> uuidDict = new Dictionary <Guid, string>();
                if (boostToApply.item.boostMetadata.scenario == null)
                {
                    foreach (Item.Effect effect in boostToApply.item.boostMetadata.effects)
                    {
                        baseBoosts.result.activeEffects.Add(new ActiveEffect {
                            effect = effect, expiration = currentTime.Add(effect.duration.Value)
                        });
                    }
                }
                else
                {
                    baseBoosts.result.scenarioBoosts.death ??= new List <ActiveBoost>();

                    baseBoosts.result.scenarioBoosts.death.Add(new ActiveBoost {
                        effects = new List <Item.Effect>(), enabled = true, expiration = currentTime.Add(boostToApply.item.boostMetadata.activeDuration.Value.TimeOfDay), instanceId = Guid.NewGuid().ToString()
                    });

                    foreach (Item.Effect effect in boostToApply.item.boostMetadata.effects)
                    {
                        baseBoosts.result.scenarioBoosts.death[indexNum].effects.Add(effect);
                    }

                    uuidDict.Add(boostId, baseBoosts.result.scenarioBoosts.death[indexNum].instanceId);
                }

                Potion potion = null;

                if (boostToApply.item.boostMetadata.activeDuration != null)
                {
                    potion = new Potion {
                        enabled = true, expiration = currentTime.Add(boostToApply.item.boostMetadata.activeDuration.Value.TimeOfDay), instanceId = Guid.NewGuid().ToString(), itemId = boostId
                    };
                }
                else if (boostToApply.item.boostMetadata.effects[0].duration != null)
                {
                    potion = new Potion {
                        enabled = true, expiration = currentTime.Add(boostToApply.item.boostMetadata.effects[0].duration.Value), instanceId = Guid.NewGuid().ToString(), itemId = boostId
                    };
                }

                if (uuidDict.ContainsKey(boostId) && potion != null)
                {
                    potion.instanceId = uuidDict[boostId];
                }

                var nullPotionIndex = baseBoosts.result.potions.FindIndex(match => match == null);
                if (nullPotionIndex != -1)
                {
                    baseBoosts.result.potions[nullPotionIndex] = potion;
                }
            }


            if (boostToApply.item.boostMetadata.canBeRemoved)
            {
                InventoryUtils.RemoveItemFromInv(playerId, boostId);                 // UNCOMMENT/COMMENT THIS LINE TO REMOVE BOOSTS FROM INVENTORY WHEN USED
                updates.updates.inventory = nextStreamId;
            }

            foreach (ActiveEffect effect in baseBoosts.result.activeEffects)
            {
                expirationTimes.Add(effect.expiration.Value);
            }

            if (baseBoosts.result.scenarioBoosts.death != null)
            {
                foreach (ActiveBoost boost in baseBoosts.result.scenarioBoosts.death)
                {
                    expirationTimes.Add(boost.expiration.Value);
                }
            }

            baseBoosts.result.expiration = expirationTimes.Min();

            baseBoosts.result.statusEffects = CalculateStatusEffects(baseBoosts);

            WriteBoosts(playerId, baseBoosts);
            updates.updates.boosts = nextStreamId;
            return(updates);
        }
コード例 #7
0
 public static JournalResponse ReadJournalForPlayer(string playerId)
 => GenericUtils.ParseJsonFile <JournalResponse>(playerId, "journal");
コード例 #8
0
        public static bool StartCraftingJob(string playerId, int slot, CraftingRequest request)         // TODO: Check if slot not unlocked (not a big priority)
        {
            recipeList ??= Recipes.FromFile("./data/recipes");

            var recipe = recipeList.result.crafting.Find(match => match.id == request.RecipeId);

            if (recipe != null)
            {
                var itemsToReturn = recipe.returnItems.ToList();

                foreach (RecipeIngredients ingredient in recipe.ingredients)
                {
                    if (itemsToReturn.Find(match =>
                                           match.id == ingredient.items[0] && match.amount == ingredient.quantity) == null)
                    {
                        InventoryUtils.RemoveItemFromInv(playerId, ingredient.items[0], ingredient.quantity * request.Multiplier);
                    }
                }

                var nextStreamId = GenericUtils.GetNextStreamVersion();

                CraftingSlotInfo job = new CraftingSlotInfo
                {
                    available          = 0,
                    boostState         = null,
                    completed          = 0,
                    escrow             = request.Ingredients,
                    nextCompletionUtc  = null,
                    output             = recipe.output,
                    recipeId           = recipe.id,
                    sessionId          = request.SessionId,
                    state              = "Active",
                    streamVersion      = nextStreamId,
                    total              = request.Multiplier,
                    totalCompletionUtc = DateTime.UtcNow.Add(recipe.duration.TimeOfDay * request.Multiplier),
                    unlockPrice        = null
                };

                if (request.Multiplier != 1)
                {
                    job.nextCompletionUtc = DateTime.UtcNow.Add(recipe.duration.TimeOfDay);
                }

                if (!craftingJobs.ContainsKey(playerId))
                {
                    craftingJobs.Add(playerId, new Dictionary <int, CraftingSlotInfo>());
                    craftingJobs[playerId].Add(1, new CraftingSlotInfo());
                    craftingJobs[playerId].Add(2, new CraftingSlotInfo());
                    craftingJobs[playerId].Add(3, new CraftingSlotInfo());
                }

                craftingJobs[playerId][slot] = job;

                UtilityBlockUtils.UpdateUtilityBlocks(playerId, slot, job);

                Log.Debug($"[{playerId}]: Initiated crafting job in slot {slot}.");

                return(true);
            }

            return(false);
        }
コード例 #9
0
 public static bool WriteBoosts(string playerId, BoostResponse resp)
 {
     return(GenericUtils.WriteJsonFile(playerId, resp, "boosts"));
 }
コード例 #10
0
 public static UtilityBlocksResponse ReadUtilityBlocks(string playerId)
 {
     return(GenericUtils.ParseJsonFile <UtilityBlocksResponse>(playerId, "utilityBlocks"));
 }
コード例 #11
0
        public static CollectItemsResponse FinishCraftingJob(string playerId, int slot)
        {
            var job           = craftingJobs[playerId][slot];
            var recipe        = recipeList.result.crafting.Find(match => match.id == job.recipeId & !match.deprecated);
            int craftedAmount = 0;

            var nextStreamId = GenericUtils.GetNextStreamVersion();

            var returnResponse = new CollectItemsResponse {
                result = new CollectItemsInfo {
                    rewards = new Rewards(),
                }, updates = new Updates()
            };

            if (job.completed != job.total && job.nextCompletionUtc != null)
            {
                if (DateTime.UtcNow >= job.nextCompletionUtc)
                {
                    craftedAmount++;
                    while (DateTime.UtcNow >= job.nextCompletionUtc && job.nextCompletionUtc.Value.Add(recipe.duration.TimeOfDay) < job.totalCompletionUtc && craftedAmount < job.total - job.completed)
                    {
                        job.nextCompletionUtc = job.nextCompletionUtc.Value.Add(recipe.duration.TimeOfDay);
                        craftedAmount++;
                    }

                    job.nextCompletionUtc = job.nextCompletionUtc.Value.Add(recipe.duration.TimeOfDay);
                    job.completed        += craftedAmount;
                    //job.available -= craftedAmount;
                    for (int i = 0; i < job.escrow.Length - 1; i++)
                    {
                        job.escrow[i].quantity -= recipe.ingredients[i].quantity * craftedAmount;
                    }

                    job.streamVersion = nextStreamId;

                    InventoryUtils.AddItemToInv(playerId, job.output.itemId, job.output.quantity * craftedAmount);
                }
            }
            else
            {
                craftedAmount = job.available;
                InventoryUtils.AddItemToInv(playerId, job.output.itemId, job.output.quantity * craftedAmount);
                // TODO: Add to challenges, tokens, journal (when implemented)
            }

            if (!TokenUtils.GetTokenResponseForUserId(playerId).Result.tokens.Any(match => match.Value.clientProperties.ContainsKey("itemid") && match.Value.clientProperties["itemid"] == job.output.itemId.ToString()))
            {
                //TokenUtils.AddItemToken(playerId, job.output.itemId); -> List of item tokens not known. Could cause issues later, for now we just disable it.
                returnResponse.updates.tokens = nextStreamId;
            }

            returnResponse.result.rewards.Inventory = returnResponse.result.rewards.Inventory.Append(new RewardComponent {
                Amount = job.output.quantity * craftedAmount, Id = job.output.itemId
            }).ToArray();

            returnResponse.updates.crafting      = nextStreamId;
            returnResponse.updates.inventory     = nextStreamId;
            returnResponse.updates.playerJournal = nextStreamId;


            if (job.completed == job.total || job.nextCompletionUtc == null)
            {
                job.nextCompletionUtc  = null;
                job.available          = 0;
                job.completed          = 0;
                job.recipeId           = null;
                job.sessionId          = null;
                job.state              = "Empty";
                job.total              = 0;
                job.boostState         = null;
                job.totalCompletionUtc = null;
                job.unlockPrice        = null;
                job.output             = null;
                job.streamVersion      = nextStreamId;
            }

            UtilityBlockUtils.UpdateUtilityBlocks(playerId, slot, job);

            Log.Debug($"[{playerId}]: Collected results of crafting slot {slot}.");

            return(returnResponse);
        }
コード例 #12
0
 public static bool WriteUtilityBlocks(string playerId, UtilityBlocksResponse obj)
 {
     return(GenericUtils.WriteJsonFile(playerId, obj, "utilityBlocks"));
 }
コード例 #13
0
 public static ProfileData ReadProfile(string playerId)
 {
     return(GenericUtils.ParseJsonFile <ProfileData>(playerId, "profile"));
 }
コード例 #14
0
 private static bool WriteProfile(string playerId, ProfileData playerProfile)
 {
     return(GenericUtils.WriteJsonFile(playerId, playerProfile, "profile"));
 }
コード例 #15
0
 private static bool WriteChallenges(string playerId, ChallengesResponse challenges)
 {
     return(GenericUtils.WriteJsonFile(playerId, challenges, "challenges"));
 }
コード例 #16
0
 private static ChallengesResponse ReadChallenges(string playerId)
 {
     return(GenericUtils.ParseJsonFile <ChallengesResponse>(playerId, "challenges"));
 }