Compare commits
10 Commits
ced02c8bc7
...
0.0.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
2726b56243
|
|||
|
8de6750dca
|
|||
|
d0802de7ae
|
|||
|
bd9e9f37aa
|
|||
|
fc16dbb42d
|
|||
|
ac5869e63b
|
|||
|
1eac67d09a
|
|||
|
65dc43267a
|
|||
|
eff339d8fe
|
|||
|
80aa96ed4e
|
14
.gitignore
vendored
Normal file
14
.gitignore
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
*.pbo
|
||||
*.bak
|
||||
*.dll
|
||||
|
||||
*.so
|
||||
|
||||
RangerMetrics.h
|
||||
|
||||
RangerMetrics_x64.h
|
||||
|
||||
*.log
|
||||
|
||||
settings.json
|
||||
!*.example
|
||||
1015
.vs/Arma3-Influx/config/applicationhost.config
Normal file
1015
.vs/Arma3-Influx/config/applicationhost.config
Normal file
File diff suppressed because it is too large
Load Diff
BIN
.vs/Arma3-Influx/v16/.suo
Normal file
BIN
.vs/Arma3-Influx/v16/.suo
Normal file
Binary file not shown.
BIN
.vs/Arma3-Influx/v16/Browse.VC.db
Normal file
BIN
.vs/Arma3-Influx/v16/Browse.VC.db
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
3
.vs/ProjectSettings.json
Normal file
3
.vs/ProjectSettings.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"CurrentProjectSetting": "x64-Release"
|
||||
}
|
||||
7
.vs/VSWorkspaceState.json
Normal file
7
.vs/VSWorkspaceState.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"ExpandedNodes": [
|
||||
""
|
||||
],
|
||||
"SelectedNode": "\\RVExtension.c",
|
||||
"PreviewInSolutionExplorer": false
|
||||
}
|
||||
BIN
.vs/slnx.sqlite
Normal file
BIN
.vs/slnx.sqlite
Normal file
Binary file not shown.
10
.vs/tasks.vs.json
Normal file
10
.vs/tasks.vs.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"version": "0.2.1",
|
||||
"tasks": [
|
||||
{
|
||||
"taskLabel": "task-Arma3-Influx",
|
||||
"appliesTo": "/",
|
||||
"type": "launch"
|
||||
}
|
||||
]
|
||||
}
|
||||
15
@RangerMetrics/settings.json.example
Normal file
15
@RangerMetrics/settings.json.example
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"influxdb": {
|
||||
"host": "http://host:8086",
|
||||
"token": "",
|
||||
"org": "ranger-metrics"
|
||||
},
|
||||
"timescaledb": {
|
||||
"connectionUrl": "postgresql://postgres:password@host:5432/postgres",
|
||||
"databaseName": "ranger_metrics",
|
||||
"description": "TimescaleDB is an open-source time-series database built on Postgres. Please leave the final section of the connection URL as 'postgres' as this is the maintenance database name. The extension will connect here first and create the database with desired name, then shift connections to the newly created database to create the schema and conduct write operations."
|
||||
},
|
||||
"arma3": {
|
||||
"refreshRateMs": 1000
|
||||
}
|
||||
}
|
||||
22
README.md
22
README.md
@@ -2,4 +2,24 @@
|
||||
|
||||
A3 extension for sending metrics to InfluxDB using Golang
|
||||
|
||||
> See more: https://github.com/code34/armago_x64
|
||||
## Build
|
||||
|
||||
### Windows
|
||||
|
||||
_Requires Go 1.20.1+ & MinGW_
|
||||
|
||||
```powershell
|
||||
$ENV:GOARCH = "amd64"
|
||||
$ENV:CGO_ENABLED = 1
|
||||
go build -o RangerMetrics_x64.dll -buildmode=c-shared .
|
||||
```
|
||||
|
||||
To validate exported functions:
|
||||
|
||||
```powershell
|
||||
. "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30133\bin\Hostx64\x64\dumpbin.exe" /exports .\RangerMetrics_x64.dll
|
||||
```
|
||||
|
||||
## Notes
|
||||
>
|
||||
> See more: <https://github.com/code34/armago_x64>
|
||||
|
||||
@@ -4,40 +4,58 @@
|
||||
|
||||
extern void goRVExtension(char *output, size_t outputSize, char *input);
|
||||
extern void goRVExtensionVersion(char *output, size_t outputSize);
|
||||
extern void goRVExtensionArgs(char* output, size_t outputSize, char* input, char** argv, int argc);
|
||||
// extern void goRVExtensionRegisterCallback(extensionCallback fnc);
|
||||
extern void goRVExtensionArgs(char *output, size_t outputSize, char *input, char **argv, int argc);
|
||||
extern void goRVExtensionRegisterCallback(extensionCallback fnc);
|
||||
|
||||
#ifdef WIN64
|
||||
__declspec(dllexport) void RVExtension(char *output, size_t outputSize, char *input) {
|
||||
goRVExtension(output, outputSize, input);
|
||||
__declspec(dllexport) void RVExtension(char *output, size_t outputSize, char *input)
|
||||
{
|
||||
goRVExtension(output, outputSize, input);
|
||||
}
|
||||
|
||||
__declspec(dllexport) void RVExtensionVersion(char *output, size_t outputSize) {
|
||||
goRVExtensionVersion(output, outputSize);
|
||||
__declspec(dllexport) void RVExtensionVersion(char *output, size_t outputSize)
|
||||
{
|
||||
goRVExtensionVersion(output, outputSize);
|
||||
}
|
||||
|
||||
__declspec(dllexport) void RVExtensionArgs(char* output, size_t outputSize, char* input, char** argv, int argc) {
|
||||
goRVExtensionArgs(output, outputSize, input, argv, argc);
|
||||
__declspec(dllexport) void RVExtensionArgs(char *output, size_t outputSize, char *input, char **argv, int argc)
|
||||
{
|
||||
goRVExtensionArgs(output, outputSize, input, argv, argc);
|
||||
}
|
||||
|
||||
//__declspec(dllexport) void RVExtensionRegisterCallback(extensionCallback fnc) {
|
||||
// goRVExtensionRegisterCallback(fnc);
|
||||
//}
|
||||
__declspec(dllexport) void RVExtensionRegisterCallback(extensionCallback fnc)
|
||||
{
|
||||
goRVExtensionRegisterCallback(fnc);
|
||||
}
|
||||
#else
|
||||
__declspec(dllexport) void __stdcall _RVExtension(char *output, size_t outputSize, char *input) {
|
||||
goRVExtension(output, outputSize, input);
|
||||
__declspec(dllexport) void __stdcall _RVExtension(char *output, size_t outputSize, char *input)
|
||||
{
|
||||
goRVExtension(output, outputSize, input);
|
||||
}
|
||||
|
||||
__declspec(dllexport) void __stdcall _RVExtensionVersion(char *output, size_t outputSize) {
|
||||
goRVExtensionVersion(output, outputSize);
|
||||
__declspec(dllexport) void __stdcall _RVExtensionVersion(char *output, size_t outputSize)
|
||||
{
|
||||
goRVExtensionVersion(output, outputSize);
|
||||
}
|
||||
|
||||
__declspec(dllexport) void __stdcall _RVExtensionArgs(char* output, size_t outputSize, char* input, char** argv, int argc) {
|
||||
goRVExtensionArgs(output, outputSize, input, argv, argc);
|
||||
__declspec(dllexport) void __stdcall _RVExtensionArgs(char *output, size_t outputSize, char *input, char **argv, int argc)
|
||||
{
|
||||
goRVExtensionArgs(output, outputSize, input, argv, argc);
|
||||
}
|
||||
|
||||
// __declspec(dllexport) void __stdcall _RVExtensionRegisterCallback(extensionCallback fnc) {
|
||||
// goRVExtensionRegisterCallback(fnc);
|
||||
// }
|
||||
__declspec(dllexport) void __stdcall _RVExtensionRegisterCallback(extensionCallback fnc)
|
||||
{
|
||||
goRVExtensionRegisterCallback(fnc);
|
||||
}
|
||||
#endif
|
||||
// do this for all the other exported functions
|
||||
// do this for all the other exported functions
|
||||
|
||||
// dll entrypoint
|
||||
// Path: RVExtension.c
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BIN
a3influx.dll
BIN
a3influx.dll
Binary file not shown.
Binary file not shown.
87
a3influx.h
87
a3influx.h
@@ -1,87 +0,0 @@
|
||||
/* Code generated by cmd/cgo; DO NOT EDIT. */
|
||||
|
||||
/* package github.com/7cav/a3-fone-home */
|
||||
|
||||
|
||||
#line 1 "cgo-builtin-export-prolog"
|
||||
|
||||
#include <stddef.h> /* for ptrdiff_t below */
|
||||
|
||||
#ifndef GO_CGO_EXPORT_PROLOGUE_H
|
||||
#define GO_CGO_EXPORT_PROLOGUE_H
|
||||
|
||||
#ifndef GO_CGO_GOSTRING_TYPEDEF
|
||||
typedef struct { const char *p; ptrdiff_t n; } _GoString_;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* Start of preamble from import "C" comments. */
|
||||
|
||||
|
||||
#line 3 "arma.go"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "extensionCallback.h"
|
||||
|
||||
#line 1 "cgo-generated-wrapper"
|
||||
|
||||
|
||||
/* End of preamble from import "C" comments. */
|
||||
|
||||
|
||||
/* Start of boilerplate cgo prologue. */
|
||||
#line 1 "cgo-gcc-export-header-prolog"
|
||||
|
||||
#ifndef GO_CGO_PROLOGUE_H
|
||||
#define GO_CGO_PROLOGUE_H
|
||||
|
||||
typedef signed char GoInt8;
|
||||
typedef unsigned char GoUint8;
|
||||
typedef short GoInt16;
|
||||
typedef unsigned short GoUint16;
|
||||
typedef int GoInt32;
|
||||
typedef unsigned int GoUint32;
|
||||
typedef long long GoInt64;
|
||||
typedef unsigned long long GoUint64;
|
||||
typedef GoInt64 GoInt;
|
||||
typedef GoUint64 GoUint;
|
||||
typedef __SIZE_TYPE__ GoUintptr;
|
||||
typedef float GoFloat32;
|
||||
typedef double GoFloat64;
|
||||
typedef float _Complex GoComplex64;
|
||||
typedef double _Complex GoComplex128;
|
||||
|
||||
/*
|
||||
static assertion to make sure the file is being used on architecture
|
||||
at least with matching size of GoInt.
|
||||
*/
|
||||
typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];
|
||||
|
||||
#ifndef GO_CGO_GOSTRING_TYPEDEF
|
||||
typedef _GoString_ GoString;
|
||||
#endif
|
||||
typedef void *GoMap;
|
||||
typedef void *GoChan;
|
||||
typedef struct { void *t; void *v; } GoInterface;
|
||||
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
|
||||
|
||||
#endif
|
||||
|
||||
/* End of boilerplate cgo prologue. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern __declspec(dllexport) void goRVExtensionVersion(char* output, size_t outputsize);
|
||||
extern __declspec(dllexport) GoInt goRVExtensionArgs(char* output, size_t outputsize, char* input, char** argv, int argc);
|
||||
extern __declspec(dllexport) void goRVExtension(char* output, size_t outputsize, char* input);
|
||||
extern __declspec(dllexport) void goRVExtensionRegisterCallback(extensionCallback fnc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
BIN
a3influx_x64.dll
BIN
a3influx_x64.dll
Binary file not shown.
@@ -1,87 +0,0 @@
|
||||
/* Code generated by cmd/cgo; DO NOT EDIT. */
|
||||
|
||||
/* package github.com/7cav/a3-fone-home */
|
||||
|
||||
|
||||
#line 1 "cgo-builtin-export-prolog"
|
||||
|
||||
#include <stddef.h> /* for ptrdiff_t below */
|
||||
|
||||
#ifndef GO_CGO_EXPORT_PROLOGUE_H
|
||||
#define GO_CGO_EXPORT_PROLOGUE_H
|
||||
|
||||
#ifndef GO_CGO_GOSTRING_TYPEDEF
|
||||
typedef struct { const char *p; ptrdiff_t n; } _GoString_;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* Start of preamble from import "C" comments. */
|
||||
|
||||
|
||||
#line 3 "arma.go"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "extensionCallback.h"
|
||||
|
||||
#line 1 "cgo-generated-wrapper"
|
||||
|
||||
|
||||
/* End of preamble from import "C" comments. */
|
||||
|
||||
|
||||
/* Start of boilerplate cgo prologue. */
|
||||
#line 1 "cgo-gcc-export-header-prolog"
|
||||
|
||||
#ifndef GO_CGO_PROLOGUE_H
|
||||
#define GO_CGO_PROLOGUE_H
|
||||
|
||||
typedef signed char GoInt8;
|
||||
typedef unsigned char GoUint8;
|
||||
typedef short GoInt16;
|
||||
typedef unsigned short GoUint16;
|
||||
typedef int GoInt32;
|
||||
typedef unsigned int GoUint32;
|
||||
typedef long long GoInt64;
|
||||
typedef unsigned long long GoUint64;
|
||||
typedef GoInt64 GoInt;
|
||||
typedef GoUint64 GoUint;
|
||||
typedef __SIZE_TYPE__ GoUintptr;
|
||||
typedef float GoFloat32;
|
||||
typedef double GoFloat64;
|
||||
typedef float _Complex GoComplex64;
|
||||
typedef double _Complex GoComplex128;
|
||||
|
||||
/*
|
||||
static assertion to make sure the file is being used on architecture
|
||||
at least with matching size of GoInt.
|
||||
*/
|
||||
typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];
|
||||
|
||||
#ifndef GO_CGO_GOSTRING_TYPEDEF
|
||||
typedef _GoString_ GoString;
|
||||
#endif
|
||||
typedef void *GoMap;
|
||||
typedef void *GoChan;
|
||||
typedef struct { void *t; void *v; } GoInterface;
|
||||
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
|
||||
|
||||
#endif
|
||||
|
||||
/* End of boilerplate cgo prologue. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern __declspec(dllexport) void goRVExtensionVersion(char* output, size_t outputsize);
|
||||
extern __declspec(dllexport) GoInt goRVExtensionArgs(char* output, size_t outputsize, char* input, char** argv, int argc);
|
||||
extern __declspec(dllexport) void goRVExtension(char* output, size_t outputsize, char* input);
|
||||
extern __declspec(dllexport) void goRVExtensionRegisterCallback(extensionCallback fnc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
894
arma.go
894
arma.go
@@ -4,32 +4,696 @@ package main
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "extensionCallback.h"
|
||||
*/
|
||||
import "C"
|
||||
import "C" // This is required to import the C code
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
influxdb2 "github.com/influxdata/influxdb-client-go/v2"
|
||||
"github.com/jackc/pgx/v4"
|
||||
"github.com/jackc/pgx/v4/pgxpool"
|
||||
)
|
||||
|
||||
// declare list of functions available for call
|
||||
var AVAILABLE_FUNCTIONS = map[string]interface{}{
|
||||
"initExtension": initExtension,
|
||||
"deinitExtension": deinitExtension,
|
||||
"loadSettings": loadSettings,
|
||||
"connectToInflux": connectToInflux,
|
||||
"writeToInflux": writeToInflux,
|
||||
"connectToTimescale": connectToTimescale,
|
||||
"initTimescale": initTimescale,
|
||||
"writeToTimescale": writeToTimescale,
|
||||
"getDir": getDir,
|
||||
"sanitizeLineProtocol": sanitizeLineProtocol,
|
||||
"version": version,
|
||||
"getUnixTimeNano": getUnixTimeNano,
|
||||
}
|
||||
|
||||
var EXTENSION_VERSION string = "0.0.2"
|
||||
var extensionCallbackFnc C.extensionCallback
|
||||
|
||||
type ServerPollSetting struct {
|
||||
Name string `json:"name"`
|
||||
Enabled bool `json:"enabled"`
|
||||
ServerOnly bool `json:"serverOnly"`
|
||||
IntervalMs int `json:"intervalMs"`
|
||||
Bucket string `json:"bucket"`
|
||||
Measurement string `json:"measurement"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
var ServerPollSettingProperties []string = []string{
|
||||
"Name",
|
||||
"Enabled",
|
||||
"ServerOnly",
|
||||
"IntervalMs",
|
||||
"Bucket",
|
||||
"Measurement",
|
||||
"Description",
|
||||
}
|
||||
|
||||
type CBAEventHandler struct {
|
||||
Name string `json:"name"`
|
||||
Enabled bool `json:"enabled"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
var CBAEventHandlerProperties []string = []string{
|
||||
"Name",
|
||||
"Enabled",
|
||||
"Description",
|
||||
}
|
||||
|
||||
type settingsJson struct {
|
||||
Influx struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
Host string `json:"host"`
|
||||
Token string `json:"token"`
|
||||
Org string `json:"org"`
|
||||
} `json:"influxdb"`
|
||||
Timescale struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
ConnectionUrl string `json:"connectionUrl"`
|
||||
DatabaseName string `json:"databaseName"`
|
||||
} `json:"timescaledb"`
|
||||
Arma3 struct {
|
||||
RefreshRateMs int `json:"refreshRateMs"`
|
||||
Debug bool `json:"debug"`
|
||||
} `json:"arma3"`
|
||||
RecordingSettings map[string]interface{} `json:"recordingSettings"`
|
||||
}
|
||||
|
||||
var activeSettings settingsJson
|
||||
|
||||
// InfluxDB variables
|
||||
var influxClient influxdb2.Client
|
||||
|
||||
// TimescaleDB variables
|
||||
var timescaleDbPool *pgxpool.Pool
|
||||
|
||||
// file paths
|
||||
var ADDON_FOLDER string = getDir() + "\\@RangerMetrics"
|
||||
var LOG_FILE string = ADDON_FOLDER + "\\rangermetrics.log"
|
||||
var SETTINGS_FILE string = ADDON_FOLDER + "\\settings.json"
|
||||
var SETTINGS_FILE_EXAMPLE string = ADDON_FOLDER + "\\settings.example.json"
|
||||
|
||||
// var BACKUP_FILE_PATH string = ADDON_FOLDER + "/local_backup.log.gzip"
|
||||
// var BACKUP_WRITER *gzip.Writer
|
||||
|
||||
// configure log output
|
||||
func init() {
|
||||
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
||||
// log to file
|
||||
f, err := os.OpenFile(LOG_FILE, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
|
||||
if err != nil {
|
||||
log.Fatalf("error opening file: %v", err)
|
||||
}
|
||||
// log to console as well
|
||||
// log.SetOutput(io.MultiWriter(f, os.Stdout))
|
||||
// log only to file
|
||||
log.SetOutput(f)
|
||||
}
|
||||
|
||||
func initExtension() {
|
||||
functionName := "initExtension"
|
||||
logLine(functionName, `["Initializing RangerMetrics extension", "INFO"]`, false)
|
||||
logLine(functionName, fmt.Sprintf(`["RangerMetrics Extension Version: %v", "INFO"]`, EXTENSION_VERSION), false)
|
||||
|
||||
var err error
|
||||
|
||||
activeSettings, err = loadSettings()
|
||||
if err != nil {
|
||||
logLine(functionName, fmt.Sprintf(`["Error loading settings: %v", "ERROR"]`, err), false)
|
||||
return
|
||||
}
|
||||
|
||||
if activeSettings.Influx.Enabled {
|
||||
influxClient, err = connectToInflux()
|
||||
if err != nil {
|
||||
logLine(functionName, fmt.Sprintf(`["Error connecting to InfluxDB: %v", "ERROR"]`, err), false)
|
||||
return
|
||||
}
|
||||
}
|
||||
if activeSettings.Timescale.Enabled {
|
||||
timescaleDbPool, err = connectToTimescale()
|
||||
if err != nil {
|
||||
logLine(functionName, fmt.Sprintf(`["Error connecting to TimescaleDB: %v", "ERROR"]`, err), false)
|
||||
return
|
||||
}
|
||||
|
||||
initTimescale()
|
||||
}
|
||||
logLine("extensionReady", `["Extension ready", "INFO"]`, false)
|
||||
}
|
||||
|
||||
func deinitExtension() {
|
||||
functionName := "deinitExtension"
|
||||
logLine(functionName, `["Deinitializing RangerMetrics extension", "INFO"]`, false)
|
||||
|
||||
if timescaleDbPool != nil {
|
||||
logLine(functionName, `["Closing TimescaleDB connection", "INFO"]`, false)
|
||||
timescaleDbPool.Close()
|
||||
} else {
|
||||
logLine(functionName, `["TimescaleDB connection not open", "INFO"]`, false)
|
||||
}
|
||||
|
||||
logLine(functionName, `[true]`, false)
|
||||
}
|
||||
|
||||
// func RVExtensionContext(output *C.char, argc *C.int) {
|
||||
|
||||
// }
|
||||
|
||||
func version() {
|
||||
functionName := "version"
|
||||
logLine(functionName, fmt.Sprintf(`["RangerMetrics Extension Version:%s", "INFO"]`, EXTENSION_VERSION), false)
|
||||
}
|
||||
|
||||
// return db client and error
|
||||
func connectToInflux() (influxdb2.Client, error) {
|
||||
if activeSettings.Influx.Host == "" ||
|
||||
activeSettings.Influx.Host == "http://host:8086" {
|
||||
|
||||
return nil, errors.New("influxConnectionSettings.Host is empty")
|
||||
// logLine("connectToInflux", `["Creating backup file", "INFO"]`)
|
||||
// file, err := os.Open(BACKUP_FILE_PATH)
|
||||
// if err != nil {
|
||||
// log.Fatal(err)
|
||||
// logLine("connectToInflux", `["Error opening backup file", "ERROR"]`)
|
||||
// }
|
||||
// BACKUP_WRITER = gzip.NewWriter(file)
|
||||
// if err != nil {
|
||||
// log.Fatal(err)
|
||||
// logLine("connectToInflux", `["Error creating gzip writer", "ERROR"]`)
|
||||
// }
|
||||
// return "Error connecting to Influx. Using local backup"
|
||||
}
|
||||
|
||||
influxClient := influxdb2.NewClientWithOptions(activeSettings.Influx.Host, activeSettings.Influx.Token, influxdb2.DefaultOptions().SetBatchSize(1000).SetFlushInterval(1000))
|
||||
|
||||
return influxClient, nil
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
// TIMESCALE
|
||||
//////////////////////////////////
|
||||
|
||||
func connectToTimescale() (*pgxpool.Pool, error) {
|
||||
functionName := "connectToTimescale"
|
||||
var err error
|
||||
|
||||
// urlExample := "postgres://username:password@localhost:5432/database_name"
|
||||
// logLine("connectToTimescale", fmt.Sprintf(`["timescaleConnectionSettings.ConnectionUrl: %s", "INFO"]`, timescaleConnectionSettings.ConnectionUrl))
|
||||
conn, err := pgx.Connect(context.Background(), activeSettings.Timescale.ConnectionUrl+"/postgres")
|
||||
|
||||
if err != nil {
|
||||
logLine(
|
||||
functionName,
|
||||
fmt.Sprintf(`["Error connecting to Timescale DB: %v", "ERROR"]`, err.Error()),
|
||||
false,
|
||||
)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// ensure database exists
|
||||
logLine(
|
||||
functionName,
|
||||
fmt.Sprintf(`["TimescaleDB: 'CREATE DATABASE %s'", "INFO"]`, activeSettings.Timescale.DatabaseName),
|
||||
false,
|
||||
)
|
||||
conn.Query(context.Background(), fmt.Sprintf(`CREATE DATABASE %s`, activeSettings.Timescale.DatabaseName))
|
||||
|
||||
// close connection
|
||||
conn.Close(context.Background())
|
||||
|
||||
// create connection pool
|
||||
var dbPool *pgxpool.Pool
|
||||
dbPool, err = pgxpool.Connect(
|
||||
context.Background(),
|
||||
fmt.Sprintf(`%s/%s`, activeSettings.Timescale.ConnectionUrl, activeSettings.Timescale.DatabaseName),
|
||||
)
|
||||
if err != nil {
|
||||
logLine(
|
||||
functionName,
|
||||
fmt.Sprintf(`["Error connecting to Timescale DB: %v", "ERROR"]`, err.Error()),
|
||||
false,
|
||||
)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
logLine("connectToTimescale", `["Connected to Timescale successfully", "INFO"]`, false)
|
||||
return dbPool, nil
|
||||
}
|
||||
|
||||
func initTimescale() {
|
||||
|
||||
functionName := "initTimescale"
|
||||
var err error
|
||||
|
||||
// schema init sql
|
||||
var tableCreationSql string = `
|
||||
CREATE TABLE "Missions" (
|
||||
"id" serial NOT NULL UNIQUE,
|
||||
"world_name" VARCHAR(255) NOT NULL,
|
||||
"briefing_name" VARCHAR(255) NOT NULL,
|
||||
"mission_name" VARCHAR(255) NOT NULL,
|
||||
"mission_author" VARCHAR(255) NOT NULL,
|
||||
"server_name" VARCHAR(255) NOT NULL,
|
||||
"server_mods" TEXT,
|
||||
"ace_medical" BOOLEAN NOT NULL,
|
||||
"radio_tfar" BOOLEAN NOT NULL,
|
||||
"radio_acre" BOOLEAN NOT NULL,
|
||||
"start_game" TIMESTAMP NOT NULL,
|
||||
"start_utc" TIMESTAMP NOT NULL,
|
||||
"frame_count" FLOAT NOT NULL,
|
||||
"capture_delay_s" FLOAT NOT NULL,
|
||||
"addon_ver_major" integer NOT NULL,
|
||||
"addon_ver_minor" integer NOT NULL,
|
||||
"addon_ver_patch" integer NOT NULL,
|
||||
"extension_ver_major" integer NOT NULL,
|
||||
"extension_ver_minor" integer NOT NULL,
|
||||
"extension_ver_patch" integer NOT NULL,
|
||||
"tags" VARCHAR(255) NOT NULL,
|
||||
CONSTRAINT "Missions_pk" PRIMARY KEY ("id")
|
||||
) WITH (
|
||||
OIDS=FALSE
|
||||
);
|
||||
|
||||
|
||||
|
||||
CREATE TABLE "Worlds" (
|
||||
"world_name" VARCHAR(255) NOT NULL,
|
||||
"display_name" VARCHAR(255) NOT NULL,
|
||||
"world_size_m" integer NOT NULL,
|
||||
CONSTRAINT "Worlds_pk" PRIMARY KEY ("world_name")
|
||||
) WITH (
|
||||
OIDS=FALSE
|
||||
);
|
||||
|
||||
|
||||
|
||||
CREATE TABLE "Units" (
|
||||
"mission_id" integer NOT NULL,
|
||||
"unit_id" integer NOT NULL,
|
||||
"frame" integer NOT NULL,
|
||||
"steamid64" varchar(100),
|
||||
"steam_name" VARCHAR(255) NOT NULL,
|
||||
"a3_profile_name" VARCHAR(255) NOT NULL,
|
||||
"is_human" BOOLEAN NOT NULL,
|
||||
"is_afk" BOOLEAN NOT NULL,
|
||||
"is_alive" BOOLEAN NOT NULL,
|
||||
"unit_type" VARCHAR(255) NOT NULL,
|
||||
"role_description" VARCHAR(255),
|
||||
"side" integer NOT NULL,
|
||||
"group_id" varchar(100) NOT NULL,
|
||||
"name" VARCHAR(255),
|
||||
"position" VARCHAR(255) NOT NULL,
|
||||
"direction" FLOAT NOT NULL,
|
||||
"anim_state" varchar(100),
|
||||
"stance" VARCHAR(255),
|
||||
"traits" VARCHAR(255),
|
||||
"damage" FLOAT NOT NULL,
|
||||
"is_speaking" integer NOT NULL,
|
||||
CONSTRAINT "Units_pk" PRIMARY KEY ("mission_id","unit_id","frame")
|
||||
) WITH (
|
||||
OIDS=FALSE
|
||||
);
|
||||
|
||||
|
||||
|
||||
CREATE TABLE "Vehicles" (
|
||||
"mission_id" integer NOT NULL,
|
||||
"frame" integer NOT NULL,
|
||||
"vehicle_id" integer NOT NULL,
|
||||
"object_type" VARCHAR(255),
|
||||
"weapons" varchar(3000),
|
||||
"customization" varchar(1000),
|
||||
"position" VARCHAR(255) NOT NULL,
|
||||
"direction" FLOAT NOT NULL,
|
||||
"vector_dir" varchar(70) NOT NULL,
|
||||
"vector_up" varchar(70) NOT NULL,
|
||||
"is_alive" BOOLEAN NOT NULL,
|
||||
"damage" FLOAT NOT NULL,
|
||||
CONSTRAINT "Vehicles_pk" PRIMARY KEY ("mission_id","frame","vehicle_id")
|
||||
) WITH (
|
||||
OIDS=FALSE
|
||||
);
|
||||
|
||||
|
||||
|
||||
CREATE TABLE "Markers" (
|
||||
"mission_id" integer NOT NULL,
|
||||
"frame" integer NOT NULL,
|
||||
"marker_name" VARCHAR(255) NOT NULL,
|
||||
"data" VARCHAR(255) NOT NULL,
|
||||
CONSTRAINT "Markers_pk" PRIMARY KEY ("mission_id","frame","marker_name")
|
||||
) WITH (
|
||||
OIDS=FALSE
|
||||
);
|
||||
|
||||
|
||||
|
||||
CREATE TABLE "Chat" (
|
||||
"id" serial NOT NULL,
|
||||
"mission_id" integer NOT NULL,
|
||||
"sender_id" integer NOT NULL,
|
||||
"frame" integer NOT NULL,
|
||||
"timestamp_utc" TIMESTAMP NOT NULL,
|
||||
"content" VARCHAR(255) NOT NULL,
|
||||
"channel" integer NOT NULL,
|
||||
CONSTRAINT "Chat_pk" PRIMARY KEY ("id")
|
||||
) WITH (
|
||||
OIDS=FALSE
|
||||
);
|
||||
|
||||
|
||||
|
||||
CREATE TABLE "UniqueUsers" (
|
||||
"steamid64" varchar(100) NOT NULL,
|
||||
CONSTRAINT "UniqueUsers_pk" PRIMARY KEY ("steamid64")
|
||||
) WITH (
|
||||
OIDS=FALSE
|
||||
);
|
||||
|
||||
|
||||
|
||||
CREATE TABLE "Environment" (
|
||||
"mission_id" integer NOT NULL,
|
||||
"frame" integer NOT NULL,
|
||||
"date_game" TIMESTAMP NOT NULL,
|
||||
"date_utc" TIMESTAMP NOT NULL,
|
||||
"overcast" FLOAT NOT NULL,
|
||||
"rain" FLOAT NOT NULL,
|
||||
"humidity" FLOAT NOT NULL,
|
||||
"fog_value" FLOAT NOT NULL,
|
||||
"fog_decay" FLOAT NOT NULL,
|
||||
"fog_base" FLOAT NOT NULL,
|
||||
"wind_vector" VARCHAR(255) NOT NULL,
|
||||
"gusts" FLOAT NOT NULL,
|
||||
"waves" FLOAT NOT NULL,
|
||||
CONSTRAINT "Environment_pk" PRIMARY KEY ("mission_id","frame")
|
||||
) WITH (
|
||||
OIDS=FALSE
|
||||
);
|
||||
|
||||
|
||||
|
||||
CREATE TABLE "StaticObjects" (
|
||||
"mission_id" integer NOT NULL,
|
||||
"frame" integer NOT NULL,
|
||||
"building_id" integer NOT NULL,
|
||||
"position" integer NOT NULL,
|
||||
"direction" FLOAT NOT NULL,
|
||||
"vector_dir" varchar(70) NOT NULL,
|
||||
"vector_up" varchar(70) NOT NULL,
|
||||
"object_type" VARCHAR(255) NOT NULL,
|
||||
"classname" VARCHAR(255) NOT NULL,
|
||||
"simple_object_data" varchar(1500) NOT NULL,
|
||||
CONSTRAINT "StaticObjects_pk" PRIMARY KEY ("mission_id","frame","building_id")
|
||||
) WITH (
|
||||
OIDS=FALSE
|
||||
);
|
||||
|
||||
|
||||
|
||||
CREATE TABLE "Campaigns" (
|
||||
"id" serial NOT NULL,
|
||||
"name" VARCHAR(255) NOT NULL,
|
||||
"description" TEXT NOT NULL,
|
||||
"image" bytea NOT NULL,
|
||||
CONSTRAINT "Campaigns_pk" PRIMARY KEY ("id")
|
||||
) WITH (
|
||||
OIDS=FALSE
|
||||
);
|
||||
|
||||
|
||||
|
||||
CREATE TABLE "Missions_In_Campaigns" (
|
||||
"mission" integer NOT NULL,
|
||||
"campaign" integer NOT NULL,
|
||||
CONSTRAINT "Missions_In_Campaigns_pk" PRIMARY KEY ("mission","campaign")
|
||||
) WITH (
|
||||
OIDS=FALSE
|
||||
);
|
||||
`
|
||||
|
||||
relationCreationSql := []string{
|
||||
`ALTER TABLE "Missions" ADD CONSTRAINT "Missions_fk0" FOREIGN KEY ("world_name") REFERENCES "Worlds"("world_name");`,
|
||||
|
||||
`ALTER TABLE "Units" ADD CONSTRAINT "Units_fk0" FOREIGN KEY ("mission_id") REFERENCES "Missions"("id");`,
|
||||
`ALTER TABLE "Units" ADD CONSTRAINT "Units_fk1" FOREIGN KEY ("steamid64") REFERENCES "UniqueUsers"("steamid64");`,
|
||||
|
||||
`ALTER TABLE "Vehicles" ADD CONSTRAINT "Vehicles_fk0" FOREIGN KEY ("mission_id") REFERENCES "Missions"("id");`,
|
||||
|
||||
`ALTER TABLE "Markers" ADD CONSTRAINT "Markers_fk0" FOREIGN KEY ("mission_id") REFERENCES "Missions"("id");`,
|
||||
|
||||
`ALTER TABLE "Chat" ADD CONSTRAINT "Chat_fk0" FOREIGN KEY ("mission_id") REFERENCES "Missions"("id");`,
|
||||
`ALTER TABLE "Chat" ADD CONSTRAINT "Chat_fk1" FOREIGN KEY ("sender_id") REFERENCES "Units"("unit_id");`,
|
||||
|
||||
`ALTER TABLE "Environment" ADD CONSTRAINT "Environment_fk0" FOREIGN KEY ("mission_id") REFERENCES "Missions"("id");`,
|
||||
|
||||
`ALTER TABLE "StaticObjects" ADD CONSTRAINT "StaticObjects_fk0" FOREIGN KEY ("mission_id") REFERENCES "Missions"("id");`,
|
||||
|
||||
`ALTER TABLE "Missions_In_Campaigns" ADD CONSTRAINT "Missions_In_Campaigns_fk0" FOREIGN KEY ("mission") REFERENCES "Missions"("id");`,
|
||||
`ALTER TABLE "Missions_In_Campaigns" ADD CONSTRAINT "Missions_In_Campaigns_fk1" FOREIGN KEY ("campaign") REFERENCES "Campaigns"("id");`,
|
||||
}
|
||||
|
||||
var tx pgx.Tx
|
||||
tx, err = timescaleDbPool.Begin(context.Background())
|
||||
if err != nil {
|
||||
logLine(functionName, fmt.Sprintf(`["Error creating transaction: %v", "ERROR"]`, err.Error()), false)
|
||||
return
|
||||
}
|
||||
|
||||
_, err = tx.Exec(context.Background(), tableCreationSql)
|
||||
if err != nil {
|
||||
logLine(functionName, fmt.Sprintf(`["Error creating tables: %v", "ERROR"]`, err.Error()), false)
|
||||
tx.Rollback(context.Background())
|
||||
tx.Commit(context.Background())
|
||||
return
|
||||
}
|
||||
err = tx.Commit(context.Background())
|
||||
if err != nil {
|
||||
logLine(functionName, fmt.Sprintf(`["Error committing table creation transaction: %v", "ERROR"]`, err.Error()), false)
|
||||
return
|
||||
}
|
||||
|
||||
// run each relation creation sql statement
|
||||
for _, sql := range relationCreationSql {
|
||||
_, err = tx.Exec(context.Background(), sql)
|
||||
|
||||
if err != nil {
|
||||
logLine(functionName, fmt.Sprintf(`["Error creating relation: %v", "ERROR"]`, err.Error()), false)
|
||||
tx.Rollback(context.Background())
|
||||
tx.Commit(context.Background())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
err = tx.Commit(context.Background())
|
||||
if err != nil {
|
||||
logLine(functionName, fmt.Sprintf(`["Error committing relation creation transaction: %v", "ERROR"]`, err.Error()), false)
|
||||
return
|
||||
}
|
||||
|
||||
logLine(functionName, `["Timescale schema initialized", "INFO"]`, false)
|
||||
|
||||
}
|
||||
|
||||
func writeToTimescale(table string, line string) {
|
||||
// logLine("writeToTimescale", fmt.Sprintf(`["line: %s", "INFO"]`, line))
|
||||
functionName := "writeToTimescale"
|
||||
_, err := timescaleDbPool.Exec(context.Background(), "INSERT INTO %1 (time, line) VALUES (NOW(), $2);", table, line)
|
||||
if err != nil {
|
||||
logLine(functionName, fmt.Sprintf(`["Error writing to timescale: %v", "ERROR"]`, err.Error()), false)
|
||||
}
|
||||
}
|
||||
|
||||
func writeToInflux(a3DataRaw *[]string) string {
|
||||
|
||||
// convert to string array
|
||||
a3Data := *a3DataRaw
|
||||
|
||||
logLine("writeToInflux", fmt.Sprintf(`["Received %d params", "DEBUG"]`, len(a3Data)), true)
|
||||
|
||||
MIN_PARAMS_COUNT := 1
|
||||
|
||||
var logData string
|
||||
functionName := "writeToInflux"
|
||||
|
||||
if len(a3Data) < MIN_PARAMS_COUNT {
|
||||
logData = fmt.Sprintf(`["Not all parameters present (got %d, expected at least %d)", "ERROR"]`, len(a3Data), MIN_PARAMS_COUNT)
|
||||
logLine(functionName, logData, false)
|
||||
return logData
|
||||
}
|
||||
|
||||
// use custom bucket or default
|
||||
var bucket string = fixEscapeQuotes(trimQuotes(string(a3Data[0])))
|
||||
|
||||
// Get non-blocking write client
|
||||
WRITE_API := influxClient.WriteAPI(activeSettings.Influx.Org, bucket)
|
||||
|
||||
if WRITE_API == nil {
|
||||
logData = `["Error creating write API", "ERROR"]`
|
||||
logLine(functionName, logData, false)
|
||||
return logData
|
||||
}
|
||||
|
||||
// Get errors channel
|
||||
errorsCh := WRITE_API.Errors()
|
||||
go func() {
|
||||
for writeErr := range errorsCh {
|
||||
logData = fmt.Sprintf(`["Error parsing line protocol: %s", "ERROR"]`, strings.Replace(writeErr.Error(), `"`, `'`, -1))
|
||||
logLine(functionName, logData, false)
|
||||
}
|
||||
}()
|
||||
|
||||
// now we have our write client, we'll go through the rest of the receive array items in line protocol format and write them to influx
|
||||
for i := 1; i < len(a3Data); i++ {
|
||||
var p string = fixEscapeQuotes(trimQuotes(string(a3Data[i])))
|
||||
|
||||
// write the line to influx
|
||||
WRITE_API.WriteRecord(p)
|
||||
|
||||
// TODO: Add backup writer
|
||||
// // append backup line to file if BACKUP_WRITER is set
|
||||
// //
|
||||
// if BACKUP_WRITER != nil {
|
||||
// _, err = BACKUP_WRITER.Write([]byte(p + "\n"))
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
// schedule cleanup
|
||||
WRITE_API.Flush()
|
||||
logData = fmt.Sprintf(`["Wrote %d lines to influx", "DEBUG"]`, len(a3Data)-1)
|
||||
logLine(functionName, logData, true)
|
||||
|
||||
return "Success"
|
||||
}
|
||||
|
||||
// sanitize line protocol for influx
|
||||
func sanitizeLineProtocol(line string) string {
|
||||
// replace all spaces with underscores
|
||||
// line = strings.ReplaceAll(line, ` `, `\ `)
|
||||
// replace all commas with underscores
|
||||
// line = strings.ReplaceAll(line, `,`, `\,`)
|
||||
// replace all equals with underscores
|
||||
// line = strings.ReplaceAll(line, "=", "_")
|
||||
// replace all quotes with underscores
|
||||
// line = strings.ReplaceAll(line, "\"", "_")
|
||||
|
||||
return line
|
||||
}
|
||||
|
||||
func getDir() string {
|
||||
dir, err := os.Getwd()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return dir
|
||||
}
|
||||
|
||||
// return true if the program should continue
|
||||
func loadSettings() (settingsJson, error) {
|
||||
functionName := "loadSettings"
|
||||
logLine(functionName, fmt.Sprintf(`["ADDON_FOLDER: %s", "INFO"]`, ADDON_FOLDER), false)
|
||||
logLine(functionName, fmt.Sprintf(`["LOG_FILE: %s", "INFO"]`, LOG_FILE), false)
|
||||
logLine(functionName, fmt.Sprintf(`["SETTINGS_FILE: %s", "INFO"]`, SETTINGS_FILE), false)
|
||||
|
||||
settings := settingsJson{}
|
||||
|
||||
// print the current working directory
|
||||
var file *os.File
|
||||
var err error
|
||||
// read settings from file
|
||||
// settings.json should be in the same directory as the .dll
|
||||
// see if the file exists
|
||||
if _, err = os.Stat(SETTINGS_FILE); os.IsNotExist(err) {
|
||||
// file does not exist
|
||||
logLine(
|
||||
functionName,
|
||||
fmt.Sprintf(`["%s does not exist", "ERROR"]`, SETTINGS_FILE),
|
||||
false,
|
||||
)
|
||||
// copy settings.json.example to settings.json
|
||||
// load contents
|
||||
fileContents, err := ioutil.ReadFile(SETTINGS_FILE_EXAMPLE)
|
||||
if err != nil {
|
||||
return settings, err
|
||||
}
|
||||
// write contents to settings.json
|
||||
err = ioutil.WriteFile(SETTINGS_FILE, fileContents, 0644)
|
||||
if err != nil {
|
||||
return settings, err
|
||||
}
|
||||
|
||||
// Exit false to discontinue initialization since settings are defaults
|
||||
logLine(functionName, `["CREATED SETTINGS"]`, false)
|
||||
// return a new error
|
||||
return settings, errors.New("settings.json does not exist")
|
||||
} else {
|
||||
// file exists
|
||||
logLine(functionName, `["settings.json found", "DEBUG"]`, true)
|
||||
// read the file
|
||||
file, err = os.Open(SETTINGS_FILE)
|
||||
if err != nil {
|
||||
return settings, err
|
||||
}
|
||||
defer file.Close()
|
||||
decoder := json.NewDecoder(file)
|
||||
err = decoder.Decode(&settings)
|
||||
if err != nil {
|
||||
return settings, err
|
||||
}
|
||||
|
||||
// send contents of settings file
|
||||
// get the file contents
|
||||
fileContents, err := ioutil.ReadFile(SETTINGS_FILE)
|
||||
if err != nil {
|
||||
return settings, err
|
||||
}
|
||||
|
||||
// compact the json
|
||||
var jsonStr bytes.Buffer
|
||||
err = json.Compact(&jsonStr, fileContents)
|
||||
if err != nil {
|
||||
return settings, err
|
||||
}
|
||||
|
||||
logLine(
|
||||
"loadSettingsJSON",
|
||||
jsonStr.String(),
|
||||
false,
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
return settings, nil
|
||||
}
|
||||
|
||||
func runExtensionCallback(name *C.char, function *C.char, data *C.char) C.int {
|
||||
return C.runExtensionCallback(extensionCallbackFnc, name, function, data)
|
||||
}
|
||||
|
||||
//export goRVExtensionVersion
|
||||
func goRVExtensionVersion(output *C.char, outputsize C.size_t) {
|
||||
result := C.CString("Version 1.2.3")
|
||||
result := C.CString(EXTENSION_VERSION)
|
||||
defer C.free(unsafe.Pointer(result))
|
||||
var size = C.strlen(result) + 1
|
||||
if size > outputsize {
|
||||
@@ -39,14 +703,23 @@ func goRVExtensionVersion(output *C.char, outputsize C.size_t) {
|
||||
}
|
||||
|
||||
//export goRVExtensionArgs
|
||||
func goRVExtensionArgs(output *C.char, outputsize C.size_t, input *C.char, argv **C.char, argc C.int) int {
|
||||
func goRVExtensionArgs(output *C.char, outputsize C.size_t, input *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))
|
||||
}
|
||||
temp := fmt.Sprintf("Function: %s nb params: %d params: %s!", C.GoString(input), argc, out)
|
||||
|
||||
var temp string
|
||||
temp = fmt.Sprintf("Function: %s nb params: %d params: %s!", C.GoString(input), argc, out)
|
||||
|
||||
if C.GoString(input) == "sendToInflux" {
|
||||
// start a goroutine to send the data to influx
|
||||
// param string is argv[0] which is the data to send to influx
|
||||
go writeToInflux(&out)
|
||||
temp = fmt.Sprintf("Function: %s nb params: %d", C.GoString(input), argc)
|
||||
}
|
||||
|
||||
// Return a result to Arma
|
||||
result := C.CString(temp)
|
||||
@@ -55,8 +728,8 @@ func goRVExtensionArgs(output *C.char, outputsize C.size_t, input *C.char, argv
|
||||
if size > outputsize {
|
||||
size = outputsize
|
||||
}
|
||||
|
||||
C.memmove(unsafe.Pointer(output), unsafe.Pointer(result), size)
|
||||
return 1
|
||||
}
|
||||
|
||||
func callBackExample() {
|
||||
@@ -73,118 +746,117 @@ func callBackExample() {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
func sendToInflux(data string) {
|
||||
|
||||
fields := strings.Split(data, ",")
|
||||
|
||||
host := fields[0]
|
||||
token := fields[1]
|
||||
org := fields[2]
|
||||
bucket := fields[3]
|
||||
profile := fields[4]
|
||||
locality := fields[5]
|
||||
metric := fields[6]
|
||||
value := fields[7]
|
||||
|
||||
int_value, err := strconv.Atoi(value)
|
||||
client := influxdb2.NewClient(host, token)
|
||||
writeAPI := client.WriteAPI(org, bucket)
|
||||
|
||||
p := influxdb2.NewPoint(metric,
|
||||
map[string]string{"profile": profile, "locality": locality},
|
||||
map[string]interface{}{"count": int_value},
|
||||
time.Now())
|
||||
|
||||
// write point asynchronously
|
||||
writeAPI.WritePoint(p)
|
||||
|
||||
// Flush writes
|
||||
writeAPI.Flush()
|
||||
|
||||
defer client.Close()
|
||||
|
||||
f, err := os.OpenFile("a3metrics.log",
|
||||
os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
//logger := log.New(f, "", log.LstdFlags)
|
||||
//logger.Println(err)
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
func sendToInflux(data string) {
|
||||
|
||||
fields := strings.Split(data, ",")
|
||||
|
||||
host := fields[0]
|
||||
token := fields[1]
|
||||
org := fields[2]
|
||||
bucket := fields[3]
|
||||
profile := fields[4]
|
||||
locality := fields[5]
|
||||
metric := fields[6]
|
||||
value := fields[7]
|
||||
|
||||
|
||||
client := influxdb2.NewClient(host, token)
|
||||
writeAPI := client.WriteAPI(org, bucket)
|
||||
int_value, err := strconv.Atoi(value)
|
||||
|
||||
|
||||
|
||||
p := influxdb2.NewPoint(metric,
|
||||
map[string]string{"profile": profile, "locality": locality},
|
||||
map[string]interface{}{"count": int_value},
|
||||
time.Now())
|
||||
|
||||
// write point asynchronously
|
||||
writeAPI.WritePoint(p)
|
||||
|
||||
|
||||
|
||||
// Flush writes
|
||||
writeAPI.Flush()
|
||||
|
||||
defer client.Close()
|
||||
|
||||
f, err := os.OpenFile("a3metrics.log",
|
||||
os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
//logger := log.New(f, "", log.LstdFlags)
|
||||
//logger.Println(err)
|
||||
|
||||
func getUnixTimeNano() int64 {
|
||||
// get the current unix timestamp in nanoseconds
|
||||
return time.Now().UnixNano()
|
||||
}
|
||||
|
||||
func trimQuotes(s string) string {
|
||||
// trim the start and end quotes from a string
|
||||
return strings.Trim(s, `"`)
|
||||
}
|
||||
|
||||
func fixEscapeQuotes(s string) string {
|
||||
// fix the escape quotes in a string
|
||||
return strings.Replace(s, `""`, `"`, -1)
|
||||
}
|
||||
|
||||
func logLine(functionName string, data string, isDebug bool) {
|
||||
statusName := C.CString("RangerMetrics")
|
||||
defer C.free(unsafe.Pointer(statusName))
|
||||
statusFunction := C.CString(functionName)
|
||||
defer C.free(unsafe.Pointer(statusFunction))
|
||||
statusParam := C.CString(data)
|
||||
defer C.free(unsafe.Pointer(statusParam))
|
||||
runExtensionCallback(statusName, statusFunction, statusParam)
|
||||
|
||||
if activeSettings.Arma3.Debug && isDebug {
|
||||
log.Println(data)
|
||||
} else if !isDebug {
|
||||
log.Println(data)
|
||||
}
|
||||
}
|
||||
|
||||
//export goRVExtension
|
||||
func goRVExtension(output *C.char, outputsize C.size_t, input *C.char) {
|
||||
// Return by default through ExtensionCallback arma handler the result
|
||||
if extensionCallbackFnc != nil {
|
||||
go callBackExample()
|
||||
} else {
|
||||
// Return a result through callextension Arma call
|
||||
temp := fmt.Sprintf("Rangermetrics: %s", C.GoString(input))
|
||||
result := C.CString(temp)
|
||||
defer C.free(unsafe.Pointer(result))
|
||||
var size = C.strlen(result) + 1
|
||||
if size > outputsize {
|
||||
size = outputsize
|
||||
|
||||
var temp string
|
||||
|
||||
// logLine("goRVExtension", fmt.Sprintf(`["Input: %s", "DEBUG"]`, C.GoString(input)), true)
|
||||
|
||||
switch C.GoString(input) {
|
||||
case "version":
|
||||
temp = EXTENSION_VERSION
|
||||
case "getDir":
|
||||
temp = getDir()
|
||||
case "getUnixTimeNano":
|
||||
time := getUnixTimeNano()
|
||||
temp = fmt.Sprintf(`["%s"]`, strconv.FormatInt(time, 10))
|
||||
|
||||
default:
|
||||
// check if input is in AVAILABLE_FUNCTIONS
|
||||
// if not, return error
|
||||
// if yes, continue
|
||||
if _, ok := AVAILABLE_FUNCTIONS[C.GoString(input)]; !ok {
|
||||
temp = fmt.Sprintf(`["Function: %s not found!", "ERROR"]`, C.GoString(input))
|
||||
} else {
|
||||
// call the function by name
|
||||
go reflect.ValueOf(AVAILABLE_FUNCTIONS[C.GoString(input)]).Call([]reflect.Value{})
|
||||
temp = fmt.Sprintf(`["Function: %s called successfully", "DEBUG"]`, C.GoString(input))
|
||||
}
|
||||
|
||||
go sendToInflux(C.GoString(input))
|
||||
|
||||
C.memmove(unsafe.Pointer(output), unsafe.Pointer(result), size)
|
||||
}
|
||||
|
||||
// switch C.GoString(input) {
|
||||
// case "version":
|
||||
// logLine("goRVExtension", fmt.Sprintf(`["Input: %s", "INFO"]`, C.GoString(input)))
|
||||
// temp = EXTENSION_VERSION
|
||||
// case "getDir":
|
||||
// logLine("goRVExtension", fmt.Sprintf(`["Input: %s", "INFO"]`, C.GoString(input)))
|
||||
// temp = getDir()
|
||||
// case "loadSettings":
|
||||
// logLine("goRVExtension", fmt.Sprintf(`["Input: %s", "INFO"]`, C.GoString(input)))
|
||||
// cwd, result, influxHost, timescaleUrl := loadSettings()
|
||||
// log.Println("CWD:", cwd)
|
||||
// log.Println("RESULT:", result)
|
||||
// log.Println("INFLUX HOST:", influxHost)
|
||||
// log.Println("TIMESCALE URL:", timescaleUrl)
|
||||
// if result != "" {
|
||||
// logLine("goRVExtension", result)
|
||||
// temp = fmt.Sprintf(
|
||||
// `["%s", "%s", "%s", "%d"]`,
|
||||
// EXTENSION_VERSION,
|
||||
// influxConnectionSettings.Host,
|
||||
// influxConnectionSettings.Org,
|
||||
// a3Settings.RefreshRateMs,
|
||||
// )
|
||||
// }
|
||||
// case "connectToInflux":
|
||||
// // logLine("goRVExtension", fmt.Sprintf(`["Input: %s", "INFO"]`, C.GoString(input)))
|
||||
// go connectToInflux()
|
||||
// temp = `["Connecting to InfluxDB", "INFO"]`
|
||||
// case "connectToTimescale":
|
||||
// // logLine("goRVExtension", fmt.Sprintf(`["Input: %s", "INFO"]`, C.GoString(input)))
|
||||
// go connectToTimescale()
|
||||
// temp = `["Connecting to TimescaleDB", "INFO"]`
|
||||
// case "getUnixTimeNano":
|
||||
// temp = fmt.Sprintf(`["%d", "INFO"]`, getUnixTimeNano())
|
||||
// case "deinitialize":
|
||||
// logLine("goRVExtension", fmt.Sprintf(`["Input: %s", "INFO"]`, C.GoString(input)))
|
||||
// deinitialize()
|
||||
// temp = `["Deinitializing", "INFO"]`
|
||||
// default:
|
||||
// temp = fmt.Sprintf(`["Unknown command: %s", "ERROR"]`, C.GoString(input))
|
||||
// }
|
||||
|
||||
result := C.CString(temp)
|
||||
defer C.free(unsafe.Pointer(result))
|
||||
var size = C.strlen(result) + 1
|
||||
if size > outputsize {
|
||||
size = outputsize
|
||||
}
|
||||
|
||||
C.memmove(unsafe.Pointer(output), unsafe.Pointer(result), size)
|
||||
// return
|
||||
}
|
||||
|
||||
//export goRVExtensionRegisterCallback
|
||||
|
||||
@@ -1,191 +0,0 @@
|
||||
package main
|
||||
|
||||
/*
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "extensionCallback.h"
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
influxdb2 "github.com/influxdata/influxdb-client-go/v2"
|
||||
)
|
||||
|
||||
var extensionCallbackFnc C.extensionCallback
|
||||
|
||||
func runExtensionCallback(name *C.char, function *C.char, data *C.char) C.int {
|
||||
return C.runExtensionCallback(extensionCallbackFnc, name, function, data)
|
||||
}
|
||||
|
||||
//export goRVExtensionVersion
|
||||
func goRVExtensionVersion(output *C.char, outputsize C.size_t) {
|
||||
result := C.CString("Version 1.2.3")
|
||||
defer C.free(unsafe.Pointer(result))
|
||||
var size = C.strlen(result) + 1
|
||||
if size > outputsize {
|
||||
size = outputsize
|
||||
}
|
||||
C.memmove(unsafe.Pointer(output), unsafe.Pointer(result), size)
|
||||
}
|
||||
|
||||
//export goRVExtensionArgs
|
||||
func goRVExtensionArgs(output *C.char, outputsize C.size_t, input *C.char, argv **C.char, argc C.int) 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))
|
||||
}
|
||||
temp := fmt.Sprintf("Function: %s nb params: %d params: %s!", C.GoString(input), argc, out)
|
||||
|
||||
// Return a result to Arma
|
||||
result := C.CString(temp)
|
||||
defer C.free(unsafe.Pointer(result))
|
||||
var size = C.strlen(result) + 1
|
||||
if size > outputsize {
|
||||
size = outputsize
|
||||
}
|
||||
C.memmove(unsafe.Pointer(output), unsafe.Pointer(result), size)
|
||||
return 1
|
||||
}
|
||||
|
||||
func callBackExample() {
|
||||
name := C.CString("arma")
|
||||
defer C.free(unsafe.Pointer(name))
|
||||
function := C.CString("funcToExecute")
|
||||
defer C.free(unsafe.Pointer(function))
|
||||
// Make a callback to Arma
|
||||
for i := 0; i < 3; i++ {
|
||||
time.Sleep(2 * time.Second)
|
||||
param := C.CString(fmt.Sprintf("Loop: %d", i))
|
||||
defer C.free(unsafe.Pointer(param))
|
||||
runExtensionCallback(name, function, param)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
func sendToInflux(data string) {
|
||||
|
||||
fields := strings.Split(data, ",")
|
||||
|
||||
host := fields[0]
|
||||
token := fields[1]
|
||||
org := fields[2]
|
||||
bucket := fields[3]
|
||||
profile := fields[4]
|
||||
locality := fields[5]
|
||||
metric := fields[6]
|
||||
value := fields[7]
|
||||
|
||||
int_value, err := strconv.Atoi(value)
|
||||
client := influxdb2.NewClient(host, token)
|
||||
writeAPI := client.WriteAPI(org, bucket)
|
||||
|
||||
p := influxdb2.NewPoint(metric,
|
||||
map[string]string{"profile": profile, "locality": locality},
|
||||
map[string]interface{}{"count": int_value},
|
||||
time.Now())
|
||||
|
||||
// write point asynchronously
|
||||
writeAPI.WritePoint(p)
|
||||
|
||||
// Flush writes
|
||||
writeAPI.Flush()
|
||||
|
||||
defer client.Close()
|
||||
|
||||
f, err := os.OpenFile("a3metrics.log",
|
||||
os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
//logger := log.New(f, "", log.LstdFlags)
|
||||
//logger.Println(err)
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
func sendToInflux(data string) {
|
||||
|
||||
fields := strings.Split(data, ",")
|
||||
|
||||
host := fields[0]
|
||||
token := fields[1]
|
||||
org := fields[2]
|
||||
bucket := fields[3]
|
||||
profile := fields[4]
|
||||
locality := fields[5]
|
||||
metric := fields[6]
|
||||
value := fields[7]
|
||||
|
||||
|
||||
int_value, err := strconv.Atoi(value)
|
||||
client := influxdb2.NewClient(host, token)
|
||||
writeAPI := client.WriteAPI(org, bucket)
|
||||
|
||||
p := influxdb2.NewPoint(metric,
|
||||
map[string]string{"profile": profile, "locality": locality},
|
||||
map[string]interface{}{"count": int_value},
|
||||
time.Now())
|
||||
|
||||
// write point asynchronously
|
||||
writeAPI.WritePoint(p)
|
||||
|
||||
// Flush writes
|
||||
writeAPI.Flush()
|
||||
|
||||
defer client.Close()
|
||||
|
||||
f, err := os.OpenFile("a3metrics.log",
|
||||
os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
//logger := log.New(f, "", log.LstdFlags)
|
||||
//logger.Println(err)
|
||||
|
||||
}
|
||||
|
||||
|
||||
//export goRVExtension
|
||||
func goRVExtension(output *C.char, outputsize C.size_t, input *C.char) {
|
||||
// Return by default through ExtensionCallback arma handler the result
|
||||
if extensionCallbackFnc != nil {
|
||||
go callBackExample()
|
||||
} else {
|
||||
// Return a result through callextension Arma call
|
||||
temp := fmt.Sprintf("Rangermetrics: %s", C.GoString(input))
|
||||
result := C.CString(temp)
|
||||
defer C.free(unsafe.Pointer(result))
|
||||
var size = C.strlen(result) + 1
|
||||
if size > outputsize {
|
||||
size = outputsize
|
||||
}
|
||||
|
||||
go sendToInflux(C.GoString(input))
|
||||
|
||||
C.memmove(unsafe.Pointer(output), unsafe.Pointer(result), size)
|
||||
}
|
||||
}
|
||||
|
||||
//export goRVExtensionRegisterCallback
|
||||
func goRVExtensionRegisterCallback(fnc C.extensionCallback) {
|
||||
extensionCallbackFnc = fnc
|
||||
}
|
||||
|
||||
func main() {}
|
||||
@@ -1,195 +0,0 @@
|
||||
package main
|
||||
|
||||
/*
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "extensionCallback.h"
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
influxdb2 "github.com/influxdata/influxdb-client-go/v2"
|
||||
)
|
||||
|
||||
var extensionCallbackFnc C.extensionCallback
|
||||
|
||||
func runExtensionCallback(name *C.char, function *C.char, data *C.char) C.int {
|
||||
return C.runExtensionCallback(extensionCallbackFnc, name, function, data)
|
||||
}
|
||||
|
||||
//export goRVExtensionVersion
|
||||
func goRVExtensionVersion(output *C.char, outputsize C.size_t) {
|
||||
result := C.CString("Version 1.2.3")
|
||||
defer C.free(unsafe.Pointer(result))
|
||||
var size = C.strlen(result) + 1
|
||||
if size > outputsize {
|
||||
size = outputsize
|
||||
}
|
||||
C.memmove(unsafe.Pointer(output), unsafe.Pointer(result), size)
|
||||
}
|
||||
|
||||
//export goRVExtensionArgs
|
||||
func goRVExtensionArgs(output *C.char, outputsize C.size_t, input *C.char, argv **C.char, argc C.int) 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))
|
||||
}
|
||||
temp := fmt.Sprintf("Function: %s nb params: %d params: %s!", C.GoString(input), argc, out)
|
||||
|
||||
// Return a result to Arma
|
||||
result := C.CString(temp)
|
||||
defer C.free(unsafe.Pointer(result))
|
||||
var size = C.strlen(result) + 1
|
||||
if size > outputsize {
|
||||
size = outputsize
|
||||
}
|
||||
C.memmove(unsafe.Pointer(output), unsafe.Pointer(result), size)
|
||||
return 1
|
||||
}
|
||||
|
||||
func callBackExample() {
|
||||
name := C.CString("arma")
|
||||
defer C.free(unsafe.Pointer(name))
|
||||
function := C.CString("funcToExecute")
|
||||
defer C.free(unsafe.Pointer(function))
|
||||
// Make a callback to Arma
|
||||
for i := 0; i < 3; i++ {
|
||||
time.Sleep(2 * time.Second)
|
||||
param := C.CString(fmt.Sprintf("Loop: %d", i))
|
||||
defer C.free(unsafe.Pointer(param))
|
||||
runExtensionCallback(name, function, param)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
func sendToInflux(data string) {
|
||||
|
||||
fields := strings.Split(data, ",")
|
||||
|
||||
host := fields[0]
|
||||
token := fields[1]
|
||||
org := fields[2]
|
||||
bucket := fields[3]
|
||||
profile := fields[4]
|
||||
locality := fields[5]
|
||||
metric := fields[6]
|
||||
value := fields[7]
|
||||
|
||||
int_value, err := strconv.Atoi(value)
|
||||
client := influxdb2.NewClient(host, token)
|
||||
writeAPI := client.WriteAPI(org, bucket)
|
||||
|
||||
p := influxdb2.NewPoint(metric,
|
||||
map[string]string{"profile": profile, "locality": locality},
|
||||
map[string]interface{}{"count": int_value},
|
||||
time.Now())
|
||||
|
||||
// write point asynchronously
|
||||
writeAPI.WritePoint(p)
|
||||
|
||||
// Flush writes
|
||||
writeAPI.Flush()
|
||||
|
||||
defer client.Close()
|
||||
|
||||
f, err := os.OpenFile("a3metrics.log",
|
||||
os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
//logger := log.New(f, "", log.LstdFlags)
|
||||
//logger.Println(err)
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
func sendToInflux(data string) {
|
||||
|
||||
fields := strings.Split(data, ",")
|
||||
|
||||
host := fields[0]
|
||||
token := fields[1]
|
||||
org := fields[2]
|
||||
bucket := fields[3]
|
||||
profile := fields[4]
|
||||
locality := fields[5]
|
||||
metric := fields[6]
|
||||
value := fields[7]
|
||||
|
||||
|
||||
client := influxdb2.NewClient(host, token)
|
||||
writeAPI := client.WriteAPI(org, bucket)
|
||||
// int_value, err := strconv.Atoi(value)
|
||||
|
||||
|
||||
|
||||
p := influxdb2.NewPoint(metric,
|
||||
map[string]string{"profile": profile, "locality": locality},
|
||||
map[string]interface{}{"count": int_value},
|
||||
time.Now())
|
||||
|
||||
// write point asynchronously
|
||||
writeAPI.WritePoint(p)
|
||||
|
||||
|
||||
|
||||
// Flush writes
|
||||
writeAPI.Flush()
|
||||
|
||||
defer client.Close()
|
||||
|
||||
f, err := os.OpenFile("a3metrics.log",
|
||||
os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
//logger := log.New(f, "", log.LstdFlags)
|
||||
//logger.Println(err)
|
||||
|
||||
}
|
||||
|
||||
|
||||
//export goRVExtension
|
||||
func goRVExtension(output *C.char, outputsize C.size_t, input *C.char) {
|
||||
// Return by default through ExtensionCallback arma handler the result
|
||||
if extensionCallbackFnc != nil {
|
||||
go callBackExample()
|
||||
} else {
|
||||
// Return a result through callextension Arma call
|
||||
temp := fmt.Sprintf("Rangermetrics: %s", C.GoString(input))
|
||||
result := C.CString(temp)
|
||||
defer C.free(unsafe.Pointer(result))
|
||||
var size = C.strlen(result) + 1
|
||||
if size > outputsize {
|
||||
size = outputsize
|
||||
}
|
||||
|
||||
go sendToInflux(C.GoString(input))
|
||||
|
||||
C.memmove(unsafe.Pointer(output), unsafe.Pointer(result), size)
|
||||
}
|
||||
}
|
||||
|
||||
//export goRVExtensionRegisterCallback
|
||||
func goRVExtensionRegisterCallback(fnc C.extensionCallback) {
|
||||
extensionCallbackFnc = fnc
|
||||
}
|
||||
|
||||
func main() {}
|
||||
195
armaMission.go
195
armaMission.go
@@ -1,195 +0,0 @@
|
||||
package main
|
||||
|
||||
/*
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "extensionCallback.h"
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
influxdb2 "github.com/influxdata/influxdb-client-go/v2"
|
||||
)
|
||||
|
||||
var extensionCallbackFnc C.extensionCallback
|
||||
|
||||
func runExtensionCallback(name *C.char, function *C.char, data *C.char) C.int {
|
||||
return C.runExtensionCallback(extensionCallbackFnc, name, function, data)
|
||||
}
|
||||
|
||||
//export goRVExtensionVersion
|
||||
func goRVExtensionVersion(output *C.char, outputsize C.size_t) {
|
||||
result := C.CString("Version 1.2.3")
|
||||
defer C.free(unsafe.Pointer(result))
|
||||
var size = C.strlen(result) + 1
|
||||
if size > outputsize {
|
||||
size = outputsize
|
||||
}
|
||||
C.memmove(unsafe.Pointer(output), unsafe.Pointer(result), size)
|
||||
}
|
||||
|
||||
//export goRVExtensionArgs
|
||||
func goRVExtensionArgs(output *C.char, outputsize C.size_t, input *C.char, argv **C.char, argc C.int) 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))
|
||||
}
|
||||
temp := fmt.Sprintf("Function: %s nb params: %d params: %s!", C.GoString(input), argc, out)
|
||||
|
||||
// Return a result to Arma
|
||||
result := C.CString(temp)
|
||||
defer C.free(unsafe.Pointer(result))
|
||||
var size = C.strlen(result) + 1
|
||||
if size > outputsize {
|
||||
size = outputsize
|
||||
}
|
||||
C.memmove(unsafe.Pointer(output), unsafe.Pointer(result), size)
|
||||
return 1
|
||||
}
|
||||
|
||||
func callBackExample() {
|
||||
name := C.CString("arma")
|
||||
defer C.free(unsafe.Pointer(name))
|
||||
function := C.CString("funcToExecute")
|
||||
defer C.free(unsafe.Pointer(function))
|
||||
// Make a callback to Arma
|
||||
for i := 0; i < 3; i++ {
|
||||
time.Sleep(2 * time.Second)
|
||||
param := C.CString(fmt.Sprintf("Loop: %d", i))
|
||||
defer C.free(unsafe.Pointer(param))
|
||||
runExtensionCallback(name, function, param)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
func sendToInflux(data string) {
|
||||
|
||||
fields := strings.Split(data, ",")
|
||||
|
||||
host := fields[0]
|
||||
token := fields[1]
|
||||
org := fields[2]
|
||||
bucket := fields[3]
|
||||
profile := fields[4]
|
||||
locality := fields[5]
|
||||
metric := fields[6]
|
||||
value := fields[7]
|
||||
|
||||
int_value, err := strconv.Atoi(value)
|
||||
client := influxdb2.NewClient(host, token)
|
||||
writeAPI := client.WriteAPI(org, bucket)
|
||||
|
||||
p := influxdb2.NewPoint(metric,
|
||||
map[string]string{"profile": profile, "locality": locality},
|
||||
map[string]interface{}{"count": int_value},
|
||||
time.Now())
|
||||
|
||||
// write point asynchronously
|
||||
writeAPI.WritePoint(p)
|
||||
|
||||
// Flush writes
|
||||
writeAPI.Flush()
|
||||
|
||||
defer client.Close()
|
||||
|
||||
f, err := os.OpenFile("a3metrics.log",
|
||||
os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
//logger := log.New(f, "", log.LstdFlags)
|
||||
//logger.Println(err)
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
func sendToInflux(data string) {
|
||||
|
||||
fields := strings.Split(data, ",")
|
||||
|
||||
host := fields[0]
|
||||
token := fields[1]
|
||||
org := fields[2]
|
||||
bucket := fields[3]
|
||||
profile := fields[4]
|
||||
locality := fields[5]
|
||||
metric := fields[6]
|
||||
value := fields[7]
|
||||
|
||||
|
||||
client := influxdb2.NewClient(host, token)
|
||||
writeAPI := client.WriteAPI(org, bucket)
|
||||
// int_value, err := strconv.Atoi(value)
|
||||
|
||||
|
||||
|
||||
p := influxdb2.NewPoint(metric,
|
||||
map[string]string{"profile": profile, "locality": locality},
|
||||
map[string]interface{}{"count": int_value},
|
||||
time.Now())
|
||||
|
||||
// write point asynchronously
|
||||
writeAPI.WritePoint(p)
|
||||
|
||||
|
||||
|
||||
// Flush writes
|
||||
writeAPI.Flush()
|
||||
|
||||
defer client.Close()
|
||||
|
||||
f, err := os.OpenFile("a3metrics.log",
|
||||
os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
//logger := log.New(f, "", log.LstdFlags)
|
||||
//logger.Println(err)
|
||||
|
||||
}
|
||||
|
||||
|
||||
//export goRVExtension
|
||||
func goRVExtension(output *C.char, outputsize C.size_t, input *C.char) {
|
||||
// Return by default through ExtensionCallback arma handler the result
|
||||
if extensionCallbackFnc != nil {
|
||||
go callBackExample()
|
||||
} else {
|
||||
// Return a result through callextension Arma call
|
||||
temp := fmt.Sprintf("Rangermetrics: %s", C.GoString(input))
|
||||
result := C.CString(temp)
|
||||
defer C.free(unsafe.Pointer(result))
|
||||
var size = C.strlen(result) + 1
|
||||
if size > outputsize {
|
||||
size = outputsize
|
||||
}
|
||||
|
||||
go sendToInflux(C.GoString(input))
|
||||
|
||||
C.memmove(unsafe.Pointer(output), unsafe.Pointer(result), size)
|
||||
}
|
||||
}
|
||||
|
||||
//export goRVExtensionRegisterCallback
|
||||
func goRVExtensionRegisterCallback(fnc C.extensionCallback) {
|
||||
extensionCallbackFnc = fnc
|
||||
}
|
||||
|
||||
func main() {}
|
||||
48
build.txt
Normal file
48
build.txt
Normal file
@@ -0,0 +1,48 @@
|
||||
$ENV:GOARCH = "amd64"
|
||||
$ENV:CGO_ENABLED = 1
|
||||
# # $ENV:CC = "C:`\Program Files (x86)`\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30133\bin\Hostx64\x64\cl.exe"
|
||||
go1.16.4 build -o RangerMetrics_x64.dll -buildmode=c-shared .
|
||||
|
||||
# THIS ONE WORKS
|
||||
$ENV:GOARCH = "amd64"
|
||||
$ENV:CGO_ENABLED = 1
|
||||
go1.16.4 build -o RangerMetrics_x64.dll -buildmode=c-shared .
|
||||
|
||||
|
||||
. "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30133\bin\Hostx64\x64\dumpbin.exe" /exports .\RangerMetrics_x64.dll
|
||||
|
||||
|
||||
go build -buildmode=c-archive basictest.go
|
||||
gcc -shared -W -c -c -c -o basictest_x64.dll RVExtension.c bases -Wl, --subsystem -Wl, windows -Wl, --inable-ctdcall-fixuptes -Wl, --subsystem -Wl, windows -Wl, --enable-stdcall-fixupt.a -Wl, --subsystem -Wl, windows -Wl, --enable-stdcall-fixup
|
||||
|
||||
g++ -o test -l mingw32 RVExtension.c .\RangerMetrics_x64.dll
|
||||
|
||||
|
||||
go build -buildmode=c-archive arma.go
|
||||
gcc -shared -pthread -o RangerMetrics_x64.dll RVExtension.c arma.a -lWinMM -lntdll -lWS2_32
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
$ENV:GOARCH = 386
|
||||
$ENV:CGO_ENABLED = 1
|
||||
go build -buildmode=c-archive basictest.go
|
||||
gcc -shared -pthread -o basictest_x64.dll -fPIC RVExtension.c basictest.a
|
||||
|
||||
$ENV:GOARCH = "amd64"
|
||||
$ENV:CGO_ENABLED = 1
|
||||
go build -buildmode=c-archive basictest.go
|
||||
. "C:\TDM-GCC-64-9.2.0\bin\gcc.exe" -shared -pthread -o basictest_x64.dll RVExtension.c basictest.a
|
||||
|
||||
$ENV:GOARCH = 386
|
||||
$ENV:CGO_ENABLED = 1
|
||||
go build -o basictest.dll -buildmode=c-shared .
|
||||
. "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30133\bin\Hostx64\x64\dumpbin.exe" /exports .\basictest.dll
|
||||
|
||||
$ENV:GOARCH = "amd64"
|
||||
$ENV:CGO_ENABLED = 1
|
||||
$ENV:GOOS = "windows"
|
||||
$ENV:CC = "x86_64-w64-mingw32-gcc"
|
||||
go build -o basictest_x64.dll -buildmode=c-shared .
|
||||
. "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.29.30133\bin\Hostx64\x64\dumpbin.exe" /exports .\basictest_x64.dll
|
||||
BIN
callExtension.exe
Normal file
BIN
callExtension.exe
Normal file
Binary file not shown.
BIN
callExtension_x64.exe
Normal file
BIN
callExtension_x64.exe
Normal file
Binary file not shown.
@@ -5,6 +5,7 @@
|
||||
typedef int (*extensionCallback)(char const *name, char const *function, char const *data);
|
||||
|
||||
/* https://golang.org/cmd/cgo/#hdr-C_references_to_Go */
|
||||
static inline int runExtensionCallback(extensionCallback fnc, char const *name, char const *function, char const *data) {
|
||||
static inline int runExtensionCallback(extensionCallback fnc, char const *name, char const *function, char const *data)
|
||||
{
|
||||
return fnc(name, function, data);
|
||||
}
|
||||
7
go.mod
7
go.mod
@@ -1,5 +1,8 @@
|
||||
module github.com/7cav/a3-fone-home
|
||||
module main
|
||||
|
||||
go 1.16
|
||||
|
||||
require github.com/influxdata/influxdb-client-go/v2 v2.6.0
|
||||
require (
|
||||
github.com/influxdata/influxdb-client-go/v2 v2.6.0
|
||||
github.com/jackc/pgx/v4 v4.18.1
|
||||
)
|
||||
|
||||
184
go.sum
184
go.sum
@@ -1,63 +1,202 @@
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
||||
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/deepmap/oapi-codegen v1.6.0 h1:w/d1ntwh91XI0b/8ja7+u5SvA4IFfM0UNNLmiDR1gg0=
|
||||
github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M=
|
||||
github.com/deepmap/oapi-codegen v1.8.2 h1:SegyeYGcdi0jLLrpbCMoJxnUUn8GBXHsvr4rbzjuhfU=
|
||||
github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4=
|
||||
github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs=
|
||||
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/influxdata/influxdb-client-go/v2 v2.3.0 h1:4YzLWRsPUoHuQYWDwPoybaJjN01e0/k0AIQO85ymCKI=
|
||||
github.com/influxdata/influxdb-client-go/v2 v2.3.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8=
|
||||
github.com/influxdata/influxdb-client-go/v2 v2.6.0 h1:bIOaGTgvvv1Na2hG+nIvqyv7PK2UiU2WrJN1ck1ykyM=
|
||||
github.com/influxdata/influxdb-client-go/v2 v2.6.0/go.mod h1:Y/0W1+TZir7ypoQZYd2IrnVOKB3Tq6oegAQeSVN/+EU=
|
||||
github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 h1:W9WBk7wlPfJLvMCdtV4zPulc4uCPrlywQOmbFOhgQNU=
|
||||
github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo=
|
||||
github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0=
|
||||
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
|
||||
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
||||
github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
|
||||
github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
||||
github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA=
|
||||
github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE=
|
||||
github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s=
|
||||
github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o=
|
||||
github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY=
|
||||
github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI=
|
||||
github.com/jackc/pgconn v1.14.0 h1:vrbA9Ud87g6JdFWkHTJXppVce58qPIdP7N8y0Ml/A7Q=
|
||||
github.com/jackc/pgconn v1.14.0/go.mod h1:9mBNlny0UvkgJdCDvdVHYSjI+8tD2rnKK69Wz8ti++E=
|
||||
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
|
||||
github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
|
||||
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
|
||||
github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c=
|
||||
github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak=
|
||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||
github.com/jackc/pgproto3 v1.1.0 h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A=
|
||||
github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78=
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA=
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg=
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
|
||||
github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||
github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||
github.com/jackc/pgproto3/v2 v2.3.2 h1:7eY55bdBeCz1F2fTzSz69QC+pG46jYq9/jtSPiJ5nn0=
|
||||
github.com/jackc/pgproto3/v2 v2.3.2/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg=
|
||||
github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=
|
||||
github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
|
||||
github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM=
|
||||
github.com/jackc/pgtype v1.14.0 h1:y+xUdabmyMkJLyApYuPj38mW+aAIqCe5uuBB51rH3Vw=
|
||||
github.com/jackc/pgtype v1.14.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
|
||||
github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
|
||||
github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
|
||||
github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
|
||||
github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs=
|
||||
github.com/jackc/pgx/v4 v4.18.1 h1:YP7G1KABtKpB5IHrO9vYwSrCOhs7p3uqhvhhQBptya0=
|
||||
github.com/jackc/pgx/v4 v4.18.1/go.mod h1:FydWkUyadDmdNH/mHnGob881GawxeEm7TcMCzkb+qQE=
|
||||
github.com/jackc/pgx/v5 v5.3.1 h1:Fcr8QJ1ZeLi5zsPZqQeUZhNhxfkkKBOgJuYkJHoBOtU=
|
||||
github.com/jackc/pgx/v5 v5.3.1/go.mod h1:t3JDKnCBlYIc0ewLF0Q7B8MXmoIaBOZj/ic7iHozM/8=
|
||||
github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v1.3.0 h1:eHK/5clGOatcjX3oWGBO/MpxpbHzSwud5EWTSCI+MX0=
|
||||
github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle/v2 v2.2.0 h1:RdcDk92EJBuBS55nQMMYFXTxwstHug4jkhT5pq8VxPk=
|
||||
github.com/jackc/puddle/v2 v2.2.0/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg=
|
||||
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ=
|
||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
|
||||
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
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/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
||||
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777 h1:003p0dJM77cxMSyCPFphvZf/Y5/NXf5fzg6ufd1/Oew=
|
||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -66,18 +205,51 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
|
||||
10
makefile
10
makefile
@@ -1,4 +1,12 @@
|
||||
build:
|
||||
export GOARCH="amd64"
|
||||
export CGO_ENABLED=1
|
||||
go build -o armago.dll -buildmode=c-shared .
|
||||
go build -o RangerMetrics_x64.so -buildmode=c-shared .
|
||||
|
||||
export GOARCH = "386"
|
||||
export CGO_ENABLED = 1
|
||||
go build -o RangerMetrics.dll -buildmode=c-shared .
|
||||
|
||||
export GOARCH = "amd64"
|
||||
export CGO_ENABLED = 1
|
||||
go build -o RangerMetrics_x64.dll -buildmode=c-shared .
|
||||
|
||||
26
testsqf.sqf
Normal file
26
testsqf.sqf
Normal file
@@ -0,0 +1,26 @@
|
||||
freeExtension "RangerMetrics";
|
||||
// sleep 0.5;
|
||||
// "RangerMetrics" callExtension "loadSettings";
|
||||
// "RangerMetrics" callExtension "version";
|
||||
// "RangerMetrics" callExtension "connectToInflux";
|
||||
// "RangerMetrics" callExtension "connectToTimescale";
|
||||
// sleep 5;
|
||||
// "RangerMetrics" callExtension "initTimescale";
|
||||
|
||||
// addMissionEventHandler ["ExtensionCallback", {
|
||||
// params ["_extension", "_function", "_data"];
|
||||
// if (
|
||||
// _extension == "RangerMetrics" && _function isEqualTo "connectToTimescale"
|
||||
// ) then {
|
||||
// diag_log format ["RangerMetrics: %1", _data];
|
||||
// };
|
||||
// }];
|
||||
"RangerMetrics" callExtension "deinitExtension";
|
||||
sleep 1;
|
||||
"RangerMetrics" callExtension "initExtension";
|
||||
|
||||
sleep 20;
|
||||
"RangerMetrics" callExtension "deinitExtension";
|
||||
// freeExtension "RangerMetrics";
|
||||
sleep 5;
|
||||
exit;
|
||||
Reference in New Issue
Block a user