Initial Commit - Dirty AF but it gets the job done.

This commit is contained in:
Sacha Ligthert 2024-01-15 23:10:59 +01:00
parent 79498dea20
commit 3b737a5f23
7 changed files with 243 additions and 0 deletions

34
functions.go Normal file
View File

@ -0,0 +1,34 @@
package main
import (
"math"
"github.com/umahmood/haversine"
)
func rad2deg(rad float64) float64 {
return rad * (180 / math.Pi)
}
func calcDistance(lat_from float64, lon_from float64, lat_to float64, lon_to float64) float64 {
from := haversine.Coord{Lat: lat_from, Lon: lon_from}
to := haversine.Coord{Lat: lat_to, Lon: lon_to}
_, km := haversine.Distance(from, to)
return km
}
func calcMps(km float64, seconds float64) float64 {
return (km * 1000) / seconds
}
func calcKnots(mps float64) float64 {
return mps * 1.94384449
}
func calcKph(mps float64) float64 {
return mps * 3.6
}
func calcMph(mps float64) float64 {
return mps * 2.23694
}

5
go.mod Normal file
View File

@ -0,0 +1,5 @@
module gitea.ligthert.net/dcsw_server_map/Listener
go 1.21.6
require github.com/umahmood/haversine v0.0.0-20151105152445-808ab04add26 // indirect

2
go.sum Normal file
View File

@ -0,0 +1,2 @@
github.com/umahmood/haversine v0.0.0-20151105152445-808ab04add26 h1:UFHFmFfixpmfRBcxuu+LA9l8MdURWVdVNUHxO5n1d2w=
github.com/umahmood/haversine v0.0.0-20151105152445-808ab04add26/go.mod h1:IGhd0qMDsUa9acVjsbsT7bu3ktadtGOHI79+idTew/M=

11
http_listener.go Normal file
View File

@ -0,0 +1,11 @@
package main
import (
"io"
"net/http"
)
func (pool *Pool) getRoot(w http.ResponseWriter, r *http.Request) {
//fmt.Printf("got / request\n")
io.WriteString(w, string(pool.jsonst)+"\n")
}

28
main.go Normal file
View File

@ -0,0 +1,28 @@
package main
import (
"errors"
"net/http"
"os"
"log"
)
func main() {
var pool Pool
pool.logger = log.New(os.Stdout, "[DCS] ", log.Ldate | log.Ltime)
http.HandleFunc("/", pool.getRoot)
pool.logger.Println("Starting TCP listener.")
go pool.tcplistener()
pool.logger.Println("Starting HTTP listener.")
err := http.ListenAndServe("0.0.0.0:8888", nil)
if errors.Is(err, http.ErrServerClosed) {
pool.logger.Println("server closed.")
} else if err != nil {
pool.logger.Printf("error starting server: %s\n", err)
os.Exit(1)
}
}

112
tcp_listener.go Normal file
View File

@ -0,0 +1,112 @@
package main
import (
"encoding/json"
"net"
"os"
)
func (pool *Pool) tcplistener() {
// Listen for incoming connections.
l, err := net.Listen("tcp", "0.0.0.0:12345")
if err != nil {
pool.logger.Println("Error listening:", err.Error())
os.Exit(1)
}
// Close the listener when the application closes.
defer l.Close()
for {
// Listen for an incoming connection.
conn, err := l.Accept()
if err != nil {
pool.logger.Println("Error accepting: ", err.Error())
os.Exit(1)
}
// Handle connections in a new goroutine.
pool.logger.Println("DCS Mission Started")
go pool.handleRequest(conn)
}
}
// Handles incoming requests.
func (pool *Pool) handleRequest(conn net.Conn) {
// Close the connection when you're done with it.
defer conn.Close()
for {
// Make an MB of buffer to hold incoming data.
buf := make([]byte, 1024*1024)
// Read the incoming connection into the buffer.
read_len, err := conn.Read(buf)
if err != nil {
if err.Error() == "EOF" {
pool.logger.Println("Socket closed -- DCS Mission over?")
// Reset buffers
pool.latest = ""
pool.oldest = ""
pool.jsonst = ""
} else {
pool.logger.Println("Error reading:", err.Error())
}
return
}
// Copy messages around
pool.oldest = pool.latest
pool.latest = string(buf)[:read_len]
// Make sure we only do things if there is actual data:
if pool.oldest != "" {
// Parse JSON
var err error
var json_oldest json_units
var json_latest json_units
err = json.Unmarshal([]byte(pool.oldest), &json_oldest)
if err != nil {
pool.logger.Println("json_oldest error:", err)
pool.logger.Println("pool.oldest", pool.oldest)
pool.logger.Println("json_oldest", json_oldest)
}
err = json.Unmarshal([]byte(pool.latest), &json_latest)
if err != nil {
pool.logger.Println("json.latest error:", err)
pool.logger.Println("pool.latest", pool.latest)
pool.logger.Println("json_latest", json_latest)
}
// Compare JSON
var units []Unit
for _, vvoor := range json_latest.Units {
for _, vna := range json_oldest.Units {
if vna.UnitName == vvoor.UnitName {
SpeedInMps := calcMps(calcDistance(vvoor.Latitude, vvoor.Longitude, vna.Latitude, vna.Longitude), vvoor.AgeInSeconds-vna.AgeInSeconds)
SpeedInKnots := calcKnots(SpeedInMps)
SpeedInKph := calcKph(SpeedInMps)
SpeedInMph := calcMph(SpeedInMps)
units = append(units, Unit{vna.AgeInSeconds, vna.UnitName, vna.GroupName, vna.Name, vna.Latitude, vna.Longitude, vna.AltitudeInFeet, SpeedInKnots, SpeedInKph, SpeedInMps, SpeedInMph, vna.HeadingInRads, rad2deg(vna.HeadingInRads), vna.PitchInRads, rad2deg(vna.PitchInRads), vna.BankInRads, rad2deg(vna.BankInRads), vna.Coalition, vna.Type})
}
}
}
if pool.jsonst == "" {
pool.logger.Println("Making JSON available on HTTP.")
}
json_final, _ := json.Marshal(units)
pool.jsonst = string(json_final)
}
// Send a response back to person contacting us.
//conn.Write([]byte("Message received\n"))
}
}

51
types.go Normal file
View File

@ -0,0 +1,51 @@
package main
import (
"log"
)
type Pool struct {
latest string
oldest string
jsonst string // JSON string, trust me
logger *log.Logger
}
type json_units struct {
Units []struct {
AgeInSeconds float64 `json:"age_in_seconds"`
UnitName string `json:"unit_name"`
GroupName string `json:"group_name"`
Name string `json:"name"`
Latitude float64 `json:"latitude"`
Longitude float64 `json:"longitude"`
AltitudeInFeet float64 `json:"altitude_in_feet"`
HeadingInRads float64 `json:"heading_in_rads"`
PitchInRads float64 `json:"pitch_in_rads"`
BankInRads float64 `json:"bank_in_rads"`
Coalition string `json:"coalition"`
Type string `json:"type"`
} `json:"units"`
}
type Unit struct {
AgeInSeconds float64
UnitName string
GroupName string
Name string
Latitude float64
Longitude float64
AltitudeInFeet float64
SpeedInKnots float64
SpeedInKph float64
SpeedInMps float64
SpeedInMph float64
HeadingInRads float64
Heading float64
PitchInRads float64
Pitch float64
BankInRads float64
Bank float64
Coalition string
Type string
}