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); }
// 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); }
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); }