feat: support german and french signatures

This commit is contained in:
Guarzo
2025-05-14 09:44:38 -04:00
parent cb318aa6c6
commit 1364779f81
8 changed files with 344 additions and 168 deletions

View File

@@ -25,12 +25,16 @@ function useSignatureUndo(
settings: SignatureSettingsType, settings: SignatureSettingsType,
outCommand: OutCommandHandler, outCommand: OutCommandHandler,
) { ) {
const [pendingIds, setPendingIds] = useState<string[]>([]); const [countdown, setCountdown] = useState<number>(0);
const [countdown, setCountdown] = useState(0); const [pendingIds, setPendingIds] = useState<Set<string>>(new Set());
const intervalRef = useRef<number | null>(null); const intervalRef = useRef<number | null>(null);
const addDeleted = useCallback((ids: string[]) => { const addDeleted = useCallback((ids: string[]) => {
setPendingIds(prev => [...prev, ...ids]); setPendingIds(prev => {
const next = new Set(prev);
ids.forEach(id => next.add(id));
return next;
});
}, []); }, []);
// kick off or clear countdown whenever pendingIds changes // kick off or clear countdown whenever pendingIds changes
@@ -41,7 +45,7 @@ function useSignatureUndo(
intervalRef.current = null; intervalRef.current = null;
} }
if (pendingIds.length === 0) { if (pendingIds.size === 0) {
setCountdown(0); setCountdown(0);
return; return;
} }
@@ -58,7 +62,7 @@ function useSignatureUndo(
if (prev <= 1) { if (prev <= 1) {
clearInterval(intervalRef.current!); clearInterval(intervalRef.current!);
intervalRef.current = null; intervalRef.current = null;
setPendingIds([]); setPendingIds(new Set());
return 0; return 0;
} }
return prev - 1; return prev - 1;
@@ -71,16 +75,16 @@ function useSignatureUndo(
intervalRef.current = null; intervalRef.current = null;
} }
}; };
}, [pendingIds, settings]); }, [pendingIds, settings[SETTINGS_KEYS.DELETION_TIMING]]);
// undo handler // undo handler
const handleUndo = useCallback(async () => { const handleUndo = useCallback(async () => {
if (!systemId || pendingIds.length === 0) return; if (!systemId || pendingIds.size === 0) return;
await outCommand({ await outCommand({
type: OutCommand.undoDeleteSignatures, type: OutCommand.undoDeleteSignatures,
data: { system_id: systemId, eve_ids: pendingIds }, data: { system_id: systemId, eve_ids: Array.from(pendingIds) },
}); });
setPendingIds([]); setPendingIds(new Set());
setCountdown(0); setCountdown(0);
if (intervalRef.current != null) { if (intervalRef.current != null) {
clearInterval(intervalRef.current); clearInterval(intervalRef.current);
@@ -117,7 +121,7 @@ export const SystemSignatures = () => {
const { pendingIds, countdown, addDeleted, handleUndo } = useSignatureUndo(systemId, currentSettings, outCommand); const { pendingIds, countdown, addDeleted, handleUndo } = useSignatureUndo(systemId, currentSettings, outCommand);
useHotkey(true, ['z', 'Z'], (event: KeyboardEvent) => { useHotkey(true, ['z', 'Z'], (event: KeyboardEvent) => {
if (pendingIds.length > 0 && countdown > 0) { if (pendingIds.size > 0 && countdown > 0) {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
handleUndo(); handleUndo();
@@ -154,7 +158,7 @@ export const SystemSignatures = () => {
<SystemSignaturesHeader <SystemSignaturesHeader
sigCount={sigCount} sigCount={sigCount}
lazyDeleteValue={currentSettings[SETTINGS_KEYS.LAZY_DELETE_SIGNATURES] as boolean} lazyDeleteValue={currentSettings[SETTINGS_KEYS.LAZY_DELETE_SIGNATURES] as boolean}
pendingCount={pendingIds.length} pendingCount={pendingIds.size}
undoCountdown={countdown} undoCountdown={countdown}
onLazyDeleteChange={handleLazyDeleteToggle} onLazyDeleteChange={handleLazyDeleteToggle}
onUndoClick={handleUndo} onUndoClick={handleUndo}

View File

@@ -90,8 +90,15 @@ export const SystemSignaturesContent = ({
{ defaultValue: SORT_DEFAULT_VALUES }, { defaultValue: SORT_DEFAULT_VALUES },
); );
const { signatures, selectedSignatures, setSelectedSignatures, handleDeleteSelected, handleSelectAll, handlePaste } = const {
useSystemSignaturesData({ signatures,
selectedSignatures,
setSelectedSignatures,
handleDeleteSelected,
handleSelectAll,
handlePaste,
hasUnsupportedLanguage,
} = useSystemSignaturesData({
systemId, systemId,
settings, settings,
onCountChange, onCountChange,
@@ -186,7 +193,11 @@ export const SystemSignaturesContent = ({
x => GROUPS_LIST.includes(x as SignatureGroup) && settings[x as SETTINGS_KEYS], x => GROUPS_LIST.includes(x as SignatureGroup) && settings[x as SETTINGS_KEYS],
); );
return enabledGroups.includes(getGroupIdByRawGroup(sig.group)); const mappedGroup = getGroupIdByRawGroup(sig.group);
if (!mappedGroup) {
return true; // If we can't determine the group, still show it
}
return enabledGroups.includes(mappedGroup);
} }
return true; return true;
@@ -234,6 +245,13 @@ export const SystemSignaturesContent = ({
No signatures No signatures
</div> </div>
) : ( ) : (
<>
{hasUnsupportedLanguage && (
<div className="w-full flex justify-center items-center text-amber-500 text-xs p-1 bg-amber-950/20 border-b border-amber-800/30">
<i className={PrimeIcons.EXCLAMATION_TRIANGLE + ' mr-1'} />
Non-English signatures detected. Some signatures may not display correctly. Double-click to edit signature details.
</div>
)}
<DataTable <DataTable
value={filteredSignatures} value={filteredSignatures}
size="small" size="small"
@@ -341,6 +359,7 @@ export const SystemSignaturesContent = ({
/> />
)} )}
</DataTable> </DataTable>
</>
)} )}
<WdTooltip <WdTooltip

View File

@@ -1,10 +1,14 @@
import { import {
GroupType, GroupType,
SignatureGroup, SignatureGroup,
SignatureGroupDE,
SignatureGroupENG, SignatureGroupENG,
SignatureGroupFR,
SignatureGroupRU, SignatureGroupRU,
SignatureKind, SignatureKind,
SignatureKindDE,
SignatureKindENG, SignatureKindENG,
SignatureKindFR,
SignatureKindRU, SignatureKindRU,
} from '@/hooks/Mapper/types'; } from '@/hooks/Mapper/types';
@@ -40,8 +44,8 @@ export const GROUPS: Record<SignatureGroup, GroupType> = {
[SignatureGroup.CosmicSignature]: { id: SignatureGroup.CosmicSignature, icon: '/icons/x_close14.png', w: 9, h: 9 }, [SignatureGroup.CosmicSignature]: { id: SignatureGroup.CosmicSignature, icon: '/icons/x_close14.png', w: 9, h: 9 },
}; };
export const MAPPING_GROUP_TO_ENG = { export const LANGUAGE_GROUP_MAPPINGS = {
// ENGLISH EN: {
[SignatureGroupENG.GasSite]: SignatureGroup.GasSite, [SignatureGroupENG.GasSite]: SignatureGroup.GasSite,
[SignatureGroupENG.RelicSite]: SignatureGroup.RelicSite, [SignatureGroupENG.RelicSite]: SignatureGroup.RelicSite,
[SignatureGroupENG.DataSite]: SignatureGroup.DataSite, [SignatureGroupENG.DataSite]: SignatureGroup.DataSite,
@@ -49,8 +53,8 @@ export const MAPPING_GROUP_TO_ENG = {
[SignatureGroupENG.CombatSite]: SignatureGroup.CombatSite, [SignatureGroupENG.CombatSite]: SignatureGroup.CombatSite,
[SignatureGroupENG.Wormhole]: SignatureGroup.Wormhole, [SignatureGroupENG.Wormhole]: SignatureGroup.Wormhole,
[SignatureGroupENG.CosmicSignature]: SignatureGroup.CosmicSignature, [SignatureGroupENG.CosmicSignature]: SignatureGroup.CosmicSignature,
},
// RUSSIAN RU: {
[SignatureGroupRU.GasSite]: SignatureGroup.GasSite, [SignatureGroupRU.GasSite]: SignatureGroup.GasSite,
[SignatureGroupRU.RelicSite]: SignatureGroup.RelicSite, [SignatureGroupRU.RelicSite]: SignatureGroup.RelicSite,
[SignatureGroupRU.DataSite]: SignatureGroup.DataSite, [SignatureGroupRU.DataSite]: SignatureGroup.DataSite,
@@ -58,28 +62,40 @@ export const MAPPING_GROUP_TO_ENG = {
[SignatureGroupRU.CombatSite]: SignatureGroup.CombatSite, [SignatureGroupRU.CombatSite]: SignatureGroup.CombatSite,
[SignatureGroupRU.Wormhole]: SignatureGroup.Wormhole, [SignatureGroupRU.Wormhole]: SignatureGroup.Wormhole,
[SignatureGroupRU.CosmicSignature]: SignatureGroup.CosmicSignature, [SignatureGroupRU.CosmicSignature]: SignatureGroup.CosmicSignature,
},
FR: {
[SignatureGroupFR.GasSite]: SignatureGroup.GasSite,
[SignatureGroupFR.RelicSite]: SignatureGroup.RelicSite,
[SignatureGroupFR.DataSite]: SignatureGroup.DataSite,
[SignatureGroupFR.OreSite]: SignatureGroup.OreSite,
[SignatureGroupFR.CombatSite]: SignatureGroup.CombatSite,
[SignatureGroupFR.Wormhole]: SignatureGroup.Wormhole,
[SignatureGroupFR.CosmicSignature]: SignatureGroup.CosmicSignature,
},
DE: {
[SignatureGroupDE.GasSite]: SignatureGroup.GasSite,
[SignatureGroupDE.RelicSite]: SignatureGroup.RelicSite,
[SignatureGroupDE.DataSite]: SignatureGroup.DataSite,
[SignatureGroupDE.OreSite]: SignatureGroup.OreSite,
[SignatureGroupDE.CombatSite]: SignatureGroup.CombatSite,
[SignatureGroupDE.Wormhole]: SignatureGroup.Wormhole,
[SignatureGroupDE.CosmicSignature]: SignatureGroup.CosmicSignature,
},
}; };
export const MAPPING_TYPE_TO_ENG = { // Flatten the structure for backward compatibility
// ENGLISH export const MAPPING_GROUP_TO_ENG: Record<string, SignatureGroup> = (() => {
[SignatureKindENG.CosmicSignature]: SignatureKind.CosmicSignature, const flattened: Record<string, SignatureGroup> = {};
[SignatureKindENG.CosmicAnomaly]: SignatureKind.CosmicAnomaly, for (const [, mappings] of Object.entries(LANGUAGE_GROUP_MAPPINGS)) {
[SignatureKindENG.Structure]: SignatureKind.Structure, Object.assign(flattened, mappings);
[SignatureKindENG.Ship]: SignatureKind.Ship, }
[SignatureKindENG.Deployable]: SignatureKind.Deployable, return flattened;
[SignatureKindENG.Drone]: SignatureKind.Drone, })();
// RUSSIAN export const getGroupIdByRawGroup = (val: string): SignatureGroup | undefined => {
[SignatureKindRU.CosmicSignature]: SignatureKind.CosmicSignature, return MAPPING_GROUP_TO_ENG[val] || undefined;
[SignatureKindRU.CosmicAnomaly]: SignatureKind.CosmicAnomaly,
[SignatureKindRU.Structure]: SignatureKind.Structure,
[SignatureKindRU.Ship]: SignatureKind.Ship,
[SignatureKindRU.Deployable]: SignatureKind.Deployable,
[SignatureKindRU.Drone]: SignatureKind.Drone,
}; };
export const getGroupIdByRawGroup = (val: string) => MAPPING_GROUP_TO_ENG[val as SignatureGroup];
export const SIGNATURE_WINDOW_ID = 'system_signatures_window'; export const SIGNATURE_WINDOW_ID = 'system_signatures_window';
export const SIGNATURE_SETTING_STORE_KEY = 'wanderer_system_signature_settings_v6_5'; export const SIGNATURE_SETTING_STORE_KEY = 'wanderer_system_signature_settings_v6_5';
@@ -123,7 +139,7 @@ export type Setting = {
name: string; name: string;
type: SettingsTypes; type: SettingsTypes;
isSeparator?: boolean; isSeparator?: boolean;
options?: { label: string; value: any }[]; options?: { label: string; value: number | string | boolean }[];
}; };
export enum SIGNATURES_DELETION_TIMING { export enum SIGNATURES_DELETION_TIMING {
@@ -208,3 +224,52 @@ export const SIGNATURE_DELETION_TIMEOUTS: SignatureDeletionTimingType = {
[SIGNATURES_DELETION_TIMING.IMMEDIATE]: 0, [SIGNATURES_DELETION_TIMING.IMMEDIATE]: 0,
[SIGNATURES_DELETION_TIMING.EXTENDED]: 30_000, [SIGNATURES_DELETION_TIMING.EXTENDED]: 30_000,
}; };
// Replace the flat structure with a nested structure by language
export const LANGUAGE_TYPE_MAPPINGS = {
EN: {
[SignatureKindENG.CosmicSignature]: SignatureKind.CosmicSignature,
[SignatureKindENG.CosmicAnomaly]: SignatureKind.CosmicAnomaly,
[SignatureKindENG.Structure]: SignatureKind.Structure,
[SignatureKindENG.Ship]: SignatureKind.Ship,
[SignatureKindENG.Deployable]: SignatureKind.Deployable,
[SignatureKindENG.Drone]: SignatureKind.Drone,
[SignatureKindENG.Starbase]: SignatureKind.Starbase,
},
RU: {
[SignatureKindRU.CosmicSignature]: SignatureKind.CosmicSignature,
[SignatureKindRU.CosmicAnomaly]: SignatureKind.CosmicAnomaly,
[SignatureKindRU.Structure]: SignatureKind.Structure,
[SignatureKindRU.Ship]: SignatureKind.Ship,
[SignatureKindRU.Deployable]: SignatureKind.Deployable,
[SignatureKindRU.Drone]: SignatureKind.Drone,
[SignatureKindRU.Starbase]: SignatureKind.Starbase,
},
FR: {
[SignatureKindFR.CosmicSignature]: SignatureKind.CosmicSignature,
[SignatureKindFR.CosmicAnomaly]: SignatureKind.CosmicAnomaly,
[SignatureKindFR.Structure]: SignatureKind.Structure,
[SignatureKindFR.Ship]: SignatureKind.Ship,
[SignatureKindFR.Deployable]: SignatureKind.Deployable,
[SignatureKindFR.Drone]: SignatureKind.Drone,
[SignatureKindFR.Starbase]: SignatureKind.Starbase,
},
DE: {
[SignatureKindDE.CosmicSignature]: SignatureKind.CosmicSignature,
[SignatureKindDE.CosmicAnomaly]: SignatureKind.CosmicAnomaly,
[SignatureKindDE.Structure]: SignatureKind.Structure,
[SignatureKindDE.Ship]: SignatureKind.Ship,
[SignatureKindDE.Deployable]: SignatureKind.Deployable,
[SignatureKindDE.Drone]: SignatureKind.Drone,
[SignatureKindDE.Starbase]: SignatureKind.Starbase,
},
};
// Flatten the structure for backward compatibility
export const MAPPING_TYPE_TO_ENG: Record<string, SignatureKind> = (() => {
const flattened: Record<string, SignatureKind> = {};
for (const [, mappings] of Object.entries(LANGUAGE_TYPE_MAPPINGS)) {
Object.assign(flattened, mappings);
}
return flattened;
})();

View File

@@ -19,10 +19,13 @@ export const useSystemSignaturesData = ({
onPendingChange, onPendingChange,
onLazyDeleteChange, onLazyDeleteChange,
onSignatureDeleted, onSignatureDeleted,
}: Omit<UseSystemSignaturesDataProps, 'deletionTiming'> & { onSignatureDeleted?: (deletedIds: string[]) => void }) => { }: Omit<UseSystemSignaturesDataProps, 'deletionTiming'> & {
onSignatureDeleted?: (deletedIds: string[]) => void;
}) => {
const { outCommand } = useMapRootState(); const { outCommand } = useMapRootState();
const [signatures, setSignatures, signaturesRef] = useRefState<ExtendedSystemSignature[]>([]); const [signatures, setSignatures, signaturesRef] = useRefState<ExtendedSystemSignature[]>([]);
const [selectedSignatures, setSelectedSignatures] = useState<ExtendedSystemSignature[]>([]); const [selectedSignatures, setSelectedSignatures] = useState<ExtendedSystemSignature[]>([]);
const [hasUnsupportedLanguage, setHasUnsupportedLanguage] = useState<boolean>(false);
const { pendingDeletionMapRef, processRemovedSignatures, clearPendingDeletions } = usePendingDeletions({ const { pendingDeletionMapRef, processRemovedSignatures, clearPendingDeletions } = usePendingDeletions({
systemId, systemId,
@@ -41,6 +44,7 @@ export const useSystemSignaturesData = ({
async (clipboardString: string) => { async (clipboardString: string) => {
const lazyDeleteValue = settings[SETTINGS_KEYS.LAZY_DELETE_SIGNATURES] as boolean; const lazyDeleteValue = settings[SETTINGS_KEYS.LAZY_DELETE_SIGNATURES] as boolean;
// Parse the incoming signatures
const incomingSignatures = parseSignatures( const incomingSignatures = parseSignatures(
clipboardString, clipboardString,
Object.keys(settings).filter(skey => skey in SignatureKind), Object.keys(settings).filter(skey => skey in SignatureKind),
@@ -50,6 +54,18 @@ export const useSystemSignaturesData = ({
return; return;
} }
// Check if any signatures might be using unsupported languages
// This is a basic heuristic: if we have signatures where the original group wasn't mapped
const clipboardRows = clipboardString.split('\n').filter(row => row.trim() !== '');
const detectedSignatureCount = clipboardRows.filter(row => row.match(/^[A-Z]{3}-\d{3}/)).length;
// If we detected valid IDs but got fewer parsed signatures, we might have language issues
if (detectedSignatureCount > 0 && incomingSignatures.length < detectedSignatureCount) {
setHasUnsupportedLanguage(true);
} else {
setHasUnsupportedLanguage(false);
}
const currentNonPending = lazyDeleteValue const currentNonPending = lazyDeleteValue
? signaturesRef.current.filter(sig => !sig.pendingDeletion) ? signaturesRef.current.filter(sig => !sig.pendingDeletion)
: signaturesRef.current.filter(sig => !sig.pendingDeletion || !sig.pendingAddition); : signaturesRef.current.filter(sig => !sig.pendingDeletion || !sig.pendingAddition);
@@ -127,5 +143,6 @@ export const useSystemSignaturesData = ({
handleDeleteSelected, handleDeleteSelected,
handleSelectAll, handleSelectAll,
handlePaste, handlePaste,
hasUnsupportedLanguage,
}; };
}; };

View File

@@ -1,5 +1,8 @@
import { SignatureGroup, SignatureKind, SystemSignature } from '@/hooks/Mapper/types'; import { SignatureGroup, SignatureKind, SystemSignature } from '@/hooks/Mapper/types';
import { MAPPING_TYPE_TO_ENG } from '@/hooks/Mapper/components/mapInterface/widgets/SystemSignatures/constants.ts'; import {
MAPPING_GROUP_TO_ENG,
MAPPING_TYPE_TO_ENG,
} from '@/hooks/Mapper/components/mapInterface/widgets/SystemSignatures/constants.ts';
export const parseSignatures = (value: string, availableKeys: string[]): SystemSignature[] => { export const parseSignatures = (value: string, availableKeys: string[]): SystemSignature[] => {
const outArr: SystemSignature[] = []; const outArr: SystemSignature[] = [];
@@ -14,13 +17,37 @@ export const parseSignatures = (value: string, availableKeys: string[]): SystemS
continue; continue;
} }
const kind = MAPPING_TYPE_TO_ENG[sigArrInfo[1] as SignatureKind]; // Extract the signature ID and check if it's valid (XXX-XXX format)
const sigId = sigArrInfo[0];
if (!sigId || !sigId.match(/^[A-Z]{3}-\d{3}$/)) {
continue;
}
// Try to map the kind, or fall back to CosmicSignature if unknown
const typeString = sigArrInfo[1];
let kind = SignatureKind.CosmicSignature;
// Try to map the kind using the flattened mapping
const mappedKind = MAPPING_TYPE_TO_ENG[typeString];
if (mappedKind && availableKeys.includes(mappedKind)) {
kind = mappedKind;
}
// Try to map the group, or fall back to CosmicSignature if unknown
const rawGroup = sigArrInfo[2];
let group = SignatureGroup.CosmicSignature;
// Try to map the group using the flattened mapping
const mappedGroup = MAPPING_GROUP_TO_ENG[rawGroup];
if (mappedGroup) {
group = mappedGroup;
}
const signature: SystemSignature = { const signature: SystemSignature = {
eve_id: sigArrInfo[0], eve_id: sigId,
kind: availableKeys.includes(kind) ? kind : SignatureKind.CosmicSignature, kind,
group: sigArrInfo[2] as SignatureGroup, group,
name: sigArrInfo[3], name: sigArrInfo[3] || 'Unknown',
type: '', type: '',
}; };

View File

@@ -78,6 +78,26 @@ export enum SignatureKindRU {
Starbase = 'Starbase', Starbase = 'Starbase',
} }
export enum SignatureKindFR {
CosmicSignature = 'Signature cosmique (type)',
CosmicAnomaly = 'Anomalie cosmique',
Structure = 'Structure',
Ship = 'Vaisseau',
Deployable = 'Déployable',
Drone = 'Drone',
Starbase = 'Base stellaire',
}
export enum SignatureKindDE {
CosmicSignature = 'Kosmische Signatur (typ)',
CosmicAnomaly = 'Kosmische Anomalie',
Structure = 'Struktur',
Ship = 'Schiff',
Deployable = 'Mobile Struktur',
Drone = 'Drohne',
Starbase = 'Sternenbasis',
}
export enum SignatureGroupENG { export enum SignatureGroupENG {
CosmicSignature = 'Cosmic Signature', CosmicSignature = 'Cosmic Signature',
Wormhole = 'Wormhole', Wormhole = 'Wormhole',
@@ -97,3 +117,23 @@ export enum SignatureGroupRU {
OreSite = 'Астероидный район', OreSite = 'Астероидный район',
CombatSite = 'Боевой район', CombatSite = 'Боевой район',
} }
export enum SignatureGroupFR {
CosmicSignature = 'Signature cosmique (groupe)',
Wormhole = 'Trou de ver',
GasSite = 'Site de gaz',
RelicSite = 'Site de reliques',
DataSite = 'Site de données',
OreSite = 'Site de minerai',
CombatSite = 'Site de combat',
}
export enum SignatureGroupDE {
CosmicSignature = 'Kosmische Signatur (gruppe)',
Wormhole = 'Wurmloch',
GasSite = 'Gasgebiet',
RelicSite = 'Reliktgebiet',
DataSite = 'Datengebiet',
OreSite = 'Mineraliengebiet',
CombatSite = 'Kampfgebiet',
}

View File

@@ -204,7 +204,7 @@ defmodule WandererApp.Api.MapSystemSignature do
:kind, :kind,
:group, :group,
:custom_info, :custom_info,
:updated, :deleted,
:inserted_at, :inserted_at,
:updated_at :updated_at
] ]

View File

@@ -97,7 +97,7 @@ defmodule WandererApp.Map.Server.SignaturesImpl do
%MapSystemSignature{deleted: true} = deleted_sig -> %MapSystemSignature{deleted: true} = deleted_sig ->
MapSystemSignature.update!( MapSystemSignature.update!(
deleted_sig, deleted_sig,
%{sig | deleted: false} Map.take(sig, [:name, :description, :kind, :group, :type, :custom_info, :deleted])
) )
_ -> _ ->
@@ -152,7 +152,11 @@ defmodule WandererApp.Map.Server.SignaturesImpl do
defp apply_update_signature(%MapSystemSignature{} = existing, update_params) defp apply_update_signature(%MapSystemSignature{} = existing, update_params)
when not is_nil(update_params) do when not is_nil(update_params) do
MapSystemSignature.update(existing, update_params) case MapSystemSignature.update(existing, update_params) do
{:ok, _} -> :ok
{:error, reason} ->
Logger.error("Failed to update signature #{existing.id}: #{inspect(reason)}")
end
end end
defp track_activity(event, map_id, solar_system_id, user_id, character_id, signatures) do defp track_activity(event, map_id, solar_system_id, user_id, character_id, signatures) do