[Wiki] Оптимизация Actions (#3538)

This commit is contained in:
Pok 2026-03-19 17:20:23 +02:00 • committed by GitHub
parent a547342d19
commit 6ba193848c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 348 additions and 241 deletions

View file

@ -18,264 +18,388 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout Master
uses: actions/checkout@v4.2.2
- name: Checkout Master
uses: actions/checkout@v4.2.2
with:
fetch-depth: 0
- name: Setup Submodule
run: |
git submodule update --init --recursive
- name: Detect changed paths
id: changes
uses: dorny/paths-filter@v3
with:
filters: |
general:
- '.github/workflows/update-wiki.yml'
- 'Content.Shared/**'
- 'Content.Server/**'
- 'Content.Client/**'
- 'Resources/**'
- 'RobustToolbox/**'
- name: Pull Engine Updates
uses: space-wizards/submodule-dependency@v0.1.5
prototypes:
- '.github/workflows/update-wiki.yml'
- 'Resources/Prototypes/**'
- name: Update Engine Submodules
run: |
cd RobustToolbox/
git submodule update --init --recursive
- name: Setup Submodule
run: |
git submodule update --init --recursive
- name: Setup .NET Core
uses: actions/setup-dotnet@v4.1.0
with:
dotnet-version: 9.0.x
- name: Pull Engine Updates
uses: space-wizards/submodule-dependency@v0.1.5
- name: Install Dependencies
run: dotnet restore
- name: Update Engine Submodules
run: |
cd RobustToolbox/
git submodule update --init --recursive
- name: Build Project
run: dotnet build --configuration Release --no-restore /p:WarningsAsErrors=nullable /m
- name: Setup .NET Core
uses: actions/setup-dotnet@v4.1.0
with:
dotnet-version: 9.0.x
- name: Generate JSON blobs for prototypes
run: dotnet ./bin/Content.Server/Content.Server.dll --cvar autogen.destination_file=prototypes.json
continue-on-error: true
- name: Install Dependencies
run: dotnet restore
# Проходит по всем JSON-файлам в директории BASE и загружает каждый файл как страницу в MediaWiki.
# Имя страницы формируется из относительного пути к файлу.
- name: Upload JSON files to wiki
shell: bash
run: |
set -euo pipefail
- name: Build Project
run: dotnet build --configuration Release --no-restore /p:WarningsAsErrors=nullable /m
BASE="./bin/Content.Server/data"
ROOT="${{ secrets.WIKI_PAGE_ROOT }}"
MODULE_ROOT="Модуль:IanComradeBot"
API="${{ secrets.WIKI_ROOT_URL }}/api.php"
USER="${{ secrets.WIKI_BOT_USER }}"
PASS="${{ secrets.WIKI_BOT_PASS }}"
- name: Generate JSON blobs for prototypes
run: dotnet ./bin/Content.Server/Content.Server.dll --cvar autogen.destination_file=prototypes.json
continue-on-error: true
API="$(printf "%s" "$API" | tr -d '\r\n' | sed 's/[[:space:]]*$//')"
USER="$(printf "%s" "$USER" | tr -d '\r\n')"
PASS="$(printf "%s" "$PASS" | tr -d '\r\n')"
ROOT="$(printf "%s" "$ROOT" | tr -d '\r\n' | sed 's/[[:space:]]*$//')"
# Проходит по всем JSON-файлам в директории BASE и загружает каждый файл как страницу в MediaWiki.
# Имя страницы формируется из относительного пути к файлу.
- name: Upload JSON files to wiki
if: ${{ github.event_name == 'workflow_dispatch' || steps.changes.outputs.general == 'true' }}
continue-on-error: true
shell: bash
run: |
set -euo pipefail
cookiejar="$(mktemp)"
trap 'rm -f "$cookiejar"' EXIT
BASE="./bin/Content.Server/data"
ROOT="${{ secrets.WIKI_PAGE_ROOT }}"
MODULE_ROOT="Модуль:IanComradeBot"
API="${{ secrets.WIKI_ROOT_URL }}/api.php"
USER="${{ secrets.WIKI_BOT_USER }}"
PASS="${{ secrets.WIKI_BOT_PASS }}"
login_token=$(curl -sS -c "$cookiejar" --data "action=query&meta=tokens&type=login&format=json" "$API" | jq -r '.query.tokens.logintoken')
curl -sS -c "$cookiejar" -b "$cookiejar" \
--data-urlencode "action=login" \
--data-urlencode "lgname=$USER" \
--data-urlencode "lgpassword=$PASS" \
--data-urlencode "lgtoken=$login_token" \
--data-urlencode "format=json" \
"$API" > /dev/null
API="$(printf "%s" "$API" | tr -d '\r\n' | sed 's/[[:space:]]*$//')"
USER="$(printf "%s" "$USER" | tr -d '\r\n')"
PASS="$(printf "%s" "$PASS" | tr -d '\r\n')"
ROOT="$(printf "%s" "$ROOT" | tr -d '\r\n' | sed 's/[[:space:]]*$//')"
edit_page_file() {
local title="$1"
local summary="$2"
local textfile="$3"
local token="$4"
cookiejar="$(mktemp)"
trap 'rm -f "$cookiejar"' EXIT
curl -sS -b "$cookiejar" \
--data-urlencode "action=edit" \
--data-urlencode "title=$title" \
--data-urlencode "summary=$summary" \
--data-urlencode "text@${textfile}" \
--data-urlencode "token=$token" \
--data-urlencode "bot=true" \
--data-urlencode "minor=true" \
login_token=$(curl -sS -c "$cookiejar" \
--data "action=query&meta=tokens&type=login&format=json" "$API" | jq -r '.query.tokens.logintoken')
curl -sS -c "$cookiejar" -b "$cookiejar" \
--data-urlencode "action=login" \
--data-urlencode "lgname=$USER" \
--data-urlencode "lgpassword=$PASS" \
--data-urlencode "lgtoken=$login_token" \
--data-urlencode "format=json" \
"$API" | jq -r '.'
}
"$API" > /dev/null
edit_page() {
local title="$1"
local summary="$2"
local text="$3"
local token="$4"
token=$(curl -sS -b "$cookiejar" \
--data "action=query&meta=tokens&format=json" "$API" | jq -r '.query.tokens.csrftoken')
curl -sS -b "$cookiejar" \
--data-urlencode "action=edit" \
--data-urlencode "title=$title" \
--data-urlencode "summary=$summary" \
--data-urlencode "text=$text" \
--data-urlencode "token=$token" \
--data-urlencode "bot=true" \
--data-urlencode "minor=true" \
edit_page_file() {
local title="$1"
local summary="$2"
local textfile="$3"
local token="$4"
curl -sS -b "$cookiejar" \
--data-urlencode "action=edit" \
--data-urlencode "title=$title" \
--data-urlencode "summary=$summary" \
--data-urlencode "text@${textfile}" \
--data-urlencode "token=$token" \
--data-urlencode "bot=true" \
--data-urlencode "minor=true" \
--data-urlencode "format=json" \
"$API" | jq -r '.edit.result // "null"'
}
edit_page() {
local title="$1"
local summary="$2"
local text="$3"
local token="$4"
curl -sS -b "$cookiejar" \
--data-urlencode "action=edit" \
--data-urlencode "title=$title" \
--data-urlencode "summary=$summary" \
--data-urlencode "text=$text" \
--data-urlencode "token=$token" \
--data-urlencode "bot=true" \
--data-urlencode "minor=true" \
--data-urlencode "format=json" \
"$API" | jq -r '.edit.result // "null"'
}
query_page_linecounts() {
local -n titles_ref=$1
local -n linecounts_ref=$2
linecounts_ref=()
(( ${#titles_ref[@]} == 0 )) && return 0
local titles
titles=$(printf '%s|' "${titles_ref[@]}")
titles="${titles%|}"
local resp
resp=$(curl -sS -b "$cookiejar" \
--data-urlencode "action=query" \
--data-urlencode "format=json" \
--data-urlencode "formatversion=2" \
--data-urlencode "prop=revisions" \
--data-urlencode "rvprop=content" \
--data-urlencode "rvslots=main" \
--data-urlencode "titles=$titles" \
"$API")
while IFS=$'\t' read -r title linecount; do
[[ -z "${title:-}" ]] && continue
[[ -z "${linecount:-}" ]] && continue
linecounts_ref["$title"]="$linecount"
done < <(
jq -r '
.query.pages[]
| [.title, ((.revisions[0].slots.main.content? // "")| split("\n")| length)]
| @tsv
' <<< "$resp"
)
}
count_lines() {
awk 'END { print NR }'
}
files=()
while IFS= read -r -d '' file; do
files+=("$file")
done < <(find "$BASE" -type f -name '*.json' -print0)
batch_size=50
for ((i=0; i<${#files[@]}; i+=batch_size)); do
batch_files=("${files[@]:i:batch_size}")
declare -a json_titles=()
declare -a module_titles=()
for file in "${batch_files[@]}"; do
rel="${file#$BASE/}"
rel="$(printf "%s" "$rel" | tr -d '\r\n' | sed 's/:/_/g')"
json_titles+=("$ROOT/$rel")
module_titles+=("$MODULE_ROOT/$rel/data")
done
declare -A json_lines=()
declare -A module_lines=()
query_page_linecounts json_titles json_lines
query_page_linecounts module_titles module_lines
for file in "${batch_files[@]}"; do
rel="${file#$BASE/}"
rel="$(printf "%s" "$rel" | tr -d '\r\n' | sed 's/:/_/g')"
json_title="$ROOT/$rel"
module_title="$MODULE_ROOT/$rel/data"
echo "Processing $rel → $json_title"
local_lines=$(awk 'END { print NR }' "$file")
remote_lines="${json_lines[$json_title]:-}"
if [[ -n "$remote_lines" && "$remote_lines" == "$local_lines" ]]; then
echo "Skipping unchanged page: $json_title"
else
echo "Uploading $rel → $json_title"
edit_page_file "$json_title" "Update $rel via GitHub Actions" "$file" "$token"
fi
lua_content=$'local loader = require("Module:JsonLoader")\nreturn loader.getFromTitle("'"$json_title"'")'
local_lines=$(printf '%s' "$lua_content" | awk 'END { print NR }')
remote_lines="${module_lines[$module_title]:-}"
if [[ -n "$remote_lines" && "$remote_lines" == "$local_lines" ]]; then
echo "Skipping unchanged module: $module_title"
else
echo "Creating/updating module → $module_title"
edit_page "$module_title" "Auto-create loader module for $rel" "$lua_content" "$token"
fi
done
done
# Создает страницы по каждому id подходящей сущности.
# Имя страницы формируется из имени сущности в entity_name.json.
- name: Create entity pages
if: ${{ github.event_name == 'workflow_dispatch' || steps.changes.outputs.prototypes == 'true' }}
continue-on-error: true
shell: bash
run: |
set -euo pipefail
FILE="./bin/Content.Server/data/entity_name.json"
API="${{ secrets.WIKI_ROOT_URL }}/api.php"
USER="${{ secrets.WIKI_BOT_USER }}"
PASS="${{ secrets.WIKI_BOT_PASS }}"
API="$(printf "%s" "$API" | tr -d '\r\n')"
USER="$(printf "%s" "$USER" | tr -d '\r\n')"
PASS="$(printf "%s" "$PASS" | tr -d '\r\n')"
cookiejar="$(mktemp)"
trap 'rm -f "$cookiejar"' EXIT
login_token=$(curl -sS -c "$cookiejar" \
--data "action=query&meta=tokens&type=login&format=json" "$API" | jq -r '.query.tokens.logintoken')
curl -sS -c "$cookiejar" -b "$cookiejar" \
--data-urlencode "action=login" \
--data-urlencode "lgname=$USER" \
--data-urlencode "lgpassword=$PASS" \
--data-urlencode "lgtoken=$login_token" \
--data-urlencode "format=json" \
"$API" | jq -r '.'
}
"$API" > /dev/null
find "$BASE" -type f -name '*.json' | while IFS= read -r file; do
rel="${file#$BASE/}"
rel="$(printf "%s" "$rel" | tr -d '\r\n' | sed 's/:/_/g')"
json_title="$ROOT/$rel"
echo "Uploading $rel → $json_title"
token=$(curl -sS -b "$cookiejar" \
--data "action=query&meta=tokens&format=json" "$API" | jq -r '.query.tokens.csrftoken')
token=$(curl -sS -b "$cookiejar" --data "action=query&meta=tokens&format=json" "$API" | jq -r '.query.tokens.csrftoken')
mapfile -t pages < <(
jq -r '
to_entries[]
| "\(.key)|\(.value | if type == "array" then .[0] else . end)"
' "$FILE" | grep -v '|$'
)
# файл JSON
edit_page_file "$json_title" "Update $rel via GitHub Actions" "$file" "$token"
batch_size=50
module_title="$MODULE_ROOT/$rel/data"
for ((i=0; i<${#pages[@]}; i+=batch_size)); do
batch=("${pages[@]:i:batch_size}")
# файл для lua-контента
lua_content=$'local loader = require("Module:JsonLoader")\nreturn loader.getFromTitle("'"$json_title"'")'
echo "Creating/updating module → $module_title"
titles=$(printf '%s\n' "${batch[@]}" | cut -d'|' -f1 | paste -sd'|' -)
edit_page "$module_title" "Auto-create loader module for $rel" "$lua_content" "$token"
done
existing_titles=$(
curl -sS -b "$cookiejar" \
--data-urlencode "action=query" \
--data-urlencode "format=json" \
--data-urlencode "titles=$titles" \
"$API" | jq -r '
.query.pages[]
| select(.missing != true)
| .title
'
)
# Создает страницы по каждому id подходящей сущности.
# Имя страницы формируется из имени сущности в entity_name.json.
- name: Create entity pages
shell: bash
run: |
set -euo pipefail
while IFS='|' read -r name id; do
[[ -z "${name:-}" ]] && continue
[[ -z "${id:-}" ]] && continue
FILE="./bin/Content.Server/data/entity_name.json"
API="${{ secrets.WIKI_ROOT_URL }}/api.php"
USER="${{ secrets.WIKI_BOT_USER }}"
PASS="${{ secrets.WIKI_BOT_PASS }}"
if grep -Fxq "$name" <<< "$existing_titles"; then
echo "Skipping existing page: $name"
continue
fi
API="$(printf "%s" "$API" | tr -d '\r\n')"
USER="$(printf "%s" "$USER" | tr -d '\r\n')"
PASS="$(printf "%s" "$PASS" | tr -d '\r\n')"
content="{{сущность|$id}}"
echo "Creating page: $name → $id"
cookiejar="$(mktemp)"
trap 'rm -f "$cookiejar"' EXIT
curl -sS -b "$cookiejar" \
--data-urlencode "action=edit" \
--data-urlencode "createonly=true" \
--data-urlencode "title=$name" \
--data-urlencode "text=$content" \
--data-urlencode "summary=Create $id via GitHub Actions" \
--data-urlencode "token=$token" \
--data-urlencode "bot=true" \
--data-urlencode "minor=true" \
--data-urlencode "format=json" \
"$API" | jq -r '.edit.result // "null"' || true
done < <(printf '%s\n' "${batch[@]}")
done
# Login
login_token=$(curl -sS -c "$cookiejar" \
--data "action=query&meta=tokens&type=login&format=json" "$API" | jq -r '.query.tokens.logintoken')
# Добавляет предупреждение дубликатам страниц сущностей.
- name: Duplicates entity pages
if: ${{ github.event_name == 'workflow_dispatch' || steps.changes.outputs.prototypes == 'true' }}
continue-on-error: true
shell: bash
run: |
set -euo pipefail
curl -sS -c "$cookiejar" -b "$cookiejar" \
--data-urlencode "action=login" \
--data-urlencode "lgname=$USER" \
--data-urlencode "lgpassword=$PASS" \
--data-urlencode "lgtoken=$login_token" \
--data-urlencode "format=json" \
"$API" > /dev/null
FILE="./bin/Content.Server/data/entity_name_wiki.json"
API="${{ secrets.WIKI_ROOT_URL }}/api.php"
USER="${{ secrets.WIKI_BOT_USER }}"
PASS="${{ secrets.WIKI_BOT_PASS }}"
# CSRF
token=$(curl -sS -b "$cookiejar" \
--data "action=query&meta=tokens&format=json" "$API" | jq -r '.query.tokens.csrftoken')
API="$(printf "%s" "$API" | tr -d '\r\n')"
USER="$(printf "%s" "$USER" | tr -d '\r\n')"
PASS="$(printf "%s" "$PASS" | tr -d '\r\n')"
# JSON
jq -r 'to_entries[] | "\(.key)|\(.value | if type == "array" then .[0] else . end)"' "$FILE" |
grep -v '|$' |
xargs -r -d '\n' -P 1 -I{} bash -c '
set -uo pipefail
name_id="$1"
api="$2"
token="$3"
cookiejar="$4"
cookiejar="$(mktemp)"
trap 'rm -f "$cookiejar"' EXIT
warning="{{сущность/infobox|тип=дубликат}}"
IFS="|" read -r name id <<< "$name_id"
login_token=$(curl -sS -c "$cookiejar" \
--data "action=query&meta=tokens&type=login&format=json" "$API" | jq -r '.query.tokens.logintoken')
if [[ -z "$id" ]]; then
exit 0
fi
content="{{сущность|$id}}"
echo "Creating page: $name → $id"
curl -sS -b "$cookiejar" \
--data-urlencode "action=edit" \
--data-urlencode "createonly=true" \
--data-urlencode "title=$name" \
--data-urlencode "text=$content" \
--data-urlencode "summary=Create $id via GitHub Actions" \
--data-urlencode "token=$token" \
--data-urlencode "bot=true" \
--data-urlencode "minor=true" \
curl -sS -c "$cookiejar" -b "$cookiejar" \
--data-urlencode "action=login" \
--data-urlencode "lgname=$USER" \
--data-urlencode "lgpassword=$PASS" \
--data-urlencode "lgtoken=$login_token" \
--data-urlencode "format=json" \
"$api" | jq -r ".edit.result // \"null\"" || true
' _ "{}" "$API" "$token" "$cookiejar"
"$API" > /dev/null
# Добавляет предупреждение дубликатам страниц сущностей.
- name: Duplicates entity pages
shell: bash
run: |
set -euo pipefail
token=$(curl -sS -b "$cookiejar" \
--data "action=query&meta=tokens&format=json" "$API" | jq -r '.query.tokens.csrftoken')
FILE="./bin/Content.Server/data/entity_name_wiki.json"
API="${{ secrets.WIKI_ROOT_URL }}/api.php"
USER="${{ secrets.WIKI_BOT_USER }}"
PASS="${{ secrets.WIKI_BOT_PASS }}"
jq -r '.[]' "$FILE" |
xargs -r -d '\n' -P 1 -I{} bash -c '
set -uo pipefail
title="$1"
api="$2"
token="$3"
cookiejar="$4"
warning="$5"
API="$(printf "%s" "$API" | tr -d '\r\n')"
USER="$(printf "%s" "$USER" | tr -d '\r\n')"
PASS="$(printf "%s" "$PASS" | tr -d '\r\n')"
if [[ -z "$title" ]]; then
exit 0
fi
cookiejar="$(mktemp)"
trap 'rm -f "$cookiejar"' EXIT
warning="{{сущность/infobox|тип=дубликат}}"
page_json=$(curl -sS -b "$cookiejar" \
--data-urlencode "action=query" \
--data-urlencode "prop=revisions" \
--data-urlencode "rvprop=content" \
--data-urlencode "rvslots=main" \
--data-urlencode "format=json" \
--data-urlencode "titles=$title" \
"$api")
# Login
login_token=$(curl -sS -c "$cookiejar" \
--data "action=query&meta=tokens&type=login&format=json" "$API" | jq -r '.query.tokens.logintoken')
content=$(printf "%s" "$page_json" | jq -r \
".query.pages | to_entries[0].value.revisions[0].slots.main[\"*\"] // \"\"")
curl -sS -c "$cookiejar" -b "$cookiejar" \
--data-urlencode "action=login" \
--data-urlencode "lgname=$USER" \
--data-urlencode "lgpassword=$PASS" \
--data-urlencode "lgtoken=$login_token" \
--data-urlencode "format=json" \
"$API" > /dev/null
if printf "%s" "$content" | grep -q "${warning%}}"; then
exit 0
fi
# CSRF
token=$(curl -sS -b "$cookiejar" \
--data "action=query&meta=tokens&format=json" "$API" | jq -r '.query.tokens.csrftoken')
echo "Prepending Infobox to: $title"
jq -r '.[]' "$FILE" |
xargs -r -d '\n' -P 1 -I{} bash -c '
set -uo pipefail
title="$1"
api="$2"
token="$3"
cookiejar="$4"
warning="$5"
if [[ -z "$title" ]]; then
exit 0
fi
page_json=$(curl -sS -b "$cookiejar" \
--data-urlencode "action=query" \
--data-urlencode "prop=revisions" \
--data-urlencode "rvprop=content" \
--data-urlencode "rvslots=main" \
--data-urlencode "format=json" \
--data-urlencode "titles=$title" \
"$api")
content=$(printf "%s" "$page_json" | jq -r \
".query.pages | to_entries[0].value.revisions[0].slots.main[\"*\"] // \"\"")
if printf "%s" "$content" | grep -q "${warning%}}"; then
exit 0
fi
echo "Prepending Infobox to: $title"
curl -sS -b "$cookiejar" \
--data-urlencode "action=edit" \
--data-urlencode "title=$title" \
--data-urlencode "prependtext=${warning}" \
--data-urlencode "summary=Add Warning via GitHub Actions" \
--data-urlencode "token=$token" \
--data-urlencode "bot=true" \
--data-urlencode "minor=true" \
--data-urlencode "format=json" \
"$api" | jq -r ".edit.result // \"null\"" || true
' _ "{}" "$API" "$token" "$cookiejar" "$warning"
curl -sS -b "$cookiejar" \
--data-urlencode "action=edit" \
--data-urlencode "title=$title" \
--data-urlencode "prependtext=${warning}" \
--data-urlencode "summary=Add Warning via GitHub Actions" \
--data-urlencode "token=$token" \
--data-urlencode "bot=true" \
--data-urlencode "minor=true" \
--data-urlencode "format=json" \
"$api" | jq -r ".edit.result // \"null\"" || true
' _ "{}" "$API" "$token" "$cookiejar" "$warning"

View file

@ -83,7 +83,7 @@ public static class ComponentJsonGenerator
};
res.UserData.CreateDir(destRoot);
var fileName = compName + ".json";
var fileName = compName.ToLower() + ".json";
var file = res.UserData.OpenWriteText(destRoot / fileName);
file.Write(JsonSerializer.Serialize(outObj, serializeOptions));
file.Flush();

View file

@ -30,7 +30,7 @@ public sealed class EntityEntry
Id = proto.ID;
Name = TextTools.CapitalizeString(TextTools.GetDisplayName(proto, prototypeManager, loc));
Description = proto.Description;
Suffix = TextTools.GetEditorSuffix(proto, prototypeManager, loc) ?? "";
Suffix = proto.EditorSuffix ?? "";
Label = proto.Components.Values
.Select(x => x.Component)

View file

@ -3,7 +3,6 @@ using System.Linq;
using System.Text.Encodings.Web;
using System.Text.Json;
using Content.Shared.Labels.Components;
using Robust.Shared.Localization;
using Robust.Shared.Physics;
using Robust.Shared.Prototypes;
@ -44,7 +43,7 @@ public static class EntityNameDuplicatesJsonGenerator
var label = GetLabel(p);
var rawSuffix = TextTools.GetEditorSuffix(p, prototypeManager, loc);
var rawSuffix = p.EditorSuffix;
var suffix = string.Empty;
if (!string.IsNullOrWhiteSpace(rawSuffix))
{

View file

@ -70,8 +70,7 @@ public static class PrototypeJsonGenerator
var kindName = proto.TryGetKindFrom(kind, out var actualKindName)
? actualKindName
: kind.Name;
kindName = TextTools.CapitalizeString(kindName);
var fileName = kindName + ".json";
var fileName = kindName.ToLower() + ".json";
var file = res.UserData.OpenWriteText(destRoot / fileName);
file.Write(JsonSerializer.Serialize(outObj, serializeOptions));
file.Flush();

View file

@ -1,4 +1,3 @@
using Robust.Shared.Localization;
using Robust.Shared.Prototypes;
namespace Content.Server.Corvax.GuideGenerator;
@ -22,29 +21,15 @@ public sealed class TextTools
public static string GetDisplayName(EntityPrototype proto, IPrototypeManager prototypeManager, ILocalizationManager loc)
{
foreach (var (id, parentProto) in prototypeManager.EnumerateAllParents<EntityPrototype>(proto.ID, includeSelf: true))
foreach (var (_, parentProto) in prototypeManager.EnumerateAllParents<EntityPrototype>(proto.ID, includeSelf: true))
{
if (parentProto == null)
continue;
var name = parentProto?.Name ?? loc.GetEntityData(id).Name;
var name = parentProto.Name;
if (!string.IsNullOrEmpty(name))
return name;
}
return proto.Name;
}
public static string? GetEditorSuffix(EntityPrototype proto, IPrototypeManager prototypeManager, ILocalizationManager loc)
{
foreach (var (id, parentProto) in prototypeManager.EnumerateAllParents<EntityPrototype>(proto.ID, includeSelf: true))
{
if (parentProto == null)
continue;
var suffix = parentProto?.EditorSuffix ?? loc.GetEntityData(id).Suffix;
if (!string.IsNullOrEmpty(suffix))
return suffix;
}
return proto.EditorSuffix;
}
}