예제 #1
0
        public async Task <IActionResult> Create(NewsPost model)
        {
            if (!ModelState.IsValid)
            {
                return(View(model));
            }

            User user = await _userManager.GetUserAsync(User);

            Group group = await _context.Groups.FindAsync(model.GroupID);

            if (group == null)
            {
                return(await RedirectBack($"Error: Could not find group {model.GroupID}"));
            }

            if (!await PressPass.HasPressPass(group, _context))
            {
                return(await RedirectBack($"Error: Group does not have a press pass!"));
            }

            if (!await group.HasPermissionAsync(user, "news"))
            {
                return(await RedirectBack($"Error: You do not have permission!"));
            }

            model.Timestamp = DateTime.UtcNow;

            await _context.NewsPosts.AddAsync(model);

            await _context.SaveChangesAsync();

            SocketUser duser = user.GetDiscordSocket();

            if (duser == null)
            {
                duser = VoopAI.discordClient.CurrentUser;
            }

            EmbedBuilder embed = new EmbedBuilder()
            {
                Color = new Color(0, 100, 255),
                Title = $"**{model.Title}** by *{user.UserName}*"
            }
            .WithAuthor(duser)
            .WithCurrentTimestamp()
            .WithUrl($"https://spookvooper.com/News/View?postid={model.PostID}");

            embed.AddField("News Outlet", group.Name);
            embed.AddField("Author", user.UserName);
            embed.AddField("Content", $"{model.Content.Substring(0, Math.Min(model.Content.Length, 1000))}" + "...");

            VoopAI.newsChannel.SendMessageAsync(embed: embed.Build());

            return(RedirectToAction("View", new { postid = model.PostID }));
        }
예제 #2
0
        public async Task Migrate()
        {
            using (NerdcraftContext nc = new NerdcraftContext(NCDBOptions))
                using (VooperContext c = new VooperContext(DBOptions))
                {
                    foreach (District d in c.Districts)
                    {
                        if (!(await c.Groups.AsQueryable().AnyAsync(x => x.Id == d.Group_Id)))
                        {
                            Group group = new Group()
                            {
                                Description    = "The district of " + d.Name,
                                District_Id    = d.Name,
                                Api_Key        = Guid.NewGuid().ToString(),
                                Group_Category = "District",
                                Open           = true,
                                Owner_Id       = d.Senator,
                                Name           = d.Name,
                                Id             = d.Group_Id
                            };

                            c.Groups.Add(group);
                            await c.SaveChangesAsync();
                        }
                    }
                }
        }
예제 #3
0
        public async void DoSalary()
        {
            using (VooperContext context = new VooperContext(DBOptions))
            {
                Console.WriteLine("Doing salary job");

                var groupRoles = context.GroupRoles;

                foreach (var rank in context.GroupRoles.AsQueryable().Where(x => x.Salary > 0m))
                {
                    Group group = await rank.GetGroup();

                    if (group == null)
                    {
                        context.GroupRoles.Remove(rank);
                        await context.SaveChangesAsync();
                    }
                    else
                    {
                        foreach (var user in await rank.GetUsers())
                        {
                            await new TransactionRequest(group.Id, user.Id, rank.Salary, $"{group.Name} salary for {rank.Name}", ApplicableTax.Payroll, false).Execute();
                        }
                    }
                }

                Console.WriteLine("Finished salary job");
            }
        }
예제 #4
0
        /// <summary>
        /// Sets the owner of this group to the specified new owner
        /// </summary>
        public async Task SetOwnerAsync(Entity newOwner)
        {
            // Change locally
            this.Owner_Id = newOwner.Id;

            using (VooperContext context = new VooperContext(VooperContext.DBOptions))
            {
                // Change in DB
                Group dummy = new Group {
                    Id = this.Id, Owner_Id = newOwner.Id
                };
                context.Groups.Attach(dummy);

                // Set to update owner field
                context.Entry(dummy).Property(x => x.Owner_Id).IsModified = true;
                await context.SaveChangesAsync();
            }

            // Set top owner to new owner
            Entity topOwner = await Entity.FindAsync(newOwner.Id);

            // Scale up to top owner
            while (topOwner is Group)
            {
                topOwner = await((Group)topOwner).GetOwner();
            }

            // By this point the top owner should be a user
            // Add that user to this group
            await AddMember((User)topOwner);
        }
예제 #5
0
 public async Task ClearRoles()
 {
     using (VooperContext context = new VooperContext(VooperContext.DBOptions))
     {
         context.GroupRoles.RemoveRange(context.GroupRoles.AsQueryable().Where(x => x.GroupId == Id));
         await context.SaveChangesAsync();
     }
 }
예제 #6
0
        public static async Task MessageReceived(SocketMessage message)
        {
            SocketUser user = message.Author;

            using (VooperContext context = new VooperContext(VoopAI.DBOptions))
            {
                User userData = context.Users.FirstOrDefault(u => u.discord_id == user.Id);

                if (userData != null && userData.Id == "u-be323eec-014a-420c-afd5-cddfe308b8c4")
                {
                    message.AddReactionAsync(yeahok);
                }

                if (!(message.Channel is SocketDMChannel))
                {
                    if (userData != null)
                    {
                        userData.discord_message_count += 1;

                        if (!message.Author.IsBot)
                        {
                            // In this case it's been a minute since the last message
                            if (DateTime.Now.Minute != userData.discord_last_message_minute)
                            {
                                // Give message XP
                                userData.discord_message_xp++;
                                userData.discord_last_message_minute = DateTime.Now.Minute;
                                userData.Discord_Last_Message_Time   = DateTime.UtcNow;
                            }
                        }

                        await context.SaveChangesAsync();
                    }
                }
            }



            if (message.Channel.Id == VoopAI.botChannel.Id)
            {
                //VoopAI.logger.LogInformation("Recieved message in Bot channel.");
                await OnMessageBotChannel(message);
            }
            else if (message.Channel.GetType() == typeof(SocketDMChannel))
            {
                //VoopAI.logger.LogInformation("Recieved message in DM.");
                await OnMessageDM(message);
            }

            await OnMessageChannel(message);

            await ChatFilter.FilterMessage(message);
        }
예제 #7
0
        public async Task <IActionResult> DeleteRole(string roleid)
        {
            GroupRole role = _context.GroupRoles.FirstOrDefault(r => r.RoleId.ToLower() == roleid.ToLower());

            if (role == null)
            {
                StatusMessage = "Error: The Role was null!";
                return(Redirect(Request.Headers["Referer"].ToString()));
            }

            Group group = _context.Groups.FirstOrDefault(g => g.Id == role.GroupId);

            if (group == null)
            {
                StatusMessage = "Error: The Role's Group was null!";
                return(Redirect(Request.Headers["Referer"].ToString()));
            }

            User user = await _userManager.GetUserAsync(User);

            if (!await group.HasPermissionAsync(user, "createrole"))
            {
                StatusMessage = "Error: You don't have permission!";
                return(Redirect(Request.Headers["Referer"].ToString()));
            }

            _context.GroupRoles.Remove(role);
            await _context.SaveChangesAsync();

            StatusMessage = $"Successfully deleted the role {role.Name}!";
            return(Redirect(Request.Headers["Referer"].ToString()));
        }
