private async Task <bool> PlaceMultipixelPacket(string instructions, short placeDiscordUserId)
        {
            PlaceDBManager placeDBManager = PlaceDBManager.Instance();

            foreach (var instruction in instructions.Split(';'))
            {
                Stopwatch watch = new Stopwatch();
                watch.Start();

                var delay = Task.Delay(990); // wait for 990 ms instead of 1000ms so if the main method takes longer we dont loose too many
                var args  = instruction.Split('|');

                short x = short.Parse(args[0]);
                short y = short.Parse(args[1]);

                //SKColor color = ColorTranslator.FromHtml(args[2]);

                if (!SKColor.TryParse(args[2], out SKColor color))
                {
                    continue;
                }

                var success = placeDBManager.PlacePixel(x, y, color, placeDiscordUserId);

                watch.Stop();

                // TODO ensure the perf info is updated if only multipixels are placed, for now this should be fine

                if (success)
                {
                    PlaceModule.PixelPlacementTimeLastMinute.Add(watch.ElapsedMilliseconds);
                }
                else
                {
                    lock (PlaceModule.PlaceAggregateObj)
                    {
                        PlaceModule.FailedPixelPlacements++;
                    }
                }

                await delay;
            }

            return(true);
        }
예제 #2
0
        // end duplicate

        private byte[] GetTotalPixelCount()
        {
            byte[] returnData = new byte[5];
            returnData[0] = (byte)MessageEnum.TotalPixelCount_Response;

            PlaceDBManager dbManager = PlaceDBManager.Instance();

            var lastPixelIdChunked = GetLastPixelIdChunked();
            var totalPixelsChunked = GetTotalChunkedPixels();

            // current limit 2.147 B pixels
            var totalPixelsPlaced = Convert.ToInt32(dbManager.GetBoardHistoryCount(lastPixelIdChunked, totalPixelsChunked));

            byte[] pixelAmountBytes = BitConverter.GetBytes(totalPixelsPlaced);
            returnData[1] = pixelAmountBytes[0];
            returnData[2] = pixelAmountBytes[1];
            returnData[3] = pixelAmountBytes[2];
            returnData[4] = pixelAmountBytes[3];

            return(returnData);
        }
예제 #3
0
        private byte[] GetFullUserInfos()
        {
            try
            {
                PlaceDBManager  placeDbManager = PlaceDBManager.Instance();
                DatabaseManager dbManager      = DatabaseManager.Instance();

                var   discordUserInfos = new List <DiscordUser>();
                short userCount        = Convert.ToInt16(PlaceModule.PlaceDiscordUsers.Count);

                // TODO Load with PlaceDiscordUsers the DiscordUser table aswel
                // todo do with 1 query only -> faster
                foreach (var user in PlaceModule.PlaceDiscordUsers)
                {
                    discordUserInfos.Add(dbManager.GetDiscordUserById(user.DiscordUserId));
                }

                /// 0 | ID
                /// 1-2 | Amount of users loaded
                /// USER REPEAT (rel) Total 199
                /// 0-1 | user id (int 16)
                /// 2-97 Username (utf8 3 bytes per char)
                /// 98-197 | Url of the Profile (10 chars around spare) ASCII 1 byte per char
                /// 198 | IsBot 1 byte (could move 1 bit to user id as we wont need all 16 bits but me lazy)
                byte[] response = new byte[3 + userCount * (2 + 32 * 3 + 100 + 1)];

                response[0] = (byte)MessageEnum.GetUsers_Response;


                byte[] userAmountBytes = BitConverter.GetBytes(userCount);
                response[1] = userAmountBytes[0];
                response[2] = userAmountBytes[1];

                int index = 3;

                foreach (var discordUser in discordUserInfos)
                {
                    short  userId = PlaceModule.PlaceDiscordUsers.Single(i => i.DiscordUserId == discordUser.DiscordUserId).PlaceDiscordUserId;
                    string name   = discordUser.Nickname ?? discordUser.Username;
                    string url    = discordUser.AvatarUrl ?? "";

                    byte[] userIdBytes = BitConverter.GetBytes(userId);
                    var    nameBytes   = Encoding.UTF8.GetBytes(name);
                    var    urlBytes    = Encoding.ASCII.GetBytes(url);

                    response[index]     = userIdBytes[0];
                    response[index + 1] = userIdBytes[1];
                    index += 2;

                    nameBytes.CopyTo(response, index);
                    index += 32 * 3; // TODO verify this is indeed enough

                    urlBytes.CopyTo(response, index);
                    index += 100; // TODO verify this is indeed enough

                    response[index] = (byte)(discordUser.IsBot ? 1 : 0);
                    index++;
                }
                return(response);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }

            return(new byte[1]);
        }
        public async Task <bool> MultiPixelProcess()
        {
            PlaceDBManager placeDBManager = PlaceDBManager.Instance();

            while (true)
            {
                var delay = Task.Delay(TimeSpan.FromSeconds(100));
                var verifiedPlaceUsers = placeDBManager.GetPlaceDiscordUsers(true);

                List <PlaceMultipixelJob> allActiveJobs = new List <PlaceMultipixelJob>();

                foreach (var placeUser in verifiedPlaceUsers)
                {
                    var activeJobs = placeDBManager.GetMultipixelJobs(placeUser.PlaceDiscordUserId);

                    var job = activeJobs.FirstOrDefault();

                    if (job == null)
                    {
                        continue; // the user has nothing queued up;
                    }
                    // set job status to Active
                    if (job.Status == (int)MultipixelJobStatus.Ready)
                    {
                        placeDBManager.UpdatePlaceMultipixelJobStatus(job.PlaceMultipixelJobId, MultipixelJobStatus.Active);
                    }

                    allActiveJobs.Add(job);
                }

                List <Task> tasks            = new List <Task>();
                List <int>  currentPacketIds = new List <int>();
                foreach (var job in allActiveJobs)
                {
                    var lastPacket = placeDBManager.GetNextFreeMultipixelJobPacket(job.PlaceMultipixelJobId);
                    currentPacketIds.Add(lastPacket.PlaceMultipixelPacketId);
                    tasks.Add(PlaceMultipixelPacket(lastPacket.Instructions, job.PlaceDiscordUserId));
                }

                await Task.WhenAll(tasks);

                foreach (var packetId in currentPacketIds)
                {
                    placeDBManager.MarkMultipixelJobPacketAsDone(packetId);
                }

                // chack if any job finished TODO maybe save in the job the count done
                foreach (var job in allActiveJobs)
                {
                    var lastPacket = placeDBManager.GetNextFreeMultipixelJobPacket(job.PlaceMultipixelJobId);
                    if (lastPacket == null)
                    {
                        // job is done
                        placeDBManager.UpdatePlaceMultipixelJobStatus(job.PlaceMultipixelJobId, MultipixelJobStatus.Done);
                    }
                }

                await delay; // Ensure 1 packet / user / 100 sec
            }

            return(true);
        }