From a2e6a6fc539509d161746e51043cbc6fffd149ce Mon Sep 17 00:00:00 2001
From: Vitaly Kuprin <vitas_s@inbox.lv>
Date: Sun, 15 Dec 2024 14:15:09 +0100
Subject: [PATCH 1/7] chore: cleanups

Signed-off-by: Vitaly Kuprin <vitas_s@inbox.lv>
---
 GomokuAI/Dockerfile                           | 11 ++-
 GomokuAI/wrapper.js                           | 68 +++++++++++++++++++
 GomokuAI/wrapper.py                           | 52 --------------
 .../Controllers/v1/RapfiEngineController.cs   |  2 +-
 4 files changed, 74 insertions(+), 59 deletions(-)
 create mode 100644 GomokuAI/wrapper.js
 delete mode 100644 GomokuAI/wrapper.py

diff --git a/GomokuAI/Dockerfile b/GomokuAI/Dockerfile
index 50d91dd3..0e3aef21 100644
--- a/GomokuAI/Dockerfile
+++ b/GomokuAI/Dockerfile
@@ -8,8 +8,8 @@ RUN apt-get update && apt-get install -y \
     cmake \
     g++ \
     make \
-    python3 \
-    python3-pip \
+    nodejs \
+    npm \
     && rm -rf /var/lib/apt/lists/*
 
 WORKDIR /app/GomokuAI
@@ -28,10 +28,9 @@ RUN git clone --recurse-submodules https://github.com/dhbloo/rapfi.git rapfi &&
         -DUSE_NEON_DOTPROD=OFF && \
     cmake --build .
 
-RUN pip3 install flask
-
 WORKDIR /app/GomokuAI/rapfi/Rapfi
+COPY wrapper.js .
 
-COPY wrapper.py .
+RUN npm install express
 
-CMD ["python3", "wrapper.py"]
+CMD ["node", "wrapper.js"]
diff --git a/GomokuAI/wrapper.js b/GomokuAI/wrapper.js
new file mode 100644
index 00000000..a10deb14
--- /dev/null
+++ b/GomokuAI/wrapper.js
@@ -0,0 +1,68 @@
+const express = require('express');
+const { spawn } = require('child_process');
+const { Readable, Writable } = require('stream');
+
+const app = express();
+app.use(express.json());
+
+const process = spawn('./build/pbrain-rapfi', ['--mode', 'gomocup'], {
+    stdio: ['pipe', 'pipe', 'pipe']
+});
+
+const commandQueue = [];
+const responseQueue = [];
+
+const inputStream = new Writable({
+    write(chunk, encoding, callback) {
+        process.stdin.write(chunk, encoding, callback);
+    }
+});
+
+const outputStream = new Readable({
+    read() {}
+});
+
+process.stdout.on('data', (data) => {
+    const response = data.toString().trim();
+    if (responseQueue.length > 0) {
+        const resolve = responseQueue.shift();
+        resolve(response);
+    }
+});
+
+process.on('error', (err) => {
+    console.error('Failed to start subprocess:', err);
+});
+
+app.get('/test', (req, res) => {
+    res.json({ status: "Engine is running" });
+});
+
+app.post('/command', async (req, res) => {
+    const cmd = req.body.command;
+    if (!cmd) {
+        return res.status(400).json({ error: "No command provided" });
+    }
+
+    commandQueue.push(cmd);
+
+    inputStream.write(cmd + '\n');
+
+    try {
+        const response = await new Promise((resolve, reject) => {
+            const timeout = setTimeout(() => reject(new Error("Timeout waiting for response")), 5000);
+            responseQueue.push((data) => {
+                clearTimeout(timeout);
+                resolve(data);
+            });
+        });
+        res.json({ response });
+    } catch (err) {
+        res.status(408).json({ error: err.message });
+    }
+});
+
+const PORT = 5005;
+app.listen(PORT, () => {
+    console.log(`Server running on http://0.0.0.0:${PORT}`);
+});
diff --git a/GomokuAI/wrapper.py b/GomokuAI/wrapper.py
deleted file mode 100644
index 29177085..00000000
--- a/GomokuAI/wrapper.py
+++ /dev/null
@@ -1,52 +0,0 @@
-from flask import Flask, request, jsonify
-import subprocess
-import threading
-import queue
-
-app = Flask(__name__)
-
-process = subprocess.Popen(
-    ['./build/pbrain-rapfi', '--mode', 'gomocup'],
-    stdin=subprocess.PIPE,
-    stdout=subprocess.PIPE,
-    stderr=subprocess.PIPE,
-    text=True
-)
-
-command_queue = queue.Queue()
-response_queue = queue.Queue()
-
-def process_io():
-    while True:
-        try:
-            command = command_queue.get(timeout=0.1)
-            process.stdin.write(command + '\n')
-            process.stdin.flush()
-            response = process.stdout.readline().strip()
-            response_queue.put(response)
-        except queue.Empty:
-            continue
-
-io_thread = threading.Thread(target=process_io, daemon=True)
-io_thread.start()
-
-@app.route('/test')
-def test():
-    return jsonify({"status": "Engine is running"})
-
-@app.route('/command', methods=['POST'])
-def command():
-    cmd = request.json.get('command')
-    if not cmd:
-        return jsonify({"error": "No command provided"}), 400
-
-    command_queue.put(cmd)
-
-    try:
-        response = response_queue.get(timeout=5)
-        return jsonify({"response": response})
-    except queue.Empty:
-        return jsonify({"error": "Timeout waiting for response"}), 408
-
-if __name__ == '__main__':
-    app.run(host='0.0.0.0', port=5005)
diff --git a/GomokuServer/src/GomokuServer.Api/Controllers/v1/RapfiEngineController.cs b/GomokuServer/src/GomokuServer.Api/Controllers/v1/RapfiEngineController.cs
index 258979ec..d5af31af 100644
--- a/GomokuServer/src/GomokuServer.Api/Controllers/v1/RapfiEngineController.cs
+++ b/GomokuServer/src/GomokuServer.Api/Controllers/v1/RapfiEngineController.cs
@@ -2,7 +2,7 @@ namespace GomokuServer.Api.Controllers.v1;
 
 [ApiController]
 [ApiVersion("1.0")]
-[Route("api/v1/rapfi")]
+[Route("api/rapfi")]
 [EnableCors(CorsPolicyName.GomokuClient)]
 public class RapfiEngineController : Controller
 {

From 54e324273e9748c63062bc6f95e198078b15e31b Mon Sep 17 00:00:00 2001
From: Vitaly Kuprin <vitas_s@inbox.lv>
Date: Sun, 15 Dec 2024 14:40:22 +0100
Subject: [PATCH 2/7] chore: better wrapper

Signed-off-by: Vitaly Kuprin <vitas_s@inbox.lv>
---
 GomokuAI/wrapper.js | 41 +++++++++++++++++++++++++++--------------
 1 file changed, 27 insertions(+), 14 deletions(-)

diff --git a/GomokuAI/wrapper.js b/GomokuAI/wrapper.js
index a10deb14..87d5b83e 100644
--- a/GomokuAI/wrapper.js
+++ b/GomokuAI/wrapper.js
@@ -1,12 +1,13 @@
 const express = require('express');
 const { spawn } = require('child_process');
-const { Readable, Writable } = require('stream');
+const { Writable } = require('stream');
 
 const app = express();
 app.use(express.json());
 
-const process = spawn('./build/pbrain-rapfi', ['--mode', 'gomocup'], {
-    stdio: ['pipe', 'pipe', 'pipe']
+const subprocess = spawn('./build/pbrain-rapfi', ['--mode', 'gomocup'], {
+    stdio: ['pipe', 'pipe', 'pipe'],
+    shell: true
 });
 
 const commandQueue = [];
@@ -14,24 +15,26 @@ const responseQueue = [];
 
 const inputStream = new Writable({
     write(chunk, encoding, callback) {
-        process.stdin.write(chunk, encoding, callback);
+        subprocess.stdin.write(chunk, encoding, callback);
     }
 });
 
-const outputStream = new Readable({
-    read() {}
-});
-
-process.stdout.on('data', (data) => {
+subprocess.stdout.on('data', (data) => {
     const response = data.toString().trim();
+    console.log(`[Subprocess Response]: ${response}`); // Debugging
+
     if (responseQueue.length > 0) {
         const resolve = responseQueue.shift();
         resolve(response);
     }
 });
 
-process.on('error', (err) => {
-    console.error('Failed to start subprocess:', err);
+subprocess.on('error', (err) => {
+    console.error(`[Subprocess Error]: Failed to start subprocess - ${err.message}`);
+});
+
+subprocess.on('exit', (code, signal) => {
+    console.error(`[Subprocess Exit]: Exited with code ${code}, signal ${signal}`);
 });
 
 app.get('/test', (req, res) => {
@@ -44,11 +47,11 @@ app.post('/command', async (req, res) => {
         return res.status(400).json({ error: "No command provided" });
     }
 
-    commandQueue.push(cmd);
-
-    inputStream.write(cmd + '\n');
+    console.log(`[Command Sent]: ${cmd}`); // Debugging
 
     try {
+        inputStream.write(cmd + '\n');
+
         const response = await new Promise((resolve, reject) => {
             const timeout = setTimeout(() => reject(new Error("Timeout waiting for response")), 5000);
             responseQueue.push((data) => {
@@ -56,12 +59,22 @@ app.post('/command', async (req, res) => {
                 resolve(data);
             });
         });
+
+        console.log(`[Response Received]: ${response}`); // Debugging
         res.json({ response });
+
     } catch (err) {
+        console.error(`[Command Error]: ${err.message}`);
         res.status(408).json({ error: err.message });
     }
 });
 
+process.on('SIGINT', () => {
+    console.log("Shutting down server and subprocess...");
+    subprocess.kill();
+    process.exit();
+});
+
 const PORT = 5005;
 app.listen(PORT, () => {
     console.log(`Server running on http://0.0.0.0:${PORT}`);

From 5a0c0f297669eee1e24ac07def72196203902b98 Mon Sep 17 00:00:00 2001
From: Vitaly Kuprin <vitas_s@inbox.lv>
Date: Sun, 15 Dec 2024 14:41:22 +0100
Subject: [PATCH 3/7] chore: custom prettier

Signed-off-by: Vitaly Kuprin <vitas_s@inbox.lv>
---
 GomokuAI/wrapper.js | 44 +++++++++++++++++++++++++-------------------
 1 file changed, 25 insertions(+), 19 deletions(-)

diff --git a/GomokuAI/wrapper.js b/GomokuAI/wrapper.js
index 87d5b83e..53b1e452 100644
--- a/GomokuAI/wrapper.js
+++ b/GomokuAI/wrapper.js
@@ -1,13 +1,13 @@
-const express = require('express');
-const { spawn } = require('child_process');
-const { Writable } = require('stream');
+const express = require("express");
+const { spawn } = require("child_process");
+const { Writable } = require("stream");
 
 const app = express();
 app.use(express.json());
 
-const subprocess = spawn('./build/pbrain-rapfi', ['--mode', 'gomocup'], {
-    stdio: ['pipe', 'pipe', 'pipe'],
-    shell: true
+const subprocess = spawn("./build/pbrain-rapfi", ["--mode", "gomocup"], {
+    stdio: ["pipe", "pipe", "pipe"],
+    shell: true,
 });
 
 const commandQueue = [];
@@ -16,12 +16,12 @@ const responseQueue = [];
 const inputStream = new Writable({
     write(chunk, encoding, callback) {
         subprocess.stdin.write(chunk, encoding, callback);
-    }
+    },
 });
 
-subprocess.stdout.on('data', (data) => {
+subprocess.stdout.on("data", (data) => {
     const response = data.toString().trim();
-    console.log(`[Subprocess Response]: ${response}`); // Debugging
+    console.log(`[Subprocess Response]: ${response}`);
 
     if (responseQueue.length > 0) {
         const resolve = responseQueue.shift();
@@ -29,19 +29,23 @@ subprocess.stdout.on('data', (data) => {
     }
 });
 
-subprocess.on('error', (err) => {
-    console.error(`[Subprocess Error]: Failed to start subprocess - ${err.message}`);
+subprocess.on("error", (err) => {
+    console.error(
+        `[Subprocess Error]: Failed to start subprocess - ${err.message}`,
+    );
 });
 
-subprocess.on('exit', (code, signal) => {
-    console.error(`[Subprocess Exit]: Exited with code ${code}, signal ${signal}`);
+subprocess.on("exit", (code, signal) => {
+    console.error(
+        `[Subprocess Exit]: Exited with code ${code}, signal ${signal}`,
+    );
 });
 
-app.get('/test', (req, res) => {
+app.get("/test", (req, res) => {
     res.json({ status: "Engine is running" });
 });
 
-app.post('/command', async (req, res) => {
+app.post("/command", async (req, res) => {
     const cmd = req.body.command;
     if (!cmd) {
         return res.status(400).json({ error: "No command provided" });
@@ -50,10 +54,13 @@ app.post('/command', async (req, res) => {
     console.log(`[Command Sent]: ${cmd}`); // Debugging
 
     try {
-        inputStream.write(cmd + '\n');
+        inputStream.write(cmd + "\n");
 
         const response = await new Promise((resolve, reject) => {
-            const timeout = setTimeout(() => reject(new Error("Timeout waiting for response")), 5000);
+            const timeout = setTimeout(
+                () => reject(new Error("Timeout waiting for response")),
+                5000,
+            );
             responseQueue.push((data) => {
                 clearTimeout(timeout);
                 resolve(data);
@@ -62,14 +69,13 @@ app.post('/command', async (req, res) => {
 
         console.log(`[Response Received]: ${response}`); // Debugging
         res.json({ response });
-
     } catch (err) {
         console.error(`[Command Error]: ${err.message}`);
         res.status(408).json({ error: err.message });
     }
 });
 
-process.on('SIGINT', () => {
+process.on("SIGINT", () => {
     console.log("Shutting down server and subprocess...");
     subprocess.kill();
     process.exit();

From 3fce842d2c3e661b2ffbc746ff3a1a2428ecf641 Mon Sep 17 00:00:00 2001
From: Vitaly Kuprin <vitas_s@inbox.lv>
Date: Sun, 15 Dec 2024 14:55:02 +0100
Subject: [PATCH 4/7] chore: add rapfi engine

Signed-off-by: Vitaly Kuprin <vitas_s@inbox.lv>
---
 .../packages/gomoku-api/client/hooks/index.ts |   2 +-
 .../client/hooks/useGetApiRapfiTest.ts        | 167 +++++++++++++++++
 .../client/hooks/useGetApiV1RapfiTest.ts      | 168 ------------------
 .../client/models/GetApiRapfiTest.ts          |  20 +++
 .../client/models/GetApiV1RapfiTest.ts        |  20 ---
 .../gomoku-api/client/models/index.ts         |   2 +-
 GomokuClient/packages/gomoku-api/schema.json  |   2 +-
 7 files changed, 190 insertions(+), 191 deletions(-)
 create mode 100644 GomokuClient/packages/gomoku-api/client/hooks/useGetApiRapfiTest.ts
 delete mode 100644 GomokuClient/packages/gomoku-api/client/hooks/useGetApiV1RapfiTest.ts
 create mode 100644 GomokuClient/packages/gomoku-api/client/models/GetApiRapfiTest.ts
 delete mode 100644 GomokuClient/packages/gomoku-api/client/models/GetApiV1RapfiTest.ts

diff --git a/GomokuClient/packages/gomoku-api/client/hooks/index.ts b/GomokuClient/packages/gomoku-api/client/hooks/index.ts
index 42e00cc6..d6e6c45e 100644
--- a/GomokuClient/packages/gomoku-api/client/hooks/index.ts
+++ b/GomokuClient/packages/gomoku-api/client/hooks/index.ts
@@ -5,7 +5,7 @@ export * from "./useGetApiGameRegisteredActive";
 export * from "./useGetApiGameRegisteredAvailableToJoin";
 export * from "./useGetApiGameRegisteredGameidHistory";
 export * from "./useGetApiProfilesUsernameGames";
-export * from "./useGetApiV1RapfiTest";
+export * from "./useGetApiRapfiTest";
 export * from "./useGetHealth";
 export * from "./usePostApiGameAnonymous";
 export * from "./usePostApiGameAnonymousGameidJoin";
diff --git a/GomokuClient/packages/gomoku-api/client/hooks/useGetApiRapfiTest.ts b/GomokuClient/packages/gomoku-api/client/hooks/useGetApiRapfiTest.ts
new file mode 100644
index 00000000..aa59fed8
--- /dev/null
+++ b/GomokuClient/packages/gomoku-api/client/hooks/useGetApiRapfiTest.ts
@@ -0,0 +1,167 @@
+import client from "../../http";
+import {
+  useQuery,
+  queryOptions,
+  useSuspenseQuery,
+} from "@tanstack/react-query";
+import type {
+  GetApiRapfiTestQueryResponse,
+  GetApiRapfiTestHeaderParams,
+  GetApiRapfiTest500,
+} from "../models/GetApiRapfiTest";
+import type {
+  QueryObserverOptions,
+  UseQueryResult,
+  QueryKey,
+  UseSuspenseQueryOptions,
+  UseSuspenseQueryResult,
+} from "@tanstack/react-query";
+
+type GetApiRapfiTestClient = typeof client<
+  GetApiRapfiTestQueryResponse,
+  GetApiRapfiTest500,
+  never
+>;
+type GetApiRapfiTest = {
+  data: GetApiRapfiTestQueryResponse;
+  error: GetApiRapfiTest500;
+  request: never;
+  pathParams: never;
+  queryParams: never;
+  headerParams: GetApiRapfiTestHeaderParams;
+  response: GetApiRapfiTestQueryResponse;
+  client: {
+    parameters: Partial<Parameters<GetApiRapfiTestClient>[0]>;
+    return: Awaited<ReturnType<GetApiRapfiTestClient>>;
+  };
+};
+export const getApiRapfiTestQueryKey = () =>
+  [{ url: "/api/rapfi/test" }] as const;
+export type GetApiRapfiTestQueryKey = ReturnType<
+  typeof getApiRapfiTestQueryKey
+>;
+export function getApiRapfiTestQueryOptions(
+  headers?: GetApiRapfiTest["headerParams"],
+  options: GetApiRapfiTest["client"]["parameters"] = {},
+) {
+  const queryKey = getApiRapfiTestQueryKey();
+  return queryOptions({
+    queryKey,
+    queryFn: async () => {
+      const res = await client<
+        GetApiRapfiTest["data"],
+        GetApiRapfiTest["error"]
+      >({
+        method: "get",
+        url: `/api/rapfi/test`,
+        headers: { ...headers, ...options.headers },
+        ...options,
+      });
+      return res.data;
+    },
+  });
+}
+/**
+ * @summary Test connection with Rapfi engine
+ * @link /api/rapfi/test
+ */
+export function useGetApiRapfiTest<
+  TData = GetApiRapfiTest["response"],
+  TQueryData = GetApiRapfiTest["response"],
+  TQueryKey extends QueryKey = GetApiRapfiTestQueryKey,
+>(
+  headers?: GetApiRapfiTest["headerParams"],
+  options: {
+    query?: Partial<
+      QueryObserverOptions<
+        GetApiRapfiTest["response"],
+        GetApiRapfiTest["error"],
+        TData,
+        TQueryData,
+        TQueryKey
+      >
+    >;
+    client?: GetApiRapfiTest["client"]["parameters"];
+  } = {},
+): UseQueryResult<TData, GetApiRapfiTest["error"]> & {
+  queryKey: TQueryKey;
+} {
+  const { query: queryOptions, client: clientOptions = {} } = options ?? {};
+  const queryKey = queryOptions?.queryKey ?? getApiRapfiTestQueryKey();
+  const query = useQuery({
+    ...(getApiRapfiTestQueryOptions(
+      headers,
+      clientOptions,
+    ) as unknown as QueryObserverOptions),
+    queryKey,
+    ...(queryOptions as unknown as Omit<QueryObserverOptions, "queryKey">),
+  }) as UseQueryResult<TData, GetApiRapfiTest["error"]> & {
+    queryKey: TQueryKey;
+  };
+  query.queryKey = queryKey as TQueryKey;
+  return query;
+}
+export const getApiRapfiTestSuspenseQueryKey = () =>
+  [{ url: "/api/rapfi/test" }] as const;
+export type GetApiRapfiTestSuspenseQueryKey = ReturnType<
+  typeof getApiRapfiTestSuspenseQueryKey
+>;
+export function getApiRapfiTestSuspenseQueryOptions(
+  headers?: GetApiRapfiTest["headerParams"],
+  options: GetApiRapfiTest["client"]["parameters"] = {},
+) {
+  const queryKey = getApiRapfiTestSuspenseQueryKey();
+  return queryOptions({
+    queryKey,
+    queryFn: async () => {
+      const res = await client<
+        GetApiRapfiTest["data"],
+        GetApiRapfiTest["error"]
+      >({
+        method: "get",
+        url: `/api/rapfi/test`,
+        headers: { ...headers, ...options.headers },
+        ...options,
+      });
+      return res.data;
+    },
+  });
+}
+/**
+ * @summary Test connection with Rapfi engine
+ * @link /api/rapfi/test
+ */
+export function useGetApiRapfiTestSuspense<
+  TData = GetApiRapfiTest["response"],
+  TQueryKey extends QueryKey = GetApiRapfiTestSuspenseQueryKey,
+>(
+  headers?: GetApiRapfiTest["headerParams"],
+  options: {
+    query?: Partial<
+      UseSuspenseQueryOptions<
+        GetApiRapfiTest["response"],
+        GetApiRapfiTest["error"],
+        TData,
+        TQueryKey
+      >
+    >;
+    client?: GetApiRapfiTest["client"]["parameters"];
+  } = {},
+): UseSuspenseQueryResult<TData, GetApiRapfiTest["error"]> & {
+  queryKey: TQueryKey;
+} {
+  const { query: queryOptions, client: clientOptions = {} } = options ?? {};
+  const queryKey = queryOptions?.queryKey ?? getApiRapfiTestSuspenseQueryKey();
+  const query = useSuspenseQuery({
+    ...(getApiRapfiTestSuspenseQueryOptions(
+      headers,
+      clientOptions,
+    ) as unknown as UseSuspenseQueryOptions),
+    queryKey,
+    ...(queryOptions as unknown as Omit<UseSuspenseQueryOptions, "queryKey">),
+  }) as UseSuspenseQueryResult<TData, GetApiRapfiTest["error"]> & {
+    queryKey: TQueryKey;
+  };
+  query.queryKey = queryKey as TQueryKey;
+  return query;
+}
diff --git a/GomokuClient/packages/gomoku-api/client/hooks/useGetApiV1RapfiTest.ts b/GomokuClient/packages/gomoku-api/client/hooks/useGetApiV1RapfiTest.ts
deleted file mode 100644
index 4660782d..00000000
--- a/GomokuClient/packages/gomoku-api/client/hooks/useGetApiV1RapfiTest.ts
+++ /dev/null
@@ -1,168 +0,0 @@
-import client from "../../http";
-import {
-  useQuery,
-  queryOptions,
-  useSuspenseQuery,
-} from "@tanstack/react-query";
-import type {
-  GetApiV1RapfiTestQueryResponse,
-  GetApiV1RapfiTestHeaderParams,
-  GetApiV1RapfiTest500,
-} from "../models/GetApiV1RapfiTest";
-import type {
-  QueryObserverOptions,
-  UseQueryResult,
-  QueryKey,
-  UseSuspenseQueryOptions,
-  UseSuspenseQueryResult,
-} from "@tanstack/react-query";
-
-type GetApiV1RapfiTestClient = typeof client<
-  GetApiV1RapfiTestQueryResponse,
-  GetApiV1RapfiTest500,
-  never
->;
-type GetApiV1RapfiTest = {
-  data: GetApiV1RapfiTestQueryResponse;
-  error: GetApiV1RapfiTest500;
-  request: never;
-  pathParams: never;
-  queryParams: never;
-  headerParams: GetApiV1RapfiTestHeaderParams;
-  response: GetApiV1RapfiTestQueryResponse;
-  client: {
-    parameters: Partial<Parameters<GetApiV1RapfiTestClient>[0]>;
-    return: Awaited<ReturnType<GetApiV1RapfiTestClient>>;
-  };
-};
-export const getApiV1RapfiTestQueryKey = () =>
-  [{ url: "/api/v1/rapfi/test" }] as const;
-export type GetApiV1RapfiTestQueryKey = ReturnType<
-  typeof getApiV1RapfiTestQueryKey
->;
-export function getApiV1RapfiTestQueryOptions(
-  headers?: GetApiV1RapfiTest["headerParams"],
-  options: GetApiV1RapfiTest["client"]["parameters"] = {},
-) {
-  const queryKey = getApiV1RapfiTestQueryKey();
-  return queryOptions({
-    queryKey,
-    queryFn: async () => {
-      const res = await client<
-        GetApiV1RapfiTest["data"],
-        GetApiV1RapfiTest["error"]
-      >({
-        method: "get",
-        url: `/api/v1/rapfi/test`,
-        headers: { ...headers, ...options.headers },
-        ...options,
-      });
-      return res.data;
-    },
-  });
-}
-/**
- * @summary Test connection with Rapfi engine
- * @link /api/v1/rapfi/test
- */
-export function useGetApiV1RapfiTest<
-  TData = GetApiV1RapfiTest["response"],
-  TQueryData = GetApiV1RapfiTest["response"],
-  TQueryKey extends QueryKey = GetApiV1RapfiTestQueryKey,
->(
-  headers?: GetApiV1RapfiTest["headerParams"],
-  options: {
-    query?: Partial<
-      QueryObserverOptions<
-        GetApiV1RapfiTest["response"],
-        GetApiV1RapfiTest["error"],
-        TData,
-        TQueryData,
-        TQueryKey
-      >
-    >;
-    client?: GetApiV1RapfiTest["client"]["parameters"];
-  } = {},
-): UseQueryResult<TData, GetApiV1RapfiTest["error"]> & {
-  queryKey: TQueryKey;
-} {
-  const { query: queryOptions, client: clientOptions = {} } = options ?? {};
-  const queryKey = queryOptions?.queryKey ?? getApiV1RapfiTestQueryKey();
-  const query = useQuery({
-    ...(getApiV1RapfiTestQueryOptions(
-      headers,
-      clientOptions,
-    ) as unknown as QueryObserverOptions),
-    queryKey,
-    ...(queryOptions as unknown as Omit<QueryObserverOptions, "queryKey">),
-  }) as UseQueryResult<TData, GetApiV1RapfiTest["error"]> & {
-    queryKey: TQueryKey;
-  };
-  query.queryKey = queryKey as TQueryKey;
-  return query;
-}
-export const getApiV1RapfiTestSuspenseQueryKey = () =>
-  [{ url: "/api/v1/rapfi/test" }] as const;
-export type GetApiV1RapfiTestSuspenseQueryKey = ReturnType<
-  typeof getApiV1RapfiTestSuspenseQueryKey
->;
-export function getApiV1RapfiTestSuspenseQueryOptions(
-  headers?: GetApiV1RapfiTest["headerParams"],
-  options: GetApiV1RapfiTest["client"]["parameters"] = {},
-) {
-  const queryKey = getApiV1RapfiTestSuspenseQueryKey();
-  return queryOptions({
-    queryKey,
-    queryFn: async () => {
-      const res = await client<
-        GetApiV1RapfiTest["data"],
-        GetApiV1RapfiTest["error"]
-      >({
-        method: "get",
-        url: `/api/v1/rapfi/test`,
-        headers: { ...headers, ...options.headers },
-        ...options,
-      });
-      return res.data;
-    },
-  });
-}
-/**
- * @summary Test connection with Rapfi engine
- * @link /api/v1/rapfi/test
- */
-export function useGetApiV1RapfiTestSuspense<
-  TData = GetApiV1RapfiTest["response"],
-  TQueryKey extends QueryKey = GetApiV1RapfiTestSuspenseQueryKey,
->(
-  headers?: GetApiV1RapfiTest["headerParams"],
-  options: {
-    query?: Partial<
-      UseSuspenseQueryOptions<
-        GetApiV1RapfiTest["response"],
-        GetApiV1RapfiTest["error"],
-        TData,
-        TQueryKey
-      >
-    >;
-    client?: GetApiV1RapfiTest["client"]["parameters"];
-  } = {},
-): UseSuspenseQueryResult<TData, GetApiV1RapfiTest["error"]> & {
-  queryKey: TQueryKey;
-} {
-  const { query: queryOptions, client: clientOptions = {} } = options ?? {};
-  const queryKey =
-    queryOptions?.queryKey ?? getApiV1RapfiTestSuspenseQueryKey();
-  const query = useSuspenseQuery({
-    ...(getApiV1RapfiTestSuspenseQueryOptions(
-      headers,
-      clientOptions,
-    ) as unknown as UseSuspenseQueryOptions),
-    queryKey,
-    ...(queryOptions as unknown as Omit<UseSuspenseQueryOptions, "queryKey">),
-  }) as UseSuspenseQueryResult<TData, GetApiV1RapfiTest["error"]> & {
-    queryKey: TQueryKey;
-  };
-  query.queryKey = queryKey as TQueryKey;
-  return query;
-}
diff --git a/GomokuClient/packages/gomoku-api/client/models/GetApiRapfiTest.ts b/GomokuClient/packages/gomoku-api/client/models/GetApiRapfiTest.ts
new file mode 100644
index 00000000..9ee31b92
--- /dev/null
+++ b/GomokuClient/packages/gomoku-api/client/models/GetApiRapfiTest.ts
@@ -0,0 +1,20 @@
+export type GetApiRapfiTestHeaderParams = {
+  /**
+   * @type string | undefined
+   */
+  "X-Version"?: string;
+};
+/**
+ * @description Connection successful
+ */
+export type GetApiRapfiTest200 = any;
+/**
+ * @description Connection failed
+ */
+export type GetApiRapfiTest500 = any;
+export type GetApiRapfiTestQueryResponse = any;
+export type GetApiRapfiTestQuery = {
+  Response: GetApiRapfiTestQueryResponse;
+  HeaderParams: GetApiRapfiTestHeaderParams;
+  Errors: GetApiRapfiTest500;
+};
diff --git a/GomokuClient/packages/gomoku-api/client/models/GetApiV1RapfiTest.ts b/GomokuClient/packages/gomoku-api/client/models/GetApiV1RapfiTest.ts
deleted file mode 100644
index 50cd37d6..00000000
--- a/GomokuClient/packages/gomoku-api/client/models/GetApiV1RapfiTest.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-export type GetApiV1RapfiTestHeaderParams = {
-  /**
-   * @type string | undefined
-   */
-  "X-Version"?: string;
-};
-/**
- * @description Connection successful
- */
-export type GetApiV1RapfiTest200 = any;
-/**
- * @description Connection failed
- */
-export type GetApiV1RapfiTest500 = any;
-export type GetApiV1RapfiTestQueryResponse = any;
-export type GetApiV1RapfiTestQuery = {
-  Response: GetApiV1RapfiTestQueryResponse;
-  HeaderParams: GetApiV1RapfiTestHeaderParams;
-  Errors: GetApiV1RapfiTest500;
-};
diff --git a/GomokuClient/packages/gomoku-api/client/models/index.ts b/GomokuClient/packages/gomoku-api/client/models/index.ts
index a66b93ed..c8e0c8a0 100644
--- a/GomokuClient/packages/gomoku-api/client/models/index.ts
+++ b/GomokuClient/packages/gomoku-api/client/models/index.ts
@@ -12,7 +12,7 @@ export * from "./GetApiGameRegisteredActive";
 export * from "./GetApiGameRegisteredAvailableToJoin";
 export * from "./GetApiGameRegisteredGameidHistory";
 export * from "./GetApiProfilesUsernameGames";