예제 #8
0
        public async Task <IActionResult> EditDistrict(District model)
        {
            if (!ModelState.IsValid)
            {
                return(View(model));
            }

            District old = await _context.Districts.AsNoTracking().AsQueryable().FirstOrDefaultAsync(x => x.Name == model.Name);

            User user = await _userManager.GetUserAsync(User);

            if (user.Id != old.Senator)
            {
                StatusMessage = "Failed: You do not have permission to edit this district!";
                return(View());
            }

            if (!(await _context.Districts.AsQueryable().AnyAsync(d => d.Name.ToLower() == model.Name.ToLower())))
            {
                _context.Districts.Add(model);
            }
            else
            {
                // Ensure senator is not changed
                model.Senator = old.Senator;

                _context.Districts.Update(model);
            }

            await _context.SaveChangesAsync();

            return(RedirectToAction("ViewDistrict", new { id = model.Name }));
        }
예제 #9
0
        public async Task RemoveMember(User user)
        {
            using (VooperContext context = new VooperContext(VooperContext.DBOptions))
            {
                GroupMember member = await context.GroupMembers.AsQueryable().FirstOrDefaultAsync(x => x.Group_Id == Id && x.User_Id == user.Id);

                if (member != null)
                {
                    context.GroupMembers.Remove(member);
                    await context.SaveChangesAsync();
                }
            }
        }
예제 #10
0
        public static async Task CommandDM(SocketMessage message, string[] args)
        {
            string rootCmd = args[0].ToLower();

            //VoopAI.logger.LogInformation(rootCmd);

            if (rootCmd == "connectsite")
            {
                if (args.Length < 2)
                {
                    await message.Channel.SendMessageAsync("Please include your key!");

                    return;
                }

                int key = -1;

                bool success = int.TryParse(args[1], out key);

                if (success)
                {
                    using (VooperContext context = new VooperContext(VoopAI.DBOptions))
                    {
                        var user = context.Users.FirstOrDefault(u => u.Id == VoopAI.service._connectionHandler.GetUserFromKey(key));
                        VoopAI.logger.LogInformation("0");

                        if (user != null)
                        {
                            user.discord_id = message.Author.Id;

                            await context.SaveChangesAsync();

                            VoopAI.service._connectionHandler.RemoveKey(key);

                            await message.Author.SendMessageAsync($"Successfully linked to {user.UserName}!");
                        }
                        else
                        {
                            await message.Author.SendMessageAsync("Failed to verify this key.");

                            return;
                        }
                    }
                }
                else
                {
                    await message.Author.SendMessageAsync($"Unable to read your key.");
                }
            }
        }
예제 #11
0
        public async static Task <TaskResult> AddToRole(Group group, User user, User target, GroupRole role)
        {
            using (VooperContext context = new VooperContext(VooperContext.DBOptions))
            {
                // Validate arguments
                TaskResult validate = await TargetedCommandValidate(group, user, target, "addrole");

                if (!validate.Succeeded)
                {
                    return(validate);
                }

                // Authority check
                if (role.Weight > await group.GetAuthority(user))
                {
                    return(new TaskResult(false, $"{role.Name} has more authority than you!"));
                }

                if (role == null)
                {
                    return(new TaskResult(false, "Error: The role value was empty."));
                }

                if (await context.GroupRoleMembers.AnyAsync(x => x.Role_Id == role.RoleId && x.User_Id == target.Id))
                {
                    return(new TaskResult(false, "Error: The user already has this role."));
                }

                if (role.GroupId != group.Id)
                {
                    return(new TaskResult(false, "Error: The role does not belong to this group!"));
                }

                // Add pipe-delimited group name
                GroupRoleMember member = new GroupRoleMember()
                {
                    Id       = Guid.NewGuid().ToString(),
                    Role_Id  = role.RoleId,
                    Group_Id = role.GroupId,
                    User_Id  = target.Id
                };

                await context.GroupRoleMembers.AddAsync(member);

                await context.SaveChangesAsync();

                return(new TaskResult(true, $"Successfully added {target.UserName} to {role.Name}"));
            }
        }
예제 #12
0
        public async static Task <TaskResult> AddInvite(Group group, User user, User target)
        {
            // Validate arguments
            TaskResult validate = await TargetedCommandValidate(group, user, target, "addinvite");

            if (!validate.Succeeded)
            {
                return(validate);
            }

            using (VooperContext context = new VooperContext(VooperContext.DBOptions))
            {
                if (await context.GroupInvites.AnyAsync(x => x.User_Id == target.Id && x.Group_Id == group.Id))
                {
                    return(new TaskResult(false, $"Error: That user is already invited!"));
                }

                GroupInvite invite = new GroupInvite()
                {
                    Id       = Guid.NewGuid().ToString(),
                    Group_Id = group.Id,
                    User_Id  = target.Id
                };

                await context.GroupInvites.AddAsync(invite);

                // Send a notification
                Notification notification = new Notification()
                {
                    NotificationID = Guid.NewGuid().ToString(),
                    Author         = user.Id,
                    Content        = $"Click above to see and join the group!",
                    Source         = 0,
                    Linkback       = $"https://spookvooper.com/Group/View?groupid={group.Id}",
                    Target         = target.Id,
                    TimeSent       = DateTime.UtcNow,
                    Title          = $"You were invited to {group.Name}!",
                    Type           = "Group Invite"
                };

                await context.Notifications.AddAsync(notification);

                await context.SaveChangesAsync();

                return(new TaskResult(true, $"Invited {target.UserName} to {group.Name}."));
            }
        }
예제 #13
0
        public static async Task EndGame(bool success)
        {
            int coinxp = 0;

            if (success)
            {
                coinxp = 2 * player.coins;
            }

            int fullxp = coinxp + player.xp;

            await gameChannel.SendMessageAsync((string)($"Your journey is complete, {player.name}. You earned {player.xp} normal xp, " +
                                                        $"during this game!"));

            if (success)
            {
                await gameChannel.SendMessageAsync($"Ultimately, you succeeded in your goal, and managed to {goal.GetObjective()} " +
                                                   $"! You managed to collect {player.coins} coins which " +
                                                   $"remained unused and has been converted into {coinxp} xp! You will not be forgotten. Because of this, you have earned DOUBLE XP!");

                fullxp *= 2;
            }
            else
            {
                await gameChannel.SendMessageAsync($"Ultimately, you have failed to {goal.GetObjective()}. The people of {location.name} " +
                                                   $"are dead, or worse. You will be forgotten. Because of this, you have earned HALF XP!");

                fullxp /= 2;
            }

            using (VooperContext context = new VooperContext(VoopAI.DBOptions))
            {
                foreach (SocketUser data in currentPlayers)
                {
                    User user = context.Users.FirstOrDefault(u => u.discord_id == data.Id);

                    if (user != null)
                    {
                        user.discord_game_xp += fullxp;
                        await context.SaveChangesAsync();
                    }
                }
            }

            game_running = false;
        }
