2 Commits

435
arma.go
View File

@@ -44,7 +44,7 @@ var AVAILABLE_FUNCTIONS = map[string]interface{}{
"getUnixTimeNano": getUnixTimeNano, "getUnixTimeNano": getUnixTimeNano,
} }
var EXTENSION_VERSION string = "0.0.2" var EXTENSION_VERSION string = "0.0.3"
var extensionCallbackFnc C.extensionCallback var extensionCallbackFnc C.extensionCallback
type ServerPollSetting struct { type ServerPollSetting struct {
@@ -136,6 +136,19 @@ func initExtension() {
var err error 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() activeSettings, err = loadSettings()
if err != nil { if err != nil {
logLine(functionName, fmt.Sprintf(`["Error loading settings: %v", "ERROR"]`, err), false) logLine(functionName, fmt.Sprintf(`["Error loading settings: %v", "ERROR"]`, err), false)
@@ -267,210 +280,298 @@ func initTimescale() {
// schema init sql // schema init sql
var tableCreationSql string = ` var tableCreationSql string = `
CREATE TABLE "Missions" ( CREATE TABLE IF NOT EXISTS units."State"
"id" serial NOT NULL UNIQUE, (
"world_name" VARCHAR(255) NOT NULL, "timestamp" timestamp with time zone NOT NULL,
"briefing_name" VARCHAR(255) NOT NULL, mission_id integer NOT NULL,
"mission_name" VARCHAR(255) NOT NULL, net_id text COLLATE pg_catalog."default" NOT NULL,
"mission_author" VARCHAR(255) NOT NULL, player_uid text COLLATE pg_catalog."default" NOT NULL DEFAULT '-1'::integer,
"server_name" VARCHAR(255) NOT NULL, is_alive boolean NOT NULL,
"server_mods" TEXT, is_afk boolean,
"ace_medical" BOOLEAN NOT NULL, is_speaking smallint,
"radio_tfar" BOOLEAN NOT NULL, unit_name text COLLATE pg_catalog."default" NOT NULL,
"radio_acre" BOOLEAN NOT NULL, side text COLLATE pg_catalog."default" NOT NULL,
"start_game" TIMESTAMP NOT NULL, "position" point NOT NULL,
"start_utc" TIMESTAMP NOT NULL, direction numeric(2, 0) NOT NULL,
"frame_count" FLOAT NOT NULL, health numeric(2, 0),
"capture_delay_s" FLOAT NOT NULL, traits text[] COLLATE pg_catalog."default",
"addon_ver_major" integer NOT NULL, CONSTRAINT "UnitStates_pkey" PRIMARY KEY (net_id, "timestamp", player_uid, mission_id)
"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
); );
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 IF NOT EXISTS units."Identity"
CREATE TABLE "Worlds" ( (
"world_name" VARCHAR(255) NOT NULL, "timestamp" timestamp with time zone NOT NULL,
"display_name" VARCHAR(255) NOT NULL, mission_id integer NOT NULL,
"world_size_m" integer NOT NULL, net_id text COLLATE pg_catalog."default" NOT NULL,
CONSTRAINT "Worlds_pk" PRIMARY KEY ("world_name") player_uid text COLLATE pg_catalog."default" NOT NULL DEFAULT '-1'::integer,
) WITH ( class_name text COLLATE pg_catalog."default" NOT NULL,
OIDS=FALSE 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 IF NOT EXISTS events."Chat"
CREATE TABLE "Units" ( (
"mission_id" integer NOT NULL, id bigserial NOT NULL,
"unit_id" integer NOT NULL, "timestamp" timestamp with time zone NOT NULL,
"frame" integer NOT NULL, mission_id integer NOT NULL,
"steamid64" varchar(100), player_uid text COLLATE pg_catalog."default" NOT NULL DEFAULT -1,
"steam_name" VARCHAR(255) NOT NULL, channel integer,
"a3_profile_name" VARCHAR(255) NOT NULL, owner integer,
"is_human" BOOLEAN NOT NULL, name text COLLATE pg_catalog."default",
"is_afk" BOOLEAN NOT NULL, "from" text COLLATE pg_catalog."default",
"is_alive" BOOLEAN NOT NULL, text text COLLATE pg_catalog."default",
"unit_type" VARCHAR(255) NOT NULL, "forcedDisplay" boolean,
"role_description" VARCHAR(255), "isPlayerMessage" boolean,
"side" integer NOT NULL, "sentenceType" integer,
"group_id" varchar(100) NOT NULL, "chatMessageType" integer,
"name" VARCHAR(255), CONSTRAINT "Chat_pkey" PRIMARY KEY ("timestamp", mission_id, player_uid, id),
"position" VARCHAR(255) NOT NULL, UNIQUE (id)
"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 missions."Played"
(
CREATE TABLE "Vehicles" ( id serial NOT NULL,
"mission_id" integer NOT NULL, start_time_utc timestamp with time zone NOT NULL,
"frame" integer NOT NULL, start_time_game timestamp with time zone NOT NULL,
"vehicle_id" integer NOT NULL, world_name text COLLATE pg_catalog."default" NOT NULL,
"object_type" VARCHAR(255), briefing_name text COLLATE pg_catalog."default" NOT NULL,
"weapons" varchar(3000), mission_name text COLLATE pg_catalog."default" NOT NULL,
"customization" varchar(1000), mission_name_source text COLLATE pg_catalog."default" NOT NULL,
"position" VARCHAR(255) NOT NULL, on_load_name text NOT NULL,
"direction" FLOAT NOT NULL, author text COLLATE pg_catalog."default" NOT NULL,
"vector_dir" varchar(70) NOT NULL, server_name text COLLATE pg_catalog."default" NOT NULL,
"vector_up" varchar(70) NOT NULL, server_mods json,
"is_alive" BOOLEAN NOT NULL, ace_medical boolean,
"damage" FLOAT NOT NULL, radio_tfar boolean,
CONSTRAINT "Vehicles_pk" PRIMARY KEY ("mission_id","frame","vehicle_id") radio_acre boolean,
) WITH ( duration interval,
OIDS=FALSE 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 IF NOT EXISTS players."ConnectionsMission"
CREATE TABLE "Markers" ( (
"mission_id" integer NOT NULL, id bigserial NOT NULL,
"frame" integer NOT NULL, "timestamp" timestamp with time zone NOT NULL,
"marker_name" VARCHAR(255) NOT NULL, mission_id integer NOT NULL,
"data" VARCHAR(255) NOT NULL, player_uid text COLLATE pg_catalog."default" NOT NULL,
CONSTRAINT "Markers_pk" PRIMARY KEY ("mission_id","frame","marker_name") event_type text COLLATE pg_catalog."default" NOT NULL,
) WITH ( profile_name text COLLATE pg_catalog."default" NOT NULL,
OIDS=FALSE 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 IF NOT EXISTS units."Inventory"
(
CREATE TABLE "Chat" ( "timestamp" timestamp with time zone NOT NULL,
"id" serial NOT NULL, mission_id integer NOT NULL,
"mission_id" integer NOT NULL, net_id text NOT NULL,
"sender_id" integer NOT NULL, player_uid text NOT NULL DEFAULT -1,
"frame" integer NOT NULL, inventory jsonb NOT NULL,
"timestamp_utc" TIMESTAMP NOT NULL, PRIMARY KEY ("timestamp", net_id, mission_id, player_uid)
"content" VARCHAR(255) NOT NULL,
"channel" integer NOT NULL,
CONSTRAINT "Chat_pk" PRIMARY KEY ("id")
) WITH (
OIDS=FALSE
); );
COMMENT ON TABLE units."Inventory"
IS 'This is used to track the inventory state of units.';
CREATE TABLE IF NOT EXISTS players."ConnectionsServer"
CREATE TABLE "UniqueUsers" ( (
"steamid64" varchar(100) NOT NULL, "timestamp" timestamp with time zone NOT NULL,
CONSTRAINT "UniqueUsers_pk" PRIMARY KEY ("steamid64") player_uid text COLLATE pg_catalog."default" NOT NULL,
) WITH ( event_type text COLLATE pg_catalog."default" NOT NULL,
OIDS=FALSE 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 IF NOT EXISTS missions."Environment"
(
CREATE TABLE "Environment" ( "timestamp" timestamp with time zone NOT NULL,
"mission_id" integer NOT NULL, mission_id integer NOT NULL,
"frame" integer NOT NULL, fog numeric(2),
"date_game" TIMESTAMP NOT NULL, overcast numeric(2),
"date_utc" TIMESTAMP NOT NULL, rain numeric(2),
"overcast" FLOAT NOT NULL, humidity numeric(2),
"rain" FLOAT NOT NULL, waves numeric(2),
"humidity" FLOAT NOT NULL, "windDir" numeric(2),
"fog_value" FLOAT NOT NULL, "windStr" numeric(2),
"fog_decay" FLOAT NOT NULL, gusts numeric(2),
"fog_base" FLOAT NOT NULL, lightnings numeric(2),
"wind_vector" VARCHAR(255) NOT NULL, "moonIntensity" numeric(2),
"gusts" FLOAT NOT NULL, "moonPhase" numeric(2),
"waves" FLOAT NOT NULL, "sunOrMoon" numeric(2),
CONSTRAINT "Environment_pk" PRIMARY KEY ("mission_id","frame") PRIMARY KEY ("timestamp", mission_id)
) WITH (
OIDS=FALSE
); );
COMMENT ON TABLE missions."Environment"
IS 'Contains periodically collected environmental information during missions.';
CREATE TABLE IF NOT EXISTS vehicles."Identity"
CREATE TABLE "StaticObjects" ( (
"mission_id" integer NOT NULL, "timestamp" timestamp with time zone NOT NULL,
"frame" integer NOT NULL, mission_id integer NOT NULL,
"building_id" integer NOT NULL, net_id text NOT NULL,
"position" integer NOT NULL, class_name text NOT NULL,
"direction" FLOAT NOT NULL, display_name text,
"vector_dir" varchar(70) NOT NULL, customization jsonb,
"vector_up" varchar(70) NOT NULL, weapons jsonb,
"object_type" VARCHAR(255) NOT NULL, PRIMARY KEY ("timestamp", mission_id, net_id)
"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
); );
COMMENT ON TABLE vehicles."Identity"
IS 'Periodically polled identity information about a vehicle.';
CREATE TABLE IF NOT EXISTS vehicles."State"
CREATE TABLE "Campaigns" ( (
"id" serial NOT NULL, "timestamp" timestamp with time zone NOT NULL,
"name" VARCHAR(255) NOT NULL, mission_id integer NOT NULL,
"description" TEXT NOT NULL, net_id text NOT NULL,
"image" bytea NOT NULL, is_alive boolean,
CONSTRAINT "Campaigns_pk" PRIMARY KEY ("id") side text,
) WITH ( "position" point NOT NULL,
OIDS=FALSE 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 IF NOT EXISTS players."AllObserved"
CREATE TABLE "Missions_In_Campaigns" ( (
"mission" integer NOT NULL, id serial NOT NULL,
"campaign" integer NOT NULL, player_uid text NOT NULL,
CONSTRAINT "Missions_In_Campaigns_pk" PRIMARY KEY ("mission","campaign") PRIMARY KEY (id, player_uid),
) WITH ( UNIQUE (player_uid)
OIDS=FALSE
); );
` `
relationCreationSql := []string{ 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 IF EXISTS units."State"
`ALTER TABLE "Units" ADD CONSTRAINT "Units_fk1" FOREIGN KEY ("steamid64") REFERENCES "UniqueUsers"("steamid64");`, 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 IF EXISTS events."Chat"
`ALTER TABLE "Chat" ADD CONSTRAINT "Chat_fk1" FOREIGN KEY ("sender_id") REFERENCES "Units"("unit_id");`, 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 IF EXISTS players."ConnectionsMission"
`ALTER TABLE "Missions_In_Campaigns" ADD CONSTRAINT "Missions_In_Campaigns_fk1" FOREIGN KEY ("campaign") REFERENCES "Campaigns"("id");`, 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 var tx pgx.Tx