bug fixes, 3 table split, update readme

This commit is contained in:
2023-06-14 09:59:45 -07:00
parent 7608df9e53
commit f6ff42e467
22 changed files with 129 additions and 77 deletions

View File

@@ -1,2 +0,0 @@
params [["_value", "", [""]]];
("AttendanceTracker" callExtension ["getMissionHash", _value]) select 0;

View File

@@ -1 +0,0 @@
(parseSimpleArray ("AttendanceTracker" callExtension "getTimestamp")) select 0;

BIN
@AttendanceTracker.7z Normal file

Binary file not shown.

View File

@@ -43,16 +43,25 @@ addMissionEventHandler ["ExtensionCallback", {
missionNamespace setVariable ["AttendanceTracker_DBConnected", true];
// log mission info and get back the row Id to send with future messages
private _response = "AttendanceTracker" callExtension ["logMission", [
private _response = "AttendanceTracker" callExtension [
"logMission",
[
[AttendanceTracker getVariable ["missionContext", createHashMap]] call CBA_fnc_encodeJSON
]];
AttendanceTracker_missionId = parseNumber _response;
]
];
// log world info
private _response = "AttendanceTracker" callExtension ["logWorld", [
[call attendanceTracker_fnc_getWorldInfo] call CBA_fnc_encodeJSON
]];
private _response = "AttendanceTracker" callExtension [
"logWorld",
[
[(call attendanceTracker_fnc_getWorldInfo)] call CBA_fnc_encodeJSON
]
];
};
};
case "writeMissionInfo": {
if (_response#0 == "MISSION_ID") then {
AttendanceTracker_missionId = parseNumber _response;
};
};
case "writeAttendance": {

View File

@@ -0,0 +1 @@
(parseSimpleArray ("AttendanceTracker" callExtension "getMissionHash")) select 0;

View File

@@ -14,7 +14,7 @@ _workshopID = '';
} foreach getLoadedModsInfo;
// [_name, _author, _workshopID];
[
_return = createHashMapFromArray [
["author", _author],
["workshopID", _workshopID],
["displayName", _name],
@@ -24,3 +24,5 @@ _workshopID = '';
["latitude", getNumber( _world >> "latitude" )],
["longitude", getNumber( _world >> "longitude" )]
];
diag_log format ["Attendance Tracker: WorldInfo is: %1", _return];
_return

View File

@@ -2,7 +2,9 @@
AttendanceTracker = false call CBA_fnc_createNamespace;
AttendanceTracker_missionStartTimestamp = call attendanceTracker_fnc_timestamp;
AttendanceTracker_missionHash = [AttendanceTracker_missionStartTimestamp] call attendanceTracker_fnc_getMissionHash;
diag_log format ["AttendanceTracker: Mission started at %1", AttendanceTracker_missionStartTimestamp];
AttendanceTracker_missionHash = call attendanceTracker_fnc_getMissionHash;
diag_log format ["AttendanceTracker: Mission hash is %1", AttendanceTracker_missionHash];
AttendanceTracker setVariable ["missionContext", createHashMapFromArray [
["missionName", missionName],

View File

@@ -0,0 +1,24 @@
// (parseSimpleArray ("AttendanceTracker" callExtension "getTimestamp")) select 0;
// need date for MySQL in format 2006-01-02 15:04:05
systemTimeUTC params [
"_year",
"_month",
"_day",
"_hour",
"_minute",
"_second"
"_millisecond"
];
format[
"%1-%2-%3 %4:%5:%6",
_year,
_month,
_day,
_hour,
_minute,
_second
];

View File

@@ -0,0 +1,7 @@
{
"mysqlHost": "127.0.0.1",
"mysqlPort": 12730,
"mysqlUser": "root",
"mysqlPassword": "i&Lz8A3RuPcY5b326ALXgjl",
"mysqlDatabase": "testdb"
}

View File

@@ -9,58 +9,65 @@ Create a database with a name of your choosing. Then, run the following SQL comm
```sql
-- a3server.attendancelog definition
CREATE TABLE `attendancelog` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`timestamp` datetime NOT NULL,
`event_hash` varchar(100) NOT NULL,
`event_type` varchar(100) NOT NULL,
`player_id` varchar(30) NOT NULL,
`player_uid` varchar(100) NOT NULL,
`profile_name` varchar(100) NOT NULL,
`steam_name` varchar(100) DEFAULT NULL,
`is_jip` tinyint(4) DEFAULT NULL,
`role_description` varchar(100) DEFAULT NULL,
`mission_start` datetime NOT NULL,
`mission_name` varchar(100) DEFAULT NULL,
`briefing_name` varchar(100) DEFAULT NULL,
`mission_name_source` varchar(100) DEFAULT NULL,
`on_load_name` varchar(100) DEFAULT NULL,
`author` varchar(100) DEFAULT NULL,
`server_name` varchar(100) NOT NULL,
`server_profile` varchar(100) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb3;
CREATE TABLE `attendance` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`join_time` DATETIME NULL DEFAULT NULL,
`disconnect_time` DATETIME NULL DEFAULT NULL,
`mission_hash` VARCHAR(100) NULL DEFAULT '' COLLATE 'utf8mb3_general_ci',
`event_type` VARCHAR(100) NOT NULL COLLATE 'utf8mb3_general_ci',
`player_id` VARCHAR(30) NOT NULL COLLATE 'utf8mb3_general_ci',
`player_uid` VARCHAR(100) NOT NULL COLLATE 'utf8mb3_general_ci',
`profile_name` VARCHAR(100) NOT NULL COLLATE 'utf8mb3_general_ci',
`steam_name` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8mb3_general_ci',
`is_jip` TINYINT(4) NULL DEFAULT NULL,
`role_description` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8mb3_general_ci',
PRIMARY KEY (`id`) USING BTREE
)
COLLATE='utf8mb3_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=5868
;
-- a3server.`missions` definition
CREATE TABLE `missions` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`mission_name` varchar(100) NOT NULL,
`mission_name_source` varchar(100) DEFAULT NULL,
`briefing_name` varchar(100) DEFAULT NULL,
`on_load_name` varchar(100) DEFAULT NULL,
`author` varchar(100) DEFAULT NULL,
`server_name` varchar(100) DEFAULT NULL,
`server_profile` varchar(100) DEFAULT NULL,
`mission_start` datetime DEFAULT NULL,
`mission_hash` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb3;
`id` INT(11) NOT NULL AUTO_INCREMENT,
`mission_name` VARCHAR(100) NOT NULL COLLATE 'utf8mb3_general_ci',
`mission_name_source` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8mb3_general_ci',
`briefing_name` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8mb3_general_ci',
`on_load_name` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8mb3_general_ci',
`author` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8mb3_general_ci',
`server_name` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8mb3_general_ci',
`server_profile` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8mb3_general_ci',
`mission_start` DATETIME NULL DEFAULT NULL,
`mission_hash` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8mb3_general_ci',
PRIMARY KEY (`id`) USING BTREE
)
COLLATE='utf8mb3_general_ci'
ENGINE=InnoDB
;
-- a3server.`worlds` definition
CREATE TABLE `worlds` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`author` varchar(100) DEFAULT NULL,
`display_name` varchar(100) DEFAULT NULL,
`world_name` varchar(100) NOT NULL,
`world_name_original` varchar(100) DEFAULT NULL,
`world_size` int(11) DEFAULT NULL,
`latitude` float DEFAULT NULL,
`longitude` float DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb3;
`id` INT(11) NOT NULL AUTO_INCREMENT,
`author` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8mb3_general_ci',
`display_name` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8mb3_general_ci',
`world_name` VARCHAR(100) NOT NULL COLLATE 'utf8mb3_general_ci',
`world_name_original` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8mb3_general_ci',
`world_size` INT(11) NULL DEFAULT NULL,
`latitude` FLOAT NULL DEFAULT NULL,
`longitude` FLOAT NULL DEFAULT NULL,
`workshop_id` VARCHAR(50) NULL DEFAULT NULL COLLATE 'utf8mb3_general_ci',
PRIMARY KEY (`id`) USING BTREE
)
COLLATE='utf8mb3_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=2
;
```

Binary file not shown.

View File

@@ -16,6 +16,8 @@ import (
"fmt"
"log"
"os"
"path"
"runtime"
"strconv"
"strings"
"time"
@@ -108,11 +110,11 @@ func loadConfig() {
writeLog(functionName, `["Config loaded", "INFO"]`)
}
func getMissionHash(time string) string {
func getMissionHash() string {
functionName := "getMissionHash"
// get md5 hash of string
// https://stackoverflow.com/questions/2377881/how-to-get-a-md5-hash-from-a-string-in-golang
hash := md5.Sum([]byte(time))
hash := md5.Sum([]byte(time.Now().Format("2006-01-02 15:04:05")))
// convert to string
hashString := fmt.Sprintf("%x", hash)
@@ -176,9 +178,11 @@ type WorldInfo struct {
func writeWorldInfo(worldInfo string) {
functionName := "writeWorldInfo"
writeLog(functionName, fmt.Sprintf(`["%s", "DEBUG"]`, worldInfo))
// worldInfo is json, parse it
var wi WorldInfo
err := json.Unmarshal([]byte(worldInfo), &wi)
fixedString := fixEscapeQuotes(trimQuotes(worldInfo))
err := json.Unmarshal([]byte(fixedString), &wi)
if err != nil {
writeLog(functionName, fmt.Sprintf(`["%s", "ERROR"]`, err))
return
@@ -256,9 +260,11 @@ type MissionInfo struct {
func writeMissionInfo(missionInfo string) {
functionName := "writeMissionInfo"
writeLog(functionName, fmt.Sprintf(`["%s", "DEBUG"]`, missionInfo))
// missionInfo is json, parse it
var mi MissionInfo
err := json.Unmarshal([]byte(missionInfo), &mi)
fixedString := fixEscapeQuotes(trimQuotes(missionInfo))
err := json.Unmarshal([]byte(fixedString), &mi)
if err != nil {
writeLog(functionName, fmt.Sprintf(`["%s", "ERROR"]`, err))
return
@@ -286,7 +292,7 @@ func writeMissionInfo(missionInfo string) {
return
}
defer stmt.Close()
res, err := stmt.Exec(mi.MissionName, mi.BriefingName, mi.MissionNameSource, mi.OnLoadName, mi.Author, mi.ServerName, mi.ServerProfile, t, mi.MissionStart, mi.MissionHash)
res, err := stmt.Exec(mi.MissionName, mi.BriefingName, mi.MissionNameSource, mi.OnLoadName, mi.Author, mi.ServerName, mi.ServerProfile, mi.MissionStart, mi.MissionHash)
if err != nil {
writeLog(functionName, fmt.Sprintf(`["%s", "ERROR"]`, err))
return
@@ -297,6 +303,7 @@ func writeMissionInfo(missionInfo string) {
return
}
writeLog(functionName, fmt.Sprintf(`["Mission inserted with ID %d", "INFO"]`, lastID))
writeLog(functionName, fmt.Sprintf(`["MISSION_ID", "%d"]`, lastID))
}
type AttendanceLogItem struct {
@@ -332,13 +339,11 @@ func writeAttendance(data string) {
return
}
//
// send to DB
result, err := db.ExecContext(
context.Background(),
fmt.Sprintf(
`INSERT INTO %s (join_time, disconnect_time, event_type, player_id, player_uid, profile_name, steam_name, is_jip, role_description, mission_hash) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
`INSERT INTO %s (join_time, event_type, player_id, player_uid, profile_name, steam_name, is_jip, role_description, mission_hash) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
ATTENDANCE_TABLE,
),
now,
@@ -364,7 +369,7 @@ func writeAttendance(data string) {
}
writeLog(functionName, fmt.Sprintf(`["Saved attendance for %s to row id %d", "INFO"]`, event.ProfileName, id))
writeLog(functionName, fmt.Sprintf(`["ATT_LOG", ["%s", %d]]`, event.PlayerId, id))
writeLog(functionName, fmt.Sprintf(`["ATT_LOG", ["%s", "%d"]]`, event.PlayerId, id))
}
@@ -469,12 +474,6 @@ func goRVExtensionArgs(output *C.char, outputsize C.size_t, input *C.char, argv
if argc == 1 {
go writeWorldInfo(out[0])
}
case "getMissionHash":
{
if argc == 1 {
go getMissionHash(out[0])
}
}
}
// Return a result to Arma
@@ -502,9 +501,10 @@ func callBackExample() {
}
}
func getTimestamp() int64 {
func getTimestamp() string {
// get the current unix timestamp in nanoseconds
return time.Now().UnixNano()
// return time.Now().Local().Unix()
return time.Now().Format("2006-01-02 15:04:05")
}
func trimQuotes(s string) string {
@@ -526,6 +526,9 @@ func writeLog(functionName string, data string) {
defer C.free(unsafe.Pointer(statusParam))
runExtensionCallback(statusName, statusFunction, statusParam)
// get calling function & line
_, file, line, _ := runtime.Caller(1)
log.Printf(`%s:%d: %s`, path.Base(file), line, data)
log.Printf(`%s: %s`, functionName, data)
}
@@ -542,12 +545,12 @@ func goRVExtension(output *C.char, outputsize C.size_t, input *C.char) {
case "getDir":
temp = getDir()
case "getTimestamp":
time := getTimestamp()
temp = fmt.Sprintf(`["%s"]`, strconv.FormatInt(time, 10))
temp = fmt.Sprintf(`["%s"]`, getTimestamp())
case "connectDB":
go connectDB()
temp = fmt.Sprintf(`["%s"]`, "Connecting to DB")
case "getMissionHash":
temp = fmt.Sprintf(`["%s"]`, getMissionHash())
default:
temp = fmt.Sprintf(`["%s"]`, "Unknown Function")
}