예제 #14
0
        public async Task SetOwnerAsync(Entity newOwner)
        {
            // Set locally
            Owner_Id = newOwner.Id;

            using (VooperContext context = new VooperContext(VooperContext.DBOptions))
            {
                // Set in DB
                StockObject dummy = new StockObject {
                    Id = this.Id, Owner_Id = Owner_Id
                };
                context.Attach(dummy);
                context.Entry(dummy).Property(x => x.Owner_Id).IsModified = true;

                await context.SaveChangesAsync();
            }
        }
예제 #15
0
        public async static Task <TaskResult> KickFromGroup(Group group, User user, User target)
        {
            // Validate arguments
            TaskResult validate = await TargetedCommandValidate(group, user, target, "kick");

            if (!validate.Succeeded)
            {
                return(validate);
            }

            // Authority check
            if (await group.GetAuthority(target) > await group.GetAuthority(user))
            {
                return(new TaskResult(false, $"{target.UserName} has more authority than you!"));
            }

            // Remove user from group
            TaskResult remove = await RemoveFromGroup(target, group);

            if (!remove.Succeeded)
            {
                return(remove);
            }

            // Send a notification
            Notification notification = new Notification()
            {
                NotificationID = Guid.NewGuid().ToString(),
                Author         = user.Id,
                Content        = $"You have been kicked from this group.",
                Source         = 0,
                Linkback       = $"https://spookvooper.com/Group/View?groupid={group.Id}",
                Target         = target.Id,
                TimeSent       = DateTime.UtcNow,
                Title          = $"{group.Name} kicked you!",
                Type           = "Group Kick"
            };

            using (VooperContext context = new VooperContext(VooperContext.DBOptions))
            {
                context.Notifications.Add(notification);
                await context.SaveChangesAsync();
            }

            return(new TaskResult(true, $"Successfully kicked {target.UserName}!"));
        }
예제 #16
0
        public async static Task <TaskResult> RemoveFromRole(Group group, User user, User target, GroupRole role)
        {
            using (VooperContext context = new VooperContext(VooperContext.DBOptions))
            {
                // Validate arguments
                TaskResult validate = await TargetedCommandValidate(group, user, target, "removerole");

                if (!validate.Succeeded)
                {
                    return(validate);
                }

                // Authority check
                if (await group.GetAuthority(target) > await group.GetAuthority(user))
                {
                    return(new TaskResult(false, $"{target.UserName} has more authority than you!"));
                }

                if (role == null)
                {
                    return(new TaskResult(false, "Error: The role value was empty."));
                }

                if (group.Id != role.GroupId)
                {
                    return(new TaskResult(false, "Error: The role does not belong to this group!"));
                }

                GroupRoleMember member = await context.GroupRoleMembers.FirstOrDefaultAsync(x => x.Role_Id == role.RoleId && x.User_Id == target.Id);

                if (member != null)
                {
                    context.GroupRoleMembers.Remove(member);
                    await context.SaveChangesAsync();

                    return(new TaskResult(true, $"Successfully removed from {role.Name}"));
                }
                else
                {
                    return(new TaskResult(true, $"Error: That user did not have the role {role.Name}"));
                }
            }
        }
예제 #17
0
        public async static Task <TaskResult> RemoveInvite(Group group, User user, User target)
        {
            // Validate arguments
            TaskResult validate = await TargetedCommandValidate(group, user, target, "invite");

            if (!validate.Succeeded)
            {
                return(validate);
            }

            using (VooperContext context = new VooperContext(VooperContext.DBOptions))
            {
                GroupInvite invite = await context.GroupInvites.FirstOrDefaultAsync(x => x.Group_Id == group.Id && x.User_Id == target.Id);

                if (invite == null)
                {
                    return(new TaskResult(false, $"Error: User hasn't been invited!"));
                }

                context.GroupInvites.Remove(invite);

                // Send a notification
                Notification notification = new Notification()
                {
                    NotificationID = Guid.NewGuid().ToString(),
                    Author         = user.Id,
                    Content        = $"You can no longer join this group.",
                    Source         = 0,
                    Linkback       = $"https://spookvooper.com/Group/View?groupid={group.Id}",
                    Target         = target.Id,
                    TimeSent       = DateTime.UtcNow,
                    Title          = $"{group.Name} has removed your invite!",
                    Type           = "Group Uninvite"
                };

                context.Notifications.Add(notification);
                await context.SaveChangesAsync();

                return(new TaskResult(true, $"{user.UserName} has been uninvited!"));
            }
        }
예제 #18
0
        public async Task AddMember(User user)
        {
            using (VooperContext context = new VooperContext(VooperContext.DBOptions))
            {
                // Cancel if the member is already there
                if (context.GroupMembers.Any(x => x.Group_Id == Id && x.User_Id == user.Id))
                {
                    return;
                }

                GroupMember member = new GroupMember()
                {
                    Id       = Guid.NewGuid().ToString(),
                    Group_Id = Id,
                    User_Id  = user.Id
                };

                await context.GroupMembers.AddAsync(member);

                await context.SaveChangesAsync();
            }
        }
예제 #19
0
        public static async Task AddStock(string ticker, int amount, string svid, VooperContext context)
        {
            StockObject stock = await context.StockObjects.AsQueryable().FirstOrDefaultAsync(s => s.Owner_Id == svid && s.Ticker == ticker);

            if (stock != null)
            {
                stock.Amount += amount;
                context.StockObjects.Update(stock);
            }
            else
            {
                stock = new StockObject()
                {
                    Amount   = amount,
                    Ticker   = ticker,
                    Id       = Guid.NewGuid().ToString(),
                    Owner_Id = svid
                };

                await context.StockObjects.AddAsync(stock);
            }

            await context.SaveChangesAsync();
        }
예제 #20
0
        public static async Task CmdBan(SocketMessage msg)
        {
            if (!((IGuildUser)msg.Author).GetPermissions((IGuildChannel)msg.Channel).ManageRoles)
            {
                await SendMessage((SocketTextChannel)msg.Channel, "You are not an administrator.");

                return;
            }

            if (msg.MentionedUsers.Count < 1)
            {
                await SendMessage((SocketTextChannel)msg.Channel, "Please specify a user!");

                return;
            }

            SocketUser target = msg.MentionedUsers.First();

            using (VooperContext context = new VooperContext(VoopAI.DBOptions))
            {
                User userData = context.Users.FirstOrDefault(u => u.discord_id == target.Id);

                if (userData != null)
                {
                    userData.discord_ban_count += 1;
                    await context.SaveChangesAsync();
                }
            }

            SocketGuildChannel channel = msg.Channel as SocketGuildChannel;

            if (channel != null)
            {
                await channel.Guild.AddBanAsync(target);
            }
        }
예제 #21
0
        public static async Task RemoveCommend(IUser target, IUser giver, ulong messageID)
        {
            using (VooperContext context = new VooperContext(VoopAI.DBOptions))
            {
                User giverData = context.Users.FirstOrDefault(u => u.discord_id == giver.Id);
                User user      = context.Users.FirstOrDefault(u => u.discord_id == target.Id);

                if (giverData != null && giverData.discord_last_commend_message == messageID)
                {
                    Console.WriteLine(giver.Username + " un-commended " + target.Username);

                    if (user != null)
                    {
                        user.discord_commends--;
                    }

                    giverData.discord_commends_sent--;
                    giverData.discord_last_commend_hour    = DateTime.Now.Hour;
                    giverData.discord_last_commend_message = 0;

                    await context.SaveChangesAsync();
                }
            }
        }
