667 lines
23 KiB
PHP
667 lines
23 KiB
PHP
<?php
|
|
|
|
require_once __DIR__ . '/config.php';
|
|
|
|
function sccharacters_column_exists(PDO $db, string $table, string $column): bool
|
|
{
|
|
$stmt = $db->query("SHOW COLUMNS FROM `{$table}` LIKE " . $db->quote($column));
|
|
|
|
return (bool) $stmt->fetch();
|
|
}
|
|
|
|
function sccharacters_index_exists(PDO $db, string $table, string $index): bool
|
|
{
|
|
$stmt = $db->query("SHOW INDEX FROM `{$table}` WHERE Key_name = " . $db->quote($index));
|
|
|
|
return (bool) $stmt->fetch();
|
|
}
|
|
|
|
function sccharacters_foreign_key_exists(PDO $db, string $table, string $constraint): bool
|
|
{
|
|
$stmt = $db->prepare(
|
|
"SELECT COUNT(*)
|
|
FROM information_schema.TABLE_CONSTRAINTS
|
|
WHERE TABLE_SCHEMA = DATABASE()
|
|
AND TABLE_NAME = :table_name
|
|
AND CONSTRAINT_NAME = :constraint_name
|
|
AND CONSTRAINT_TYPE = 'FOREIGN KEY'"
|
|
);
|
|
$stmt->execute([
|
|
'table_name' => $table,
|
|
'constraint_name' => $constraint,
|
|
]);
|
|
|
|
return (int) $stmt->fetchColumn() > 0;
|
|
}
|
|
|
|
function sccharacters_bootstrap(): void
|
|
{
|
|
static $bootstrapped = false;
|
|
|
|
if ($bootstrapped) {
|
|
return;
|
|
}
|
|
|
|
$db = db();
|
|
|
|
$db->exec(
|
|
"CREATE TABLE IF NOT EXISTS tbl_sccharacters (
|
|
cl_sccharacter_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
cl_sccharacter_owner_auth_id INT UNSIGNED NOT NULL,
|
|
cl_sccharacter_name VARCHAR(190) NOT NULL,
|
|
cl_sccharacter_role VARCHAR(190) NOT NULL DEFAULT '',
|
|
cl_sccharacter_faction VARCHAR(190) NOT NULL DEFAULT '',
|
|
cl_sccharacter_avatar_url VARCHAR(255) NOT NULL DEFAULT '',
|
|
cl_sccharacter_description TEXT DEFAULT NULL,
|
|
cl_sccharacter_notes TEXT DEFAULT NULL,
|
|
cl_sccharacter_share_token VARCHAR(64) NOT NULL,
|
|
cl_sccharacter_share_enabled TINYINT(1) NOT NULL DEFAULT 0,
|
|
cl_sccharacter_is_pinned TINYINT(1) NOT NULL DEFAULT 0,
|
|
cl_sccharacter_category_order TEXT DEFAULT NULL,
|
|
cl_sccharacter_created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
cl_sccharacter_updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (cl_sccharacter_id),
|
|
UNIQUE KEY uq_sccharacter_share_token (cl_sccharacter_share_token),
|
|
KEY idx_sccharacter_owner (cl_sccharacter_owner_auth_id),
|
|
KEY idx_sccharacter_name (cl_sccharacter_name),
|
|
CONSTRAINT fk_sccharacter_owner_auth FOREIGN KEY (cl_sccharacter_owner_auth_id)
|
|
REFERENCES tbl_auth (cl_auth_id)
|
|
ON DELETE CASCADE
|
|
ON UPDATE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"
|
|
);
|
|
|
|
if (!sccharacters_column_exists($db, 'tbl_sccharacters', 'cl_sccharacter_owner_auth_id')) {
|
|
$db->exec(
|
|
'ALTER TABLE tbl_sccharacters
|
|
ADD COLUMN cl_sccharacter_owner_auth_id INT UNSIGNED NULL AFTER cl_sccharacter_id'
|
|
);
|
|
}
|
|
|
|
if (!sccharacters_column_exists($db, 'tbl_sccharacters', 'cl_sccharacter_share_token')) {
|
|
$db->exec(
|
|
"ALTER TABLE tbl_sccharacters
|
|
ADD COLUMN cl_sccharacter_share_token VARCHAR(64) NOT NULL DEFAULT '' AFTER cl_sccharacter_notes"
|
|
);
|
|
}
|
|
|
|
if (!sccharacters_column_exists($db, 'tbl_sccharacters', 'cl_sccharacter_share_enabled')) {
|
|
$db->exec(
|
|
'ALTER TABLE tbl_sccharacters
|
|
ADD COLUMN cl_sccharacter_share_enabled TINYINT(1) NOT NULL DEFAULT 0 AFTER cl_sccharacter_share_token'
|
|
);
|
|
}
|
|
|
|
if (!sccharacters_column_exists($db, 'tbl_sccharacters', 'cl_sccharacter_is_pinned')) {
|
|
$db->exec(
|
|
'ALTER TABLE tbl_sccharacters
|
|
ADD COLUMN cl_sccharacter_is_pinned TINYINT(1) NOT NULL DEFAULT 0 AFTER cl_sccharacter_share_enabled'
|
|
);
|
|
}
|
|
|
|
if (!sccharacters_column_exists($db, 'tbl_sccharacters', 'cl_sccharacter_category_order')) {
|
|
$db->exec(
|
|
'ALTER TABLE tbl_sccharacters
|
|
ADD COLUMN cl_sccharacter_category_order TEXT NULL AFTER cl_sccharacter_is_pinned'
|
|
);
|
|
}
|
|
|
|
if (!sccharacters_index_exists($db, 'tbl_sccharacters', 'idx_sccharacter_owner')) {
|
|
$db->exec(
|
|
'ALTER TABLE tbl_sccharacters
|
|
ADD INDEX idx_sccharacter_owner (cl_sccharacter_owner_auth_id)'
|
|
);
|
|
}
|
|
|
|
if (!sccharacters_index_exists($db, 'tbl_sccharacters', 'uq_sccharacter_share_token')) {
|
|
$db->exec(
|
|
'ALTER TABLE tbl_sccharacters
|
|
ADD UNIQUE KEY uq_sccharacter_share_token (cl_sccharacter_share_token)'
|
|
);
|
|
}
|
|
|
|
if (!sccharacters_foreign_key_exists($db, 'tbl_sccharacters', 'fk_sccharacter_owner_auth')) {
|
|
$db->exec(
|
|
'ALTER TABLE tbl_sccharacters
|
|
ADD CONSTRAINT fk_sccharacter_owner_auth FOREIGN KEY (cl_sccharacter_owner_auth_id)
|
|
REFERENCES tbl_auth (cl_auth_id)
|
|
ON DELETE CASCADE
|
|
ON UPDATE CASCADE'
|
|
);
|
|
}
|
|
|
|
$db->exec(
|
|
"CREATE TABLE IF NOT EXISTS tbl_sccharacteritems (
|
|
cl_sccharacteritem_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
cl_sccharacteritem_character_id INT UNSIGNED NOT NULL,
|
|
cl_sccharacteritem_source ENUM('base', 'custom') NOT NULL DEFAULT 'base',
|
|
cl_sccharacteritem_scobjs_id INT UNSIGNED DEFAULT NULL,
|
|
cl_sccharacteritem_scitemcustom_id INT(11) DEFAULT NULL,
|
|
cl_sccharacteritem_slot VARCHAR(120) NOT NULL DEFAULT '',
|
|
cl_sccharacteritem_quantity INT UNSIGNED DEFAULT NULL,
|
|
cl_sccharacteritem_note TEXT DEFAULT NULL,
|
|
cl_sccharacteritem_sort_order INT UNSIGNED NOT NULL DEFAULT 0,
|
|
cl_sccharacteritem_created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (cl_sccharacteritem_id),
|
|
KEY idx_sccharacteritem_character (cl_sccharacteritem_character_id),
|
|
KEY idx_sccharacteritem_scobjs (cl_sccharacteritem_scobjs_id),
|
|
KEY idx_sccharacteritem_scitemcustom (cl_sccharacteritem_scitemcustom_id),
|
|
KEY idx_sccharacteritem_character_sort (cl_sccharacteritem_character_id, cl_sccharacteritem_sort_order, cl_sccharacteritem_id),
|
|
CONSTRAINT fk_sccharacteritem_character FOREIGN KEY (cl_sccharacteritem_character_id)
|
|
REFERENCES tbl_sccharacters (cl_sccharacter_id)
|
|
ON DELETE CASCADE
|
|
ON UPDATE CASCADE,
|
|
CONSTRAINT fk_sccharacteritem_scobjs FOREIGN KEY (cl_sccharacteritem_scobjs_id)
|
|
REFERENCES tbl_scobjs (cl_scobjs_id)
|
|
ON DELETE SET NULL
|
|
ON UPDATE CASCADE,
|
|
CONSTRAINT fk_sccharacteritem_scitemcustom FOREIGN KEY (cl_sccharacteritem_scitemcustom_id)
|
|
REFERENCES tbl_scitemcustom (cl_scitemcustom_id)
|
|
ON DELETE SET NULL
|
|
ON UPDATE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"
|
|
);
|
|
|
|
if (!sccharacters_column_exists($db, 'tbl_sccharacteritems', 'cl_sccharacteritem_scobjs_id')) {
|
|
$db->exec(
|
|
'ALTER TABLE tbl_sccharacteritems
|
|
ADD COLUMN cl_sccharacteritem_scobjs_id INT UNSIGNED NULL AFTER cl_sccharacteritem_source'
|
|
);
|
|
}
|
|
|
|
if (!sccharacters_column_exists($db, 'tbl_sccharacteritems', 'cl_sccharacteritem_scitemcustom_id')) {
|
|
$db->exec(
|
|
'ALTER TABLE tbl_sccharacteritems
|
|
ADD COLUMN cl_sccharacteritem_scitemcustom_id INT(11) NULL AFTER cl_sccharacteritem_scobjs_id'
|
|
);
|
|
}
|
|
|
|
if (!sccharacters_column_exists($db, 'tbl_sccharacteritems', 'cl_sccharacteritem_quantity')) {
|
|
$db->exec(
|
|
'ALTER TABLE tbl_sccharacteritems
|
|
ADD COLUMN cl_sccharacteritem_quantity INT UNSIGNED NULL AFTER cl_sccharacteritem_slot'
|
|
);
|
|
}
|
|
|
|
if (!sccharacters_column_exists($db, 'tbl_sccharacteritems', 'cl_sccharacteritem_sort_order')) {
|
|
$db->exec(
|
|
'ALTER TABLE tbl_sccharacteritems
|
|
ADD COLUMN cl_sccharacteritem_sort_order INT UNSIGNED NOT NULL DEFAULT 0 AFTER cl_sccharacteritem_note'
|
|
);
|
|
}
|
|
|
|
if (!sccharacters_index_exists($db, 'tbl_sccharacteritems', 'idx_sccharacteritem_character')) {
|
|
$db->exec(
|
|
'ALTER TABLE tbl_sccharacteritems
|
|
ADD INDEX idx_sccharacteritem_character (cl_sccharacteritem_character_id)'
|
|
);
|
|
}
|
|
|
|
if (!sccharacters_index_exists($db, 'tbl_sccharacteritems', 'idx_sccharacteritem_scobjs')) {
|
|
$db->exec(
|
|
'ALTER TABLE tbl_sccharacteritems
|
|
ADD INDEX idx_sccharacteritem_scobjs (cl_sccharacteritem_scobjs_id)'
|
|
);
|
|
}
|
|
|
|
if (!sccharacters_index_exists($db, 'tbl_sccharacteritems', 'idx_sccharacteritem_scitemcustom')) {
|
|
$db->exec(
|
|
'ALTER TABLE tbl_sccharacteritems
|
|
ADD INDEX idx_sccharacteritem_scitemcustom (cl_sccharacteritem_scitemcustom_id)'
|
|
);
|
|
}
|
|
|
|
if (!sccharacters_index_exists($db, 'tbl_sccharacteritems', 'idx_sccharacteritem_character_sort')) {
|
|
$db->exec(
|
|
'ALTER TABLE tbl_sccharacteritems
|
|
ADD INDEX idx_sccharacteritem_character_sort (cl_sccharacteritem_character_id, cl_sccharacteritem_sort_order, cl_sccharacteritem_id)'
|
|
);
|
|
}
|
|
|
|
if (!sccharacters_foreign_key_exists($db, 'tbl_sccharacteritems', 'fk_sccharacteritem_character')) {
|
|
$db->exec(
|
|
'ALTER TABLE tbl_sccharacteritems
|
|
ADD CONSTRAINT fk_sccharacteritem_character FOREIGN KEY (cl_sccharacteritem_character_id)
|
|
REFERENCES tbl_sccharacters (cl_sccharacter_id)
|
|
ON DELETE CASCADE
|
|
ON UPDATE CASCADE'
|
|
);
|
|
}
|
|
|
|
if (!sccharacters_foreign_key_exists($db, 'tbl_sccharacteritems', 'fk_sccharacteritem_scobjs')) {
|
|
$db->exec(
|
|
'ALTER TABLE tbl_sccharacteritems
|
|
ADD CONSTRAINT fk_sccharacteritem_scobjs FOREIGN KEY (cl_sccharacteritem_scobjs_id)
|
|
REFERENCES tbl_scobjs (cl_scobjs_id)
|
|
ON DELETE SET NULL
|
|
ON UPDATE CASCADE'
|
|
);
|
|
}
|
|
|
|
if (!sccharacters_foreign_key_exists($db, 'tbl_sccharacteritems', 'fk_sccharacteritem_scitemcustom')) {
|
|
$db->exec(
|
|
'ALTER TABLE tbl_sccharacteritems
|
|
ADD CONSTRAINT fk_sccharacteritem_scitemcustom FOREIGN KEY (cl_sccharacteritem_scitemcustom_id)
|
|
REFERENCES tbl_scitemcustom (cl_scitemcustom_id)
|
|
ON DELETE SET NULL
|
|
ON UPDATE CASCADE'
|
|
);
|
|
}
|
|
|
|
$stmt_missing_tokens = $db->query(
|
|
"SELECT cl_sccharacter_id
|
|
FROM tbl_sccharacters
|
|
WHERE cl_sccharacter_share_token IS NULL
|
|
OR cl_sccharacter_share_token = ''"
|
|
);
|
|
|
|
$stmt_update_token = $db->prepare(
|
|
'UPDATE tbl_sccharacters
|
|
SET cl_sccharacter_share_token = :token
|
|
WHERE cl_sccharacter_id = :id'
|
|
);
|
|
|
|
foreach ($stmt_missing_tokens->fetchAll() as $row) {
|
|
$stmt_update_token->execute([
|
|
'token' => sccharacters_generate_share_token($db),
|
|
'id' => (int) $row['cl_sccharacter_id'],
|
|
]);
|
|
}
|
|
|
|
$bootstrapped = true;
|
|
}
|
|
|
|
function sccharacters_generate_share_token(PDO $db): string
|
|
{
|
|
do {
|
|
$token = bin2hex(random_bytes(16));
|
|
$stmt = $db->prepare(
|
|
'SELECT cl_sccharacter_id
|
|
FROM tbl_sccharacters
|
|
WHERE cl_sccharacter_share_token = :token
|
|
LIMIT 1'
|
|
);
|
|
$stmt->execute(['token' => $token]);
|
|
} while ($stmt->fetch());
|
|
|
|
return $token;
|
|
}
|
|
|
|
function sccharacters_reindex_character_items(PDO $db, int $character_id): void
|
|
{
|
|
if ($character_id <= 0) {
|
|
return;
|
|
}
|
|
|
|
$stmt = $db->prepare(
|
|
'SELECT cl_sccharacteritem_id
|
|
FROM tbl_sccharacteritems
|
|
WHERE cl_sccharacteritem_character_id = :character_id
|
|
ORDER BY
|
|
CASE WHEN cl_sccharacteritem_sort_order <= 0 THEN 0 ELSE 1 END,
|
|
cl_sccharacteritem_sort_order ASC,
|
|
cl_sccharacteritem_id ASC'
|
|
);
|
|
$stmt->execute(['character_id' => $character_id]);
|
|
$item_ids = array_map('intval', $stmt->fetchAll(PDO::FETCH_COLUMN));
|
|
|
|
if ($item_ids === []) {
|
|
return;
|
|
}
|
|
|
|
$stmt_update = $db->prepare(
|
|
'UPDATE tbl_sccharacteritems
|
|
SET cl_sccharacteritem_sort_order = :sort_order
|
|
WHERE cl_sccharacteritem_character_id = :character_id
|
|
AND cl_sccharacteritem_id = :item_id'
|
|
);
|
|
|
|
$db->beginTransaction();
|
|
|
|
try {
|
|
$position = 1;
|
|
foreach ($item_ids as $item_id) {
|
|
$stmt_update->execute([
|
|
'sort_order' => $position,
|
|
'character_id' => $character_id,
|
|
'item_id' => $item_id,
|
|
]);
|
|
$position++;
|
|
}
|
|
|
|
$db->commit();
|
|
} catch (Throwable $exception) {
|
|
if ($db->inTransaction()) {
|
|
$db->rollBack();
|
|
}
|
|
|
|
throw $exception;
|
|
}
|
|
}
|
|
|
|
function sccharacters_next_item_sort_order(PDO $db, int $character_id): int
|
|
{
|
|
if ($character_id <= 0) {
|
|
return 1;
|
|
}
|
|
|
|
sccharacters_reindex_character_items($db, $character_id);
|
|
|
|
$stmt = $db->prepare(
|
|
'SELECT COALESCE(MAX(cl_sccharacteritem_sort_order), 0)
|
|
FROM tbl_sccharacteritems
|
|
WHERE cl_sccharacteritem_character_id = :character_id'
|
|
);
|
|
$stmt->execute(['character_id' => $character_id]);
|
|
|
|
return ((int) $stmt->fetchColumn()) + 1;
|
|
}
|
|
|
|
|
|
function sccharacters_item_category_options(): array
|
|
{
|
|
return [
|
|
'weapon' => 'Armes',
|
|
'armor' => 'Armures',
|
|
'tools' => 'Outils',
|
|
'consumables' => 'Consommables',
|
|
'ammunition' => 'Munitions',
|
|
'attachments' => 'Accessoires',
|
|
'clothing' => 'Vêtements',
|
|
'cargo' => 'Cargo / Conteneurs',
|
|
'ship' => 'Composants / Véhicule',
|
|
'access' => 'Accès / Mobilier',
|
|
'misc' => 'Divers',
|
|
];
|
|
}
|
|
|
|
function sccharacters_default_category_order(): array
|
|
{
|
|
return array_keys(sccharacters_item_category_options());
|
|
}
|
|
|
|
function sccharacters_normalize_category_order(array $category_order): array
|
|
{
|
|
$known_categories = sccharacters_default_category_order();
|
|
$known_lookup = array_fill_keys($known_categories, true);
|
|
$normalized = [];
|
|
|
|
foreach ($category_order as $category_key) {
|
|
$category_key = trim((string) $category_key);
|
|
if ($category_key === '' || !isset($known_lookup[$category_key]) || isset($normalized[$category_key])) {
|
|
continue;
|
|
}
|
|
|
|
$normalized[$category_key] = $category_key;
|
|
}
|
|
|
|
foreach ($known_categories as $category_key) {
|
|
if (!isset($normalized[$category_key])) {
|
|
$normalized[$category_key] = $category_key;
|
|
}
|
|
}
|
|
|
|
return array_values($normalized);
|
|
}
|
|
|
|
function sccharacters_parse_category_order(?string $raw_value): array
|
|
{
|
|
$raw_value = trim((string) $raw_value);
|
|
if ($raw_value === '') {
|
|
return sccharacters_default_category_order();
|
|
}
|
|
|
|
$decoded = json_decode($raw_value, true);
|
|
if (!is_array($decoded)) {
|
|
return sccharacters_default_category_order();
|
|
}
|
|
|
|
return sccharacters_normalize_category_order($decoded);
|
|
}
|
|
|
|
function sccharacters_encode_category_order(array $category_order): string
|
|
{
|
|
$encoded = json_encode(
|
|
sccharacters_normalize_category_order($category_order),
|
|
JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES
|
|
);
|
|
|
|
return $encoded !== false
|
|
? $encoded
|
|
: json_encode(sccharacters_default_category_order(), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
|
}
|
|
|
|
function sccharacters_character_category_order(array $character_row): array
|
|
{
|
|
return sccharacters_parse_category_order((string) ($character_row['cl_sccharacter_category_order'] ?? ''));
|
|
}
|
|
|
|
function sccharacters_sort_items_by_category_order(array $items_by_category, array $category_order): array
|
|
{
|
|
if ($items_by_category === []) {
|
|
return [];
|
|
}
|
|
|
|
$sorted = [];
|
|
foreach (sccharacters_normalize_category_order($category_order) as $category_key) {
|
|
if (isset($items_by_category[$category_key])) {
|
|
$sorted[$category_key] = $items_by_category[$category_key];
|
|
}
|
|
}
|
|
|
|
foreach ($items_by_category as $category_key => $category_items) {
|
|
if (!isset($sorted[$category_key])) {
|
|
$sorted[$category_key] = $category_items;
|
|
}
|
|
}
|
|
|
|
return $sorted;
|
|
}
|
|
|
|
function sccharacters_save_character_category_order(PDO $db, int $character_id, array $category_order): void
|
|
{
|
|
if ($character_id <= 0) {
|
|
return;
|
|
}
|
|
|
|
$stmt = $db->prepare(
|
|
'UPDATE tbl_sccharacters
|
|
SET cl_sccharacter_category_order = :category_order
|
|
WHERE cl_sccharacter_id = :character_id'
|
|
);
|
|
$stmt->execute([
|
|
'category_order' => sccharacters_encode_category_order($category_order),
|
|
'character_id' => $character_id,
|
|
]);
|
|
}
|
|
|
|
function sccharacters_item_category_label(string $category): string
|
|
{
|
|
$options = sccharacters_item_category_options();
|
|
|
|
return $options[$category] ?? $options['misc'];
|
|
}
|
|
|
|
function sccharacters_item_category_slug(string $value): string
|
|
{
|
|
$value = trim($value);
|
|
if ($value == '') {
|
|
return '';
|
|
}
|
|
|
|
if (function_exists('iconv')) {
|
|
$converted = @iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $value);
|
|
if ($converted !== false) {
|
|
$value = $converted;
|
|
}
|
|
}
|
|
|
|
$value = strtolower($value);
|
|
$value = preg_replace('/[^a-z0-9]+/', '_', $value) ?? '';
|
|
|
|
return trim($value, '_');
|
|
}
|
|
|
|
function sccharacters_string_contains_any(string $haystack, array $needles): bool
|
|
{
|
|
foreach ($needles as $needle) {
|
|
if ($needle !== '' && strpos($haystack, $needle) !== false) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
function sccharacters_normalize_item_category(?string $value): string
|
|
{
|
|
$slug = sccharacters_item_category_slug((string) $value);
|
|
if ($slug === '' || in_array($slug, ['auto', 'automatic', 'automatique', 'default', 'defaut'], true)) {
|
|
return '';
|
|
}
|
|
|
|
$options = sccharacters_item_category_options();
|
|
if (isset($options[$slug])) {
|
|
return $slug;
|
|
}
|
|
|
|
$exact_aliases = [
|
|
'arme' => 'weapon',
|
|
'armes' => 'weapon',
|
|
'weapon' => 'weapon',
|
|
'weapons' => 'weapon',
|
|
'armure' => 'armor',
|
|
'armures' => 'armor',
|
|
'armor' => 'armor',
|
|
'armors' => 'armor',
|
|
'outil' => 'tools',
|
|
'outils' => 'tools',
|
|
'tool' => 'tools',
|
|
'tools' => 'tools',
|
|
'consommable' => 'consumables',
|
|
'consommables' => 'consumables',
|
|
'usable' => 'consumables',
|
|
'food' => 'consumables',
|
|
'drink' => 'consumables',
|
|
'munition' => 'ammunition',
|
|
'munitions' => 'ammunition',
|
|
'ammo' => 'ammunition',
|
|
'ammunition' => 'ammunition',
|
|
'accessoire' => 'attachments',
|
|
'accessoires' => 'attachments',
|
|
'attachment' => 'attachments',
|
|
'attachments' => 'attachments',
|
|
'vetement' => 'clothing',
|
|
'vetements' => 'clothing',
|
|
'clothing' => 'clothing',
|
|
'clothes' => 'clothing',
|
|
'cargo' => 'cargo',
|
|
'container' => 'cargo',
|
|
'conteneur' => 'cargo',
|
|
'conteneurs' => 'cargo',
|
|
'composant' => 'ship',
|
|
'composants' => 'ship',
|
|
'component' => 'ship',
|
|
'components' => 'ship',
|
|
'vaisseau' => 'ship',
|
|
'vaisseaux' => 'ship',
|
|
'vehicule' => 'ship',
|
|
'vehicules' => 'ship',
|
|
'acces' => 'access',
|
|
'access' => 'access',
|
|
'mobilier' => 'access',
|
|
'divers' => 'misc',
|
|
'misc' => 'misc',
|
|
'autre' => 'misc',
|
|
'autres' => 'misc',
|
|
'other' => 'misc',
|
|
];
|
|
|
|
if (isset($exact_aliases[$slug])) {
|
|
return $exact_aliases[$slug];
|
|
}
|
|
|
|
$contains_aliases = [
|
|
'weapon' => ['arme', 'weapon', 'pistol', 'rifle', 'shotgun', 'sniper', 'knife', 'blade'],
|
|
'armor' => ['armure', 'armor', 'plating'],
|
|
'tools' => ['outil', 'tool', 'tractor', 'mining', 'multitool', 'multi_tool', 'gadget'],
|
|
'consumables' => ['consommable', 'consumable', 'usable', 'food', 'drink', 'med', 'medical', 'heal'],
|
|
'ammunition' => ['munition', 'ammo', 'ammunition', 'magazine', 'grenade', 'rocket'],
|
|
'attachments' => ['attachment', 'accessoire', 'scope', 'optic', 'silencer', 'sight', 'barrel'],
|
|
'clothing' => ['clothing', 'vetement', 'apparel', 'outfit', 'char_clothing', 'char_head'],
|
|
'cargo' => ['cargo', 'container', 'crate', 'box'],
|
|
'ship' => ['component', 'composant', 'vaisseau', 'vehicule', 'thruster', 'quantum', 'powerplant', 'cooler', 'radar', 'sensor', 'shield', 'turret', 'missilelauncher', 'docking', 'flightcontroller', 'fueltank', 'fuelintake', 'aimodule'],
|
|
'access' => ['door', 'seat', 'access', 'display', 'controlpanel', 'dashboard', 'mobilier'],
|
|
];
|
|
|
|
foreach ($contains_aliases as $category => $needles) {
|
|
if (sccharacters_string_contains_any($slug, $needles)) {
|
|
return $category;
|
|
}
|
|
}
|
|
|
|
return '';
|
|
}
|
|
|
|
function sccharacters_guess_item_category(?string $type, ?string $subtype = null): string
|
|
{
|
|
$haystack = strtolower(trim(((string) $type) . ' ' . ((string) $subtype)));
|
|
$slug = sccharacters_item_category_slug($haystack);
|
|
|
|
if ($slug === '') {
|
|
return 'misc';
|
|
}
|
|
|
|
if (sccharacters_string_contains_any($slug, ['char_clothing', 'char_head', 'clothing', 'apparel', 'outfit', 'hat', 'beard', 'piercing'])) {
|
|
return 'clothing';
|
|
}
|
|
|
|
if (sccharacters_string_contains_any($slug, ['weaponattachment', 'attachment', 'scope', 'optic', 'sight', 'silencer', 'barrel', 'mag_mount'])) {
|
|
return 'attachments';
|
|
}
|
|
|
|
if (sccharacters_string_contains_any($slug, ['missile', 'ammo', 'ammunition', 'magazine', 'rocket'])) {
|
|
return 'ammunition';
|
|
}
|
|
|
|
if (sccharacters_string_contains_any($slug, ['armor', 'armure'])) {
|
|
return 'armor';
|
|
}
|
|
|
|
if (sccharacters_string_contains_any($slug, ['weapon', 'gun', 'rifle', 'pistol', 'shotgun', 'sniper', 'knife', 'blade'])) {
|
|
return 'weapon';
|
|
}
|
|
|
|
if (sccharacters_string_contains_any($slug, ['usable', 'consumable', 'food', 'drink', 'fps_consumable', 'med', 'medical'])) {
|
|
return 'consumables';
|
|
}
|
|
|
|
if (sccharacters_string_contains_any($slug, ['tool', 'outil', 'mining', 'tractor', 'gadget', 'utility'])) {
|
|
return 'tools';
|
|
}
|
|
|
|
if (sccharacters_string_contains_any($slug, ['cargo', 'container', 'crate', 'box'])) {
|
|
return 'cargo';
|
|
}
|
|
|
|
if (sccharacters_string_contains_any($slug, ['door', 'seat', 'access', 'display', 'controlpanel', 'dashboard', 'shopdisplay', 'player'])) {
|
|
return 'access';
|
|
}
|
|
|
|
if (sccharacters_string_contains_any($slug, ['thruster', 'quantum', 'powerplant', 'cooler', 'radar', 'sensor', 'shield', 'turret', 'flightcontroller', 'fueltank', 'fuelintake', 'a_module', 'aimodule', 'docking', 'attachedpart'])) {
|
|
return 'ship';
|
|
}
|
|
|
|
return 'misc';
|
|
}
|
|
|
|
function sccharacters_resolve_item_category(?string $storedValue, ?string $type, ?string $subtype = null): string
|
|
{
|
|
$normalized = sccharacters_normalize_item_category($storedValue);
|
|
if ($normalized !== '') {
|
|
return $normalized;
|
|
}
|
|
|
|
return sccharacters_guess_item_category($type, $subtype);
|
|
}
|