map: RTTI class inventory (1924 types, engine=Mars); reseed board with real targets
This commit is contained in:
parent
9ad30bffce
commit
bf55a66cb5
7 changed files with 3768 additions and 9 deletions
|
|
@ -5,13 +5,18 @@ Status flow: `backlog → in-progress → mapped → verified` (or `blocked`).
|
||||||
|
|
||||||
| Target | Type | Status | Conf | Coverage | Updated | Notes |
|
| Target | Type | Status | Conf | Coverage | Updated | Notes |
|
||||||
|---|---|---|---|---|---|---|
|
|---|---|---|---|---|---|---|
|
||||||
| _RTTI class inventory_ | meta | backlog | — | — | 2026-09-07 | pull full class/vftable list from ReVa; seeds object-model rows |
|
| RTTI class inventory | meta | mapped | high | 100% | 2026-09-07 | `findings/objects/00-inventory.md` — 1924 types, engine=Mars |
|
||||||
| entry point @0x925794 | control-flow | backlog | — | 0% | 2026-09-07 | WinMain → init → main loop |
|
| `.gob` format | subsystem | mapped | high | 100% | 2026-09-07 | renamed uncompressed ZIP (community-known) |
|
||||||
| main loop / tick dispatch | control-flow | backlog | — | 0% | 2026-09-07 | how subsystems are pumped each frame/turn |
|
| `Mars::AppStartup` (entry) | control-flow | backlog | — | 0% | 2026-09-07 | bootstrap → main loop |
|
||||||
| D3D9 device init | subsystem | backlog | — | 0% | 2026-09-07 | Direct3DCreate9 → CreateDevice; renderer anchor |
|
| main loop / tick dispatch | control-flow | backlog | — | 0% | 2026-09-07 | how subsystems are pumped per frame/turn |
|
||||||
| empire/player object | object | backlog | — | 0% | 2026-09-07 | cross-ref save-editor structs |
|
| `Game::ClientPlayer` / `AIPlayer` | object | backlog | — | 0% | 2026-09-07 | the empire object (SOTS calls it "player"); root of game state |
|
||||||
| star system object | object | backlog | — | 0% | 2026-09-07 | cross-ref save-editor structs |
|
| `Game::StarSystem` | object | backlog | — | 0% | 2026-09-07 | + `PlayerView::StarSystem`; cross-ref save structs |
|
||||||
| fleet / ship object | object | backlog | — | 0% | 2026-09-07 | cross-ref save-editor structs |
|
| `Game::Planet` / `DOPlanet` | object | backlog | — | 0% | 2026-09-07 | colony/economy data |
|
||||||
| tech tree object | object | backlog | — | 0% | 2026-09-07 | cross-ref save-editor structs |
|
| `Game::ShipDesignDef` / `DesignList` | object | backlog | — | 0% | 2026-09-07 | ship design model |
|
||||||
|
| `Game::FleetLayout` | object | backlog | — | 0% | 2026-09-07 | fleet composition |
|
||||||
|
| Mars entity chain | object | backlog | — | 0% | 2026-09-07 | EntityBase→PhysicalEntity→TargetableEntity→Actor |
|
||||||
|
| `Game::GameCombatSim` + `CombatCommand*` | subsystem | backlog | — | 0% | 2026-09-07 | tactical combat (~40 command types) |
|
||||||
|
| D3D9 device init | subsystem | backlog | — | 0% | 2026-09-07 | `Mars::DrawDevice`/`Camera` → Direct3DCreate9/CreateDevice |
|
||||||
|
| `Mars::Buffer::gobio` | subsystem | backlog | — | 0% | 2026-09-07 | .gob I/O; anchors the verify/ parser |
|
||||||
|
| serializable-types vs save structs | verify | backlog | — | 0% | 2026-09-07 | cross-ref `serializable-types.txt` with community save editors |
|
||||||
| battle-load path | subsystem | backlog | — | 0% | 2026-09-07 | primary bug (many-core slowdown); LAA already on |
|
| battle-load path | subsystem | backlog | — | 0% | 2026-09-07 | primary bug (many-core slowdown); LAA already on |
|
||||||
| .gob format | subsystem | mapped | high | 100% | 2026-09-07 | renamed uncompressed ZIP (community-known); parser target for verify/ |
|
|
||||||
|
|
|
||||||
|
|
@ -33,3 +33,14 @@ extracted via innoextract to `/srv/re-lab/sots-game/`.
|
||||||
- D3D9 device init is a clean, well-anchored first renderer target.
|
- D3D9 device init is a clean, well-anchored first renderer target.
|
||||||
|
|
||||||
_Fingerprint captured 2026-09-07 via objdump on CT111._
|
_Fingerprint captured 2026-09-07 via objdump on CT111._
|
||||||
|
|
||||||
|
## Update — RTTI reality + scale (2026-09-07)
|
||||||
|
- **RTTI is fully present: 1,924 type descriptors**, **41,411 functions**. RTTI was *not*
|
||||||
|
stripped. Full class inventory extracted → `findings/objects/00-inventory.md`.
|
||||||
|
- **Engine namespace is `Mars`** (SOTS1's engine; SOTS2 later used *Mercury*); game logic in
|
||||||
|
`Game`. 194 Mars (engine) classes, 1,404 Game classes, 179 serializable types.
|
||||||
|
- Ghidra's headless RTTI analyzer ran but produced 0 `SymbolType.CLASS` namespaces on our query
|
||||||
|
— a ReVa/Ghidra tooling detail to resolve (re-run/point the right analyzer); the RTTI data
|
||||||
|
itself is intact and was read straight from the binary.
|
||||||
|
- Consequence: the object model (goal #1) is strongly de-risked — named classes + hierarchy hints
|
||||||
|
come free from RTTI; `serializable-types.txt` maps closely to the save data model.
|
||||||
|
|
|
||||||
42
findings/objects/00-inventory.md
Normal file
42
findings/objects/00-inventory.md
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
# Object-model inventory (from RTTI)
|
||||||
|
|
||||||
|
The binary retains **full MSVC RTTI — 1,924 type descriptors** across **41,411 functions**.
|
||||||
|
Extracted directly from the `.?AV`/`.?AU` type-descriptor strings. This is the spine of the
|
||||||
|
object-model map. Raw list: `rtti-raw.txt`. Cleaned: `classes-game.txt` (1,404),
|
||||||
|
`classes-mars.txt` (194), `serializable-types.txt` (179).
|
||||||
|
|
||||||
|
> Note: Ghidra's headless RTTI analyzer ran but built 0 `SymbolType.CLASS` namespaces on our
|
||||||
|
> query — a tooling detail to sort out in ReVa (re-run/point the right analyzer, or read the
|
||||||
|
> demangled names). The RTTI itself is present and rich; names here come straight from the binary.
|
||||||
|
|
||||||
|
## Architecture (two namespaces)
|
||||||
|
- **`Mars`** — the **engine** (194 classes). SOTS1's engine is *Mars* (SOTS2 later used *Mercury*).
|
||||||
|
- Render: `DrawDevice`, `Camera`, `BatchedPrimitiveImpl`, `Decal`, `Effect`/`EffectPool`,
|
||||||
|
particle painters (`Beam`, `Billboard`, `BaseParticlePainter`), `Dictionary<Mesh|Model|Texture>`.
|
||||||
|
- Scene/entity/physics: `EntityBase`, `EntityFactory`, `PhysicalEntity`, `Body`, `RigidBody`,
|
||||||
|
`Dynamics`, `CombatSim`, `SceneObject`.
|
||||||
|
- Serialization: `IStreamable` + `StreamableHelper<T>`/`VectorHelper<T>`/`StreamableEnum` (every
|
||||||
|
serializable type is wrapped — see `serializable-types.txt`). Asset I/O: **`Buffer::gobio`**
|
||||||
|
(the `.gob` reader/writer).
|
||||||
|
- Net: `BitStreamImpl`/`BitStreamExt`, `FNM*` (framed network messages).
|
||||||
|
- UI framework: `Control`, `Button`, `CheckBox`, `Dialog`, `DockablePanel`, `DropDownList`, `EditView`.
|
||||||
|
- **`Game`** — game logic + UI (1,404 classes), built on Mars.
|
||||||
|
|
||||||
|
## High-value targets (object model — goal #1)
|
||||||
|
The empire is modeled as a **Player** (SOTS terminology), not "Empire" (that's UI).
|
||||||
|
- **Player/empire:** `Game::AIPlayer`, `Game::ClientPlayer`, `Game::GameSetup_Player`, `Game::PlayerAid`.
|
||||||
|
- **Star map:** `Game::StarSystem` (+ `PlayerView@StarSystem`), `Game::Planet` / `DOPlanet` / `Creator::Planet`.
|
||||||
|
- **Ships/design:** `Game::ShipData`, `Game::ShipDesignDef`, `Game::DesignList`, `Game::ObservedDesign`.
|
||||||
|
- **Fleets:** `Game::FleetLayout` (+ manager/list UI around it).
|
||||||
|
- **Combat:** `Game::GameCombatSim`, the `Game::CombatCommand*` hierarchy (~40 command types),
|
||||||
|
`Game::Encounter*` results, `Mars::CombatSim`, `Mars::CombatSimContactHandler`.
|
||||||
|
- **Base entity:** `Game::Actor` → `Game::TargetableEntity` → `Mars::PhysicalEntity` → `Mars::EntityBase`.
|
||||||
|
|
||||||
|
## Control-flow / renderer anchors
|
||||||
|
- Entry / bootstrap: `Mars::AppStartup`.
|
||||||
|
- Renderer: `Mars::DrawDevice` + `Camera` → D3D9 device init (`Direct3DCreate9`/`CreateDevice`).
|
||||||
|
|
||||||
|
## How this feeds the campaign
|
||||||
|
`serializable-types.txt` ≈ the save/on-disk data model — the ideal cross-reference against the
|
||||||
|
community save-editor structs (verify layouts against real saves). The Player/StarSystem/Planet/
|
||||||
|
ShipDesignDef cluster is the first deepen-set; `Buffer::gobio` anchors the `.gob` parser for `verify/`.
|
||||||
1404
findings/objects/classes-game.txt
Normal file
1404
findings/objects/classes-game.txt
Normal file
File diff suppressed because it is too large
Load diff
194
findings/objects/classes-mars.txt
Normal file
194
findings/objects/classes-mars.txt
Normal file
|
|
@ -0,0 +1,194 @@
|
||||||
|
AnimController
|
||||||
|
AnimSet
|
||||||
|
AnimSetRecord
|
||||||
|
AppStartup
|
||||||
|
AttractorProxy
|
||||||
|
BaseParticlePainter
|
||||||
|
BatchedPrimitiveImpl
|
||||||
|
BeamParticlePainter
|
||||||
|
BillboardParticlePainter
|
||||||
|
BitStreamExt
|
||||||
|
BitStreamImpl
|
||||||
|
Body
|
||||||
|
Buffer::gobio
|
||||||
|
BulkTextPanel
|
||||||
|
Button
|
||||||
|
Camera
|
||||||
|
ChartLine::chart
|
||||||
|
CheckBox
|
||||||
|
CheckBoxBase
|
||||||
|
CheckBoxList
|
||||||
|
ClientContext
|
||||||
|
ClipPanel::ListFramework
|
||||||
|
CombatSim
|
||||||
|
CombatSimContactHandler
|
||||||
|
Command
|
||||||
|
Control
|
||||||
|
Creator::EntityBase
|
||||||
|
Creator::InfoEntity
|
||||||
|
Creator::PhysicalEntity
|
||||||
|
DLink
|
||||||
|
Decal
|
||||||
|
DestroyParticleSystemAggregate
|
||||||
|
DetachParticleSystemAggregate
|
||||||
|
Dialog
|
||||||
|
DialogUnderlay
|
||||||
|
Dictionary::AnimSetRecord
|
||||||
|
Dictionary::Mesh
|
||||||
|
Dictionary::Model
|
||||||
|
Dictionary::Texture
|
||||||
|
DirectionAttractorProxy
|
||||||
|
DockablePanel
|
||||||
|
DrawDevice
|
||||||
|
DropDownList
|
||||||
|
Dynamics
|
||||||
|
EditView
|
||||||
|
Effect
|
||||||
|
EffectPool
|
||||||
|
EntityBase
|
||||||
|
EntityCreator
|
||||||
|
EntityFactory
|
||||||
|
ExtraParams
|
||||||
|
FNMBase
|
||||||
|
FNMChunk
|
||||||
|
FNMChunkReply
|
||||||
|
FNMDone
|
||||||
|
FNMDoneReply
|
||||||
|
FNMError
|
||||||
|
FNMSendNotify
|
||||||
|
FNMSendReply
|
||||||
|
FactoryItem
|
||||||
|
FileStream
|
||||||
|
Font
|
||||||
|
FontDictionary
|
||||||
|
FontImpl
|
||||||
|
Frame
|
||||||
|
FreeParticlePainter
|
||||||
|
GUIResources
|
||||||
|
GZFileStream
|
||||||
|
GradientSlider
|
||||||
|
HandleObject
|
||||||
|
IApplication
|
||||||
|
IBodyContactHandler
|
||||||
|
IBuffer::gobio
|
||||||
|
ICSVRowParser
|
||||||
|
IClientImpl
|
||||||
|
IDrawDevice
|
||||||
|
IDrawDeviceClient
|
||||||
|
IDropData
|
||||||
|
IDropSource
|
||||||
|
IDropTarget
|
||||||
|
IDynamics
|
||||||
|
IEditView
|
||||||
|
IEffectPool
|
||||||
|
IFileSystem::gobio
|
||||||
|
ILinkLocation
|
||||||
|
IListView
|
||||||
|
IMatrixStack
|
||||||
|
IMenu
|
||||||
|
IPanelManager
|
||||||
|
IParticleSystemAggregate
|
||||||
|
IReference::SceneObject
|
||||||
|
IScheduledEvent
|
||||||
|
IScriptable
|
||||||
|
IServerImpl
|
||||||
|
ISimplePainter
|
||||||
|
IStreamable
|
||||||
|
ITextView
|
||||||
|
IconButton
|
||||||
|
IconToggleButton
|
||||||
|
Impl::BulkTextPanel
|
||||||
|
InfoEntity
|
||||||
|
Item::ListFramework
|
||||||
|
Item::TextListBase
|
||||||
|
LCRButton
|
||||||
|
LaunchParams
|
||||||
|
LightningParticlePainter
|
||||||
|
ListBox
|
||||||
|
ListColumn
|
||||||
|
ListFramework
|
||||||
|
ListPanel
|
||||||
|
ListUnderlay::DropDownList
|
||||||
|
ListView
|
||||||
|
LoadCallbacks::CombatSim
|
||||||
|
MatrixStack
|
||||||
|
Menu
|
||||||
|
Mesh
|
||||||
|
MeshParticlePainter
|
||||||
|
MeshPreRenderFunc
|
||||||
|
MicroButton
|
||||||
|
Model
|
||||||
|
ModelFrame
|
||||||
|
Movie
|
||||||
|
NMCommand
|
||||||
|
NMLoad
|
||||||
|
NMLoadComplete
|
||||||
|
NMSyncCheck
|
||||||
|
NMSyncError
|
||||||
|
NativeFileSystem::gobio
|
||||||
|
NetConClientImpl
|
||||||
|
NetConImpl
|
||||||
|
NetConServerImpl
|
||||||
|
NetMessage
|
||||||
|
NetMessageReceiver
|
||||||
|
NetworkIDMap
|
||||||
|
NetworkObject
|
||||||
|
NullClientImpl
|
||||||
|
NullServerImpl
|
||||||
|
Object
|
||||||
|
Owner::SceneObject
|
||||||
|
Panel
|
||||||
|
PanelManager
|
||||||
|
ParticleAttractor
|
||||||
|
ParticleChannel
|
||||||
|
ParticleDrawBuffer
|
||||||
|
ParticleEmitter
|
||||||
|
ParticleSystem
|
||||||
|
ParticleTracker
|
||||||
|
PhysicalEntity
|
||||||
|
Picture
|
||||||
|
PointAttractorProxy
|
||||||
|
ProgressPainter
|
||||||
|
QuadRenderer
|
||||||
|
RNG
|
||||||
|
RefCounted
|
||||||
|
RenderBuffer
|
||||||
|
RenderTargetTexture
|
||||||
|
RigidBody
|
||||||
|
RopeParticlePainter
|
||||||
|
ScaledMeshParticlePainter
|
||||||
|
ScalingFont
|
||||||
|
Script
|
||||||
|
Scrollbar
|
||||||
|
SimplePainter
|
||||||
|
Sound
|
||||||
|
SoundBase
|
||||||
|
Sprite
|
||||||
|
SpriteInterfaceProxy
|
||||||
|
SpriteTable
|
||||||
|
SpriteTableRowParser
|
||||||
|
StandardExtraParams
|
||||||
|
Stream
|
||||||
|
StreamImpl
|
||||||
|
SyncChecksumBuffer
|
||||||
|
SyncClient
|
||||||
|
SyncParams
|
||||||
|
SyncServer
|
||||||
|
TNMConnect
|
||||||
|
TNMDisconnect
|
||||||
|
TNMHost
|
||||||
|
TNMMessage
|
||||||
|
TNMessage
|
||||||
|
TextButton
|
||||||
|
TextFileStream
|
||||||
|
TextListBase
|
||||||
|
TextView
|
||||||
|
TextViewBase
|
||||||
|
Texture
|
||||||
|
TiledBeamParticlePainter
|
||||||
|
ToggleMicroButton
|
||||||
|
TrailParticlePainter
|
||||||
|
UISoundCSVRowParser
|
||||||
|
VorbisSound
|
||||||
|
ZipFileSystem::gobio
|
||||||
|
gobio_D3DXInclude
|
||||||
1924
findings/objects/rtti-raw.txt
Normal file
1924
findings/objects/rtti-raw.txt
Normal file
File diff suppressed because it is too large
Load diff
179
findings/objects/serializable-types.txt
Normal file
179
findings/objects/serializable-types.txt
Normal file
|
|
@ -0,0 +1,179 @@
|
||||||
|
AIAutoPeaceRun
|
||||||
|
AICombatReport
|
||||||
|
AIEncounterFlags
|
||||||
|
AIPlayerRequestStamp
|
||||||
|
AIRebellion
|
||||||
|
AIRelationRecord
|
||||||
|
AISituation
|
||||||
|
AISystem
|
||||||
|
Address
|
||||||
|
AllianceInvite
|
||||||
|
Artifact
|
||||||
|
AttribMap
|
||||||
|
BoardedShip
|
||||||
|
BuildQueue
|
||||||
|
CivilianRatios
|
||||||
|
CombatDamageReport
|
||||||
|
CombatEncounterParams
|
||||||
|
CombatLaunchParams
|
||||||
|
CombatPlayerInvariant
|
||||||
|
CombatPlayerReport
|
||||||
|
CombatPlayerStats
|
||||||
|
CombatReport
|
||||||
|
CombatShipReport
|
||||||
|
CombatTechFlags
|
||||||
|
CombatWeaponReport
|
||||||
|
CommMessageContainer
|
||||||
|
Command
|
||||||
|
CustomDataTable
|
||||||
|
DamagedShip
|
||||||
|
DefeatRecord
|
||||||
|
DefenceFleetAssignment
|
||||||
|
DefenceLayout
|
||||||
|
DefenceSummary
|
||||||
|
DesignNameGen
|
||||||
|
DiplomacyStats
|
||||||
|
EncounterParams
|
||||||
|
EncounterQuery
|
||||||
|
EncounterResult
|
||||||
|
EncounterResults
|
||||||
|
Event
|
||||||
|
EventStorage
|
||||||
|
FieldTemplate
|
||||||
|
FleetLayout
|
||||||
|
FleetNameGenerator
|
||||||
|
FlightPlan
|
||||||
|
FreighterWarning
|
||||||
|
GameTurnHistory
|
||||||
|
GunBank
|
||||||
|
GunBankSelection
|
||||||
|
HiveInfo
|
||||||
|
ICommMessage
|
||||||
|
IServerSpyManager
|
||||||
|
IndependenceInfo
|
||||||
|
Infestation
|
||||||
|
LaunchParams
|
||||||
|
LegacyGunBank
|
||||||
|
LegacyWeaponDef
|
||||||
|
LocustFleetLogistics
|
||||||
|
LocustNestState
|
||||||
|
Morale
|
||||||
|
MoraleEvent
|
||||||
|
NetMessage
|
||||||
|
NodePath
|
||||||
|
NodePointParams
|
||||||
|
NodeRoute
|
||||||
|
Objective
|
||||||
|
ObservedDesign
|
||||||
|
ObservedTech
|
||||||
|
ObservedWeapon
|
||||||
|
OutputRates
|
||||||
|
PCStat
|
||||||
|
Params
|
||||||
|
ParticleChannel
|
||||||
|
ParticleTracker
|
||||||
|
Plague
|
||||||
|
PlagueHit
|
||||||
|
PlagueStats
|
||||||
|
PlanetClientContext
|
||||||
|
PlanetStats
|
||||||
|
PlayerAid
|
||||||
|
PlayerAlliances
|
||||||
|
PlayerColorID
|
||||||
|
PlayerEncounterProgress
|
||||||
|
PlayerMessage
|
||||||
|
PlayerNotes
|
||||||
|
PlayerReport
|
||||||
|
PlayerState
|
||||||
|
PlayerStatus
|
||||||
|
PlayerTurnHistory
|
||||||
|
PlayerTurnStats
|
||||||
|
PlayerView
|
||||||
|
Point
|
||||||
|
Population
|
||||||
|
PopulationGroup
|
||||||
|
PrisonerHold
|
||||||
|
PrisonerShip
|
||||||
|
Quaternion
|
||||||
|
QueenInfo
|
||||||
|
RNG
|
||||||
|
RaidTargets
|
||||||
|
Response
|
||||||
|
RetreatingShip
|
||||||
|
SVSOScenarioBase
|
||||||
|
SVSOUpstartApes_EmpireOrder
|
||||||
|
SVScriptObject
|
||||||
|
Section
|
||||||
|
ServerNodeGraph
|
||||||
|
ServerPlayer
|
||||||
|
ServerTradeManager
|
||||||
|
ShipBuildOrderDef
|
||||||
|
ShipData
|
||||||
|
ShipDesign
|
||||||
|
ShipDesignDef
|
||||||
|
ShipHealth
|
||||||
|
ShipParams
|
||||||
|
ShipRecords
|
||||||
|
ShipRequest
|
||||||
|
ShipSectionID
|
||||||
|
ShipWeapon
|
||||||
|
SimpleNodePath
|
||||||
|
Slot
|
||||||
|
SlotData
|
||||||
|
SlotDef
|
||||||
|
SlotUser
|
||||||
|
SpecialProject
|
||||||
|
SpecialProjectImpl
|
||||||
|
SpecialProjectNameGen
|
||||||
|
SpeciesRatios
|
||||||
|
SpyCraft
|
||||||
|
SpyReport
|
||||||
|
SpyReportDefences
|
||||||
|
SpyReportEvents
|
||||||
|
SpyReportTechTree
|
||||||
|
SpyReportTrade
|
||||||
|
SpyReportTradeRoute
|
||||||
|
SpyShip
|
||||||
|
StarFleet
|
||||||
|
StarMapParams
|
||||||
|
StarShip
|
||||||
|
StarSystem
|
||||||
|
StrategyGameCreateParams
|
||||||
|
StrategyGameInfo
|
||||||
|
StrategyGameLoadParams
|
||||||
|
StrategyGameParams
|
||||||
|
StrategyPlayerGameSettings
|
||||||
|
StrategyPlayerInfo
|
||||||
|
StrategyPlayerParams
|
||||||
|
StrategyScriptParams
|
||||||
|
StrategyServer
|
||||||
|
StrategySessionParams
|
||||||
|
StrategySimParams
|
||||||
|
StrategyTimerParams
|
||||||
|
StrategyTurnInfo
|
||||||
|
StrategyUserInfo
|
||||||
|
SyncChecksumBuffer
|
||||||
|
SyncParams
|
||||||
|
SystemEvent
|
||||||
|
SystemParams
|
||||||
|
TNID
|
||||||
|
TNMConnect
|
||||||
|
TNMDisconnect
|
||||||
|
TNMHost
|
||||||
|
TNMMessage
|
||||||
|
TNMessage
|
||||||
|
TacReport
|
||||||
|
TacReportEvents
|
||||||
|
TechOffer
|
||||||
|
TechTree
|
||||||
|
TradeRoute
|
||||||
|
TradeSector
|
||||||
|
Trap
|
||||||
|
TurnCommands
|
||||||
|
TurnEvents
|
||||||
|
UpdateData
|
||||||
|
Vector2
|
||||||
|
Vector3
|
||||||
|
Waypoint
|
||||||
|
WeaponGroups
|
||||||
|
XenoTechsPerSpecies
|
||||||
Loading…
Add table
Reference in a new issue