예제 #22
0
        public static async Task RunTrades()
        {
#if DEBUG
            // Prevent local testing from running the stock exchange
            return;
#endif
            using (VooperContext context = new VooperContext(VooperContext.DBOptions))
            {
                foreach (StockDefinition def in context.StockDefinitions)
                {
                    StockOffer sell = await GetLowestSellOffer(def.Ticker, context);

                    StockOffer buy = await GetHighestBuyOffer(def.Ticker, context);

                    // If buy > sell, trade occurs
                    if (buy != null &&
                        sell != null &&
                        buy.Target >= sell.Target)
                    {
                        GovControls gov = await context.GovControls.AsQueryable().FirstAsync();

                        int remainder = buy.Amount - sell.Amount;

                        decimal beforePrice = def.Current_Value;

                        decimal tradePrice = buy.Target;

                        int tradeAmount = Math.Min(buy.Amount, sell.Amount);

                        string buyer  = buy.Owner_Id;
                        string seller = sell.Owner_Id;

                        string buyId  = buy.Id;
                        string sellId = sell.Id;

                        // If remainder is 0, they cancel out perfectly
                        // If remainder > 0, the buy order is not finished and sell is deleted
                        // If remainder < 0, the sell order is not finished and the buy is deleted
                        if (remainder == 0)
                        {
                            context.StockOffers.Remove(sell);
                            context.StockOffers.Remove(buy);
                        }
                        else if (remainder > 0)
                        {
                            context.StockOffers.Remove(sell);
                            buy.Amount = buy.Amount - sell.Amount;
                            context.StockOffers.Update(buy);
                        }
                        else
                        {
                            context.StockOffers.Remove(buy);
                            sell.Amount = sell.Amount - buy.Amount;
                            context.StockOffers.Update(sell);
                        }

                        // Volume stuff
                        if (VolumesMinute.ContainsKey(def.Ticker))
                        {
                            VolumesMinute[def.Ticker] += tradeAmount;
                            VolumesHour[def.Ticker]   += tradeAmount;
                            VolumesDay[def.Ticker]    += tradeAmount;
                        }
                        else
                        {
                            VolumesMinute.Add(def.Ticker, tradeAmount);
                            VolumesHour.Add(def.Ticker, tradeAmount);
                            VolumesDay.Add(def.Ticker, tradeAmount);
                        }
                        // End volume stuff

                        decimal totalTrade = tradeAmount * tradePrice;
                        decimal tax        = totalTrade * (gov.CapitalGainsTaxRate / 100);

                        await new TransactionRequest(EconomyManager.VooperiaID, sell.Owner_Id, totalTrade - tax, $"Stock sale: {tradeAmount} {def.Ticker}@¢{tradePrice.Round()}", ApplicableTax.None, true).Execute();
                        gov.CapitalGainsTaxRevenue += tax;
                        gov.UBIAccount             += (tax * (gov.UBIBudgetPercent / 100.0m));

                        context.GovControls.Update(gov);

                        await context.SaveChangesAsync();

                        await AddStock(def.Ticker, tradeAmount, buyer, context);

                        Console.WriteLine($"Processed Stock sale: {tradeAmount} {def.Ticker}@¢{tradePrice.Round()}");

                        decimal trueValue = 0.0m;

                        StockOffer nextBuy = await GetHighestBuyOffer(def.Ticker, context);

                        StockOffer nextSell = await GetLowestSellOffer(def.Ticker, context);

                        if (nextBuy == null && nextSell == null)
                        {
                            trueValue = tradePrice;
                        }
                        else if (nextBuy == null)
                        {
                            trueValue = nextSell.Target;
                        }
                        else if (nextSell == null)
                        {
                            trueValue = nextBuy.Target;
                        }
                        else
                        {
                            trueValue = (nextBuy.Target + nextSell.Target) / 2;
                        }

                        StockTradeModel noti = new StockTradeModel()
                        {
                            Ticker     = def.Ticker,
                            Amount     = tradeAmount,
                            Price      = tradePrice,
                            True_Price = trueValue,
                            From       = sell.Owner_Id,
                            To         = buy.Owner_Id,
                            Buy_Id     = buyId,
                            Sell_Id    = sellId
                        };

                        def.Current_Value = noti.True_Price;
                        context.StockDefinitions.Update(def);

                        Entity sellAccount = await Entity.FindAsync(seller);

                        sellAccount.Credits_Invested -= totalTrade;
                        if (sellAccount is User)
                        {
                            context.Users.Update((User)sellAccount);
                        }
                        else if (sellAccount is Group)
                        {
                            context.Groups.Update((Group)sellAccount);
                        }


                        Entity buyAccount = await Entity.FindAsync(buyer);

                        buyAccount.Credits_Invested += totalTrade;
                        if (buyAccount is User)
                        {
                            context.Users.Update((User)buyAccount);
                        }
                        else if (buyAccount is Group)
                        {
                            context.Groups.Update((Group)buyAccount);
                        }

                        await context.SaveChangesAsync();

                        await ExchangeHub.Current.Clients.All.SendAsync("StockTrade", JsonConvert.SerializeObject(noti));

                        if (trueValue < beforePrice)
                        {
                            VoopAI.ecoChannel.SendMessageAsync($":chart_with_downwards_trend: ({def.Ticker}) Trade: {tradeAmount}@{buy.Target}, price drop to ¢{trueValue.Round()}");
                        }
                        else if (trueValue > beforePrice)
                        {
                            VoopAI.ecoChannel.SendMessageAsync($":chart_with_upwards_trend: ({def.Ticker}) Trade: {tradeAmount}@{buy.Target}, price increase to ¢{trueValue.Round()}");
                        }
                    }

                    // Otherwise move on to the next stock
                }
            }
        }
