2 Commits

435
arma.go
View File

@@ -44,7 +44,7 @@ var AVAILABLE_FUNCTIONS = map[string]interface{}{
"getUnixTimeNano": getUnixTimeNano,
}
var EXTENSION_VERSION string = "0.0.2"
var EXTENSION_VERSION string = "0.0.3"
var extensionCallbackFnc C.extensionCallback
type ServerPollSetting struct {
@@ -136,6 +136,19 @@ func initExtension() {
var err error
// get location of this dll
// dllPath, err := filepath.Abs(os.Args[0])
// if err != nil {
// logLine(functionName, fmt.Sprintf(`["Error getting DLL path: %v", "ERROR"]`, err), false)
// return
// }
// set the addon directory to the parent directory of the dll
// ADDON_FOLDER = filepath.Dir(dllPath)
// LOG_FILE = ADDON_FOLDER + "\\rangermetrics.log"
// SETTINGS_FILE = ADDON_FOLDER + "\\settings.json"
// SETTINGS_FILE_EXAMPLE = ADDON_FOLDER + "\\settings.example.json"
activeSettings, err = loadSettings()
if err != nil {
logLine(functionName, fmt.Sprintf(`["Error loading settings: %v", "ERROR"]`, err), false)
@@ -267,210 +280,298 @@ func initTimescale() {
// 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 IF NOT EXISTS units."State"
(
"timestamp" timestamp with time zone NOT NULL,
mission_id integer NOT NULL,
net_id text COLLATE pg_catalog."default" NOT NULL,
player_uid text COLLATE pg_catalog."default" NOT NULL DEFAULT '-1'::integer,
is_alive boolean NOT NULL,
is_afk boolean,
is_speaking smallint,
unit_name text COLLATE pg_catalog."default" NOT NULL,
side text COLLATE pg_catalog."default" NOT NULL,
"position" point NOT NULL,
direction numeric(2, 0) NOT NULL,
health numeric(2, 0),
traits text[] COLLATE pg_catalog."default",
CONSTRAINT "UnitStates_pkey" PRIMARY KEY (net_id, "timestamp", player_uid, mission_id)
);
COMMENT ON TABLE units."State"
IS 'Reflects a unit''s (soldier''s) state during a mission. Can be AI (player_uid = -1) or a player.';
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 IF NOT EXISTS units."Identity"
(
"timestamp" timestamp with time zone NOT NULL,
mission_id integer NOT NULL,
net_id text COLLATE pg_catalog."default" NOT NULL,
player_uid text COLLATE pg_catalog."default" NOT NULL DEFAULT '-1'::integer,
class_name text COLLATE pg_catalog."default" NOT NULL,
display_name text,
side text,
role_description text COLLATE pg_catalog."default",
traits text[] COLLATE pg_catalog."default",
CONSTRAINT "Units_pkey" PRIMARY KEY (mission_id, net_id, "timestamp", player_uid)
);
COMMENT ON TABLE units."Identity"
IS 'This is polled periodically during the mission to gather static and less-dynamic traits of units (soldiers).';
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 IF NOT EXISTS events."Chat"
(
id bigserial NOT NULL,
"timestamp" timestamp with time zone NOT NULL,
mission_id integer NOT NULL,
player_uid text COLLATE pg_catalog."default" NOT NULL DEFAULT -1,
channel integer,
owner integer,
name text COLLATE pg_catalog."default",
"from" text COLLATE pg_catalog."default",
text text COLLATE pg_catalog."default",
"forcedDisplay" boolean,
"isPlayerMessage" boolean,
"sentenceType" integer,
"chatMessageType" integer,
CONSTRAINT "Chat_pkey" PRIMARY KEY ("timestamp", mission_id, player_uid, id),
UNIQUE (id)
);
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 IF NOT EXISTS missions."Played"
(
id serial NOT NULL,
start_time_utc timestamp with time zone NOT NULL,
start_time_game timestamp with time zone NOT NULL,
world_name text COLLATE pg_catalog."default" NOT NULL,
briefing_name text COLLATE pg_catalog."default" NOT NULL,
mission_name text COLLATE pg_catalog."default" NOT NULL,
mission_name_source text COLLATE pg_catalog."default" NOT NULL,
on_load_name text NOT NULL,
author text COLLATE pg_catalog."default" NOT NULL,
server_name text COLLATE pg_catalog."default" NOT NULL,
server_mods json,
ace_medical boolean,
radio_tfar boolean,
radio_acre boolean,
duration interval,
version_addon integer[] NOT NULL,
version_extension integer[] NOT NULL,
tags text[] COLLATE pg_catalog."default",
CONSTRAINT "MissionsRun_pkey" PRIMARY KEY (id, world_name, start_time_utc),
CONSTRAINT "MissionsRun_id_start_time_utc_key" UNIQUE (id, start_time_utc),
UNIQUE (id)
);
COMMENT ON TABLE missions."Played"
IS 'Contains core mission data, recorded at mission init. The IDs here are referenced by many other areas to "place" them.';
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 IF NOT EXISTS players."ConnectionsMission"
(
id bigserial NOT NULL,
"timestamp" timestamp with time zone NOT NULL,
mission_id integer NOT NULL,
player_uid text COLLATE pg_catalog."default" NOT NULL,
event_type text COLLATE pg_catalog."default" NOT NULL,
profile_name text COLLATE pg_catalog."default" NOT NULL,
display_name text COLLATE pg_catalog."default" NOT NULL,
steam_name text COLLATE pg_catalog."default" NOT NULL,
is_jip boolean,
CONSTRAINT "ConnectionsMission_pkey" PRIMARY KEY (player_uid, "timestamp", profile_name, mission_id, id),
UNIQUE ("timestamp", mission_id, player_uid, id)
);
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 IF NOT EXISTS units."Inventory"
(
"timestamp" timestamp with time zone NOT NULL,
mission_id integer NOT NULL,
net_id text NOT NULL,
player_uid text NOT NULL DEFAULT -1,
inventory jsonb NOT NULL,
PRIMARY KEY ("timestamp", net_id, mission_id, player_uid)
);
COMMENT ON TABLE units."Inventory"
IS 'This is used to track the inventory state of units.';
CREATE TABLE "UniqueUsers" (
"steamid64" varchar(100) NOT NULL,
CONSTRAINT "UniqueUsers_pk" PRIMARY KEY ("steamid64")
) WITH (
OIDS=FALSE
CREATE TABLE IF NOT EXISTS players."ConnectionsServer"
(
"timestamp" timestamp with time zone NOT NULL,
player_uid text COLLATE pg_catalog."default" NOT NULL,
event_type text COLLATE pg_catalog."default" NOT NULL,
profile_name text COLLATE pg_catalog."default" NOT NULL,
display_name text COLLATE pg_catalog."default" NOT NULL,
steam_name text COLLATE pg_catalog."default" NOT NULL,
is_jip boolean,
CONSTRAINT "PlayersObserved_pkey" PRIMARY KEY (player_uid, "timestamp", profile_name)
);
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 IF NOT EXISTS missions."Environment"
(
"timestamp" timestamp with time zone NOT NULL,
mission_id integer NOT NULL,
fog numeric(2),
overcast numeric(2),
rain numeric(2),
humidity numeric(2),
waves numeric(2),
"windDir" numeric(2),
"windStr" numeric(2),
gusts numeric(2),
lightnings numeric(2),
"moonIntensity" numeric(2),
"moonPhase" numeric(2),
"sunOrMoon" numeric(2),
PRIMARY KEY ("timestamp", mission_id)
);
COMMENT ON TABLE missions."Environment"
IS 'Contains periodically collected environmental information during missions.';
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 IF NOT EXISTS vehicles."Identity"
(
"timestamp" timestamp with time zone NOT NULL,
mission_id integer NOT NULL,
net_id text NOT NULL,
class_name text NOT NULL,
display_name text,
customization jsonb,
weapons jsonb,
PRIMARY KEY ("timestamp", mission_id, net_id)
);
COMMENT ON TABLE vehicles."Identity"
IS 'Periodically polled identity information about a vehicle.';
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 IF NOT EXISTS vehicles."State"
(
"timestamp" timestamp with time zone NOT NULL,
mission_id integer NOT NULL,
net_id text NOT NULL,
is_alive boolean,
side text,
"position" point NOT NULL,
direction numeric(2),
health numeric(2),
crew text[],
PRIMARY KEY ("timestamp", mission_id, net_id)
);
COMMENT ON TABLE vehicles."State"
IS 'State information about vehicles. Crew is an array of net_id to be referenced against the Unit tables.';
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
CREATE TABLE IF NOT EXISTS players."AllObserved"
(
id serial NOT NULL,
player_uid text NOT NULL,
PRIMARY KEY (id, player_uid),
UNIQUE (player_uid)
);
`
relationCreationSql := []string{
`ALTER TABLE "Missions" ADD CONSTRAINT "Missions_fk0" FOREIGN KEY ("world_name") REFERENCES "Worlds"("world_name");`,
`ALTER TABLE IF EXISTS units."State"
ADD FOREIGN KEY (mission_id)
REFERENCES missions."Played" (id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
NOT VALID;
`,
`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 IF EXISTS units."State"
ADD FOREIGN KEY (player_uid)
REFERENCES players."AllObserved" (player_uid) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
NOT VALID;
`,
`ALTER TABLE "Vehicles" ADD CONSTRAINT "Vehicles_fk0" FOREIGN KEY ("mission_id") REFERENCES "Missions"("id");`,
`ALTER TABLE IF EXISTS units."Identity"
ADD FOREIGN KEY (mission_id)
REFERENCES missions."Played" (id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
NOT VALID;
`,
`ALTER TABLE "Markers" ADD CONSTRAINT "Markers_fk0" FOREIGN KEY ("mission_id") REFERENCES "Missions"("id");`,
`ALTER TABLE IF EXISTS units."Identity"
ADD FOREIGN KEY (player_uid)
REFERENCES players."AllObserved" (player_uid) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
NOT VALID;
`,
`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 IF EXISTS events."Chat"
ADD FOREIGN KEY (mission_id)
REFERENCES missions."Played" (id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
NOT VALID;
`,
`ALTER TABLE "Environment" ADD CONSTRAINT "Environment_fk0" FOREIGN KEY ("mission_id") REFERENCES "Missions"("id");`,
`ALTER TABLE IF EXISTS events."Chat"
ADD FOREIGN KEY (player_uid)
REFERENCES players."AllObserved" (player_uid) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
NOT VALID;
`,
`ALTER TABLE "StaticObjects" ADD CONSTRAINT "StaticObjects_fk0" FOREIGN KEY ("mission_id") REFERENCES "Missions"("id");`,
`ALTER TABLE IF EXISTS players."ConnectionsMission"
ADD FOREIGN KEY (mission_id)
REFERENCES missions."Played" (id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
NOT VALID;
`,
`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");`,
`ALTER TABLE IF EXISTS players."ConnectionsMission"
ADD FOREIGN KEY (player_uid)
REFERENCES players."AllObserved" (player_uid) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
NOT VALID;
`,
`ALTER TABLE IF EXISTS units."Inventory"
ADD FOREIGN KEY (mission_id)
REFERENCES missions."Played" (id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
NOT VALID;
`,
`ALTER TABLE IF EXISTS units."Inventory"
ADD FOREIGN KEY (player_uid)
REFERENCES players."AllObserved" (player_uid) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
NOT VALID;
`,
`ALTER TABLE IF EXISTS missions."Environment"
ADD FOREIGN KEY (mission_id)
REFERENCES missions."Played" (id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
NOT VALID;
`,
`ALTER TABLE IF EXISTS vehicles."Identity"
ADD FOREIGN KEY (mission_id)
REFERENCES missions."Played" (id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
NOT VALID;
`,
`ALTER TABLE IF EXISTS vehicles."State"
ADD FOREIGN KEY (mission_id)
REFERENCES missions."Played" (id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
NOT VALID;
`,
}
var tx pgx.Tx