From 6c7f397a10400d52c6d0202a4b3c1488c3ff7dc4 Mon Sep 17 00:00:00 2001 From: Matt Etress Date: Sun, 29 Oct 2023 01:49:12 -0500 Subject: [PATCH 01/12] Add detected_ai_games to report interface --- src/lib/report_manager.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/report_manager.tsx b/src/lib/report_manager.tsx index 0a0cb2ed24..77ee60e8e3 100644 --- a/src/lib/report_manager.tsx +++ b/src/lib/report_manager.tsx @@ -70,6 +70,7 @@ export interface Report { }; moderator_note: string; system_note: string; + detected_ai_games: Array; automod_to_moderator?: string; // Suggestions from "automod" automod_to_reporter?: string; From 5adb560c8fe73c20a441a94ecc5c3729b613facd Mon Sep 17 00:00:00 2001 From: Matt Etress Date: Sun, 29 Oct 2023 01:52:01 -0500 Subject: [PATCH 02/12] Render reporter as System when no reporter --- src/views/ReportsCenter/ReportsCenterHistory.tsx | 3 ++- src/views/ReportsCenter/ViewReport.tsx | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/views/ReportsCenter/ReportsCenterHistory.tsx b/src/views/ReportsCenter/ReportsCenterHistory.tsx index 98dcdc22ca..cb9a754b8c 100644 --- a/src/views/ReportsCenter/ReportsCenterHistory.tsx +++ b/src/views/ReportsCenter/ReportsCenterHistory.tsx @@ -70,7 +70,8 @@ export function ReportsCenterHistory(): JSX.Element { { header: "Reporter", className: () => "state", - render: (X) => , + render: (X) => + X.reporting_user ? : "System", }, { header: "Type", diff --git a/src/views/ReportsCenter/ViewReport.tsx b/src/views/ReportsCenter/ViewReport.tsx index 193b680cf5..9df274ed60 100644 --- a/src/views/ReportsCenter/ViewReport.tsx +++ b/src/views/ReportsCenter/ViewReport.tsx @@ -369,7 +369,12 @@ export function ViewReport({ report_id, reports, onChange }: ViewReportProps): J "A label for the user name that reported an incident (followed by colon and the username)", "Reported by", )} - : + :{" "} + {report.reporting_user ? ( + + ) : ( + "System" + )} {moment(report.created).fromNow()} From d5b4f2db19a1c53b799bc0831437d1cdd4bae8e7 Mon Sep 17 00:00:00 2001 From: Matt Etress Date: Sun, 29 Oct 2023 01:54:32 -0500 Subject: [PATCH 03/12] Add annul queue button --- src/views/ReportsCenter/ViewReport.tsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/views/ReportsCenter/ViewReport.tsx b/src/views/ReportsCenter/ViewReport.tsx index 9df274ed60..a897f364f7 100644 --- a/src/views/ReportsCenter/ViewReport.tsx +++ b/src/views/ReportsCenter/ViewReport.tsx @@ -473,6 +473,13 @@ export function ViewReport({ report_id, reports, onChange }: ViewReportProps): J
+ {reportState !== "resolved" && report.detected_ai_games ? ( + + ) : null} {reportState !== "resolved" && claimed_by_me && (

{(user.is_moderator || null) && } From 75206fc9e68178924e79ceb84ebd8663a44a97c6 Mon Sep 17 00:00:00 2001 From: Matt Etress Date: Sun, 29 Oct 2023 01:57:48 -0500 Subject: [PATCH 05/12] Modify annulqueue modal for use in reports center --- .../AnnulQueueModal/AnnulQueueModal.tsx | 80 +++++++++++++------ 1 file changed, 57 insertions(+), 23 deletions(-) diff --git a/src/components/AnnulQueueModal/AnnulQueueModal.tsx b/src/components/AnnulQueueModal/AnnulQueueModal.tsx index 8be728f1e7..20beb7d77c 100644 --- a/src/components/AnnulQueueModal/AnnulQueueModal.tsx +++ b/src/components/AnnulQueueModal/AnnulQueueModal.tsx @@ -22,14 +22,16 @@ import { Goban } from "goban"; import { AIReview, GameTimings, ChatMode, GameChat, GobanContext } from "Game"; import { Player } from "Player"; import { Resizable } from "Resizable"; -import { post } from "requests"; +import { post, put } from "requests"; // Define the AnnulQueueModalProps interface interface AnnulQueueModalProps { annulQueue: any[]; - setSelectModeActive: React.Dispatch; + setSelectModeActive?: React.Dispatch; setAnnulQueue: React.Dispatch; onClose: () => void; + forDetectedAI: boolean; + player?: any; } // Define the AnnulQueueModal component @@ -38,6 +40,8 @@ export function AnnulQueueModal({ setSelectModeActive, setAnnulQueue, onClose, + forDetectedAI, + player, }: AnnulQueueModalProps) { // Declare state variables const [selectedGameIndex, setSelectedGameIndex] = React.useState(0); @@ -66,8 +70,12 @@ export function AnnulQueueModal({ // Close the modal const closeModal = () => { - setAnnulQueue([]); - setSelectModeActive(false); + if (!forDetectedAI) { + setAnnulQueue([]); + if (setSelectModeActive) { + setSelectModeActive(false); + } + } setShowAnnulOverlay(false); setAnnulResponse(null); onClose(); @@ -158,29 +166,37 @@ export function AnnulQueueModal({ // Prompt the user for a moderation note const promptForModerationNote = () => { - let moderation_note: string | null = null; + let moderationNote: string | null = null; + let currentPlayer: any; + if (forDetectedAI) { + currentPlayer = player; + } else { + currentPlayer = currentGame.player; + } do { - moderation_note = prompt( - `Annulling ${validGameIds.length} of ${currentGame.player.username}'s games.\nEnter moderation note: (will be entered with '${currentGame.player.username} mass annull:')`, + moderationNote = prompt( + `Annulling ${validGameIds.length} of ${currentPlayer.username}'s games.\nEnter moderation note: (will be entered with '${currentPlayer.username} mass annull:')`, ); - if (moderation_note == null) { + if (moderationNote == null) { return null; } - moderation_note = moderation_note.trim(); - } while (moderation_note === ""); - return `${currentGame.player.username} mass annul: ${moderation_note}`; + moderationNote = moderationNote.trim(); + } while (moderationNote === ""); + return `player ${currentPlayer.id} mass annul: ${moderationNote}`; }; // Annul the specified games - const annul = (validGameIds: number[], moderation_note: string) => { + const annul = (validGameIds: number[], moderationNote: string) => { setShowAnnulOverlay(true); + console.debug("posting"); post("moderation/annul", { games: validGameIds, annul: true, - moderation_note: moderation_note, + moderation_note: moderationNote, }) .then((res) => { + console.debug("posted"); const successful = res.done; const failed = res.failed; @@ -207,6 +223,24 @@ export function AnnulQueueModal({ }); }; + const markFalsePositive = () => { + if (confirm("Mark this game as a false positive detection?") === true) { + put("cheat_detection/false_positive", { + game_id: currentGame.id, + player_id: currentGame.player, + false_positive: true, + }) + .then((res) => { + if (res.success) { + setDequeueRequested(true); + } + }) + .catch((err) => { + console.error(err); + }); + } + }; + return ( <>
@@ -239,10 +273,10 @@ export function AnnulQueueModal({ response={annulResponse} />
- {queue[selectedGameIndex] && ( + {currentGame && (
- Black: + Black:
- White: + White:
Game Outcome: {winner} ( @@ -327,6 +361,11 @@ export function AnnulQueueModal({ } }} >{`Annul Games(${validGameIds.length})`} + {forDetectedAI && ( + + )}
@@ -358,12 +397,7 @@ export function AnnulQueueModal({ } // Open the AnnulQueueModal -export function openAnnulQueueModal( - annulQueue, - setSelectModeActive, - setAnnulQueue, - setIsAnnulQueueModalOpen, -) { +export function openAnnulQueueModal(setIsAnnulQueueModalOpen) { setIsAnnulQueueModalOpen(true); // Disable body scroll From 245f1e6d9823478238ce543d2feaccfde1ce62cc Mon Sep 17 00:00:00 2001 From: Matt Etress Date: Sun, 29 Oct 2023 01:58:42 -0500 Subject: [PATCH 06/12] Update annul queue modal props --- src/views/User/GameHistoryTable.tsx | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/views/User/GameHistoryTable.tsx b/src/views/User/GameHistoryTable.tsx index 9690b946b6..e00a574efd 100644 --- a/src/views/User/GameHistoryTable.tsx +++ b/src/views/User/GameHistoryTable.tsx @@ -206,6 +206,7 @@ export function GameHistoryTable(props: GameHistoryProps) { annulQueue={annulQueue} setAnnulQueue={setAnnulQueue} onClose={handleCloseAnnulQueueModal} + forDetectedAI={false} /> )} {/* loading-container="game_history.settings().$loading" */} @@ -226,12 +227,7 @@ export function GameHistoryTable(props: GameHistoryProps) {