mirror of
https://github.com/indig0fox/Arma3-AttendanceTracker.git/
synced 2025-12-08 09:51:47 -06:00
change to 1 row per session (networkId)
This commit is contained in:
Binary file not shown.
@@ -55,6 +55,12 @@ addMissionEventHandler ["ExtensionCallback", {
|
|||||||
]];
|
]];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
case "writeAttendance": {
|
||||||
|
if (_response#0 == "ATT_LOG") then {
|
||||||
|
_response params ["_netId", "_rowId"];
|
||||||
|
((AttendanceTracker getVariable ["allUsers", createHashMap]) get _netId) set ["_rowID", _rowID];
|
||||||
|
};
|
||||||
|
};
|
||||||
default {
|
default {
|
||||||
_response call attendanceTracker_fnc_log;
|
_response call attendanceTracker_fnc_log;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,15 +8,16 @@
|
|||||||
_userInfo params ["_playerID", "_ownerId", "_playerUID", "_profileName", "_displayName", "_steamName", "_clientState", "_isHC", "_adminState", "_networkInfo", "_unit"];
|
_userInfo params ["_playerID", "_ownerId", "_playerUID", "_profileName", "_displayName", "_steamName", "_clientState", "_isHC", "_adminState", "_networkInfo", "_unit"];
|
||||||
if (_isHC) exitWith {};
|
if (_isHC) exitWith {};
|
||||||
|
|
||||||
|
(AttendanceTracker getVariable ["allUsers", createHashMap]) set [_networkId, _userInfo];
|
||||||
[
|
[
|
||||||
"ConnectedServer",
|
"Server",
|
||||||
_playerID,
|
_playerID,
|
||||||
_playerUID,
|
_playerUID,
|
||||||
_profileName,
|
_profileName,
|
||||||
_steamName
|
_steamName,
|
||||||
] call attendanceTracker_fnc_logServerEvent;
|
nil // send rowId on d/c only
|
||||||
|
] call attendanceTracker_fnc_writeAttendance;
|
||||||
|
|
||||||
(AttendanceTracker getVariable ["allUsers", createHashMap]) set [_networkId, _userInfo];
|
|
||||||
}],
|
}],
|
||||||
["OnUserDisconnected", {
|
["OnUserDisconnected", {
|
||||||
params ["_networkId", "_clientStateNumber", "_clientState"];
|
params ["_networkId", "_clientStateNumber", "_clientState"];
|
||||||
@@ -26,16 +27,17 @@
|
|||||||
private _userInfo = (AttendanceTracker getVariable ["allUsers", createHashMap]) get _networkId;
|
private _userInfo = (AttendanceTracker getVariable ["allUsers", createHashMap]) get _networkId;
|
||||||
if (isNil "_userInfo") exitWith {};
|
if (isNil "_userInfo") exitWith {};
|
||||||
|
|
||||||
_userInfo params ["_playerID", "_ownerId", "_playerUID", "_profileName", "_displayName", "_steamName", "_clientState", "_isHC", "_adminState", "_networkInfo", "_unit"];
|
_userInfo params ["_playerID", "_ownerId", "_playerUID", "_profileName", "_displayName", "_steamName", "_clientState", "_isHC", "_adminState", "_networkInfo", "_unit", "_rowId"];
|
||||||
if (_isHC) exitWith {};
|
if (_isHC) exitWith {};
|
||||||
|
|
||||||
[
|
[
|
||||||
"DisconnectedServer",
|
"Server",
|
||||||
_playerID,
|
_playerID,
|
||||||
_playerUID,
|
_playerUID,
|
||||||
_profileName,
|
_profileName,
|
||||||
_steamName
|
_steamName,
|
||||||
] call attendanceTracker_fnc_logServerEvent;
|
(if (!isNil "_rowId") then {_rowId} else {nil}) // send rowId on d/c only
|
||||||
|
] call attendanceTracker_fnc_writeAttendance;
|
||||||
}],
|
}],
|
||||||
["PlayerConnected", {
|
["PlayerConnected", {
|
||||||
params ["_id", "_uid", "_name", "_jip", "_owner", "_idstr"];
|
params ["_id", "_uid", "_name", "_jip", "_owner", "_idstr"];
|
||||||
@@ -46,19 +48,18 @@
|
|||||||
if (isNil "_userInfo") exitWith {};
|
if (isNil "_userInfo") exitWith {};
|
||||||
|
|
||||||
_userInfo params ["_playerID", "_ownerId", "_playerUID", "_profileName", "_displayName", "_steamName", "_clientState", "_isHC", "_adminState", "_networkInfo", "_unit"];
|
_userInfo params ["_playerID", "_ownerId", "_playerUID", "_profileName", "_displayName", "_steamName", "_clientState", "_isHC", "_adminState", "_networkInfo", "_unit"];
|
||||||
|
if (_isHC) exitWith {};
|
||||||
|
|
||||||
(AttendanceTracker getVariable ["allUsers", createHashMap]) set [_playerID, _userInfo];
|
(AttendanceTracker getVariable ["allUsers", createHashMap]) set [_playerID, _userInfo];
|
||||||
|
|
||||||
if (_isHC) exitWith {};
|
|
||||||
|
|
||||||
[
|
[
|
||||||
"ConnectedMission",
|
"Mission",
|
||||||
_playerID,
|
_playerID,
|
||||||
_playerUID,
|
_playerUID,
|
||||||
_profileName,
|
_profileName,
|
||||||
_steamName,
|
_steamName,
|
||||||
_jip,
|
_jip,
|
||||||
roleDescription _unit
|
roleDescription _unit,
|
||||||
|
nil // send rowId on d/c only
|
||||||
] call attendanceTracker_fnc_logMissionEvent;
|
] call attendanceTracker_fnc_logMissionEvent;
|
||||||
}],
|
}],
|
||||||
["PlayerDisconnected", {
|
["PlayerDisconnected", {
|
||||||
@@ -72,17 +73,18 @@
|
|||||||
[format ["(EventHandler) HandleDisconnect: No user info found for %1", _idstr], "DEBUG"] call attendanceTracker_fnc_log;
|
[format ["(EventHandler) HandleDisconnect: No user info found for %1", _idstr], "DEBUG"] call attendanceTracker_fnc_log;
|
||||||
};
|
};
|
||||||
|
|
||||||
_userInfo params ["_playerID", "_ownerId", "_playerUID", "_profileName", "_displayName", "_steamName", "_clientState", "_isHC", "_adminState", "_networkInfo", "_unit"];
|
_userInfo params ["_playerID", "_ownerId", "_playerUID", "_profileName", "_displayName", "_steamName", "_clientState", "_isHC", "_adminState", "_networkInfo", "_unit", "_rowId"];
|
||||||
|
|
||||||
if (_isHC) exitWith {};
|
if (_isHC) exitWith {};
|
||||||
|
|
||||||
[
|
[
|
||||||
"DisconnectedMission",
|
"Mission",
|
||||||
_playerID,
|
_playerID,
|
||||||
_playerUID,
|
_playerUID,
|
||||||
_profileName,
|
_profileName,
|
||||||
_steamName,
|
_steamName,
|
||||||
_jip
|
_jip,
|
||||||
|
nil,
|
||||||
|
(if (!isNil "_rowId") then {_rowId} else {nil}) // send rowId on d/c only
|
||||||
] call attendanceTracker_fnc_logMissionEvent;
|
] call attendanceTracker_fnc_logMissionEvent;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ params [
|
|||||||
["_profileName", ""],
|
["_profileName", ""],
|
||||||
["_steamName", ""],
|
["_steamName", ""],
|
||||||
["_isJIP", false, [true, false]],
|
["_isJIP", false, [true, false]],
|
||||||
["_roleDescription", ""]
|
["_roleDescription", ""],
|
||||||
|
["_rowID", nil]
|
||||||
];
|
];
|
||||||
|
|
||||||
private _hash = + (AttendanceTracker getVariable ["missionContext", createHashMap]);
|
private _hash = + (AttendanceTracker getVariable ["missionContext", createHashMap]);
|
||||||
@@ -18,6 +19,11 @@ _hash set ["isJIP", _isJIP];
|
|||||||
_hash set ["roleDescription", _roleDescription];
|
_hash set ["roleDescription", _roleDescription];
|
||||||
_hash set ["missionHash", missionNamespace getVariable ["AttendanceTracker_missionHash", ""]];
|
_hash set ["missionHash", missionNamespace getVariable ["AttendanceTracker_missionHash", ""]];
|
||||||
|
|
||||||
"AttendanceTracker" callExtension ["logAttendance", [[_hash] call CBA_fnc_encodeJSON]];
|
if (!isNil "_rowID") then {
|
||||||
|
_hash set ["rowID", _rowID];
|
||||||
|
"AttendanceTracker" callExtension ["writeDisconnectEvent", [[_hash] call CBA_fnc_encodeJSON]];
|
||||||
|
} else {
|
||||||
|
"AttendanceTracker" callExtension ["writeAttendance", [[_hash] call CBA_fnc_encodeJSON]];
|
||||||
|
};
|
||||||
|
|
||||||
true;
|
true;
|
||||||
@@ -3,11 +3,13 @@ params [
|
|||||||
["_playerId", ""],
|
["_playerId", ""],
|
||||||
["_playerUID", ""],
|
["_playerUID", ""],
|
||||||
["_profileName", ""],
|
["_profileName", ""],
|
||||||
["_steamName", ""]
|
["_steamName", ""],
|
||||||
|
["_rowID", nil]
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
private _hash = + (AttendanceTracker getVariable ["missionContext", createHashMap]);
|
private _hash = + (AttendanceTracker getVariable ["missionContext", createHashMap]);
|
||||||
|
_hash set ["networkId", netID player]
|
||||||
_hash set ["eventType", _eventType];
|
_hash set ["eventType", _eventType];
|
||||||
_hash set ["playerId", _playerId];
|
_hash set ["playerId", _playerId];
|
||||||
_hash set ["playerUID", _playerUID];
|
_hash set ["playerUID", _playerUID];
|
||||||
@@ -17,6 +19,11 @@ _hash set ["isJIP", false];
|
|||||||
_hash set ["roleDescription", ""];
|
_hash set ["roleDescription", ""];
|
||||||
_hash set ["missionHash", missionNamespace getVariable ["AttendanceTracker_missionHash", ""]];
|
_hash set ["missionHash", missionNamespace getVariable ["AttendanceTracker_missionHash", ""]];
|
||||||
|
|
||||||
"AttendanceTracker" callExtension ["logAttendance", [[_hash] call CBA_fnc_encodeJSON]];
|
if (!isNil "_rowID") then {
|
||||||
|
_hash set ["rowID", _rowID];
|
||||||
|
"AttendanceTracker" callExtension ["writeDisconnectEvent", [[_hash] call CBA_fnc_encodeJSON]];
|
||||||
|
} else {
|
||||||
|
"AttendanceTracker" callExtension ["writeAttendance", [[_hash] call CBA_fnc_encodeJSON]];
|
||||||
|
};
|
||||||
|
|
||||||
true;
|
true;
|
||||||
@@ -29,7 +29,7 @@ CREATE TABLE `attendancelog` (
|
|||||||
`server_name` varchar(100) NOT NULL,
|
`server_name` varchar(100) NOT NULL,
|
||||||
`server_profile` varchar(100) NOT NULL,
|
`server_profile` varchar(100) NOT NULL,
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=2713 DEFAULT CHARSET=utf8mb3;
|
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb3;
|
||||||
|
|
||||||
-- a3server.`missions` definition
|
-- a3server.`missions` definition
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -32,6 +32,10 @@ var ADDON_FOLDER string = getDir() + "\\@AttendanceTracker"
|
|||||||
var LOG_FILE string = ADDON_FOLDER + "\\attendanceTracker.log"
|
var LOG_FILE string = ADDON_FOLDER + "\\attendanceTracker.log"
|
||||||
var CONFIG_FILE string = ADDON_FOLDER + "\\config.json"
|
var CONFIG_FILE string = ADDON_FOLDER + "\\config.json"
|
||||||
|
|
||||||
|
var ATTENDANCE_TABLE string = "attendance"
|
||||||
|
var MISSIONS_TABLE string = "missions"
|
||||||
|
var WORLDS_TABLE string = "worlds"
|
||||||
|
|
||||||
var ATConfig AttendanceTrackerConfig
|
var ATConfig AttendanceTrackerConfig
|
||||||
|
|
||||||
type AttendanceTrackerConfig struct {
|
type AttendanceTrackerConfig struct {
|
||||||
@@ -189,7 +193,10 @@ func writeWorldInfo(worldInfo string) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
// world does not exist, insert it
|
// world does not exist, insert it
|
||||||
stmt, err := db.Prepare("INSERT INTO worlds (author, workshop_id, display_name, world_name, world_name_original, world_size, latitude, longitude) VALUES (?, ?, ?, ?, ?, ?, ?, ?)")
|
stmt, err := db.Prepare(fmt.Sprintf(
|
||||||
|
"INSERT INTO %s (author, workshop_id, display_name, world_name, world_name_original, world_size, latitude, longitude) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
|
||||||
|
WORLDS_TABLE,
|
||||||
|
))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeLog(functionName, fmt.Sprintf(`["%s", "ERROR"]`, err))
|
writeLog(functionName, fmt.Sprintf(`["%s", "ERROR"]`, err))
|
||||||
return
|
return
|
||||||
@@ -212,7 +219,10 @@ func writeWorldInfo(worldInfo string) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// world exists, update it
|
// world exists, update it
|
||||||
stmt, err := db.Prepare("UPDATE worlds SET author = ?, workshop_id = ?, display_name = ?, world_name = ?, world_name_original = ?, world_size = ?, latitude = ?, longitude = ? WHERE id = ?")
|
stmt, err := db.Prepare(fmt.Sprintf(
|
||||||
|
"UPDATE %s SET author = ?, workshop_id = ?, display_name = ?, world_name = ?, world_name_original = ?, world_size = ?, latitude = ?, longitude = ? WHERE id = ?",
|
||||||
|
WORLDS_TABLE,
|
||||||
|
))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeLog(functionName, fmt.Sprintf(`["%s", "ERROR"]`, err))
|
writeLog(functionName, fmt.Sprintf(`["%s", "ERROR"]`, err))
|
||||||
return
|
return
|
||||||
@@ -267,7 +277,10 @@ func writeMissionInfo(missionInfo string) {
|
|||||||
|
|
||||||
// write to database
|
// write to database
|
||||||
// every mission is unique, so insert it
|
// every mission is unique, so insert it
|
||||||
stmt, err := db.Prepare("INSERT INTO missions (mission_name, briefing_name, mission_name_source, on_load_name, author, server_name, server_profile, mission_start, mission_hash) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)")
|
stmt, err := db.Prepare(fmt.Sprintf(
|
||||||
|
"INSERT INTO %s (mission_name, briefing_name, mission_name_source, on_load_name, author, server_name, server_profile, mission_start, mission_hash) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||||
|
MISSIONS_TABLE,
|
||||||
|
))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeLog(functionName, fmt.Sprintf(`["%s", "ERROR"]`, err))
|
writeLog(functionName, fmt.Sprintf(`["%s", "ERROR"]`, err))
|
||||||
return
|
return
|
||||||
@@ -295,6 +308,8 @@ type AttendanceLogItem struct {
|
|||||||
IsJIP bool `json:"isJIP"`
|
IsJIP bool `json:"isJIP"`
|
||||||
RoleDescription string `json:"roleDescription"`
|
RoleDescription string `json:"roleDescription"`
|
||||||
MissionHash string `json:"missionHash"`
|
MissionHash string `json:"missionHash"`
|
||||||
|
//
|
||||||
|
RowID int64 `json:"rowID"` // optional
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeAttendance(data string) {
|
func writeAttendance(data string) {
|
||||||
@@ -317,9 +332,15 @@ func writeAttendance(data string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
// send to DB
|
// send to DB
|
||||||
|
|
||||||
result, err := db.ExecContext(context.Background(), `INSERT INTO AttendanceLog (event_time, event_type, player_id, player_uid, profile_name, steam_name, is_jip, role_description, mission_hash) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
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 (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||||
|
ATTENDANCE_TABLE,
|
||||||
|
),
|
||||||
now,
|
now,
|
||||||
event.EventType,
|
event.EventType,
|
||||||
event.PlayerId,
|
event.PlayerId,
|
||||||
@@ -343,9 +364,62 @@ 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))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DisconnectItem struct {
|
||||||
|
PlayerId string `json:"playerId"`
|
||||||
|
RowId int64 `json:"rowId"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeDisconnectEvent(data string) {
|
||||||
|
functionName := "writeDisconnectEvent"
|
||||||
|
// data is json, parse it
|
||||||
|
stringjson := fixEscapeQuotes(trimQuotes(data))
|
||||||
|
var event DisconnectItem
|
||||||
|
err := json.Unmarshal([]byte(stringjson), &event)
|
||||||
|
if err != nil {
|
||||||
|
writeLog(functionName, fmt.Sprintf(`["%s", "ERROR"]`, err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// get MySQL friendly NOW
|
||||||
|
now := time.Now().Format("2006-01-02 15:04:05")
|
||||||
|
|
||||||
|
// prevent crash
|
||||||
|
if db == nil {
|
||||||
|
writeLog(functionName, `["db is nil", "ERROR"]`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// send to DB
|
||||||
|
result, err := db.ExecContext(
|
||||||
|
context.Background(),
|
||||||
|
fmt.Sprintf(
|
||||||
|
`UPDATE %s SET disconnect_time = ? WHERE id = ?`,
|
||||||
|
ATTENDANCE_TABLE,
|
||||||
|
),
|
||||||
|
now,
|
||||||
|
event.RowId,
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
writeLog(functionName, fmt.Sprintf(`["%s", "ERROR"]`, err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
rowsAffected, err := result.RowsAffected()
|
||||||
|
if err != nil {
|
||||||
|
writeLog(functionName, fmt.Sprintf(`["%s", "ERROR"]`, err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if rowsAffected == 1 {
|
||||||
|
writeLog(functionName, fmt.Sprintf(`["Saved disconnect event for %s to row id %d", "INFO"]`, event.PlayerId, event.RowId))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func runExtensionCallback(name *C.char, function *C.char, data *C.char) C.int {
|
func runExtensionCallback(name *C.char, function *C.char, data *C.char) C.int {
|
||||||
return C.runExtensionCallback(extensionCallbackFnc, name, function, data)
|
return C.runExtensionCallback(extensionCallbackFnc, name, function, data)
|
||||||
}
|
}
|
||||||
@@ -374,12 +448,19 @@ func goRVExtensionArgs(output *C.char, outputsize C.size_t, input *C.char, argv
|
|||||||
temp := fmt.Sprintf("Function: %s nb params: %d", C.GoString(input), argc)
|
temp := fmt.Sprintf("Function: %s nb params: %d", C.GoString(input), argc)
|
||||||
|
|
||||||
switch C.GoString(input) {
|
switch C.GoString(input) {
|
||||||
case "logAttendance":
|
case "writeAttendance":
|
||||||
{ // callExtension ["serverEvent", [_hash] call CBA_fnc_encodeJSON];
|
{ // callExtension ["logAttendance", [_hash] call CBA_fnc_encodeJSON]];
|
||||||
if argc == 1 {
|
if argc == 1 {
|
||||||
go writeAttendance(out[0])
|
go writeAttendance(out[0])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case "writeDisconnectEvent":
|
||||||
|
{ // callExtension ["writeDisconnectEvent", [[_hash] call CBA_fnc_encodeJSON]];
|
||||||
|
|
||||||
|
if argc == 1 {
|
||||||
|
go writeDisconnectEvent(out[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
case "logMission":
|
case "logMission":
|
||||||
if argc == 1 {
|
if argc == 1 {
|
||||||
go writeMissionInfo(out[0])
|
go writeMissionInfo(out[0])
|
||||||
|
|||||||
Reference in New Issue
Block a user