-export * from "./GetApiV1RapfiTest";
+export * from "./GetApiRapfiTest";
 export * from "./GetAvailableGamesResponse";
 export * from "./GetAvailableGamesResponseIEnumerablePaginatedResponse";
 export * from "./GetGameHistoryResponse";
diff --git a/GomokuClient/packages/gomoku-api/schema.json b/GomokuClient/packages/gomoku-api/schema.json
index dc17872a..cd5826a3 100644
--- a/GomokuClient/packages/gomoku-api/schema.json
+++ b/GomokuClient/packages/gomoku-api/schema.json
@@ -319,7 +319,7 @@
         }
       }
     },
-    "/api/v1/rapfi/test": {
+    "/api/rapfi/test": {
       "get": {
         "tags": ["RapfiEngine"],
         "summary": "Test connection with Rapfi engine",

From db30758c5a4788c1a8dd6d847ed972fdeff3f29c Mon Sep 17 00:00:00 2001
From: Vitaly Kuprin <vitas_s@inbox.lv>
Date: Sun, 15 Dec 2024 14:55:46 +0100
Subject: [PATCH 5/7] chore: debugging

Signed-off-by: Vitaly Kuprin <vitas_s@inbox.lv>
---
 GomokuAI/wrapper.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/GomokuAI/wrapper.js b/GomokuAI/wrapper.js
index 53b1e452..d1588725 100644
--- a/GomokuAI/wrapper.js
+++ b/GomokuAI/wrapper.js
@@ -51,7 +51,7 @@ app.post("/command", async (req, res) => {
         return res.status(400).json({ error: "No command provided" });
     }
 
-    console.log(`[Command Sent]: ${cmd}`); // Debugging
+    console.log(`[Command Sent]: ${cmd}`);
 
     try {
         inputStream.write(cmd + "\n");

From e6079463cd3d519eca4f33edfdd9354d49a66570 Mon Sep 17 00:00:00 2001
From: Vitaly Kuprin <vitas_s@inbox.lv>
Date: Sun, 15 Dec 2024 14:56:28 +0100
Subject: [PATCH 6/7] chore: debugging

Signed-off-by: Vitaly Kuprin <vitas_s@inbox.lv>
---
 GomokuAI/wrapper.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/GomokuAI/wrapper.js b/GomokuAI/wrapper.js
index d1588725..45f6f43a 100644
--- a/GomokuAI/wrapper.js
+++ b/GomokuAI/wrapper.js
@@ -67,7 +67,7 @@ app.post("/command", async (req, res) => {
             });
         });
 
-        console.log(`[Response Received]: ${response}`); // Debugging
+        console.log(`[Response Received]: ${response}`);
         res.json({ response });
     } catch (err) {
         console.error(`[Command Error]: ${err.message}`);

From 5c09a25494dd7af9d6623badeedc0ee7aad3fb19 Mon Sep 17 00:00:00 2001
From: Vitaly Kuprin <vitas_s@inbox.lv>
Date: Sun, 15 Dec 2024 14:58:28 +0100
Subject: [PATCH 7/7] chore: change to custom fork

Signed-off-by: Vitaly Kuprin <vitas_s@inbox.lv>
---
 GomokuAI/Dockerfile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/GomokuAI/Dockerfile b/GomokuAI/Dockerfile
index 0e3aef21..e80dd493 100644
--- a/GomokuAI/Dockerfile
+++ b/GomokuAI/Dockerfile
@@ -14,7 +14,7 @@ RUN apt-get update && apt-get install -y \
 
 WORKDIR /app/GomokuAI
 
-RUN git clone --recurse-submodules https://github.com/dhbloo/rapfi.git rapfi && \
+RUN git clone --recurse-submodules https://github.com/vkuprin/rapfi.git rapfi && \
     cd rapfi/Rapfi && \
     mkdir build && cd build && \
     cmake .. \