diff --git a/nise-frontend/src/app/text-report.service.ts b/nise-frontend/src/app/text-report.service.ts new file mode 100644 index 0000000..5ae83b8 --- /dev/null +++ b/nise-frontend/src/app/text-report.service.ts @@ -0,0 +1,46 @@ +import {UserDetails} from './userDetails'; +import {SimilarReplay, SuspiciousScore} from './replays'; + +export class TextReportService { + static generateTextReportForUserScores( + userDetails: UserDetails, + suspiciousScores: SuspiciousScore[], + similarReplays: SimilarReplay[], + ) { + const detections: string[] = []; + + if (suspiciousScores.length > 0) { + detections.push('Relax'); + } + + if (similarReplays.length > 0) { + detections.push('Replay Stealing'); + } + + let report = `[osu!std] ${userDetails.username} | ${detections.join(', ')}\n\n`; + report += `Profile: https://osu.ppy.sh/users/${userDetails.user_id}\n`; + + for (const suspiciousScore of suspiciousScores) { + report += `\n${this.getRelaxReport(suspiciousScore)}\n`; + } + + for (const similarReplay of similarReplays) { + report += `\n${this.getStealingReport(similarReplay)}\n`; + } + + report += `\nGenerated on nise.moe - [${userDetails.username} on nise.moe](https://nise.moe/u/${userDetails.user_id})`; + + return report; + } + + private static getRelaxReport(suspiciousScore: SuspiciousScore): string { + return `[Replay on ${suspiciousScore.beatmap_title}](https://osu.ppy.sh/scores/osu/${suspiciousScore.replay_id}) +cvUR: ${suspiciousScore.ur.toFixed(2)} according to Circleguard`; + } + + private static getStealingReport(similarReplay: SimilarReplay): string { + return `[${similarReplay.username_2}'s replay (cheated)](https://osu.ppy.sh/scores/osu/${similarReplay.replay_id_2}) +[${similarReplay.username_1}'s replay (original)](https://osu.ppy.sh/scores/osu/${similarReplay.replay_id_1}) +${similarReplay.similarity.toFixed(2)} similarity according to Circleguard`; + } +} diff --git a/nise-frontend/src/app/view-user/view-user.component.html b/nise-frontend/src/app/view-user/view-user.component.html index 35a7fc6..c44a3c5 100644 --- a/nise-frontend/src/app/view-user/view-user.component.html +++ b/nise-frontend/src/app/view-user/view-user.component.html @@ -82,6 +82,12 @@ + + + +

Suspicious Scores ({{ this.userInfo.suspicious_scores.length }})

diff --git a/nise-frontend/src/app/view-user/view-user.component.ts b/nise-frontend/src/app/view-user/view-user.component.ts index 1d3a964..69f7e70 100644 --- a/nise-frontend/src/app/view-user/view-user.component.ts +++ b/nise-frontend/src/app/view-user/view-user.component.ts @@ -14,6 +14,7 @@ import {CuteLoadingComponent} from "../../corelib/components/cute-loading/cute-l import {FilterManagerService} from "../filter-manager.service"; import {UserService} from "../../corelib/service/user.service"; import {FollowService} from "../../corelib/service/follow.service"; +import {TextReportService} from '../text-report.service'; interface UserInfo { user_details: UserDetails; @@ -196,6 +197,20 @@ export class ViewUserComponent implements OnInit, OnChanges, OnDestroy { }); } + async copyReportToClipboard(): Promise { + if (!this.userInfo) { + return; + } + + const report = TextReportService.generateTextReportForUserScores( + this.userInfo.user_details, + this.userInfo.suspicious_scores, + this.userInfo.similar_replays, + ); + + await navigator.clipboard.writeText(report); + } + protected readonly formatDuration = formatDuration; protected readonly countryCodeToFlag = countryCodeToFlag; protected readonly calculateTimeAgo = calculateTimeAgo;