예제 #23
0
        private static async Task <TaskResult> DoTransaction(TransactionRequest request, VooperContext context)
        {
            if (!request.Force && request.Amount < 0)
            {
                return(new TaskResult(false, "Transaction must be positive."));
            }

            if (request.Amount == 0)
            {
                return(new TaskResult(false, "Transaction must have a value."));
            }

            if (request.FromAccount == request.ToAccount)
            {
                return(new TaskResult(false, $"An entity cannot send credits to itself."));
            }

            Entity fromUser = await Entity.FindAsync(request.FromAccount);

            Entity toUser = await Entity.FindAsync(request.ToAccount);

            if (fromUser == null)
            {
                return(new TaskResult(false, $"Failed to find sender {request.FromAccount}."));
            }
            if (toUser == null)
            {
                return(new TaskResult(false, $"Failed to find reciever {request.ToAccount}."));
            }

            if (!request.Force && fromUser.Credits < request.Amount)
            {
                return(new TaskResult(false, $"{fromUser.Name} cannot afford to send ¢{request.Amount}"));
            }

            GovControls govControls = await GovControls.GetCurrentAsync(context);

            Transaction trans = new Transaction()
            {
                ID       = Guid.NewGuid().ToString(),
                Credits  = request.Amount,
                FromUser = request.FromAccount,
                ToUser   = request.ToAccount,
                Details  = request.Detail,
                Time     = DateTime.Now
            };

            await context.Transactions.AddAsync(trans);

            fromUser.Credits -= request.Amount;
            toUser.Credits   += request.Amount;

            context.Update(fromUser);
            context.Update(toUser);

            await context.SaveChangesAsync();

            if (toUser.Id != VooperiaID)
            {
                if (request.Tax == ApplicableTax.None && toUser is Group && ((Group)toUser).Group_Category == Group.GroupTypes.Company)
                {
                    request.Tax = ApplicableTax.Corporate;
                }

                if (request.Tax == ApplicableTax.Payroll)
                {
                    decimal ntax = request.Amount * (govControls.PayrollTaxRate / 100.0m);

                    govControls.UBIAccount += ntax * (govControls.UBIBudgetPercent / 100.0m);

                    govControls.PayrollTaxRevenue += ntax;

                    RequestTransaction(new TransactionRequest(toUser.Id, VooperiaID, ntax, "Payroll Tax", ApplicableTax.None, true));
                }
                else if (request.Tax == ApplicableTax.Sales)
                {
                    decimal ntax = request.Amount * (govControls.SalesTaxRate / 100.0m);

                    govControls.UBIAccount += ntax * (govControls.UBIBudgetPercent / 100.0m);

                    govControls.SalesTaxRevenue += ntax;

                    RequestTransaction(new TransactionRequest(fromUser.Id, VooperiaID, ntax, "Sales Tax", ApplicableTax.None, true));
                }
                else if (request.Tax == ApplicableTax.Corporate)
                {
                    decimal ntax = request.Amount * (govControls.CorporateTaxRate / 100.0m);

                    govControls.UBIAccount += ntax * (govControls.UBIBudgetPercent / 100.0m);

                    govControls.CorporateTaxRevenue += ntax;

                    RequestTransaction(new TransactionRequest(toUser.Id, VooperiaID, ntax, "Corporate Tax", ApplicableTax.None, true));
                }
                else if (request.Tax == ApplicableTax.CapitalGains)
                {
                    decimal ntax = request.Amount * (govControls.CapitalGainsTaxRate / 100.0m);

                    govControls.UBIAccount += ntax * (govControls.UBIBudgetPercent / 100.0m);

                    govControls.CapitalGainsTaxRevenue += ntax;

                    RequestTransaction(new TransactionRequest(fromUser.Id, VooperiaID, ntax, "Capital Gains Tax", ApplicableTax.None, true));
                }
            }
            else
            {
                if (!request.Detail.Contains("Tax") && !request.Detail.Contains("Stock purchase"))
                {
                    govControls.SalesRevenue += request.Amount;
                    govControls.UBIAccount   += (request.Amount * (govControls.UBIBudgetPercent / 100.0m));
                }
            }

            context.GovControls.Update(govControls);
            await context.SaveChangesAsync();

            return(new TaskResult(true, $"Successfully sent ¢{request.Amount} to {toUser.Name}."));
        }
