protected async void OnChat(byte packetId, ChatEvent eventData) { var cmds = eventData.Message.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (cmds.Length <= 0) { return; } if (cmds[0] == "?help") { var exeVersion = Assembly.GetExecutingAssembly().GetName().Version; var sb = new StringBuilder(); sb.AppendLine($"tobot's acsRankingPlugin {exeVersion} 명령어"); sb.AppendLine("================================="); sb.AppendLine("?help : 도움말 표시"); sb.AppendLine("?rank [top|full]: 종합 리더보드"); sb.AppendLine(" top: 상위권만 출력, full: 전체 출력"); sb.AppendLine("?carrank [top|full]: 동일차량 리더보드"); sb.AppendLine("?driverrank [top|full]: 유저별 최고기록 리더보드"); sb.AppendLine("?carname : 차량 이름 변환표"); sb.AppendLine("?ballast [숫자] : 자기 차 무게 증가 (kg)"); sb.AppendLine("================================="); await _acsClient.SendChatAsync(eventData.CarId, sb.ToString()); } else if (cmds[0] == "?rank") { var car = await _carInfos.GetAsync(eventData.CarId); await _acsClient.SendChatAsync(eventData.CarId, await GenerateMyRankAsync(car.CarName, car.DriverName, cmds)); } else if (cmds[0] == "?carrank") { var car = await _carInfos.GetAsync(eventData.CarId); await _acsClient.SendChatAsync(eventData.CarId, await GenerateCarrankAsync(car.CarName, car.DriverName, cmds)); } else if (cmds[0] == "?driverrank") { var car = await _carInfos.GetAsync(eventData.CarId); await _acsClient.SendChatAsync(eventData.CarId, await GenerateDriverrankAsync(car.CarName, car.DriverName, cmds)); } else if (cmds[0] == "?carname") { var records = new Records(await _storage.ListAsync(), _options.CarShortNameMap); await _acsClient.SendChatAsync(eventData.CarId, records.GenerateCarShortNameMapTable()); } else if (cmds.Length == 2 && cmds[0] == "?ballast") { int weight; if (Int32.TryParse(cmds[1], out weight) && weight >= 0 && weight <= 150) { await _acsClient.SendAdminMessageAsync($"/ballast {eventData.CarId} {weight}"); await _acsClient.SendChatAsync(eventData.CarId, $"?ballast 명령어를 실행했습니다."); } else { await _acsClient.SendChatAsync(eventData.CarId, $"무게를 잘못 입력했습니다: {cmds[1]}"); } } else if (eventData.Message.StartsWith("?")) { await _acsClient.SendChatAsync(eventData.CarId, $"플러그인 명령어를 잘못 입력했습니다: {eventData.Message}"); } }
/** * 내 순위를 가운데 두는 리더보드를 출력한다. * 출력하는 레코드 갯수가 maxRow가 되도록 위, 아래를 자른다. * 잘리더라도 1위와 꼴찌는 항상 보이도록 처리한다. */ public async Task <string> GenerateMyRankTableAsync(List <DriverLaptime> laptimes, IReadOnlyDictionary <string, string> carShortNameMap, string car, string driver, int maxRow = CHAT_WINDOW_RECORD_COUNT) { var myIndex = laptimes.FindIndex(v => (string.IsNullOrEmpty(car) || v.Car == car) && v.Driver == driver); var driverLaptime = myIndex >= 0 ? laptimes[myIndex] : null; if (driverLaptime == null || driverLaptime.Laptime == TimeSpan.Zero) { return(await GenerateTopRankTableAsync(laptimes, carShortNameMap)); } var myRank = myIndex + 1; var sb = new StringBuilder(); PrintRankTableHeader(sb, await _storage.GetTimestampAsync()); var records = new Records(laptimes, carShortNameMap); if (records.Count > 0) { // 순위 표시할 때 다음과 같이 하기위해 위,아래를 잘라내는 로직이 필요하다 // ------------ -- records.Count = 14, maxRow = 7, cutCount = 7 // 1. aaa -- cutTop = 2 // ... // 5. bbb -- startIndex = 4 // 6. ccc -- 내 위치는 가운데 (myRank = 6, myPrintOrder = 4) // 7. ddd -- endIndex = 7 // ... // 14. eee -- cutBottom = 5 var cutCount = Math.Max(0, records.Count - maxRow); var myPrintOrder = (maxRow + 1) / 2; // 내 순위가 출력될 줄번호 var cutTop = Math.Max(0, myRank - myPrintOrder); var cutBottom = cutCount - cutTop; // 본인 순위가 바닥권이면 cutBottom이 마이너스가 나오고 상위가 많이 잘린다. if (cutBottom < 0) { cutTop += cutBottom; cutBottom = 0; } //Console.WriteLine($"cutCount:{cutCount}, myPrintOrder:{myPrintOrder}, cutTop:{cutTop}, cutBottom:{cutBottom}"); if (cutTop > 0) { PrintRankTableRecord(sb, records[0], records.IsMixedCar); sb.AppendLine(" ..."); } var startIndex = cutTop > 0 ? cutTop + 2 : 0; var endIndex = cutBottom > 0 ? records.Count - cutBottom - 2 : records.Count; //Console.WriteLine($"startIndex:{startIndex}, endIndex:{endIndex}"); for (var i = startIndex; i < endIndex; i++) { PrintRankTableRecord(sb, records[i], records.IsMixedCar); } if (cutBottom > 0) { sb.AppendLine(" ..."); PrintRankTableRecord(sb, records.Last(), records.IsMixedCar); } } else { sb.AppendLine(" 기록이 없습니다."); } PrintRankTableBar(sb); return(sb.ToString()); }