فهرست منبع

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

Sacha Ligthert 2 سال پیش
والد
کامیت
3b737a5f23
7فایلهای تغییر یافته به همراه243 افزوده شده و 0 حذف شده
  1. 34 0
      functions.go
  2. 5 0
      go.mod
  3. 2 0
      go.sum
  4. 11 0
      http_listener.go
  5. 28 0
      main.go
  6. 112 0
      tcp_listener.go
  7. 51 0
      types.go

+ 34 - 0
functions.go

@@ -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 - 0
go.mod

@@ -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 - 0
go.sum

@@ -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 - 0
http_listener.go

@@ -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 - 0
main.go

@@ -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 - 0
tcp_listener.go

@@ -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 - 0
types.go

@@ -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
+}