예제 #24
0
        public async void UpdateRanks()
        {
            Console.WriteLine("Doing rank job");

            using (VooperContext context = new VooperContext(DBOptions))
            {
                Group government = context.Groups.AsQueryable().FirstOrDefault(x => x.Name == "Vooperia");

                if (government == null)
                {
                    Console.WriteLine("Holy f**k something is wrong.");
                }

                leaderboard = context.Users.AsEnumerable().Where(u => u.Email != u.UserName).OrderByDescending(u => u.GetTotalXP()).ToList();

                List <SocketGuildUser> userList = new List <SocketGuildUser>();

                // Add connected users
                foreach (User userData in leaderboard)
                {
                    SocketGuildUser user = null;

                    if (userData.discord_id != null)
                    {
                        //user = server.Users.FirstOrDefault(x => x.Id == (ulong)userData.discord_id);
                        user = server.GetUser((ulong)userData.discord_id);
                    }

                    if (user != null)
                    {
                        // Clear roles if muted
                        if (userData.GetDiscordRoles().Any(r => r.Name == "Muted"))
                        {
                            if (user.Roles.Contains(spleenRole))
                            {
                                await user.RemoveRoleAsync(spleenRole);
                            }
                            if (user.Roles.Contains(crabRole))
                            {
                                await user.RemoveRoleAsync(crabRole);
                            }
                            if (user.Roles.Contains(gatyRole))
                            {
                                await user.RemoveRoleAsync(gatyRole);
                            }
                            if (user.Roles.Contains(corgiRole))
                            {
                                await user.RemoveRoleAsync(corgiRole);
                            }
                            if (user.Roles.Contains(oofRole))
                            {
                                await user.RemoveRoleAsync(oofRole);
                            }
                        }
                        else
                        {
                            userList.Add(user);
                        }
                    }
                }

                int counter = 0;

                int totalUsers = userList.Count;


                GovControls govControls = await GovControls.GetCurrentAsync(context);

                decimal UBITotal = govControls.UBIAccount;
                govControls.UBIAccount = 0;

                context.GovControls.Update(govControls);
                await context.SaveChangesAsync();


                int spleenUserCount = totalUsers / 100;
                int crabUserCount   = (totalUsers / 20) - spleenUserCount;
                int gatyUserCount   = (totalUsers / 10) - spleenUserCount - crabUserCount;
                int corgiUserCount  = (totalUsers / 4) - spleenUserCount - crabUserCount - gatyUserCount;
                int oofUserCount    = (totalUsers / 2) - spleenUserCount - crabUserCount - gatyUserCount - corgiUserCount;

                int unrankedCount = totalUsers - spleenUserCount - crabUserCount - gatyUserCount - corgiUserCount - oofUserCount;

                decimal spleenPay   = 0.0m;
                decimal crabPay     = 0.0m;
                decimal gatyPay     = 0.0m;
                decimal corgiPay    = 0.0m;
                decimal oofPay      = 0.0m;
                decimal unrankedPay = 0.0m;

                if (spleenUserCount > 0)
                {
                    spleenPay = (UBITotal * (govControls.SpleenPayPercent / 100.0m)) / spleenUserCount;
                }
                if (crabUserCount > 0)
                {
                    crabPay = (UBITotal * (govControls.CrabPayPercent / 100.0m)) / crabUserCount;
                }
                if (gatyUserCount > 0)
                {
                    gatyPay = (UBITotal * (govControls.GatyPayPercent / 100.0m)) / gatyUserCount;
                }
                if (corgiUserCount > 0)
                {
                    corgiPay = (UBITotal * (govControls.CorgiPayPercent / 100.0m)) / corgiUserCount;
                }
                if (oofUserCount > 0)
                {
                    oofPay = (UBITotal * (govControls.OofPayPercent / 100.0m)) / oofUserCount;
                }
                if (unrankedCount > 0)
                {
                    unrankedPay = (UBITotal * (govControls.UnrankedPayPercent / 100.0m)) / unrankedCount;
                }

                foreach (SocketGuildUser discordUser in userList)
                {
                    User webUser = context.Users.FirstOrDefault(u => u.discord_id == discordUser.Id);

                    // Update pfp in storage
                    webUser.Image_Url = webUser.GetPfpUrl();
                    context.Update(webUser);
                    await context.SaveChangesAsync();

                    bool hasSpleen = discordUser.Roles.Contains(spleenRole);
                    bool hasCrab   = discordUser.Roles.Contains(crabRole);
                    bool hasGaty   = discordUser.Roles.Contains(gatyRole);
                    bool hasCorgi  = discordUser.Roles.Contains(corgiRole);
                    bool hasOof    = discordUser.Roles.Contains(oofRole);

                    bool hasCitizen  = discordUser.Roles.Contains(patreonCitizen) || discordUser.Roles.Contains(youtubeCitizen);
                    bool hasSoldier  = discordUser.Roles.Contains(patreonSoldier);
                    bool hasLoyalist = discordUser.Roles.Contains(patreonLoyalist);
                    bool hasHero     = discordUser.Roles.Contains(patreonHero);
                    bool hasMadlad   = discordUser.Roles.Contains(patreonMadlad);

                    bool patron = hasCitizen || hasSoldier || hasLoyalist || hasHero || hasMadlad;

                    // Inactivity tax
                    if (Math.Abs(webUser.Discord_Last_Message_Time.Subtract(DateTime.UtcNow).TotalDays) > 14 && !patron)
                    {
                        decimal tax = webUser.Credits * (govControls.InactivityTaxRate / 100.0M);

                        TransactionRequest req = new TransactionRequest(webUser.Id, EconomyManager.VooperiaID, tax, "Inactivity Tax", ApplicableTax.None, true);

                        TaskResult result = await req.Execute();

                        if (result.Succeeded)
                        {
                            govControls.InactivityTaxRevenue += tax;

                            // Add to UBI
                            govControls.UBIAccount += tax * (govControls.UBIBudgetPercent / 100.0M);

                            context.GovControls.Update(govControls);

                            await context.SaveChangesAsync();
                        }

                        // Remove last role
                        if (hasSpleen)
                        {
                            await discordUser.RemoveRoleAsync(spleenRole);
                        }
                        if (hasCrab)
                        {
                            await discordUser.RemoveRoleAsync(crabRole);
                        }
                        if (hasGaty)
                        {
                            await discordUser.RemoveRoleAsync(gatyRole);
                        }
                        if (hasCorgi)
                        {
                            await discordUser.RemoveRoleAsync(corgiRole);
                        }
                        if (hasOof)
                        {
                            await discordUser.RemoveRoleAsync(oofRole);
                        }

                        continue;
                    }

                    // Set district
                    if (!String.IsNullOrWhiteSpace(webUser.district))
                    {
                        var oldDistrictRoles = discordUser.Roles.Where(x => x.Name.Contains("District") && !x.Name.Contains(webUser.district));

                        if (oldDistrictRoles.Count() > 0)
                        {
                            await discordUser.RemoveRolesAsync(oldDistrictRoles);
                        }

                        if (!discordUser.Roles.Any(x => x.Name == webUser.district + " District"))
                        {
                            await discordUser.AddRoleAsync(districtRoles[webUser.district + " District"]);
                        }
                    }

                    // Spleen rank
                    if (counter <= spleenUserCount)
                    {
                        // Add new role
                        if (!hasSpleen)
                        {
                            await discordUser.AddRoleAsync(spleenRole);
                        }

                        // Remove last role
                        if (hasCrab)
                        {
                            await discordUser.RemoveRoleAsync(crabRole);
                        }
                        if (hasGaty)
                        {
                            await discordUser.RemoveRoleAsync(gatyRole);
                        }
                        if (hasCorgi)
                        {
                            await discordUser.RemoveRoleAsync(corgiRole);
                        }
                        if (hasOof)
                        {
                            await discordUser.RemoveRoleAsync(oofRole);
                        }

                        if (webUser != null)
                        {
                            //TransactionRequest transaction = new TransactionRequest(webUser.economy_id, government.economy_id, 238827, "UBI Mistake Fix", ApplicableTax.None, true);
                            TransactionRequest transaction = new TransactionRequest(government.Id, webUser.Id, spleenPay, "UBI Payment", ApplicableTax.None, true);
                            EconomyManager.RequestTransaction(transaction);
                        }
                    }
                    // Crab rank
                    else if (counter <= spleenUserCount + crabUserCount)
                    {
                        // Add new role
                        if (!hasCrab)
                        {
                            await discordUser.AddRoleAsync(crabRole);
                        }

                        // Remove last role
                        if (hasSpleen)
                        {
                            await discordUser.RemoveRoleAsync(spleenRole);
                        }
                        if (hasGaty)
                        {
                            await discordUser.RemoveRoleAsync(gatyRole);
                        }
                        if (hasCorgi)
                        {
                            await discordUser.RemoveRoleAsync(corgiRole);
                        }
                        if (hasOof)
                        {
                            await discordUser.RemoveRoleAsync(oofRole);
                        }

                        if (webUser != null)
                        {
                            //TransactionRequest transaction = new TransactionRequest(webUser.economy_id, government.economy_id, 146267, "UBI Mistake Fix", ApplicableTax.None, true);
                            TransactionRequest transaction = new TransactionRequest(government.Id, webUser.Id, crabPay, "UBI Payment", ApplicableTax.None, true);
                            EconomyManager.RequestTransaction(transaction);
                        }
                    }
                    // Gaty rank
                    else if (counter <= spleenUserCount + crabUserCount + gatyUserCount)
                    {
                        // Add new role
                        if (!hasGaty)
                        {
                            await discordUser.AddRoleAsync(gatyRole);
                        }

                        // Remove last role
                        if (hasSpleen)
                        {
                            await discordUser.RemoveRoleAsync(spleenRole);
                        }
                        if (hasCrab)
                        {
                            await discordUser.RemoveRoleAsync(crabRole);
                        }
                        if (hasCorgi)
                        {
                            await discordUser.RemoveRoleAsync(corgiRole);
                        }
                        if (hasOof)
                        {
                            await discordUser.RemoveRoleAsync(oofRole);
                        }

                        if (webUser != null)
                        {
                            //TransactionRequest transaction = new TransactionRequest(webUser.economy_id, government.economy_id, 125698, "UBI Mistake Fix", ApplicableTax.None, true);
                            TransactionRequest transaction = new TransactionRequest(government.Id, webUser.Id, gatyPay, "UBI Payment", ApplicableTax.None, true);
                            EconomyManager.RequestTransaction(transaction);
                        }
                    }
                    // Corgi rank
                    else if (counter <= spleenUserCount + crabUserCount + gatyUserCount + corgiUserCount)
                    {
                        // Add new role
                        if (!hasCorgi)
                        {
                            await discordUser.AddRoleAsync(corgiRole);
                        }

                        // Remove last role
                        if (hasSpleen)
                        {
                            await discordUser.RemoveRoleAsync(spleenRole);
                        }
                        if (hasCrab)
                        {
                            await discordUser.RemoveRoleAsync(crabRole);
                        }
                        if (hasGaty)
                        {
                            await discordUser.RemoveRoleAsync(gatyRole);
                        }
                        if (hasOof)
                        {
                            await discordUser.RemoveRoleAsync(oofRole);
                        }

                        if (webUser != null)
                        {
                            //TransactionRequest transaction = new TransactionRequest(webUser.economy_id, government.economy_id, 110369, "UBI Mistake Fix", ApplicableTax.None, true);
                            TransactionRequest transaction = new TransactionRequest(government.Id, webUser.Id, corgiPay, "UBI Payment", ApplicableTax.None, true);
                            EconomyManager.RequestTransaction(transaction);
                        }
                    }
                    // Oof rank
                    else if (counter <= spleenUserCount + crabUserCount + gatyUserCount + corgiUserCount + oofUserCount)
                    {
                        // Add new role
                        if (!hasOof)
                        {
                            await discordUser.AddRoleAsync(oofRole);
                        }

                        // Remove last role
                        if (hasSpleen)
                        {
                            await discordUser.RemoveRoleAsync(spleenRole);
                        }
                        if (hasCrab)
                        {
                            await discordUser.RemoveRoleAsync(crabRole);
                        }
                        if (hasGaty)
                        {
                            await discordUser.RemoveRoleAsync(gatyRole);
                        }
                        if (hasCorgi)
                        {
                            await discordUser.RemoveRoleAsync(corgiRole);
                        }

                        if (webUser != null)
                        {
                            //TransactionRequest transaction = new TransactionRequest(webUser.economy_id, government.economy_id, 91085, "UBI Mistake Fix", ApplicableTax.None, true);
                            TransactionRequest transaction = new TransactionRequest(government.Id, webUser.Id, oofPay, "UBI Payment", ApplicableTax.None, true);
                            EconomyManager.RequestTransaction(transaction);
                        }
                    }
                    // Unranked
                    else
                    {
                        // Remove last role
                        if (hasSpleen)
                        {
                            await discordUser.RemoveRoleAsync(spleenRole);
                        }
                        if (hasCrab)
                        {
                            await discordUser.RemoveRoleAsync(crabRole);
                        }
                        if (hasGaty)
                        {
                            await discordUser.RemoveRoleAsync(gatyRole);
                        }
                        if (hasCorgi)
                        {
                            await discordUser.RemoveRoleAsync(corgiRole);
                        }
                        if (hasOof)
                        {
                            await discordUser.RemoveRoleAsync(oofRole);
                        }

                        if (webUser != null)
                        {
                            //TransactionRequest transaction = new TransactionRequest(webUser.economy_id, government.economy_id, 125698, "UBI Mistake Fix", ApplicableTax.None, true);
                            TransactionRequest transaction = new TransactionRequest(government.Id, webUser.Id, unrankedPay, "UBI Payment", ApplicableTax.None, true);
                            EconomyManager.RequestTransaction(transaction);
                        }
                    }

                    if (patron)
                    {
                        webUser = await context.Users.FindAsync(webUser.Id);

                        if (hasMadlad)
                        {
                            webUser.Credits += 500;
                        }
                        else if (hasHero)
                        {
                            webUser.Credits += 350;
                        }
                        else if (hasLoyalist)
                        {
                            webUser.Credits += 175;
                        }
                        else if (hasSoldier)
                        {
                            webUser.Credits += 60;
                        }
                        else if (hasCitizen)
                        {
                            webUser.Credits += 20;
                        }

                        context.Update(webUser);
                        await context.SaveChangesAsync();
                    }

                    counter++;
                }
            }


            Console.WriteLine("Finished rank system");
        }
