mirror of
https://github.com/indig0fox/Arma3-AttendanceTracker.git/
synced 2025-12-08 09:51:47 -06:00
bug fixes, 3 table split, update readme
This commit is contained in:
BIN
@AttendanceTracker/addons/AttendanceTracker.pbo
Normal file
BIN
@AttendanceTracker/addons/AttendanceTracker.pbo
Normal file
Binary file not shown.
27
@AttendanceTracker/addons/AttendanceTracker/config.cpp
Normal file
27
@AttendanceTracker/addons/AttendanceTracker/config.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
class CfgPatches {
|
||||
class AttendanceTracker {
|
||||
units[] = {};
|
||||
weapons[] = {};
|
||||
requiredVersion = 2.10;
|
||||
requiredAddons[] = {};
|
||||
author[] = {"IndigoFox"};
|
||||
authorUrl = "http://example.com";
|
||||
};
|
||||
};
|
||||
|
||||
class CfgFunctions {
|
||||
class attendanceTracker {
|
||||
class functions {
|
||||
file = "\AttendanceTracker\functions";
|
||||
class postInit {postInit = 1;};
|
||||
class connectDB {};
|
||||
class eventHandlers {};
|
||||
class callbackHandler {postInit = 1;};
|
||||
class log {};
|
||||
class logMissionEvent {};
|
||||
class logServerEvent {};
|
||||
class timestamp {};
|
||||
class getHash {};
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,78 @@
|
||||
addMissionEventHandler ["ExtensionCallback", {
|
||||
params ["_name", "_function", "_data"];
|
||||
if !(_name == "AttendanceTracker") exitWith {};
|
||||
|
||||
// Validate data param
|
||||
if (isNil "_data") then {_data = ""};
|
||||
|
||||
if (_data isEqualTo "") exitWith {
|
||||
[
|
||||
format ["Callback empty data: %1", _function],
|
||||
"WARN"
|
||||
] call attendanceTracker_fnc_log;
|
||||
false;
|
||||
};
|
||||
|
||||
if (typeName _data != "STRING") exitWith {
|
||||
[
|
||||
format ["Callback invalid data: %1: %2", _function, _data],
|
||||
"WARN"
|
||||
] call attendanceTracker_fnc_log;
|
||||
false;
|
||||
};
|
||||
|
||||
// Parse response from string array
|
||||
private "_response";
|
||||
try {
|
||||
// diag_log format ["Raw callback: %1: %2", _function, _data];
|
||||
_response = parseSimpleArray _data;
|
||||
} catch {
|
||||
[
|
||||
format ["Callback invalid data: %1: %2: %3", _function, _data, _exception],
|
||||
"WARN"
|
||||
] call attendanceTracker_fnc_log;
|
||||
};
|
||||
|
||||
if (isNil "_response") exitWith {false};
|
||||
|
||||
switch (_function) do {
|
||||
case "connectDB": {
|
||||
systemChat format ["AttendanceTracker: %1", _response#0];
|
||||
[_response#0, _response#1, _function] call attendanceTracker_fnc_log;
|
||||
if (_response#0 == "SUCCESS") then {
|
||||
missionNamespace setVariable ["AttendanceTracker_DBConnected", true];
|
||||
|
||||
// log mission info and get back the row Id to send with future messages
|
||||
private _response = "AttendanceTracker" callExtension [
|
||||
"logMission",
|
||||
[
|
||||
[AttendanceTracker getVariable ["missionContext", createHashMap]] call CBA_fnc_encodeJSON
|
||||
]
|
||||
];
|
||||
|
||||
// log world info
|
||||
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": {
|
||||
if (_response#0 == "ATT_LOG") then {
|
||||
_response params ["_netId", "_rowId"];
|
||||
((AttendanceTracker getVariable ["allUsers", createHashMap]) get _netId) set ["_rowID", _rowID];
|
||||
};
|
||||
};
|
||||
default {
|
||||
_response call attendanceTracker_fnc_log;
|
||||
};
|
||||
};
|
||||
true;
|
||||
}];
|
||||
@@ -0,0 +1,3 @@
|
||||
private _database = "AttendanceTracker" callExtension "connectDB";
|
||||
// systemChat "AttendanceTracker: Connecting to database...";
|
||||
["Connecting to database...", "INFO"] call attendanceTracker_fnc_log;
|
||||
@@ -0,0 +1,93 @@
|
||||
[
|
||||
["OnUserConnected", {
|
||||
params ["_networkId", "_clientStateNumber", "_clientState"];
|
||||
|
||||
[format ["(EventHandler) OnUserConnected fired: %1", _this], "DEBUG"] call attendanceTracker_fnc_log;
|
||||
|
||||
private _userInfo = (getUserInfo _networkId);
|
||||
_userInfo params ["_playerID", "_ownerId", "_playerUID", "_profileName", "_displayName", "_steamName", "_clientState", "_isHC", "_adminState", "_networkInfo", "_unit"];
|
||||
if (_isHC) exitWith {};
|
||||
|
||||
(AttendanceTracker getVariable ["allUsers", createHashMap]) set [_networkId, _userInfo];
|
||||
[
|
||||
"Server",
|
||||
_playerID,
|
||||
_playerUID,
|
||||
_profileName,
|
||||
_steamName,
|
||||
nil // send rowId on d/c only
|
||||
] call attendanceTracker_fnc_writeAttendance;
|
||||
|
||||
}],
|
||||
["OnUserDisconnected", {
|
||||
params ["_networkId", "_clientStateNumber", "_clientState"];
|
||||
|
||||
[format ["(EventHandler) OnUserDisconnected fired: %1", _this], "DEBUG"] call attendanceTracker_fnc_log;
|
||||
|
||||
private _userInfo = (AttendanceTracker getVariable ["allUsers", createHashMap]) get _networkId;
|
||||
if (isNil "_userInfo") exitWith {};
|
||||
|
||||
_userInfo params ["_playerID", "_ownerId", "_playerUID", "_profileName", "_displayName", "_steamName", "_clientState", "_isHC", "_adminState", "_networkInfo", "_unit", "_rowId"];
|
||||
if (_isHC) exitWith {};
|
||||
|
||||
[
|
||||
"Server",
|
||||
_playerID,
|
||||
_playerUID,
|
||||
_profileName,
|
||||
_steamName,
|
||||
(if (!isNil "_rowId") then {_rowId} else {nil}) // send rowId on d/c only
|
||||
] call attendanceTracker_fnc_writeAttendance;
|
||||
}],
|
||||
["PlayerConnected", {
|
||||
params ["_id", "_uid", "_name", "_jip", "_owner", "_idstr"];
|
||||
|
||||
[format ["(EventHandler) PlayerConnected fired: %1", _this], "DEBUG"] call attendanceTracker_fnc_log;
|
||||
|
||||
private _userInfo = (getUserInfo _idstr);
|
||||
if (isNil "_userInfo") exitWith {};
|
||||
|
||||
_userInfo params ["_playerID", "_ownerId", "_playerUID", "_profileName", "_displayName", "_steamName", "_clientState", "_isHC", "_adminState", "_networkInfo", "_unit"];
|
||||
if (_isHC) exitWith {};
|
||||
|
||||
(AttendanceTracker getVariable ["allUsers", createHashMap]) set [_playerID, _userInfo];
|
||||
[
|
||||
"Mission",
|
||||
_playerID,
|
||||
_playerUID,
|
||||
_profileName,
|
||||
_steamName,
|
||||
_jip,
|
||||
roleDescription _unit,
|
||||
nil // send rowId on d/c only
|
||||
] call attendanceTracker_fnc_logMissionEvent;
|
||||
}],
|
||||
["PlayerDisconnected", {
|
||||
// NOTE: HandleDisconnect returns a DIFFERENT _id than PlayerDisconnected and above handlers, so we can't use it here
|
||||
params ["_id", "_uid", "_name", "_jip", "_owner", "_idstr"];
|
||||
|
||||
[format ["(EventHandler) HandleDisconnect fired: %1", _this], "DEBUG"] call attendanceTracker_fnc_log;
|
||||
|
||||
private _userInfo = (AttendanceTracker getVariable ["allUsers", createHashMap]) get _idstr;
|
||||
if (isNil "_userInfo") exitWith {
|
||||
[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", "_rowId"];
|
||||
if (_isHC) exitWith {};
|
||||
|
||||
[
|
||||
"Mission",
|
||||
_playerID,
|
||||
_playerUID,
|
||||
_profileName,
|
||||
_steamName,
|
||||
_jip,
|
||||
nil,
|
||||
(if (!isNil "_rowId") then {_rowId} else {nil}) // send rowId on d/c only
|
||||
] call attendanceTracker_fnc_logMissionEvent;
|
||||
|
||||
|
||||
false;
|
||||
}]
|
||||
];
|
||||
@@ -0,0 +1 @@
|
||||
(parseSimpleArray ("AttendanceTracker" callExtension "getMissionHash")) select 0;
|
||||
@@ -0,0 +1,28 @@
|
||||
_world = ( configfile >> "CfgWorlds" >> worldName );
|
||||
_author = getText( _world >> "author" );
|
||||
_name = getText ( _world >> "description" );
|
||||
|
||||
_source = configSourceMod ( _world );
|
||||
|
||||
_workshopID = '';
|
||||
|
||||
{
|
||||
if ( ( _x#1 ) == _source ) then {
|
||||
_workshopID = _x#7;
|
||||
break;
|
||||
};
|
||||
} foreach getLoadedModsInfo;
|
||||
|
||||
// [_name, _author, _workshopID];
|
||||
_return = createHashMapFromArray [
|
||||
["author", _author],
|
||||
["workshopID", _workshopID],
|
||||
["displayName", _name],
|
||||
["worldName", toLower worldName],
|
||||
["worldNameOriginal", _name],
|
||||
["worldSize", worldSize],
|
||||
["latitude", getNumber( _world >> "latitude" )],
|
||||
["longitude", getNumber( _world >> "longitude" )]
|
||||
];
|
||||
diag_log format ["Attendance Tracker: WorldInfo is: %1", _return];
|
||||
_return
|
||||
@@ -0,0 +1,21 @@
|
||||
params [
|
||||
["_message", "", [""]],
|
||||
["_level", "INFO", [""]],
|
||||
"_function"
|
||||
];
|
||||
|
||||
if (isNil "_message") exitWith {false};
|
||||
if (
|
||||
missionNamespace getVariable ["AttendanceTracker_debug", false] &&
|
||||
_level == "DEBUG"
|
||||
) exitWith {};
|
||||
|
||||
"AttendanceTracker" callExtension ["log", [_level, _message]];
|
||||
|
||||
if (!isNil "_function") then {
|
||||
diag_log formatText["[AttendanceTracker] (%1): <%2> %3", _level, _function, _message];
|
||||
} else {
|
||||
diag_log formatText["[AttendanceTracker] (%1): %2", _level, _message];
|
||||
};
|
||||
|
||||
true;
|
||||
@@ -0,0 +1,29 @@
|
||||
params [
|
||||
["_eventType", ""],
|
||||
["_playerId", ""],
|
||||
["_playerUID", ""],
|
||||
["_profileName", ""],
|
||||
["_steamName", ""],
|
||||
["_isJIP", false, [true, false]],
|
||||
["_roleDescription", ""],
|
||||
["_rowID", nil]
|
||||
];
|
||||
|
||||
private _hash = + (AttendanceTracker getVariable ["missionContext", createHashMap]);
|
||||
_hash set ["eventType", _eventType];
|
||||
_hash set ["playerId", _playerId];
|
||||
_hash set ["playerUID", _playerUID];
|
||||
_hash set ["profileName", _profileName];
|
||||
_hash set ["steamName", _steamName];
|
||||
_hash set ["isJIP", _isJIP];
|
||||
_hash set ["roleDescription", _roleDescription];
|
||||
_hash set ["missionHash", missionNamespace getVariable ["AttendanceTracker_missionHash", ""]];
|
||||
|
||||
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;
|
||||
@@ -0,0 +1,29 @@
|
||||
params [
|
||||
["_eventType", ""],
|
||||
["_playerId", ""],
|
||||
["_playerUID", ""],
|
||||
["_profileName", ""],
|
||||
["_steamName", ""],
|
||||
["_rowID", nil]
|
||||
];
|
||||
|
||||
|
||||
private _hash = + (AttendanceTracker getVariable ["missionContext", createHashMap]);
|
||||
_hash set ["networkId", netID player]
|
||||
_hash set ["eventType", _eventType];
|
||||
_hash set ["playerId", _playerId];
|
||||
_hash set ["playerUID", _playerUID];
|
||||
_hash set ["profileName", _profileName];
|
||||
_hash set ["steamName", _steamName];
|
||||
_hash set ["isJIP", false];
|
||||
_hash set ["roleDescription", ""];
|
||||
_hash set ["missionHash", missionNamespace getVariable ["AttendanceTracker_missionHash", ""]];
|
||||
|
||||
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;
|
||||
@@ -0,0 +1,44 @@
|
||||
|
||||
AttendanceTracker = false call CBA_fnc_createNamespace;
|
||||
|
||||
AttendanceTracker_missionStartTimestamp = call attendanceTracker_fnc_timestamp;
|
||||
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],
|
||||
["briefingName", briefingName],
|
||||
["missionNameSource", missionNameSource],
|
||||
["onLoadName", getMissionConfigValue ["onLoadName", ""]],
|
||||
["author", getMissionConfigValue ["author", ""]],
|
||||
["serverName", serverName],
|
||||
["serverProfile", profileName],
|
||||
["missionStart", AttendanceTracker_missionStartTimestamp],
|
||||
["missionHash", AttendanceTracker_missionHash]
|
||||
]];
|
||||
|
||||
|
||||
|
||||
// store all user details in a hash when they connect so we can reference it in disconnect events
|
||||
AttendanceTracker setVariable ["allUsers", createHashMap];
|
||||
missionNamespace setVariable ["AttendanceTracker_debug", false];
|
||||
|
||||
call attendanceTracker_fnc_connectDB;
|
||||
|
||||
{
|
||||
if (!isServer) exitWith {};
|
||||
_x params ["_ehName", "_code"];
|
||||
|
||||
_handle = (addMissionEventHandler [_ehName, _code]);
|
||||
if (isNil "_handle") then {
|
||||
[format["Failed to add Mission event handler: %1", _x], "ERROR"] call attendanceTracker_fnc_log;
|
||||
false;
|
||||
} else {
|
||||
missionNamespace setVariable [
|
||||
("AttendanceTracker" + "_MEH_" + _ehName),
|
||||
_handle
|
||||
];
|
||||
true;
|
||||
};
|
||||
} forEach (call attendanceTracker_fnc_eventHandlers);
|
||||
@@ -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
|
||||
];
|
||||
|
||||
7
@AttendanceTracker/config.example.json
Normal file
7
@AttendanceTracker/config.example.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"mysqlHost": "127.0.0.1",
|
||||
"mysqlPort": 3306,
|
||||
"mysqlUser": "root",
|
||||
"mysqlPassword": "root",
|
||||
"mysqlDatabase": "db"
|
||||
}
|
||||
7
@AttendanceTracker/config.json
Normal file
7
@AttendanceTracker/config.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"mysqlHost": "127.0.0.1",
|
||||
"mysqlPort": 12730,
|
||||
"mysqlUser": "root",
|
||||
"mysqlPassword": "i&Lz8A3RuPcY5b326ALXgjl",
|
||||
"mysqlDatabase": "testdb"
|
||||
}
|
||||
0
@AttendanceTracker/mod.cpp
Normal file
0
@AttendanceTracker/mod.cpp
Normal file
Reference in New Issue
Block a user