server & frontend update :: signaling

This commit is contained in:
moxitech 2024-10-11 08:12:41 +07:00
parent a3d344ee2f
commit 047a3ffd5c
15 changed files with 361 additions and 107 deletions

View File

@ -71,6 +71,10 @@ services:
context: ./src/frontend context: ./src/frontend
dockerfile: Dockerfile dockerfile: Dockerfile
env_file: ".env" env_file: ".env"
volumes:
- ./src/frontend:/app
working_dir: /app
command: ["npm", "start"]
ports: ports:
- "3000:3000" - "3000:3000"
networks: networks:

View File

@ -11,7 +11,7 @@ COPY package*.json ./
RUN npm install RUN npm install
# Bundle app source # Bundle app source
COPY . . # COPY . .
# Make port 3000 available to the world outside this container # Make port 3000 available to the world outside this container
EXPOSE 3000 EXPOSE 3000

View File

@ -12,6 +12,7 @@ import Docs from './pages/Docs'; // Импортируем страницу п
import './css/bootstrap-5.3.3-dist/css/bootstrap.min.css'; import './css/bootstrap-5.3.3-dist/css/bootstrap.min.css';
import './App.css'; import './App.css';
import "bootstrap-icons/font/bootstrap-icons.css"; import "bootstrap-icons/font/bootstrap-icons.css";
import {removeCustomCookie} from './Services/Local'
import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom'; import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom';
const App = () => { const App = () => {
@ -20,6 +21,7 @@ const App = () => {
// Функция для выхода из системы // Функция для выхода из системы
const handleLogout = () => { const handleLogout = () => {
removeCustomCookie("userToken")
setIsLoggedIn(false); setIsLoggedIn(false);
}; };

View File

@ -88,8 +88,9 @@ const useWebsocketConnection = (userToken, roomHash) => {
}; };
// Функция для отправки данных в WebSocket // Функция для отправки данных в WebSocket
const sendMessage = (message) => { const sendMessage = async (message) => {
if (socketRef.current && socketRef.current.readyState === WebSocket.OPEN) { if (socketRef.current && socketRef.current.readyState === WebSocket.OPEN) {
console.log(JSON.stringify(message))
socketRef.current.send(JSON.stringify(message)); socketRef.current.send(JSON.stringify(message));
} else { } else {
console.error('WebSocket is not open. Unable to send message:', message); console.error('WebSocket is not open. Unable to send message:', message);
@ -99,4 +100,42 @@ const useWebsocketConnection = (userToken, roomHash) => {
return { websocketStruct, sendMessage }; 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; export default useWebsocketConnection;

View File

@ -1,6 +1,6 @@
.user-account { .user-account {
padding: 20px; padding: 20px;
background-color: #f4f4f4; background-color: #3cafb7;
border-radius: 10px; border-radius: 10px;
max-width: 400px; max-width: 400px;
margin: 0 auto; margin: 0 auto;

View File

@ -6,16 +6,15 @@ import BaseStation from './model/BaseStation';
import HeightPoint from './model/HeightPoint'; import HeightPoint from './model/HeightPoint';
import { RandomHeightPoint } from './helpers/generateRandomHeightPoints' import { RandomHeightPoint } from './helpers/generateRandomHeightPoints'
import ModalWindow from './components/Modal/Modal'; 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'; import './Dashboard.css';
const Dashboard = () => { const Dashboard = () => {
const mountRef = useRef(null); // Указатель монтирования const mountRef = useRef(null); // Указатель монтирования
const sceneRef = useRef(null); // Указатель на сцену const sceneRef = useRef(null); // Указатель на сцену
const mouse = new THREE.Vector2(); // Мышка const {websocketStruct, sendMessage} = useWebsocketConnection(getCustomCookie("userToken"), 1);
const {websocketStruct, sendMessage} = useWebsocketConnection(1, 1);
const [heightData, setHeightData] = useState(RandomHeightPoint()); // Высоты const [heightData, setHeightData] = useState(RandomHeightPoint()); // Высоты
const [formData, setFormData] = useState({ x: '', y: '', height: '' }); // Форма для ввода данных карты const [formData, setFormData] = useState({ x: '', y: '', height: '' }); // Форма для ввода данных карты
const [mouseState, setMouseState] = useState({ x: 0, y: 0, z: 0 }); // Форма для ввода данных карты const [mouseState, setMouseState] = useState({ x: 0, y: 0, z: 0 }); // Форма для ввода данных карты
@ -38,6 +37,45 @@ const Dashboard = () => {
baseStationField1: "", baseStationField1: "",
baseStationField2: "" 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) => { const handleTypeChange = (type) => {
@ -45,14 +83,8 @@ const Dashboard = () => {
setFormData({ ...formData, type }); setFormData({ ...formData, type });
}; };
const handleSendMessage = () => { const handleDeleteSignal = (name) => {
const message = { sendMessage(DeleteSignal(name));
signal: 0,
data: {
key: 'value'
}
};
sendMessage(message);
}; };
@ -82,11 +114,40 @@ const Dashboard = () => {
isModalSearchOpen: false, isModalSearchOpen: false,
}); });
}; };
useEffect(() => { useEffect(() => {
if (websocketStruct) { if (websocketStruct && websocketStruct.modulation) {
console.log('Received WebSocket Data:', websocketStruct); 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]); }, [websocketStruct]);
useEffect(() => { useEffect(() => {
if (!mountRef.current) return; if (!mountRef.current) return;
@ -94,7 +155,7 @@ const Dashboard = () => {
let height = mountRef.current.clientHeight; let height = mountRef.current.clientHeight;
// Создаем объект сцены // Создаем объект сцены
const scene = new THREE.Scene(); const scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);
// Сохраняем ссылку на сцену // Сохраняем ссылку на сцену
sceneRef.current = scene; sceneRef.current = scene;
// Создаем камеру // Создаем камеру
@ -140,7 +201,7 @@ const Dashboard = () => {
mesh.rotation.x = -Math.PI / 2; mesh.rotation.x = -Math.PI / 2;
scene.add(mesh); scene.add(mesh);
const axesHelper = new THREE.AxesHelper(10); const axesHelper = new THREE.AxesHelper(100);
scene.add(axesHelper); scene.add(axesHelper);
const controls = new OrbitControls(camera, renderer.domElement); const controls = new OrbitControls(camera, renderer.domElement);
@ -149,35 +210,69 @@ const Dashboard = () => {
const light = new THREE.DirectionalLight(0xffffff, 1); const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(0, 50, 50).normalize(); light.position.set(0, 50, 50).normalize();
scene.add(light); scene.add(light);
// Обработка кликов на сцене // Обработка кликов на сцене
const handleClick = (event) => { const handleClick = (event) => {
// Рассчитываем координаты мыши в нормализованной системе координат и округляем до целого числа
const mouse = new THREE.Vector2();
mouse.x = (event.clientX / window.innerWidth) * 2 - 1; mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = - (event.clientY / window.innerHeight) * 2 + 1; mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;
console.log('Mouse coordinates:', mouse); console.log('Mouse coordinates:', mouse);
// Создаем объект Raycaster для проверки пересечений
const raycaster = new THREE.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); raycaster.setFromCamera(mouse, camera);
// Проверяем пересечения с объектами дронов
const intersects = raycaster.intersectObjects(drones.map(drone => drone.getObject()), true); const intersects = raycaster.intersectObjects(drones.map(drone => drone.getObject()), true);
console.log('Intersections:', intersects) console.log('Intersections:', intersects);
console.log('Drones:', drones.map(drone => [drone.getObject(), drone.getObject().position, drone.name])) console.log('Drones:', drones.map(drone => [drone.getObject(), drone.getObject().position, drone.name]));
if (intersects.length > 0) { if (intersects.length > 0) {
const selected = intersects[0].object; const selected = intersects[0].object;
console.log('Clicked on:', selected); // Лог для проверки объекта console.log('Clicked on:', selected); // Лог для проверки объекта
const drone = drones.find(drone => drone.getObject().children[0] === selected);
// Поиск дрона рекурсивно
const drone = drones.find(drone => containsObjectRecursively(drone.getObject(), selected));
if (drone) { if (drone) {
// Сбрасываем цвет предыдущего выбранного дрона
if (selectedDrone) { if (selectedDrone) {
selectedDrone.getObject().children[0].material.color.set(0xff0000); drone.getObject().visible = true;
// selectedDrone.getObject().material.color.set(0xff0000);
} }
drone.getObject().children[0].material.color.set(0xff1111); // Устанавливаем цвет выбранного дрона
// drone.getObject().material.color.set(0xff1111);
drone.getObject().visible = false;
console.log(drone);
setSelectedDrone(drone); setSelectedDrone(drone);
} }
} else { } else {
// Сбрасываем выбор, если ни один дрон не был выбран
if (selectedDrone) { if (selectedDrone) {
selectedDrone.getObject().children[0].material.color.set(0xff0000); // selectedDrone.getObject().material.color.set(0xff0000);
selectedDrone .getObject().visible = true;
setSelectedDrone(null); 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) => { const handleMouseMove = (event) => {
let x = event.x; let x = event.x;
@ -226,21 +321,36 @@ const Dashboard = () => {
// Создаем новый материал для каждого дрона // Создаем новый материал для каждого дрона
drone.setPosition(Math.random() * 20 - 10, 20, Math.random() * 20 - 10); drone.setPosition(Math.random() * 20 - 10, 20, Math.random() * 20 - 10);
setDrones((prevDrones) => [...prevDrones, drone]); 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()); sceneRef.current.add(drone.getObject());
} }
}; };
// Добавление дрона в сцену // Добавление дрона в сцену
const handleAddBaseStation = () => { // Добавление базовой станции в сцену
const handleAddBaseStation = () => {
if (sceneRef.current) { if (sceneRef.current) {
const current = Date.now(); const current = Date.now();
const base = new BaseStation(current / 1000); const base = new BaseStation(current / 1000);
base.setPosition(Math.random() * 20 - 10, 20, Math.random() * 20 - 10);
// Выбираем случайные координаты 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]); setBaseStation((prev) => [...prev, base]);
console.log(baseStation.map(b => b.getObject().children[0])); console.log(baseStation.map(b => b.getObject().children[0]));
sceneRef.current.add(base.getObject()); sceneRef.current.add(base.getObject());
} }
}; };
// Обработчик ввода на форму высот // Обработчик ввода на форму высот
const handleInputChange = (event) => { const handleInputChange = (event) => {
@ -449,15 +559,20 @@ const Dashboard = () => {
<ModalWindow isOpen={modals.isModalSearchOpen} onClose={closeAllModals}> <ModalWindow isOpen={modals.isModalSearchOpen} onClose={closeAllModals}>
<h2>Поиск</h2> <h2>Поиск</h2>
<input type="text" placeholder="Введите имя" /> <input
<button onClick={() => alert('Добавлено')}>Выбор</button> type="text"
placeholder="Введите имя"
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
<button onClick={handleSearch}>Найти</button>
</ModalWindow> </ModalWindow>
<ModalWindow isOpen={modals.isModalDeleteOpen} onClose={closeAllModals}> <ModalWindow isOpen={modals.isModalDeleteOpen} onClose={closeAllModals}>
<h2>Удаление</h2> <h2>Удаление</h2>
<h2>Вы точно хотите удалить объект X?</h2> <h2>Вы точно хотите удалить объект X?</h2>
<button onClick={closeAllModals}>Отмена</button> <button onClick={closeAllModals}>Отмена</button>
<button onClick={() => handleSendMessage() }>Удалить</button> <button onClick={() => handleDeleteSignal(1) }>Удалить</button>
</ModalWindow> </ModalWindow>
<ModalWindow isOpen={modals.isModalOpen} onClose={closeAllModals}> <ModalWindow isOpen={modals.isModalOpen} onClose={closeAllModals}>

View File

@ -1,5 +1,6 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { setCustomCookie, getCustomCookie } from '../Services/Local' import { setCustomCookie, getCustomCookie } from '../Services/Local'
import { giveMeServerAddress } from '../Services/Server'
import '../Login.scss'; import '../Login.scss';
@ -13,16 +14,37 @@ const Login = ({ onLogin }) => {
onLogin(); onLogin();
} }
}, []) }, [])
const handleSubmit = (e) => { const handleSubmit = async (e) => {
e.preventDefault(); 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 { try {
setError('Неверный логин или пароль'); // Отправляем запрос на сервер
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('Произошла ошибка. Пожалуйста, попробуйте снова позже.');
} }
}; };

View File

@ -8,7 +8,6 @@ const Main = () => {
useEffect(() => { useEffect(() => {
getSimulations(); getSimulations();
setCustomCookie('userToken', '12345', { expires: 7 }); // Куки с истечением через 7 дней
}, []); }, []);

View File

@ -1,6 +1,6 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import '../UserAccount.scss'; import '../UserAccount.scss';
import {getCustomCookie} from '../Services/Local';
const UserAccount = () => { const UserAccount = () => {
const [userData, setUserData] = useState({ const [userData, setUserData] = useState({
username: 'Никита Николаевич', username: 'Никита Николаевич',
@ -10,6 +10,15 @@ const UserAccount = () => {
const [isEditing, setIsEditing] = useState(false); const [isEditing, setIsEditing] = useState(false);
const [formData, setFormData] = useState(userData); const [formData, setFormData] = useState(userData);
const [debug, setDebug] = useState(false)
const enableDebug = () => {
if (debug){
setDebug(false)
} else {
setDebug(true)
}
};
const handleChange = (e) => { const handleChange = (e) => {
const { name, value } = e.target; const { name, value } = e.target;
@ -77,6 +86,18 @@ const UserAccount = () => {
</button> </button>
</div> </div>
)} )}
<button className="btn btn-info" onClick={() => enableDebug()}>
Turn Debug Mode
</button>
{debug ? <p>
debug:
UserToken: {getCustomCookie("userToken")}
</p>
:
<p></p>
}
</div> </div>
); );
}; };

View File

@ -15,6 +15,12 @@ class Drone {
}, undefined, (error) => { }, undefined, (error) => {
console.error("Ошибка загрузки GLTF:", 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) { setPosition(x, y, z) {

View File

@ -86,6 +86,7 @@ func main() {
if err != nil { if err != nil {
panic(err) panic(err)
} }
database.Instance = database.NewDbConnection()
err = server.SpawnServer() err = server.SpawnServer()
if err != nil { if err != nil {
panic(err) panic(err)

View File

@ -1,6 +1,7 @@
package websocket package websocket
import ( import (
"fmt"
"moxitech/dns/package/math/simulator" "moxitech/dns/package/math/simulator"
"moxitech/dns/package/utils/randomizer" "moxitech/dns/package/utils/randomizer"
"time" "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() { func (o *Modulation) RunSimulator() {
@ -59,6 +67,8 @@ func (o *Modulation) RunSimulator() {
// HeightData: heightData, // HeightData: heightData,
// } // }
// //
// ? mapObj := o.Map
// // Определяем дронов // // Определяем дронов
// //
// drones := []*simulator.Drone{ // drones := []*simulator.Drone{
@ -128,6 +138,7 @@ func (o *Modulation) AddObject(name string, obj_type int, coords [3]int, params
// Значит объект не станция или не дрон // Значит объект не станция или не дрон
return return
} }
fmt.Println(name, obj_type, coords, params)
if o.Objects == nil { if o.Objects == nil {
o.Objects = make([]*SystemObject, 0) o.Objects = make([]*SystemObject, 0)
} }

View File

@ -18,12 +18,12 @@ type MongoDbInstance struct {
Db *mongo.Database Db *mongo.Database
} }
var instance *MongoDbInstance var Instance *MongoDbInstance
var once sync.Once var once sync.Once
// giveMeMongoConnectionString возвращает строку подключения к MongoDB // giveMeMongoConnectionString возвращает строку подключения к MongoDB
func giveMeMongoConnectionString() string { func giveMeMongoConnectionString() string {
return "mongodb://moxitech:moxitech@localhost:27017/" // Замените строку на свою строку подключения return "mongodb://moxitech:moxitech@mongo:27017/" // Замените строку на свою строку подключения
} }
// NewDbConnection создает подключение к базе данных MongoDB и возвращает единственный экземпляр MongoDbInstance // NewDbConnection создает подключение к базе данных MongoDB и возвращает единственный экземпляр MongoDbInstance
@ -49,13 +49,13 @@ func NewDbConnection() *MongoDbInstance {
log.Println("Успешное подключение к MongoDB") log.Println("Успешное подключение к MongoDB")
instance = &MongoDbInstance{ Instance = &MongoDbInstance{
Client: client, Client: client,
Db: client.Database(os.Getenv("MONGO_INITDB_DATABASE")), Db: client.Database(os.Getenv("MONGO_INITDB_DATABASE")),
} }
}) })
return instance return Instance
} }
// InsertIntoSimulations вставляет данные в коллекцию "simulations" // InsertIntoSimulations вставляет данные в коллекцию "simulations"

View File

@ -5,24 +5,42 @@ import (
"moxitech/dns/internal/database" "moxitech/dns/internal/database"
"github.com/gofiber/fiber/v2" "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 { func AuthUser(c *fiber.Ctx) error {
username := c.Params("username") username := c.Params("username")
password := c.Params("password") password := c.Params("password")
if username == "" || 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) user, err := database.DbDriver.GetUserByName(username)
if err == gorm.ErrRecordNotFound {
return c.Status(404).JSON(fiber.Map{
"error": "User not found",
})
}
if err != nil { if err != nil {
return c.Status(501).SendString(err.Error()) return c.Status(501).JSON(fiber.Map{
"error": err.Error(),
})
} }
if user == nil { 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 { 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,
})
} }

View File

@ -111,6 +111,7 @@ func (room *WebsocketRoom) InsertObject(message websocket.SignalMessage) error {
return fmt.Errorf("[insert] error parsing data: %v", err) return fmt.Errorf("[insert] error parsing data: %v", err)
} }
fmt.Println("st 1")
// Получаем значения name и params // Получаем значения name и params
name := parsedData.Name name := parsedData.Name
params := parsedData.Params params := parsedData.Params
@ -119,25 +120,31 @@ func (room *WebsocketRoom) InsertObject(message websocket.SignalMessage) error {
if params["coords"] == "" { if params["coords"] == "" {
return fmt.Errorf("[insert] coords is empty") return fmt.Errorf("[insert] coords is empty")
} }
fmt.Println("st 2")
// Разделяем строку координат на отдельные элементы // Разделяем строку координат на отдельные элементы
coordinateStrings := strings.Split(params["coords"], ",") coordinateStrings := strings.Split(params["coords"], ",")
// Инициализируем массив для хранения координат // Инициализируем массив для хранения координат
coordinates := make([]int, len(coordinateStrings)) coordinates := make([]int, len(coordinateStrings))
fmt.Println("st 3")
// Преобразуем каждую координату в целое число // Преобразуем каждую координату в целое число
for i, coord := range coordinateStrings { for i, coord := range coordinateStrings {
parsedCoord, err := strconv.Atoi(strings.TrimSpace(coord)) parsedCoord, err := strconv.Atoi(strings.TrimSpace(coord))
if err != nil { if err != nil {
fmt.Println(fmt.Errorf("[insert] invalid coordinate: %s", coord))
return fmt.Errorf("[insert] invalid coordinate: %s", coord) return fmt.Errorf("[insert] invalid coordinate: %s", coord)
} }
coordinates[i] = parsedCoord coordinates[i] = parsedCoord
} }
fmt.Println("st 4")
params["coords"] = "" params["coords"] = ""
// Добавляем объект в комнату // Добавляем объект в комнату
roomsMutex.Lock() roomsMutex.Lock()
defer roomsMutex.Unlock() defer roomsMutex.Unlock()
fmt.Println("st 5")
room.Modulation.AddObject(name, type_obj, [3]int{coordinates[0], coordinates[1], coordinates[2]}, params) room.Modulation.AddObject(name, type_obj, [3]int{coordinates[0], coordinates[1], coordinates[2]}, params)
return nil return nil
@ -199,6 +206,13 @@ func (room *WebsocketRoom) InsertExampleData() {
room.Modulation.SpawnExampleData() room.Modulation.SpawnExampleData()
} }
// InsertBasicData вставляет базовые случайные данные в симуляцию
func (room *WebsocketRoom) StoreMongo() {
roomsMutex.Lock()
defer roomsMutex.Unlock()
room.Modulation.MirrorPayloadToSimulationStruct()
}
// InsertMapFromJson вставляет высоты и прочие данные карты в симуляцию, по шаблону // InsertMapFromJson вставляет высоты и прочие данные карты в симуляцию, по шаблону
func (room *WebsocketRoom) InsertMapFromJson(template string) { func (room *WebsocketRoom) InsertMapFromJson(template string) {
// TODO // TODO
@ -273,6 +287,8 @@ func (room *WebsocketRoom) WebsocketAction(message []byte) (error, bool) {
case 33: case 33:
// SYNC SIGNAL // SYNC SIGNAL
case 100: case 100:
case 101:
// room.StoreMongo(Signal)
case 301: case 301: