From 047a3ffd5c692552db211f197809912a753fec19 Mon Sep 17 00:00:00 2001 From: moxitech Date: Fri, 11 Oct 2024 08:12:41 +0700 Subject: [PATCH] server & frontend update :: signaling --- docker-compose.yaml | 4 + src/frontend/Dockerfile | 2 +- src/frontend/src/App.js | 2 + src/frontend/src/Services/WebsocketHook.js | 41 ++- src/frontend/src/UserAccount.scss | 2 +- src/frontend/src/pages/Dashboard.js | 251 +++++++++++++----- src/frontend/src/pages/Login.js | 40 ++- src/frontend/src/pages/Main.js | 1 - src/frontend/src/pages/UserAccount.js | 23 +- src/frontend/src/pages/model/Drone.js | 6 + src/server/cmd/main.go | 1 + src/server/entity/websocket/models.go | 41 +-- src/server/internal/database/mongo.go | 8 +- .../handlers/authorization/auth_handler.go | 30 ++- src/server/internal/server/websocket.go | 16 ++ 15 files changed, 361 insertions(+), 107 deletions(-) diff --git a/docker-compose.yaml b/docker-compose.yaml index 5da62a3..45e9a18 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -71,6 +71,10 @@ services: context: ./src/frontend dockerfile: Dockerfile env_file: ".env" + volumes: + - ./src/frontend:/app + working_dir: /app + command: ["npm", "start"] ports: - "3000:3000" networks: diff --git a/src/frontend/Dockerfile b/src/frontend/Dockerfile index 877433e..acdaea5 100644 --- a/src/frontend/Dockerfile +++ b/src/frontend/Dockerfile @@ -11,7 +11,7 @@ COPY package*.json ./ RUN npm install # Bundle app source -COPY . . +# COPY . . # Make port 3000 available to the world outside this container EXPOSE 3000 diff --git a/src/frontend/src/App.js b/src/frontend/src/App.js index 21081dc..263c5f9 100644 --- a/src/frontend/src/App.js +++ b/src/frontend/src/App.js @@ -12,6 +12,7 @@ import Docs from './pages/Docs'; // Импортируем страницу п import './css/bootstrap-5.3.3-dist/css/bootstrap.min.css'; import './App.css'; import "bootstrap-icons/font/bootstrap-icons.css"; +import {removeCustomCookie} from './Services/Local' import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom'; const App = () => { @@ -20,6 +21,7 @@ const App = () => { // Функция для выхода из системы const handleLogout = () => { + removeCustomCookie("userToken") setIsLoggedIn(false); }; diff --git a/src/frontend/src/Services/WebsocketHook.js b/src/frontend/src/Services/WebsocketHook.js index d2e2c9c..66480bc 100644 --- a/src/frontend/src/Services/WebsocketHook.js +++ b/src/frontend/src/Services/WebsocketHook.js @@ -88,8 +88,9 @@ const useWebsocketConnection = (userToken, roomHash) => { }; // Функция для отправки данных в WebSocket - const sendMessage = (message) => { + const sendMessage = async (message) => { if (socketRef.current && socketRef.current.readyState === WebSocket.OPEN) { + console.log(JSON.stringify(message)) socketRef.current.send(JSON.stringify(message)); } else { console.error('WebSocket is not open. Unable to send message:', message); @@ -99,4 +100,42 @@ const useWebsocketConnection = (userToken, roomHash) => { return { websocketStruct, sendMessage }; }; +export const spawnJsonSignal = (signal, name, coords) => { + if (![1, 2].includes(signal)) { + throw new Error('Invalid signal value. Expected 1 or 2.'); + } + + if (typeof name !== 'string' || !name.trim()) { + throw new Error('Invalid name. Expected a non-empty string.'); + } + + return { + signal, + data: { + name, + params: { + coords, + }, + }, + }; +}; + +export const DeleteSignal = (name) => { + const signal = 3; + + if (typeof name !== 'string' || !name.trim()) { + throw new Error('Invalid name. Expected a non-empty string.'); + } + + return { + signal, + data: { + name, + }, + }; +}; + + + + export default useWebsocketConnection; \ No newline at end of file diff --git a/src/frontend/src/UserAccount.scss b/src/frontend/src/UserAccount.scss index eb5cf87..ec0188c 100644 --- a/src/frontend/src/UserAccount.scss +++ b/src/frontend/src/UserAccount.scss @@ -1,6 +1,6 @@ .user-account { padding: 20px; - background-color: #f4f4f4; + background-color: #3cafb7; border-radius: 10px; max-width: 400px; margin: 0 auto; diff --git a/src/frontend/src/pages/Dashboard.js b/src/frontend/src/pages/Dashboard.js index 408838e..e0676ec 100644 --- a/src/frontend/src/pages/Dashboard.js +++ b/src/frontend/src/pages/Dashboard.js @@ -6,25 +6,24 @@ import BaseStation from './model/BaseStation'; import HeightPoint from './model/HeightPoint'; import { RandomHeightPoint } from './helpers/generateRandomHeightPoints' import ModalWindow from './components/Modal/Modal'; -import useWebsocketConnection from '../Services/WebsocketHook'; +import { getCustomCookie } from '../Services/Local'; +import useWebsocketConnection, { DeleteSignal, spawnJsonSignal } from '../Services/WebsocketHook'; import './Dashboard.css'; const Dashboard = () => { - const mountRef = useRef(null); // Указатель монтирования - const sceneRef = useRef(null); // Указатель на сцену - const mouse = new THREE.Vector2(); // Мышка - const {websocketStruct, sendMessage} = useWebsocketConnection(1, 1); - - const [heightData, setHeightData] = useState(RandomHeightPoint()); // Высоты - const [formData, setFormData] = useState({ x: '', y: '', height: '' }); // Форма для ввода данных карты - const [mouseState, setMouseState] = useState({ x: 0, y: 0, z: 0 }); // Форма для ввода данных карты - const [drones, setDrones] = useState([]) // Все дроны - const [selectedDrone, setSelectedDrone] = useState(null); // Состояние для выбранного дрона - const [baseStation, setBaseStation] = useState([]) // Все базовые станции - const [selectedBaseStation, setSelectedBaseStation] = useState(null); // Состояние для выбранной базовой станции - const [mapSettings, setMapSettings] = useState({maxHeight: 20, coordX: 0, coordY: 0, }); // Настройки карты - const [contextMenu, setContextMenu] = useState({ visible: false, x: 0, y: 0 }); // контекстное меню сцены + const mountRef = useRef(null); // Указатель монтирования + const sceneRef = useRef(null); // Указатель на сцену + const {websocketStruct, sendMessage} = useWebsocketConnection(getCustomCookie("userToken"), 1); + const [heightData, setHeightData] = useState(RandomHeightPoint()); // Высоты + const [formData, setFormData] = useState({ x: '', y: '', height: '' }); // Форма для ввода данных карты + const [mouseState, setMouseState] = useState({ x: 0, y: 0, z: 0 }); // Форма для ввода данных карты + const [drones, setDrones] = useState([]) // Все дроны + const [selectedDrone, setSelectedDrone] = useState(null); // Состояние для выбранного дрона + const [baseStation, setBaseStation] = useState([]) // Все базовые станции + const [selectedBaseStation, setSelectedBaseStation] = useState(null); // Состояние для выбранной базовой станции + const [mapSettings, setMapSettings] = useState({maxHeight: 20, coordX: 0, coordY: 0, }); // Настройки карты + const [contextMenu, setContextMenu] = useState({ visible: false, x: 0, y: 0 }); // контекстное меню сцены const [objectType, setObjectType] = useState(1); // 1 = Drone, 2 = Base Station const [formObjectData, setFormObjectData] = useState({ @@ -38,6 +37,45 @@ const Dashboard = () => { baseStationField1: "", baseStationField2: "" }); + const [searchTerm, setSearchTerm] = useState(""); + const handleSearch = () => { + const foundDrone = drones.find(drone => drone.name.toLowerCase() === searchTerm.toLowerCase()); + const foundBaseStation = baseStation.find(base => base.name.toLowerCase() === searchTerm.toLowerCase()); + + if (foundDrone) { + // Выделяем найденный дрон + if (selectedDrone) { + selectedDrone.getObject().traverse((child) => { + if (child.isMesh) { + child.material.color.set(0xff0000); + } + }); + } + foundDrone.getObject().traverse((child) => { + if (child.isMesh) { + child.material.color.set(0x00ff00); + } + }); + setSelectedDrone(foundDrone); + } else if (foundBaseStation) { + // Выделяем найденную базу + if (selectedBaseStation) { + selectedBaseStation.getObject().traverse((child) => { + if (child.isMesh) { + child.material.color.set(0x0000ff); + } + }); + } + foundBaseStation.getObject().traverse((child) => { + if (child.isMesh) { + child.material.color.set(0x00ff00); + } + }); + setSelectedBaseStation(foundBaseStation); + } else { + alert("Объект с указанным именем не найден"); + } + }; const handleTypeChange = (type) => { @@ -45,14 +83,8 @@ const Dashboard = () => { setFormData({ ...formData, type }); }; - const handleSendMessage = () => { - const message = { - signal: 0, - data: { - key: 'value' - } - }; - sendMessage(message); + const handleDeleteSignal = (name) => { + sendMessage(DeleteSignal(name)); }; @@ -82,11 +114,40 @@ const Dashboard = () => { isModalSearchOpen: false, }); }; + useEffect(() => { - if (websocketStruct) { - console.log('Received WebSocket Data:', websocketStruct); + if (websocketStruct && websocketStruct.modulation) { + const modulation = websocketStruct.modulation; + // Парсинг карты + const map = modulation.map; + setMapSettings({ + name: map.name, + minBound: map.map.MinBound, + maxBound: map.map.MaxBound, + heightData: map.map.HeightData, + maxHeight: 20, + }); + setHeightData(map.map.HeightData.flatMap((row, x) => row.map((height, y) => new HeightPoint(x, y, height)))); + + // Парсинг объектов + const parsedDrones = []; + const parsedBaseStations = []; + modulation.objects.forEach((obj) => { + if (obj.type === 1) { + const drone = new Drone(obj.name); + drone.setPosition(...obj.coords); + parsedDrones.push(drone); + } else if (obj.type === 2) { + const base = new BaseStation(obj.name); + base.setPosition(...obj.coords); + parsedBaseStations.push(base); + } + }); + setDrones(parsedDrones); + setBaseStation(parsedBaseStations); } }, [websocketStruct]); + useEffect(() => { if (!mountRef.current) return; @@ -94,7 +155,7 @@ const Dashboard = () => { let height = mountRef.current.clientHeight; // Создаем объект сцены const scene = new THREE.Scene(); - + scene.background = new THREE.Color(0xffffff); // Сохраняем ссылку на сцену sceneRef.current = scene; // Создаем камеру @@ -140,7 +201,7 @@ const Dashboard = () => { mesh.rotation.x = -Math.PI / 2; scene.add(mesh); - const axesHelper = new THREE.AxesHelper(10); + const axesHelper = new THREE.AxesHelper(100); scene.add(axesHelper); const controls = new OrbitControls(camera, renderer.domElement); @@ -149,35 +210,69 @@ const Dashboard = () => { const light = new THREE.DirectionalLight(0xffffff, 1); light.position.set(0, 50, 50).normalize(); scene.add(light); - // Обработка кликов на сцене - const handleClick = (event) => { - mouse.x = (event.clientX / window.innerWidth) * 2 - 1; - mouse.y = - (event.clientY / window.innerHeight) * 2 + 1; - console.log('Mouse coordinates:', mouse); - const raycaster = new THREE.Raycaster(); - raycaster.setFromCamera(mouse, camera); +// Обработка кликов на сцене +const handleClick = (event) => { + // Рассчитываем координаты мыши в нормализованной системе координат и округляем до целого числа + const mouse = new THREE.Vector2(); + mouse.x = (event.clientX / window.innerWidth) * 2 - 1; + mouse.y = - (event.clientY / window.innerHeight) * 2 + 1; + console.log('Mouse coordinates:', mouse); - const intersects = raycaster.intersectObjects(drones.map(drone => drone.getObject()), true); - console.log('Intersections:', intersects) - console.log('Drones:', drones.map(drone => [drone.getObject(), drone.getObject().position, drone.name])) - if (intersects.length > 0) { - const selected = intersects[0].object; - console.log('Clicked on:', selected); // Лог для проверки объекта - const drone = drones.find(drone => drone.getObject().children[0] === selected); - if (drone) { - if (selectedDrone) { - selectedDrone.getObject().children[0].material.color.set(0xff0000); - } - drone.getObject().children[0].material.color.set(0xff1111); - setSelectedDrone(drone); - } - } else { - if (selectedDrone) { - selectedDrone.getObject().children[0].material.color.set(0xff0000); - setSelectedDrone(null); - } + // Создаем объект Raycaster для проверки пересечений + const raycaster = new THREE.Raycaster(); + const rayHelper = new THREE.ArrowHelper(raycaster.ray.direction, raycaster.ray.origin, 100, 0xff4444); + scene.add(rayHelper); + raycaster.setFromCamera(mouse, camera); + + // Проверяем пересечения с объектами дронов + const intersects = raycaster.intersectObjects(drones.map(drone => drone.getObject()), true); + console.log('Intersections:', intersects); + console.log('Drones:', drones.map(drone => [drone.getObject(), drone.getObject().position, drone.name])); + + if (intersects.length > 0) { + const selected = intersects[0].object; + console.log('Clicked on:', selected); // Лог для проверки объекта + + // Поиск дрона рекурсивно + const drone = drones.find(drone => containsObjectRecursively(drone.getObject(), selected)); + + if (drone) { + // Сбрасываем цвет предыдущего выбранного дрона + if (selectedDrone) { + drone.getObject().visible = true; + // selectedDrone.getObject().material.color.set(0xff0000); } - }; + // Устанавливаем цвет выбранного дрона + // drone.getObject().material.color.set(0xff1111); + drone.getObject().visible = false; + console.log(drone); + setSelectedDrone(drone); + } + } else { + // Сбрасываем выбор, если ни один дрон не был выбран + if (selectedDrone) { + // selectedDrone.getObject().material.color.set(0xff0000); + selectedDrone .getObject().visible = true; + + setSelectedDrone(null); + } + } +}; + +// Рекурсивная функция для поиска объекта среди детей +const containsObjectRecursively = (parent, target) => { + if (parent === target) { + return true; + } + for (let child of parent.children) { + if (containsObjectRecursively(child, target)) { + return true; + } + } + return false; +}; + + const handleMouseMove = (event) => { let x = event.x; @@ -226,21 +321,36 @@ const Dashboard = () => { // Создаем новый материал для каждого дрона drone.setPosition(Math.random() * 20 - 10, 20, Math.random() * 20 - 10); setDrones((prevDrones) => [...prevDrones, drone]); - console.log(drones.map(drone => drone.getObject().children[0])); + console.log(drones.map(drone => drone.getObject())); + let json_signal = spawnJsonSignal(1, current / 1000 + "", "" + Math.round(drone.getObject().position.x) + "," + Math.round(drone.getObject().position.y) + "," + Math.round(drone.getObject().position.z) + ""); + sendMessage(json_signal) sceneRef.current.add(drone.getObject()); } }; // Добавление дрона в сцену - const handleAddBaseStation = () => { - if (sceneRef.current) { - const current = Date.now(); - const base = new BaseStation(current / 1000); - base.setPosition(Math.random() * 20 - 10, 20, Math.random() * 20 - 10); - setBaseStation((prev) => [...prev, base]); - console.log(baseStation.map(b => b.getObject().children[0])); - sceneRef.current.add(base.getObject()); - } - }; +// Добавление базовой станции в сцену +const handleAddBaseStation = () => { + if (sceneRef.current) { + const current = Date.now(); + const base = new BaseStation(current / 1000); + + // Выбираем случайные координаты X и Z + const x = Math.random() * 20 - 10; + const z = Math.random() * 20 - 10; + + // Находим точку высоты для установки базовой станции на карту + const heightPoint = heightData.find(point => point.x === Math.round(x) && point.y === Math.round(z)); + console.log(heightPoint) + const y = heightPoint ? heightPoint.height : 0; + + // Устанавливаем позицию базовой станции на основании высоты карты + base.setPosition(x, y, z); + + setBaseStation((prev) => [...prev, base]); + console.log(baseStation.map(b => b.getObject().children[0])); + sceneRef.current.add(base.getObject()); + } +}; // Обработчик ввода на форму высот const handleInputChange = (event) => { @@ -449,15 +559,20 @@ const Dashboard = () => {

