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]; missionNamespace setVariable ["AttendanceTracker_DBConnected", true];
// log mission info and get back the row Id to send with future messages // 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 getVariable ["missionContext", createHashMap]] call CBA_fnc_encodeJSON
]]; ]
AttendanceTracker_missionId = parseNumber _response; ];
// log world info // log world info
private _response = "AttendanceTracker" callExtension ["logWorld", [ private _response = "AttendanceTracker" callExtension [
[call attendanceTracker_fnc_getWorldInfo] call CBA_fnc_encodeJSON "logWorld",
]]; [
[(call attendanceTracker_fnc_getWorldInfo)] call CBA_fnc_encodeJSON
]
];
};
};
case "writeMissionInfo": {
if (_response#0 == "MISSION_ID") then {
AttendanceTracker_missionId = parseNumber _response;
}; };
}; };
case "writeAttendance": { case "writeAttendance": {

View File

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

View File

@@ -14,7 +14,7 @@ _workshopID = '';
} foreach getLoadedModsInfo; } foreach getLoadedModsInfo;
// [_name, _author, _workshopID]; // [_name, _author, _workshopID];
[ _return = createHashMapFromArray [
["author", _author], ["author", _author],
["workshopID", _workshopID], ["workshopID", _workshopID],
["displayName", _name], ["displayName", _name],
@@ -24,3 +24,5 @@ _workshopID = '';
["latitude", getNumber( _world >> "latitude" )], ["latitude", getNumber( _world >> "latitude" )],
["longitude", getNumber( _world >> "longitude" )] ["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 = false call CBA_fnc_createNamespace;
AttendanceTracker_missionStartTimestamp = call attendanceTracker_fnc_timestamp; 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 [ AttendanceTracker setVariable ["missionContext", createHashMapFromArray [
["missionName", missionName], ["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 ```sql
-- a3server.attendancelog definition -- a3server.attendancelog definition
CREATE TABLE `attendancelog` ( CREATE TABLE `attendance` (
`id` int(11) NOT NULL AUTO_INCREMENT, `id` INT(11) NOT NULL AUTO_INCREMENT,
`timestamp` datetime NOT NULL, `join_time` DATETIME NULL DEFAULT NULL,
`event_hash` varchar(100) NOT NULL, `disconnect_time` DATETIME NULL DEFAULT NULL,
`event_type` varchar(100) NOT NULL, `mission_hash` VARCHAR(100) NULL DEFAULT '' COLLATE 'utf8mb3_general_ci',
`player_id` varchar(30) NOT NULL, `event_type` VARCHAR(100) NOT NULL COLLATE 'utf8mb3_general_ci',
`player_uid` varchar(100) NOT NULL, `player_id` VARCHAR(30) NOT NULL COLLATE 'utf8mb3_general_ci',
`profile_name` varchar(100) NOT NULL, `player_uid` VARCHAR(100) NOT NULL COLLATE 'utf8mb3_general_ci',
`steam_name` varchar(100) DEFAULT NULL, `profile_name` VARCHAR(100) NOT NULL COLLATE 'utf8mb3_general_ci',
`is_jip` tinyint(4) DEFAULT NULL, `steam_name` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8mb3_general_ci',
`role_description` varchar(100) DEFAULT NULL, `is_jip` TINYINT(4) NULL DEFAULT NULL,
`mission_start` datetime NOT NULL, `role_description` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8mb3_general_ci',
`mission_name` varchar(100) DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE
`briefing_name` varchar(100) DEFAULT NULL, )
`mission_name_source` varchar(100) DEFAULT NULL, COLLATE='utf8mb3_general_ci'
`on_load_name` varchar(100) DEFAULT NULL, ENGINE=InnoDB
`author` varchar(100) DEFAULT NULL, AUTO_INCREMENT=5868
`server_name` varchar(100) NOT NULL, ;
`server_profile` varchar(100) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb3;
-- a3server.`missions` definition -- a3server.`missions` definition
CREATE TABLE `missions` ( CREATE TABLE `missions` (
`id` int(11) NOT NULL AUTO_INCREMENT, `id` INT(11) NOT NULL AUTO_INCREMENT,
`mission_name` varchar(100) NOT NULL, `mission_name` VARCHAR(100) NOT NULL COLLATE 'utf8mb3_general_ci',
`mission_name_source` varchar(100) DEFAULT NULL, `mission_name_source` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8mb3_general_ci',
`briefing_name` varchar(100) DEFAULT NULL, `briefing_name` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8mb3_general_ci',
`on_load_name` varchar(100) DEFAULT NULL, `on_load_name` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8mb3_general_ci',
`author` varchar(100) DEFAULT NULL, `author` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8mb3_general_ci',
`server_name` varchar(100) DEFAULT NULL, `server_name` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8mb3_general_ci',
`server_profile` varchar(100) DEFAULT NULL, `server_profile` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8mb3_general_ci',
`mission_start` datetime DEFAULT NULL, `mission_start` DATETIME NULL DEFAULT NULL,
`mission_hash` varchar(100) DEFAULT NULL, `mission_hash` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8mb3_general_ci',
PRIMARY KEY (`id`) PRIMARY KEY (`id`) USING BTREE
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb3; )
COLLATE='utf8mb3_general_ci'
ENGINE=InnoDB
;
-- a3server.`worlds` definition -- a3server.`worlds` definition
CREATE TABLE `worlds` ( CREATE TABLE `worlds` (
`id` int(11) NOT NULL AUTO_INCREMENT, `id` INT(11) NOT NULL AUTO_INCREMENT,
`author` varchar(100) DEFAULT NULL, `author` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8mb3_general_ci',
`display_name` varchar(100) DEFAULT NULL, `display_name` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8mb3_general_ci',
`world_name` varchar(100) NOT NULL, `world_name` VARCHAR(100) NOT NULL COLLATE 'utf8mb3_general_ci',
`world_name_original` varchar(100) DEFAULT NULL, `world_name_original` VARCHAR(100) NULL DEFAULT NULL COLLATE 'utf8mb3_general_ci',
`world_size` int(11) DEFAULT NULL, `world_size` INT(11) NULL DEFAULT NULL,
`latitude` float DEFAULT NULL, `latitude` FLOAT NULL DEFAULT NULL,
`longitude` float DEFAULT NULL, `longitude` FLOAT NULL DEFAULT NULL,
PRIMARY KEY (`id`) `workshop_id` VARCHAR(50) NULL DEFAULT NULL COLLATE 'utf8mb3_general_ci',
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb3; 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" "fmt"
"log" "log"
"os" "os"
"path"
"runtime"
"strconv" "strconv"
"strings" "strings"
"time" "time"
@@ -108,11 +110,11 @@ func loadConfig() {
writeLog(functionName, `["Config loaded", "INFO"]`) writeLog(functionName, `["Config loaded", "INFO"]`)
} }
func getMissionHash(time string) string { func getMissionHash() string {
functionName := "getMissionHash" functionName := "getMissionHash"
// get md5 hash of string // get md5 hash of string
// https://stackoverflow.com/questions/2377881/how-to-get-a-md5-hash-from-a-string-in-golang // 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 // convert to string
hashString := fmt.Sprintf("%x", hash) hashString := fmt.Sprintf("%x", hash)
@@ -176,9 +178,11 @@ type WorldInfo struct {
func writeWorldInfo(worldInfo string) { func writeWorldInfo(worldInfo string) {
functionName := "writeWorldInfo" functionName := "writeWorldInfo"
writeLog(functionName, fmt.Sprintf(`["%s", "DEBUG"]`, worldInfo))
// worldInfo is json, parse it // worldInfo is json, parse it
var wi WorldInfo var wi WorldInfo
err := json.Unmarshal([]byte(worldInfo), &wi) fixedString := fixEscapeQuotes(trimQuotes(worldInfo))
err := json.Unmarshal([]byte(fixedString), &wi)
if err != nil { if err != nil {
writeLog(functionName, fmt.Sprintf(`["%s", "ERROR"]`, err)) writeLog(functionName, fmt.Sprintf(`["%s", "ERROR"]`, err))
return return
@@ -256,9 +260,11 @@ type MissionInfo struct {
func writeMissionInfo(missionInfo string) { func writeMissionInfo(missionInfo string) {
functionName := "writeMissionInfo" functionName := "writeMissionInfo"
writeLog(functionName, fmt.Sprintf(`["%s", "DEBUG"]`, missionInfo))
// missionInfo is json, parse it // missionInfo is json, parse it
var mi MissionInfo var mi MissionInfo
err := json.Unmarshal([]byte(missionInfo), &mi) fixedString := fixEscapeQuotes(trimQuotes(missionInfo))
err := json.Unmarshal([]byte(fixedString), &mi)
if err != nil { if err != nil {
writeLog(functionName, fmt.Sprintf(`["%s", "ERROR"]`, err)) writeLog(functionName, fmt.Sprintf(`["%s", "ERROR"]`, err))
return return
@@ -286,7 +292,7 @@ func writeMissionInfo(missionInfo string) {
return return
} }
defer stmt.Close() 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 { if err != nil {
writeLog(functionName, fmt.Sprintf(`["%s", "ERROR"]`, err)) writeLog(functionName, fmt.Sprintf(`["%s", "ERROR"]`, err))
return return
@@ -297,6 +303,7 @@ func writeMissionInfo(missionInfo string) {
return return
} }
writeLog(functionName, fmt.Sprintf(`["Mission inserted with ID %d", "INFO"]`, lastID)) writeLog(functionName, fmt.Sprintf(`["Mission inserted with ID %d", "INFO"]`, lastID))
writeLog(functionName, fmt.Sprintf(`["MISSION_ID", "%d"]`, lastID))
} }
type AttendanceLogItem struct { type AttendanceLogItem struct {
@@ -332,13 +339,11 @@ func writeAttendance(data string) {
return return
} }
//
// send to DB // send to DB
result, err := db.ExecContext( result, err := db.ExecContext(
context.Background(), context.Background(),
fmt.Sprintf( 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, ATTENDANCE_TABLE,
), ),
now, 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(`["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 { if argc == 1 {
go writeWorldInfo(out[0]) go writeWorldInfo(out[0])
} }
case "getMissionHash":
{
if argc == 1 {
go getMissionHash(out[0])
}
}
} }
// Return a result to Arma // Return a result to Arma
@@ -502,9 +501,10 @@ func callBackExample() {
} }
} }
func getTimestamp() int64 { func getTimestamp() string {
// get the current unix timestamp in nanoseconds // 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 { func trimQuotes(s string) string {
@@ -526,6 +526,9 @@ func writeLog(functionName string, data string) {
defer C.free(unsafe.Pointer(statusParam)) defer C.free(unsafe.Pointer(statusParam))
runExtensionCallback(statusName, statusFunction, 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) log.Printf(`%s: %s`, functionName, data)
} }
@@ -542,12 +545,12 @@ func goRVExtension(output *C.char, outputsize C.size_t, input *C.char) {
case "getDir": case "getDir":
temp = getDir() temp = getDir()
case "getTimestamp": case "getTimestamp":
time := getTimestamp() temp = fmt.Sprintf(`["%s"]`, getTimestamp())
temp = fmt.Sprintf(`["%s"]`, strconv.FormatInt(time, 10))
case "connectDB": case "connectDB":
go connectDB() go connectDB()
temp = fmt.Sprintf(`["%s"]`, "Connecting to DB") temp = fmt.Sprintf(`["%s"]`, "Connecting to DB")
case "getMissionHash":
temp = fmt.Sprintf(`["%s"]`, getMissionHash())
default: default:
temp = fmt.Sprintf(`["%s"]`, "Unknown Function") temp = fmt.Sprintf(`["%s"]`, "Unknown Function")
} }