예제 #25
0
        public async Task <IActionResult> ListNewStock(CreateStockModel model)
        {
            // Validate model
            if (!ModelState.IsValid)
            {
                return(View());
            }

            // Additional validations
            Group group = await _context.Groups.FindAsync(model.Group_Id);

            if (group == null)
            {
                StatusMessage = $"Failed: Could not find group {model.Group_Id}";
                return(View());
            }

            // Check if group already has a stock
            if (_context.StockDefinitions.Any(s => s.Group_Id == model.Group_Id))
            {
                StatusMessage = $"Failed: {group.Name} already has a stock!";
                return(View());
            }

            if (model.Amount < 0)
            {
                StatusMessage = $"Failed: Amount must be positive!";
                return(View());
            }

            if (model.Keep < 0)
            {
                StatusMessage = $"Failed: Keep must be positive!";
                return(View());
            }

            // Check if ticker is taken
            if (_context.StockDefinitions.Any(s => s.Ticker == model.Ticker))
            {
                StatusMessage = $"Failed: A ticker {model.Ticker} already exists!";
                return(View());
            }

            if (model.Initial_Value < 1)
            {
                StatusMessage = $"Failed: Initial value must be greater or equal to 1!";
                return(View());
            }

            if (model.Keep > model.Amount)
            {
                StatusMessage = $"Failed: Keep must be less than Amount!";
                return(View());
            }

            // Create stock definition
            StockDefinition stockDef = new StockDefinition()
            {
                Ticker        = model.Ticker,
                Group_Id      = model.Group_Id,
                Current_Value = model.Initial_Value
            };

            // Add stock definition to database
            await _context.StockDefinitions.AddAsync(stockDef);

            // Create stock object for keeping
            StockObject keepStock = new StockObject()
            {
                Id       = Guid.NewGuid().ToString(),
                Amount   = model.Keep,
                Owner_Id = model.Group_Id,
                Ticker   = model.Ticker,
            };

            // Add
            await _context.StockObjects.AddAsync(keepStock);

            // Create stock sale for issued part
            StockOffer sellOffer = new StockOffer()
            {
                Id         = Guid.NewGuid().ToString(),
                Order_Type = "SELL",
                Target     = model.Initial_Value,
                Ticker     = model.Ticker,
                Amount     = model.Amount - model.Keep,
                Owner_Id   = model.Group_Id
            };

            // Add
            await _context.StockOffers.AddAsync(sellOffer);

            // Save changes if successful
            await _context.SaveChangesAsync();

            StatusMessage = $"Successfully issued {model.Amount} ${model.Ticker}";
            await VoopAI.ecoChannel.SendMessageAsync($":new: Welcome {model.Amount} {model.Ticker}, from {group.Name} to the market at ¢{model.Initial_Value}, with an initial {sellOffer.Amount} on the market!");

            return(RedirectToAction("Index"));
        }
예제 #26
0
        public async Task <IActionResult> AddCategory(CategoryViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return(View(model));
            }

            _context.ForumCategories.Add(new ForumCategory()
            {
                CategoryID  = model.Name,
                Description = model.Description,
                Tags        = model.Tags,
                Parent      = model.Parent
            });

            StatusMessage = $"Successfully added the category {model.Name}.";

            await _context.SaveChangesAsync();

            return(RedirectToAction(nameof(Index)));
        }