Поиск

- - + setSearchTerm(e.target.value)} + /> +

Удаление

Вы точно хотите удалить объект X?

- +
diff --git a/src/frontend/src/pages/Login.js b/src/frontend/src/pages/Login.js index 7a8ca8f..d9ee1a6 100644 --- a/src/frontend/src/pages/Login.js +++ b/src/frontend/src/pages/Login.js @@ -1,5 +1,6 @@ import React, { useEffect, useState } from 'react'; import { setCustomCookie, getCustomCookie } from '../Services/Local' +import { giveMeServerAddress } from '../Services/Server' import '../Login.scss'; @@ -13,16 +14,37 @@ const Login = ({ onLogin }) => { onLogin(); } }, []) - const handleSubmit = (e) => { + const handleSubmit = async (e) => { e.preventDefault(); - // Simple login/password check - if (username === 'admin' && password === 'admin') { - // TODO :: CHANGE - setCustomCookie('userToken', '12345', { expires: 7 }); // Куки с истечением через 7 дней - onLogin(); // Call function on successful login - - } else { - setError('Неверный логин или пароль'); + + try { + // Отправляем запрос на сервер + const response = await fetch(giveMeServerAddress() + "/auth/"+ username +"/" + password, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ username, password }) + }); + + // Проверяем статус ответа + if (!response.ok) { + // Если статус не 200, ничего не делаем + setError('Ошибка авторизации. Пожалуйста, попробуйте снова.'); + return; + } + + // Парсим тело ответа в формате JSON + const data = await response.json(); + + // Устанавливаем userToken из тела ответа + setCustomCookie('userToken', data.userid, { expires: 7 }); + + // Вызываем функцию после успешного входа в систему + onLogin(); + } catch (error) { + // Обработка ошибок сети + setError('Произошла ошибка. Пожалуйста, попробуйте снова позже.'); } }; diff --git a/src/frontend/src/pages/Main.js b/src/frontend/src/pages/Main.js index eca1a57..dd612b8 100644 --- a/src/frontend/src/pages/Main.js +++ b/src/frontend/src/pages/Main.js @@ -8,7 +8,6 @@ const Main = () => { useEffect(() => { getSimulations(); - setCustomCookie('userToken', '12345', { expires: 7 }); // Куки с истечением через 7 дней }, []); diff --git a/src/frontend/src/pages/UserAccount.js b/src/frontend/src/pages/UserAccount.js index 45f6ac7..7f8f14f 100644 --- a/src/frontend/src/pages/UserAccount.js +++ b/src/frontend/src/pages/UserAccount.js @@ -1,6 +1,6 @@ import React, { useState } from 'react'; import '../UserAccount.scss'; - +import {getCustomCookie} from '../Services/Local'; const UserAccount = () => { const [userData, setUserData] = useState({ username: 'Никита Николаевич', @@ -10,6 +10,15 @@ const UserAccount = () => { const [isEditing, setIsEditing] = useState(false); const [formData, setFormData] = useState(userData); + const [debug, setDebug] = useState(false) + + const enableDebug = () => { + if (debug){ + setDebug(false) + } else { + setDebug(true) + } + }; const handleChange = (e) => { const { name, value } = e.target; @@ -77,6 +86,18 @@ const UserAccount = () => { )} + + + + {debug ?

+ debug: + UserToken: {getCustomCookie("userToken")} +

+ : +

+ } ); }; diff --git a/src/frontend/src/pages/model/Drone.js b/src/frontend/src/pages/model/Drone.js index 83db1d0..16d4b7d 100644 --- a/src/frontend/src/pages/model/Drone.js +++ b/src/frontend/src/pages/model/Drone.js @@ -15,6 +15,12 @@ class Drone { }, undefined, (error) => { console.error("Ошибка загрузки GLTF:", error); }); + // Создаем красный куб вместо GLB модели + // const geometry = new THREE.BoxGeometry(2, 2, 2); + // const material = new THREE.MeshBasicMaterial({ color: 0xff0000 }); + // const cube = new THREE.Mesh(geometry, material); + // cube.scale.set(scale, scale, scale); + // this.object.add(cube); } setPosition(x, y, z) { diff --git a/src/server/cmd/main.go b/src/server/cmd/main.go index bf35d8a..70ba7d2 100644 --- a/src/server/cmd/main.go +++ b/src/server/cmd/main.go @@ -86,6 +86,7 @@ func main() { if err != nil { panic(err) } + database.Instance = database.NewDbConnection() err = server.SpawnServer() if err != nil { panic(err) diff --git a/src/server/entity/websocket/models.go b/src/server/entity/websocket/models.go index 889f89e..ec53d79 100644 --- a/src/server/entity/websocket/models.go +++ b/src/server/entity/websocket/models.go @@ -1,6 +1,7 @@ package websocket import ( + "fmt" "moxitech/dns/package/math/simulator" "moxitech/dns/package/utils/randomizer" "time" @@ -37,8 +38,15 @@ func (o *Modulation) DeleteObjectIfExists(name string) { } } } -func (o *Modulation) MirrorPayloadToSimulationStruct() { +// MirrorPayloadToSimulationStruct - вернет фулл копию симуляции +func (o *Modulation) MirrorPayloadToSimulationStruct() Modulation { + shadow_sim_copy := Modulation{ + Map: o.Map, + Objects: o.Objects, + Ts_update: o.Ts_update, + } + return shadow_sim_copy } func (o *Modulation) RunSimulator() { @@ -59,22 +67,24 @@ func (o *Modulation) RunSimulator() { // HeightData: heightData, // } // + // ? mapObj := o.Map + // // Определяем дронов // - // drones := []*simulator.Drone{ - // { - // ID: 1, - // Name: "Drone 1", - // Coords: [3]float64{100, 100, 50}, - // Params: simulator.DroneParams{ - // AntennaRadius: 500, - // AntennaDirection: [3]float64{1, 0, 0}, - // Waypoints: [][3]float64{{200, 200, 50}}, - // Speed: 10, - // MeshName: "MeshA", - // }, - // }, - // } + // drones := []*simulator.Drone{ + // { + // ID: 1, + // Name: "Drone 1", + // Coords: [3]float64{100, 100, 50}, + // Params: simulator.DroneParams{ + // AntennaRadius: 500, + // AntennaDirection: [3]float64{1, 0, 0}, + // Waypoints: [][3]float64{{200, 200, 50}}, + // Speed: 10, + // MeshName: "MeshA", + // }, + // }, + // } // // // Определяем базовые станции // @@ -128,6 +138,7 @@ func (o *Modulation) AddObject(name string, obj_type int, coords [3]int, params // Значит объект не станция или не дрон return } + fmt.Println(name, obj_type, coords, params) if o.Objects == nil { o.Objects = make([]*SystemObject, 0) } diff --git a/src/server/internal/database/mongo.go b/src/server/internal/database/mongo.go index 960d12b..dfe5c3d 100644 --- a/src/server/internal/database/mongo.go +++ b/src/server/internal/database/mongo.go @@ -18,12 +18,12 @@ type MongoDbInstance struct { Db *mongo.Database } -var instance *MongoDbInstance +var Instance *MongoDbInstance var once sync.Once // giveMeMongoConnectionString возвращает строку подключения к MongoDB func giveMeMongoConnectionString() string { - return "mongodb://moxitech:moxitech@localhost:27017/" // Замените строку на свою строку подключения + return "mongodb://moxitech:moxitech@mongo:27017/" // Замените строку на свою строку подключения } // NewDbConnection создает подключение к базе данных MongoDB и возвращает единственный экземпляр MongoDbInstance @@ -49,13 +49,13 @@ func NewDbConnection() *MongoDbInstance { log.Println("Успешное подключение к MongoDB") - instance = &MongoDbInstance{ + Instance = &MongoDbInstance{ Client: client, Db: client.Database(os.Getenv("MONGO_INITDB_DATABASE")), } }) - return instance + return Instance } // InsertIntoSimulations вставляет данные в коллекцию "simulations" diff --git a/src/server/internal/server/handlers/authorization/auth_handler.go b/src/server/internal/server/handlers/authorization/auth_handler.go index d6a4ee6..be7b14f 100644 --- a/src/server/internal/server/handlers/authorization/auth_handler.go +++ b/src/server/internal/server/handlers/authorization/auth_handler.go @@ -5,24 +5,42 @@ import ( "moxitech/dns/internal/database" "github.com/gofiber/fiber/v2" + "gorm.io/gorm" ) -// GET localhost:8080/auth/username?/password? +// POST localhost:8080/auth/username?/password? func AuthUser(c *fiber.Ctx) error { username := c.Params("username") password := c.Params("password") if username == "" || password == "" { - return c.Status(501).SendString("username and password has required!") + return c.Status(403).JSON(fiber.Map{ + "error": "username and password are required!", + }) } + user, err := database.DbDriver.GetUserByName(username) + if err == gorm.ErrRecordNotFound { + return c.Status(404).JSON(fiber.Map{ + "error": "User not found", + }) + } if err != nil { - return c.Status(501).SendString(err.Error()) + return c.Status(501).JSON(fiber.Map{ + "error": err.Error(), + }) } if user == nil { - return c.Status(403).SendString(fmt.Sprintf("User with username: %v not found", username)) + return c.Status(403).JSON(fiber.Map{ + "error": fmt.Sprintf("User with username: %v not found", username), + }) } if user.Password != password { - return c.Status(403).SendString("Bad password!") + return c.Status(403).JSON(fiber.Map{ + "error": "Bad password!", + }) } - return c.Status(200).SendString(fmt.Sprintf("Welcome to Drone Network Simulator server-side API! \n UserId: %v ", user.ID)) + + return c.Status(200).JSON(fiber.Map{ + "userid": user.ID, + }) } diff --git a/src/server/internal/server/websocket.go b/src/server/internal/server/websocket.go index b4226e4..fce4708 100644 --- a/src/server/internal/server/websocket.go +++ b/src/server/internal/server/websocket.go @@ -111,6 +111,7 @@ func (room *WebsocketRoom) InsertObject(message websocket.SignalMessage) error { return fmt.Errorf("[insert] error parsing data: %v", err) } + fmt.Println("st 1") // Получаем значения name и params name := parsedData.Name params := parsedData.Params @@ -119,25 +120,31 @@ func (room *WebsocketRoom) InsertObject(message websocket.SignalMessage) error { if params["coords"] == "" { return fmt.Errorf("[insert] coords is empty") } + fmt.Println("st 2") // Разделяем строку координат на отдельные элементы coordinateStrings := strings.Split(params["coords"], ",") // Инициализируем массив для хранения координат coordinates := make([]int, len(coordinateStrings)) + fmt.Println("st 3") // Преобразуем каждую координату в целое число for i, coord := range coordinateStrings { parsedCoord, err := strconv.Atoi(strings.TrimSpace(coord)) if err != nil { + fmt.Println(fmt.Errorf("[insert] invalid coordinate: %s", coord)) return fmt.Errorf("[insert] invalid coordinate: %s", coord) } coordinates[i] = parsedCoord } + fmt.Println("st 4") + params["coords"] = "" // Добавляем объект в комнату roomsMutex.Lock() defer roomsMutex.Unlock() + fmt.Println("st 5") room.Modulation.AddObject(name, type_obj, [3]int{coordinates[0], coordinates[1], coordinates[2]}, params) return nil @@ -199,6 +206,13 @@ func (room *WebsocketRoom) InsertExampleData() { room.Modulation.SpawnExampleData() } +// InsertBasicData вставляет базовые случайные данные в симуляцию +func (room *WebsocketRoom) StoreMongo() { + roomsMutex.Lock() + defer roomsMutex.Unlock() + room.Modulation.MirrorPayloadToSimulationStruct() +} + // InsertMapFromJson вставляет высоты и прочие данные карты в симуляцию, по шаблону func (room *WebsocketRoom) InsertMapFromJson(template string) { // TODO @@ -273,6 +287,8 @@ func (room *WebsocketRoom) WebsocketAction(message []byte) (error, bool) { case 33: // SYNC SIGNAL case 100: + case 101: + // room.StoreMongo(Signal) case 301: