Initial commit

This commit is contained in:
torsten committed 2026-08-13 18:33:10 +02:00
commit b7d90b9afe
16245 files changed
+3396666

No files matched your search

+17
View File
@@ -0,0 +1,17 @@
module legatus-rme/backend
go 1.21.5
require github.com/gorilla/websocket v1.5.1
require (
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.20.0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
golang.org/x/crypto v0.23.0 // indirect
golang.org/x/net v0.25.0 // indirect
golang.org/x/sys v0.20.0 // indirect
golang.org/x/text v0.15.0 // indirect
)
+22
View File
@@ -0,0 +1,22 @@
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8=
github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+21
View File
@@ -0,0 +1,21 @@
package main
import (
serviceportsinformation "legatus-rme/backend/servicePortsInformation"
typedata "legatus-rme/backend/typeData"
"legatus-rme/backend/websocket"
)
func main() {
servicePortsInformationSocket := websocket.OpenWebsocket("servicePortsInformation", []int{7300}).(serviceportsinformation.ServicePortsInformation)
exerciseServicePortMap, exerciseIds := servicePortsInformationSocket.GetPorts()
typeDataSocket := websocket.OpenWebsocket("typeBaseData", []int{exerciseServicePortMap["0-ParticipantManagement1"]}).(typedata.TypeData)
typeData := typeDataSocket.GetTypeData()
websocket.OpenWebsocketServer(websocket.Server{
ExerciseIds: exerciseIds,
ExerciseServicePortMap: exerciseServicePortMap,
TypeData: typeData,
})
}
@@ -0,0 +1,37 @@
package participanthandler
import "time"
// ChangeAbcProtection ändert den ABC-Schutzstatus eines Geräts.
// equipmentNumber: Die Nummer des Geräts, dessen ABC-Schutzstatus geändert werden soll.
// abcProtection: Der neue Status des ABC-Schutzes (true für aktiv, false für inaktiv).
// Rückgabewert: Gibt einen Fehler zurück, falls die Änderung fehlschlägt.
func (c *ParticipantHandler) ChangeAbcProtection(equipmentNumber int, abcProtection bool) error {
// Erstellen einer Anfrage zur Änderung des ABC-Schutzstatus
req := AbcProtectionChangeRequest{
Data: struct {
Header struct {
EquipmentNumber int `json:"equipmentNumber"`
TimeStamp int `json:"timeStamp"`
} `json:"header"`
NbcProtectionActive bool `json:"nbcProtectionActive"`
}{
Header: struct {
EquipmentNumber int `json:"equipmentNumber"`
TimeStamp int `json:"timeStamp"`
}{
EquipmentNumber: equipmentNumber,
TimeStamp: int(time.Now().UnixMilli()),
},
NbcProtectionActive: abcProtection,
},
TypeID: 7,
}
// Senden der Anfrage über den MariusSocket
if err := c.MariusSocket.WriteJSON(req); err != nil {
return err
}
return nil
}
@@ -0,0 +1,62 @@
package participanthandler
import (
"log"
"math"
"time"
)
// degreesToRadians konvertiert Grad in Radiant.
// degrees: Der Winkel in Grad.
// Rückgabewert: Der Winkel in Radiant.
func degreesToRadians(degrees float64) float64 {
return degrees * (math.Pi / 180)
}
// ChangePosition ändert die Position eines Geräts.
// equipmentNumber: Die Nummer des Geräts, dessen Position geändert werden soll.
// geoPosition: Die neue geografische Position des Geräts.
// Rückgabewert: Gibt einen Fehler zurück, falls die Änderung fehlschlägt.
func (c *ParticipantHandler) ChangePosition(equipmentNumber int, geoPosition *GeoPosition) error {
log.Println(equipmentNumber, geoPosition)
// Erstellen einer Anfrage zur Änderung der Position
req := PositionChangeRequest{
Data: struct {
Header struct {
EquipmentNumber int `json:"equipmentNumber"`
TimeStamp int `json:"timeStamp"`
} `json:"header"`
GeoPosition struct {
Lon float64 `json:"lon"`
Lat float64 `json:"lat"`
Z float64 `json:"z"`
} `json:"geoPosition"`
}{
Header: struct {
EquipmentNumber int `json:"equipmentNumber"`
TimeStamp int `json:"timeStamp"`
}{
EquipmentNumber: equipmentNumber,
TimeStamp: int(time.Now().UnixMilli()),
},
GeoPosition: struct {
Lon float64 `json:"lon"`
Lat float64 `json:"lat"`
Z float64 `json:"z"`
}{
Lon: degreesToRadians(geoPosition.Lng),
Lat: degreesToRadians(geoPosition.Lat),
Z: 0.0,
},
},
TypeID: 21,
}
// Senden der Anfrage über den MariusSocket
if err := c.MariusSocket.WriteJSON(req); err != nil {
return err
}
return nil
}
@@ -0,0 +1,55 @@
package participanthandler
import "log"
// CheckIfParticipantIsValid überprüft, ob ein Teilnehmer gültig ist.
// equipmentNumber: Die Nummer des Geräts, dessen Gültigkeit überprüft werden soll.
// Rückgabewert: Gibt eine Struktur zurück, die die Gültigkeit des Teilnehmers und seine Daten enthält.
func (c *ParticipantHandler) CheckIfParticipantIsValid(equipmentNumber int) CheckIfParticipantIsValidReturn {
// Erstellen einer Anfrage zur Überprüfung der Teilnehmergültigkeit
req := CheckIfParticipantIsValidRequest{Type: "baseDlRequest", UUID: "UUID"}
// Senden der Anfrage über das ParticipantManagement
c.ParticipantManagement.WriteJSON(req)
var res CheckIfParticipantIsValidResponse
for {
// Lesen der Antwort vom ParticipantManagement
err := c.ParticipantManagement.ReadJSON(&res)
if err != nil {
log.Fatal("CheckIfParticipantIsValidRequest - Error getting participant data:", err)
}
// Überprüfen, ob die Antwort den erwarteten Typ hat
if res.Type == "participantBaseData" {
break
}
}
var participantData *CheckIfParticipantIsValidReturn
// Durchlaufen der Teilnehmerdaten, um den passenden Teilnehmer zu finden
for _, participant := range res.Data {
if participant.EquipmentNumber == equipmentNumber {
participantData = &CheckIfParticipantIsValidReturn{
TacticalIdentifier: participant.TacticalIdentifier,
Designator: participant.Designator,
EquipmentNumber: participant.EquipmentNumber,
Valid: true,
PartyId: participant.PartyID,
}
}
}
// Falls kein passender Teilnehmer gefunden wurde, wird eine ungültige Struktur zurückgegeben
if participantData == nil {
participantData = &CheckIfParticipantIsValidReturn{
TacticalIdentifier: "",
Designator: "",
EquipmentNumber: 0,
Valid: false,
PartyId: 0,
}
}
return *participantData
}
@@ -0,0 +1,43 @@
package participanthandler
import "log"
func (c *ParticipantHandler) GetAllParticipants() []*CheckIfParticipantIsValidReturn {
// Erstellen einer Anfrage zur Überprüfung der Teilnehmergültigkeit
req := CheckIfParticipantIsValidRequest{Type: "baseDlRequest", UUID: "UUID"}
// Senden der Anfrage über das ParticipantManagement
c.ParticipantManagement.WriteJSON(req)
var res CheckIfParticipantIsValidResponse
for {
// Lesen der Antwort vom ParticipantManagement
err := c.ParticipantManagement.ReadJSON(&res)
if err != nil {
log.Fatal("CheckIfParticipantIsValidRequest - Error getting participant data:", err)
}
// Überprüfen, ob die Antwort den erwarteten Typ hat
if res.Type == "participantBaseData" {
break
}
}
var participantData []*CheckIfParticipantIsValidReturn
// Durchlaufen der Teilnehmerdaten, um den passenden Teilnehmer zu finden
for _, participant := range res.Data {
if participant.PartyID == 2 || participant.PartyID == 3 || participant.PartyID == 4 {
if participant.EquipmentNumber != 0 {
participantData = append(participantData, &CheckIfParticipantIsValidReturn{
TacticalIdentifier: participant.TacticalIdentifier,
Designator: participant.Designator,
EquipmentNumber: participant.EquipmentNumber,
Valid: true,
PartyId: participant.PartyID,
})
}
}
}
return participantData
}
@@ -0,0 +1,85 @@
package participanthandler
import (
"github.com/gorilla/websocket"
)
// ParticipantHandler verwaltet die Verbindungen und Anfragen für Teilnehmer.
type ParticipantHandler struct {
ParticipantManagement *websocket.Conn // Verbindung zum Participant Management
MariusSocket *websocket.Conn // Verbindung zum Marius Socket
}
// CheckIfParticipantIsValidRequest repräsentiert eine Anfrage zur Überprüfung der Gültigkeit eines Teilnehmers.
type CheckIfParticipantIsValidRequest struct {
Type string `json:"type"` // Typ der Anfrage
UUID string `json:"uuid"` // Eindeutige Identifikationsnummer der Anfrage
}
// CheckIfParticipantIsValidResponse repräsentiert die Antwort auf eine Anfrage zur Überprüfung der Gültigkeit eines Teilnehmers.
type CheckIfParticipantIsValidResponse struct {
Data []struct {
AssignState int `json:"assignState"` // Zuweisungsstatus
Designator string `json:"designator"` // Designator des Teilnehmers
EquipmentNumber int `json:"equipmentNumber"` // Gerätenummer
ExternalID int `json:"externalId"` // Externe ID
HierarchyNumber int `json:"hierarchyNumber"` // Hierarchienummer
ID int `json:"id"` // ID des Teilnehmers
Identification string `json:"identification"` // Identifikation
Info string `json:"info"` // Zusätzliche Informationen
IsDeleted bool `json:"isDeleted"` // Löschstatus
IsSimulated bool `json:"isSimulated"` // Simulationsstatus
Name string `json:"name"` // Name des Teilnehmers
PartyID int `json:"partyId"` // Party ID
Properties string `json:"properties"` // Eigenschaften
SuperiorID int `json:"superiorId"` // ID des Vorgesetzten
Symbol string `json:"symbol"` // Symbol
TacticalIdentifier string `json:"tacticalIdentifier"` // Taktischer Identifikator
TypeID int `json:"typeId"` // Typ ID
} `json:"data"` // Liste der Teilnehmerdaten
Type string `json:"type"` // Typ der Antwort
UUID string `json:"uuid"` // Eindeutige Identifikationsnummer der Antwort
}
// CheckIfParticipantIsValidReturn repräsentiert die Rückgabewerte der Überprüfung der Gültigkeit eines Teilnehmers.
type CheckIfParticipantIsValidReturn struct {
TacticalIdentifier string `json:"tacticalIdentifier"` // Taktischer Identifikator
Designator string `json:"designator"` // Designator des Teilnehmers
EquipmentNumber int `json:"equipmentNumber"` // Gerätenummer
Valid bool `json:"valid"` // Gültigkeitsstatus
PartyId int `json:"partyId"` // Party ID
}
// AbcProtectionChangeRequest repräsentiert eine Anfrage zur Änderung des ABC-Schutzstatus.
type AbcProtectionChangeRequest struct {
Data struct {
Header struct {
EquipmentNumber int `json:"equipmentNumber"` // Gerätenummer
TimeStamp int `json:"timeStamp"` // Zeitstempel
} `json:"header"`
NbcProtectionActive bool `json:"nbcProtectionActive"` // Status des ABC-Schutzes
} `json:"data"`
TypeID int `json:"typeId"` // Typ ID der Anfrage
}
// GeoPosition repräsentiert eine geografische Position.
type GeoPosition struct {
Lat float64 // Breitengrad
Lng float64 // Längengrad
}
// PositionChangeRequest repräsentiert eine Anfrage zur Änderung der Position eines Geräts.
type PositionChangeRequest struct {
Data struct {
Header struct {
EquipmentNumber int `json:"equipmentNumber"` // Gerätenummer
TimeStamp int `json:"timeStamp"` // Zeitstempel
} `json:"header"`
GeoPosition struct {
Lon float64 `json:"lon"` // Längengrad in Radiant
Lat float64 `json:"lat"` // Breitengrad in Radiant
Z float64 `json:"z"` // Höhe (standardmäßig 0.0)
} `json:"geoPosition"`
} `json:"data"`
TypeID int `json:"typeId"` // Typ ID der Anfrage
}
+27
View File
@@ -0,0 +1,27 @@
package partydata
import (
"log"
)
func (c *PartyData) GetPartyData() PartyDataResponse {
req := PartyDataRequest{Type: "baseDlRequest", UUID: "UUID"}
c.Websocket.WriteJSON(req)
var res PartyDataResponse
for {
err := c.Websocket.ReadJSON(&res)
if err != nil {
log.Fatal("PartyDataRequest - Error getting party data:", err)
}
if res.Type == "partyBaseData" {
break
}
}
c.Websocket.Close()
return res
}
+28
View File
@@ -0,0 +1,28 @@
package partydata
import (
"github.com/gorilla/websocket"
)
type PartyData struct {
Websocket *websocket.Conn
}
type PartyDataRequest struct {
Type string `json:"type"`
UUID string `json:"uuid"`
}
type PartyDataResponse struct {
Data []struct {
Color int `json:"color"`
FadingColor int `json:"fadingColor"`
HlaForceIdentifier int `json:"hlaForceIdentifier"`
ID int `json:"id"`
IsUsedBy bool `json:"isUsedBy"`
Name string `json:"name"`
RoleID int `json:"roleId"`
} `json:"data"`
Type string `json:"type"`
UUID string `json:"uuid"`
}
@@ -0,0 +1,37 @@
package serviceportsinformation
import (
"fmt"
"log"
)
func (c *ServicePortsInformation) GetPorts() (map[string]int, []int) {
req := ServicePortsInformationRequest{Type: "servicePortsInformationRequest", UUID: "UUID"}
c.Websocket.WriteJSON(req)
var res ServicePortsInformationResponse
err := c.Websocket.ReadJSON(&res)
if err != nil {
log.Fatal("ServicePortsInformationRequest - Error getting service ports information:", err)
}
var exerciseServicePortMap map[string]int = make(map[string]int)
for _, exercise := range res.Data {
for _, service := range exercise.Services {
for _, port := range service.Ports {
log.Printf("%d-%s%d\n", exercise.ExerciseID, service.Name, port.TypeID)
exerciseServicePortMap[fmt.Sprintf("%d-%s%d", exercise.ExerciseID, service.Name, port.TypeID)] = port.Number
}
}
}
var excerciseIds []int
for _, exercise := range res.Data {
excerciseIds = append(excerciseIds, exercise.ExerciseID)
}
c.Websocket.Close()
return exerciseServicePortMap, excerciseIds
}
@@ -0,0 +1,32 @@
package serviceportsinformation
import (
"github.com/gorilla/websocket"
)
type ServicePortsInformation struct {
Websocket *websocket.Conn
}
type ServicePortsInformationRequest struct {
Type string `json:"type"`
UUID string `json:"uuid"`
}
type ServicePortsInformationResponse struct {
Data []struct {
ExerciseID int `json:"exerciseId"`
ReplayPartitionID int `json:"replayPartitionId"`
Services []struct {
Name string `json:"name"`
NameAbbrevation string `json:"nameAbbrevation"`
Ports []struct {
Number int `json:"number"`
Properties string `json:"properties"`
TypeID int `json:"typeId"`
} `json:"ports"`
} `json:"services"`
} `json:"data"`
Type string `json:"type"`
UUID string `json:"uuid"`
}
+27
View File
@@ -0,0 +1,27 @@
package typedata
import (
"log"
)
func (c *TypeData) GetTypeData() TypeDataResponse {
req := TypeDataRequest{Type: "baseDlRequest", UUID: "UUID"}
c.Websocket.WriteJSON(req)
var res TypeDataResponse
for {
err := c.Websocket.ReadJSON(&res)
if err != nil {
log.Fatal("TypeDataRequest - Error getting type data:", err)
}
if res.Type == "typeBaseData" {
break
}
}
c.Websocket.Close()
return res
}
+31
View File
@@ -0,0 +1,31 @@
package typedata
import (
"github.com/gorilla/websocket"
)
type TypeData struct {
Websocket *websocket.Conn
}
type TypeDataRequest struct {
Type string `json:"type"`
UUID string `json:"uuid"`
}
type TypeDataResponse struct {
Data []struct {
DisEntities string `json:"disEntities"`
HierarchyLevel int `json:"hierarchyLevel"`
ID int `json:"id"`
IsDeleted bool `json:"isDeleted"`
Name string `json:"name"`
Properties string `json:"properties"`
RadioCount int `json:"radioCount"`
Symbol string `json:"symbol"`
TypeClassID int `json:"typeClassId"`
EquipmentTypeID int `json:"equipmentTypeId,omitempty"`
} `json:"data"`
Type string `json:"type"`
UUID string `json:"uuid"`
}
+17
View File
@@ -0,0 +1,17 @@
package websocket
import (
"log"
"net/http"
)
func (s *Server) exerciseIds(w http.ResponseWriter, r *http.Request) {
c, err := s.Upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println("Websocket Server - Error upgrading connection:", err)
return
}
defer c.Close()
c.WriteJSON(&s.ExerciseIds)
}
+41
View File
@@ -0,0 +1,41 @@
package websocket
import (
"fmt"
participanthandler "legatus-rme/backend/participantHandler"
partydata "legatus-rme/backend/partyData"
serviceportsinformation "legatus-rme/backend/servicePortsInformation"
typedata "legatus-rme/backend/typeData"
"log"
"net/url"
"github.com/gorilla/websocket"
)
func OpenWebsocket(websocketType string, port []int) interface{} {
var sockets []*websocket.Conn
for _, port := range port {
u := url.URL{Scheme: "ws", Host: fmt.Sprintf("localhost:%d", port)}
socket, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
if err != nil {
log.Fatal("Error connecting to websocket:", err)
}
sockets = append(sockets, socket)
}
switch websocketType {
case "servicePortsInformation":
return serviceportsinformation.ServicePortsInformation{Websocket: sockets[0]}
case "typeBaseData":
return typedata.TypeData{Websocket: sockets[0]}
case "partyBaseData":
return partydata.PartyData{Websocket: sockets[0]}
case "participantHandler":
return participanthandler.ParticipantHandler{ParticipantManagement: sockets[0], MariusSocket: sockets[1]}
default:
log.Fatal("Invalid websocket type")
return nil
}
}
@@ -0,0 +1,20 @@
package websocket
import (
"log"
"net/http"
"github.com/gorilla/websocket"
)
func OpenWebsocketServer(s Server) {
s.Upgrader = &websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool { return true },
}
http.HandleFunc("/ports", s.ports)
http.HandleFunc("/exerciseIds", s.exerciseIds)
http.HandleFunc("/partyData", s.partyData)
http.HandleFunc("/participantHandler", s.participantHandler)
log.Fatal("Websocket Server - Error while serving websockt server:", http.ListenAndServe("localhost:6969", nil))
}
@@ -0,0 +1,85 @@
package websocket
import (
"fmt"
participanthandler "legatus-rme/backend/participantHandler"
"log"
"net/http"
"github.com/go-playground/validator/v10"
)
func (s *Server) participantHandler(w http.ResponseWriter, r *http.Request) {
c, err := s.Upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println("Websocket Server - Error upgrading connection:", err)
return
}
defer c.Close()
for {
var req ParticipantHandlerWebsocketRequestWithoutData
if err := c.ReadJSON(&req); err != nil {
c.WriteJSON(&ErrorWebsocketResponse{
Error: err.Error(),
})
return
}
if req.Type != "getAllParticipants" {
req2 := ParticipantHandlerWebsocketRequest(req)
err = validator.New().Struct(req2)
if err != nil {
c.WriteJSON(&ErrorWebsocketResponse{
Error: err.Error(),
})
return
}
} else {
err = validator.New().Struct(req)
if err != nil {
c.WriteJSON(&ErrorWebsocketResponse{
Error: err.Error(),
})
return
}
}
var (
participantHandlerByExcersiseId participanthandler.ParticipantHandler
ok bool
)
if participantHandlerByExcersiseId, ok = s.ParticipantHandlers[req.ExcerciseId]; !ok {
participantHandlerByExcersiseId = OpenWebsocket("participantHandler", []int{s.ExerciseServicePortMap[fmt.Sprintf("%d-ParticipantManagement1", req.ExcerciseId)], req.ExcerciseId * 102}).(participanthandler.ParticipantHandler)
}
switch req.Type {
case "checkIfParticipantIsValid":
participantData := participantHandlerByExcersiseId.CheckIfParticipantIsValid(req.ParticipantData.ParticipantId)
c.WriteJSON(&participantData)
continue
case "getAllParticipants":
participantData := participantHandlerByExcersiseId.GetAllParticipants()
c.WriteJSON(&participantData)
continue
case "changeAbcProtection":
if err := participantHandlerByExcersiseId.ChangeAbcProtection(req.ParticipantData.ParticipantId, req.ParticipantData.AbcProtection); err != nil {
c.WriteJSON(&ErrorWebsocketResponse{
Error: err.Error(),
})
}
c.WriteJSON(req.ParticipantData)
continue
case "changePosition":
if err := participantHandlerByExcersiseId.ChangePosition(req.ParticipantData.ParticipantId, &participanthandler.GeoPosition{
Lat: req.ParticipantData.Positions[0].Lat,
Lng: req.ParticipantData.Positions[0].Lng,
}); err != nil {
c.WriteJSON(&ErrorWebsocketResponse{
Error: err.Error(),
})
}
continue
}
}
}
+68
View File
@@ -0,0 +1,68 @@
package websocket
import (
"fmt"
partydata "legatus-rme/backend/partyData"
"log"
"net/http"
"slices"
"github.com/go-playground/validator/v10"
)
func paintIt(color int) string {
hex := fmt.Sprintf("%06x", color+16777216)
return "#" + hex
}
func (s *Server) partyData(w http.ResponseWriter, r *http.Request) {
c, err := s.Upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println("Websocket Server - Error upgrading connection:", err)
return
}
defer c.Close()
for {
var req PartyDataWebsocketRequest
if err := c.ReadJSON(&req); err != nil {
c.WriteJSON(&ErrorWebsocketResponse{
Error: err.Error(),
})
}
err = validator.New().Struct(req)
if err != nil {
c.WriteJSON(&ErrorWebsocketResponse{
Error: err.Error(),
})
}
if slices.Contains(s.ExerciseIds, req.ExcerciseId) {
partyDataSocket := OpenWebsocket("partyBaseData", []int{s.ExerciseServicePortMap[fmt.Sprintf("%d-ParticipantManagement1", req.ExcerciseId)]}).(partydata.PartyData)
partyData := partyDataSocket.GetPartyData()
var res []PartyDataWebsocketResponse
for _, party := range partyData.Data {
if party.ID == 0 || party.ID == 1 {
continue
}
colorInHex := paintIt(party.Color)
res = append(res, PartyDataWebsocketResponse{
Id: party.ID,
Party: party.Name,
Color: colorInHex,
})
}
c.WriteJSON(&res)
} else {
c.WriteJSON(&ErrorWebsocketResponse{
Error: "Invalid exerciseId",
})
continue
}
}
}
+17
View File
@@ -0,0 +1,17 @@
package websocket
import (
"log"
"net/http"
)
func (s *Server) ports(w http.ResponseWriter, r *http.Request) {
c, err := s.Upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println("Websocket Server - Error upgrading connection:", err)
return
}
defer c.Close()
c.WriteJSON(&s.ExerciseServicePortMap)
}
+56
View File
@@ -0,0 +1,56 @@
package websocket
import (
participanthandler "legatus-rme/backend/participantHandler"
typedata "legatus-rme/backend/typeData"
"github.com/gorilla/websocket"
)
type Server struct {
ExerciseIds []int
ExerciseServicePortMap map[string]int
TypeData typedata.TypeDataResponse
ParticipantHandlers map[int]participanthandler.ParticipantHandler
Upgrader *websocket.Upgrader
}
type PartyDataWebsocketResponse struct {
Id int `json:"id"`
Party string `json:"party"`
Color string `json:"color"`
}
type PartyDataWebsocketRequest struct {
ExcerciseId int `json:"excerciseId" validate:"required"`
}
type ParticipantHandlerWebsocketRequestWithoutData struct {
Type string `json:"type" validate:"required"`
ExcerciseId int `json:"excerciseId" validate:"required"`
ParticipantData struct {
ParticipantId int `json:"participantId"`
Positions []struct {
Lat float64 `json:"lat"`
Lng float64 `json:"lng"`
} `json:"positions"`
AbcProtection bool `json:"abcProtection"`
} `json:"participantData"`
}
type ParticipantHandlerWebsocketRequest struct {
Type string `json:"type" validate:"required"`
ExcerciseId int `json:"excerciseId" validate:"required"`
ParticipantData struct {
ParticipantId int `json:"participantId" validate:"required"`
Positions []struct {
Lat float64 `json:"lat"`
Lng float64 `json:"lng"`
} `json:"positions"`
AbcProtection bool `json:"abcProtection"`
} `json:"participantData" validate:"required"`
}
type ErrorWebsocketResponse struct {
Error string `json:"error"`
}