예제 #27
0
        public async Task RecordValueHistory(VooperContext context, string type, DateTime time)
        {
            Stopwatch sw = new Stopwatch();

            sw.Start();

            // First clear outdated records
            if (type == "MINUTE")
            {
                context.RemoveRange(context.ValueHistory.AsQueryable().Where(v => v.Type == "MINUTE" && EF.Functions.DateDiffMinute(v.Time, time) > 2000));
            }
            else if (type == "HOUR")
            {
                context.RemoveRange(context.ValueHistory.AsQueryable().Where(v => v.Type == "HOUR" && EF.Functions.DateDiffHour(v.Time, time) > 2000));
            }
            else if (type == "DAY")
            {
                context.RemoveRange(context.ValueHistory.AsQueryable().Where(v => v.Type == "DAY" && EF.Functions.DateDiffDay(v.Time, time) > 2000));
            }

            // Add new records

            List <ValueHistory> additions = new List <ValueHistory>();

            // User Portfolios

            foreach (Entity user in context.Users)
            {
                decimal portValue = await user.GetPortfolioValue();

                if (portValue > 0)
                {
                    ValueHistory hist = new ValueHistory()
                    {
                        Id         = Guid.NewGuid().ToString(),
                        Account_Id = user.Id,
                        Time       = time,
                        Type       = type,
                        Value      = Math.Min(portValue, 9999999999M)
                    };

                    additions.Add(hist);
                }
            }

            // Group Portfolios

            foreach (Entity group in context.Groups)
            {
                decimal portValue = await group.GetPortfolioValue();

                if (portValue > 0)
                {
                    ValueHistory hist = new ValueHistory()
                    {
                        Id         = Guid.NewGuid().ToString(),
                        Account_Id = group.Id,
                        Time       = time,
                        Type       = type,
                        Value      = Math.Min(portValue, 9999999999M)
                    };

                    additions.Add(hist);
                }
            }

            // Stocks

            foreach (StockDefinition stock in context.StockDefinitions)
            {
                decimal value = stock.Current_Value;

                int volume = 0;

                Dictionary <string, int> volumesDict = null;

                if (type == "MINUTE")
                {
                    volumesDict = ExchangeManager.VolumesMinute;
                }
                else if (type == "HOUR")
                {
                    volumesDict = ExchangeManager.VolumesHour;
                }
                else
                {
                    volumesDict = ExchangeManager.VolumesDay;
                }

                if (volumesDict.ContainsKey(stock.Ticker))
                {
                    volume = volumesDict[stock.Ticker];
                    volumesDict[stock.Ticker] = 0;
                }

                ValueHistory hist = new ValueHistory()
                {
                    Id         = Guid.NewGuid().ToString(),
                    Account_Id = stock.Ticker,
                    Time       = time,
                    Type       = type,
                    Value      = Math.Min(value, 9999999999M),
                    Volume     = volume
                };

                additions.Add(hist);
            }

            await context.AddRangeAsync(additions);

            await context.SaveChangesAsync();

            sw.Stop();

            _logger.LogInformation($"Added {additions.Count} financial records in {sw.Elapsed.Seconds} seconds.");
        }
예제 #28
0
        public async Task <ActionResult <TaskResult> > SubmitStockBuy(string ticker, int count, decimal price, string accountid, string auth)
        {
            // Account logic first
            Entity account = await Entity.FindAsync(accountid);

            if (account == null)
            {
                return(new TaskResult(false, "Failed to find account " + accountid));
            }

            User authUser = await _context.Users.AsQueryable().FirstOrDefaultAsync(u => u.Api_Key == auth);

            if (authUser == null)
            {
                return(new TaskResult(false, "Failed to find auth account."));
            }

            StockDefinition stockDef = await _context.StockDefinitions.FindAsync(ticker.ToUpper());

            if (stockDef == null)
            {
                return(new TaskResult(false, "Failed to find stock with ticker " + ticker));
            }

            // Authority check
            if (!await account.HasPermissionAsync(authUser, "eco"))
            {
                return(new TaskResult(false, "You do not have permission to trade for this entity!"));
            }

            // At this point the account is authorized //
            if (count < 1)
            {
                return(new TaskResult(false, "You must buy a positive number of stocks!"));
            }

            if (price == 0)
            {
                StockOffer lowOffer = await ExchangeManager.GetLowestSellOffer(ticker, _context);

                if (lowOffer != null)
                {
                    price = lowOffer.Target;
                }
                else
                {
                    return(new TaskResult(false, "There is no market rate!"));
                }
            }

            if (price < 0)
            {
                return(new TaskResult(false, "Negatives are not allowed!"));
            }

            decimal totalPrice = count * price;

            if (totalPrice > account.Credits)
            {
                return(new TaskResult(false, "You cannot afford this!"));
            }

            TransactionRequest transaction = new TransactionRequest(account.Id, EconomyManager.VooperiaID, totalPrice, $"Stock purchase: {count} {ticker}@{price}", ApplicableTax.None, false);
            TaskResult         transResult = await transaction.Execute();

            if (!transResult.Succeeded)
            {
                return(transResult);
            }

            // Create offer
            StockOffer buyOffer = new StockOffer()
            {
                Id         = Guid.NewGuid().ToString(),
                Amount     = count,
                Order_Type = "BUY",
                Owner_Name = account.Name,
                Owner_Id   = account.Id,
                Target     = price.Round(),
                Ticker     = ticker
            };

            _context.StockOffers.Add(buyOffer);
            await _context.SaveChangesAsync();

            string json = JsonConvert.SerializeObject(buyOffer);

            await ExchangeHub.Current.Clients.All.SendAsync("StockOffer", json);

            return(new TaskResult(true, $"Successfully posted BUY order {buyOffer.Id}"));
        }
예제 #29
0
        public async Task <IActionResult> RequestToken(string grant_type, string code, string redirect_uri,
                                                       string client_id, string client_secret)
        {
            if (grant_type.ToLower() == "authorization_code")
            {
                AuthorizeModel auth = authModels.FirstOrDefault(x => x.Code == code);

                if (auth == null)
                {
                    return(NotFound("Could not find specified code."));
                }

                if (auth.ClientID != client_id)
                {
                    return(NotFound("Client ID does not match."));
                }

                if (auth.Redirect != redirect_uri)
                {
                    return(NotFound("Redirect does not match."));
                }

                OauthApp app = await _context.OauthApps.FirstOrDefaultAsync(x => x.Id == client_id);

                if (app.Secret != client_secret)
                {
                    return(Unauthorized("Failed authorization. This failure has been logged."));
                }

                app.Uses += 1;

                _context.OauthApps.Update(app);
                await _context.SaveChangesAsync();

                string hash = ToHex(SHA256.Create().ComputeHash(Guid.NewGuid().ToByteArray()), false);

                AuthToken token = new AuthToken()
                {
                    Id     = hash,
                    AppId  = client_id,
                    UserId = auth.UserID,
                    Scope  = auth.Scope,
                    Time   = DateTime.UtcNow
                };

                await _context.AuthTokens.AddAsync(token);

                await _context.SaveChangesAsync();

                TokenResponse response = new TokenResponse()
                {
                    access_token = token.Id,
                    expires_in   = 3600,
                    svid         = token.UserId
                };

                return(Json(response));
            }
            else
            {
                return(NotFound("Grant type not implemented!"));
            }
        }