From 09b0e9b5d3c31f8d8d9b7887c38b89a411557b49 Mon Sep 17 00:00:00 2001 From: jack77213 Date: Wed, 19 Feb 2020 21:44:31 +0800 Subject: [PATCH 1/4] init --- README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 From 9c0907fa3511aad927922b723811ec3c94189ba8 Mon Sep 17 00:00:00 2001 From: jack77213 Date: Thu, 20 Feb 2020 11:01:38 +0800 Subject: [PATCH 2/4] extension init commit --- README.md | 9 +++++ extension/go.mod | 3 ++ extension/go.sum | 0 extension/liba3web.go | 84 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 96 insertions(+) create mode 100644 extension/go.mod create mode 100644 extension/go.sum create mode 100644 extension/liba3web.go diff --git a/README.md b/README.md index e69de29..165d342 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,9 @@ +# A3Web + +Arma 3 Realtime Map + +## To build extension + +``` +GOARCH=386 CGO_ENABLED=1 go build -o liba3web.so -buildmode=c-shared . +``` diff --git a/extension/go.mod b/extension/go.mod new file mode 100644 index 0000000..dcc3505 --- /dev/null +++ b/extension/go.mod @@ -0,0 +1,3 @@ +module gitea.hijack.moe/huashui/a3web/extension + +go 1.13 diff --git a/extension/go.sum b/extension/go.sum new file mode 100644 index 0000000..e69de29 diff --git a/extension/liba3web.go b/extension/liba3web.go new file mode 100644 index 0000000..6017333 --- /dev/null +++ b/extension/liba3web.go @@ -0,0 +1,84 @@ +package main + +/* + #include + #include + #include + + typedef int(*callbackProc)(char const *name, char const *function, char const *data); + + static inline int bridge_cb(callbackProc cb, char const *name, char const *function, char const *data) { + return cb(name, function, data); + } + + static inline uint min(uint a, uint b) { return a < b ? a : b; } +*/ +import "C" + +import ( + "fmt" + "log" + "strings" + "unsafe" + "net/http" +) + +var cb C.callbackProc +var name = C.CString("a3web") +var serverURL = "https://localhost" + +// RVExtensionRegisterCallback on extension load +//export RVExtensionRegisterCallback +func RVExtensionRegisterCallback(cbptr unsafe.Pointer) { + cb = C.callbackProc(cbptr) + + log.Println("Calling callback function ……") + function := C.CString("registered") + defer C.free(unsafe.Pointer(function)) + C.bridge_cb(cb, name, function, function) +} + +// RVExtensionVersion on extension load +//export RVExtensionVersion +func RVExtensionVersion(output *C.char, outputsize C.size_t) { + version := C.CString("Version 0.1") + defer C.free(unsafe.Pointer(version)) + var size = C.min(C.strlen(version)+1, outputsize-1) + C.strncpy(output, version, size) +} + +// RVExtensionArgs STRING callExtension ARRAY +//export RVExtensionArgs +func RVExtensionArgs(output *C.char, outputsize C.size_t, function *C.char, argv **C.char, argc C.int) { + var offset = unsafe.Sizeof(uintptr(0)) + var out []string + for index := C.int(0); index < argc; index++ { + out = append(out, C.GoString(*argv)) + argv = (**C.char)(unsafe.Pointer(uintptr(unsafe.Pointer(argv)) + offset)) + } + + go handleArgs(C.GoString(function), argc, out) +} + +// RVExtension STRING callExtension STRING +//export RVExtension +func RVExtension(output *C.char, outputsize C.size_t, function *C.char) { + result := C.CString(fmt.Sprintf("Hello, %s!", C.GoString(function))) + defer C.free(unsafe.Pointer(result)) + var size = C.min(C.strlen(result)+1, outputsize-1) + C.strncpy(output, result, size) +} + +func main() {} + +func handleArgs(function string, argc C.int, argv []string) { + fns := strings.Split(strings.ToLower(function), ":") + if len(fns) == 3 && fns[0] == "http" && fns[1] == "post" { + resp, err := http.Post(serverURL + fns[2], "", strings.NewReader(argv[0])) + if err != nil { + log.Printf("Error Sending HTTP Request: %s", err) + return + } + resp.Body.Close() + } +} From cb033d83bf5b5f7e465a3646254d6d4f3df58cbc Mon Sep 17 00:00:00 2001 From: jack77213 Date: Thu, 20 Feb 2020 11:13:24 +0800 Subject: [PATCH 3/4] arma 3 addons init commit --- addons/$PBOPREFIX$ | 1 + addons/config.cpp | 27 +++++++++++++++++++++++++++ addons/fn_a3web.sqf | 25 +++++++++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 addons/$PBOPREFIX$ create mode 100644 addons/config.cpp create mode 100644 addons/fn_a3web.sqf diff --git a/addons/$PBOPREFIX$ b/addons/$PBOPREFIX$ new file mode 100644 index 0000000..728fd6e --- /dev/null +++ b/addons/$PBOPREFIX$ @@ -0,0 +1 @@ +x\huashui\a3web \ No newline at end of file diff --git a/addons/config.cpp b/addons/config.cpp new file mode 100644 index 0000000..9820bc5 --- /dev/null +++ b/addons/config.cpp @@ -0,0 +1,27 @@ +class CfgPatches +{ + class a3web + { + name = "Arma 3 Realtime Map"; + author = "jack77213"; + url = "https://arma.huashui.cf"; + + requiredVersion = 1.92; + requiredAddons[] = {"A3_Functions_F"}; + units[] = {}; + weapons[] = {}; + }; +}; + +class CfgFunctions +{ + class huashui + { + class a3web + { + file = "x\huashui\a3web"; + class a3web { postInit=1; }; + }; + }; +}; + diff --git a/addons/fn_a3web.sqf b/addons/fn_a3web.sqf new file mode 100644 index 0000000..b06d822 --- /dev/null +++ b/addons/fn_a3web.sqf @@ -0,0 +1,25 @@ +[] spawn { + //if (!hasInterface) exitWith {}; + if (!isServer) exitWith {}; + //if (!isDedicated) exitWith {}; + + addMissionEventHandler ["ExtensionCallback", { + params ["_name", "_function", "_data"]; + if (_name isEqualTo "a3web") then + { + diag_log format ["ExtensionCallback %1, %2, %3", _name, _function, _data]; + }; + }]; + + waitUntil {time > 0}; + + a3web_interval = 1; + + while {true} do { + sleep a3web_interval; + private _units = allUnits apply { + [netid _x, isPlayer _x, name _x, str (side _x), getPos _x]; + }; + "liba3web" callExtension ["http:post:/units-info", [_units]]; + }; +}; From fa9f6b413663411207767b6665e0ec2057350666 Mon Sep 17 00:00:00 2001 From: jack77213 Date: Fri, 21 Feb 2020 14:39:03 +0800 Subject: [PATCH 4/4] server init commit --- server/go.mod | 8 +++++ server/go.sum | 38 ++++++++++++++++++++ server/main.go | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 140 insertions(+) create mode 100644 server/go.mod create mode 100644 server/go.sum create mode 100644 server/main.go diff --git a/server/go.mod b/server/go.mod new file mode 100644 index 0000000..738d048 --- /dev/null +++ b/server/go.mod @@ -0,0 +1,8 @@ +module gitea.hijack.moe/huashui/a3web/server + +go 1.13 + +require ( + github.com/gin-contrib/static v0.0.0-20191128031702-f81c604d8ac2 + github.com/gin-gonic/gin v1.5.0 +) diff --git a/server/go.sum b/server/go.sum new file mode 100644 index 0000000..5dc5f2e --- /dev/null +++ b/server/go.sum @@ -0,0 +1,38 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-contrib/static v0.0.0-20191128031702-f81c604d8ac2 h1:xLG16iua01X7Gzms9045s2Y2niNpvSY/Zb1oBwgNYZY= +github.com/gin-contrib/static v0.0.0-20191128031702-f81c604d8ac2/go.mod h1:VhW/Ch/3FhimwZb8Oj+qJmdMmoB8r7lmJ5auRjm50oQ= +github.com/gin-gonic/gin v1.5.0 h1:fi+bqFAx/oLK54somfCtEZs9HeH1LHVoEPUgARpTqyc= +github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do= +github.com/go-playground/locales v0.12.1 h1:2FITxuFt/xuCNP1Acdhv62OzaCiviiE4kotfhkmOqEc= +github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM= +github.com/go-playground/universal-translator v0.16.0 h1:X++omBR/4cE2MNg91AoC3rmGrCjJ8eAeUP/K/EKx4DM= +github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY= +github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/leodido/go-urn v1.1.0 h1:Sm1gr51B1kKyfD2BlRcLSiEkffoG96g6TPv6eRoEiB8= +github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= +github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= +gopkg.in/go-playground/validator.v9 v9.29.1 h1:SvGtYmN60a5CVKTOzMSyfzWDeZRxRuGvRQyEAKbw1xc= +gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/server/main.go b/server/main.go new file mode 100644 index 0000000..3de483c --- /dev/null +++ b/server/main.go @@ -0,0 +1,94 @@ +package main + +import ( + "encoding/json" + "fmt" + "log" + "net/http" + "os" + "sync" + + "github.com/gin-contrib/static" + "github.com/gin-gonic/gin" +) + +var ( + unitsInfo = make([]unitInfo, 0) + unitsInfoMutex = sync.RWMutex{} +) + +type position []float64 + +type unitInfo struct { + NetID string `json:"netid"` + IsPlayer bool `json:"isplayer"` + ProfileName string `json:"profilename"` + Side string `json:"side"` + Position position `json:"position"` +} + +func (u *unitInfo) UnmarshalJSON(buf []byte) error { + tmp := []interface{}{ + &u.NetID, + &u.IsPlayer, + &u.ProfileName, + &u.Side, + &u.Position, + } + wantLen := len(tmp) + if err := json.Unmarshal(buf, &tmp); err != nil { + return err + } + if g, e := len(tmp), wantLen; g != e { + return fmt.Errorf("wrong number of fields in Notification: %d != %d", g, e) + } + return nil +} + +func main() { + listenAddress := os.Getenv("LISTEN_ADDR") + if listenAddress == "" { + listenAddress = ":5000" + } + + router := gin.Default() + router.Use(static.Serve("/", static.LocalFile("../ui/public", false))) + router.Use(static.Serve("/maps", static.LocalFile("../maps", false))) + + router.GET("/ping", func(c *gin.Context) { + c.String(http.StatusOK, "pong") + }) + + router.POST("/ping", func(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{ + "message": "pong", + }) + }) + + router.POST("/units-info", updateUnitsInfo) + router.GET("/units-info", getUnitsInfo) + + router.Run(listenAddress) +} + +func updateUnitsInfo(c *gin.Context) { + ups := make([]unitInfo, 0) + err := c.ShouldBindJSON(&ups) + if err != nil { + log.Println(err) + c.JSON(http.StatusBadRequest, err) + return + } + + unitsInfoMutex.Lock() + defer unitsInfoMutex.Unlock() + unitsInfo = ups + + c.JSON(http.StatusOK, nil) +} + +func getUnitsInfo(c *gin.Context) { + unitsInfoMutex.RLock() + defer unitsInfoMutex.RUnlock() + c.JSON(http.StatusOK, unitsInfo) +}