232 lines
9.9 KiB
PowerShell
232 lines
9.9 KiB
PowerShell
param(
|
|
[string]$DbContainer = "wingsemu-postgres",
|
|
[string]$DbName = "game",
|
|
[string]$DbUser = "postgres",
|
|
[string]$ConfigRoot = "config"
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
$root = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $MyInvocation.MyCommand.Path))
|
|
Set-Location $root
|
|
|
|
$configPath = Join-Path $root $ConfigRoot
|
|
if (-not (Test-Path $configPath)) { throw "Config path not found: $configPath" }
|
|
|
|
$maps = @()
|
|
$mapFlags = @()
|
|
$portals = @()
|
|
$npcs = @()
|
|
$monsters = @()
|
|
|
|
function To-IntOrNull($v) {
|
|
if ([string]::IsNullOrWhiteSpace($v)) { return $null }
|
|
$v = ($v -split '#')[0].Trim()
|
|
if ($v -match '^-?\d+$') { return [int]$v }
|
|
return $null
|
|
}
|
|
|
|
function SqlEsc([string]$s) {
|
|
if ($null -eq $s) { return 'NULL' }
|
|
return "'" + ($s -replace "'","''") + "'"
|
|
}
|
|
|
|
function SqlNum($n) {
|
|
if ($null -eq $n) { return 'NULL' }
|
|
return [string]$n
|
|
}
|
|
|
|
function Read-NonCommentLines([string]$file) {
|
|
Get-Content $file | ForEach-Object { $_.TrimEnd() } | Where-Object { $_ -notmatch '^\s*#' }
|
|
}
|
|
|
|
# -------- maps --------
|
|
Get-ChildItem (Join-Path $configPath 'maps') -File -ErrorAction SilentlyContinue | ForEach-Object {
|
|
$lines = Read-NonCommentLines $_.FullName
|
|
$current = $null
|
|
$inFlags = $false
|
|
|
|
foreach ($line in $lines) {
|
|
if ($line -match '^\s*-\s*map_id\s*:\s*(.+)$') {
|
|
if ($current) { $maps += $current }
|
|
$current = [ordered]@{ map_id = To-IntOrNull $matches[1]; map_vnum = $null; map_name_id = $null; map_music_id = $null; flags = @() }
|
|
$inFlags = $false
|
|
continue
|
|
}
|
|
if (-not $current) { continue }
|
|
|
|
if ($line -match '^\s*flags\s*:') { $inFlags = $true; continue }
|
|
|
|
if ($inFlags -and $line -match '^\s*-\s*([A-Z0-9_]+)\s*$') {
|
|
$current.flags += $matches[1]
|
|
continue
|
|
}
|
|
|
|
if ($line -match '^\s*map_vnum\s*:\s*(.+)$') { $current.map_vnum = To-IntOrNull $matches[1]; $inFlags=$false; continue }
|
|
if ($line -match '^\s*map_name_id\s*:\s*(.+)$') { $current.map_name_id = To-IntOrNull $matches[1]; $inFlags=$false; continue }
|
|
if ($line -match '^\s*map_music_id\s*:\s*(.+)$') { $current.map_music_id = To-IntOrNull $matches[1]; $inFlags=$false; continue }
|
|
}
|
|
|
|
if ($current) { $maps += $current }
|
|
}
|
|
|
|
foreach ($m in $maps) {
|
|
foreach ($f in $m.flags) {
|
|
$mapFlags += [ordered]@{ map_id = $m.map_id; flag = $f }
|
|
}
|
|
}
|
|
|
|
# -------- portals --------
|
|
Get-ChildItem (Join-Path $configPath 'map_portals') -File -ErrorAction SilentlyContinue | ForEach-Object {
|
|
$lines = Read-NonCommentLines $_.FullName
|
|
$current = $null
|
|
foreach ($line in $lines) {
|
|
if ($line -match '^\s*-\s*destination_map_id\s*:\s*(.+)$') {
|
|
if ($current) { $portals += $current }
|
|
$current = [ordered]@{
|
|
destination_map_id = To-IntOrNull $matches[1]
|
|
destination_map_x = $null
|
|
destination_map_y = $null
|
|
source_map_id = $null
|
|
source_map_x = $null
|
|
source_map_y = $null
|
|
type = $null
|
|
}
|
|
continue
|
|
}
|
|
if (-not $current) { continue }
|
|
if ($line -match '^\s*destination_map_x\s*:\s*(.+)$') { $current.destination_map_x = To-IntOrNull $matches[1]; continue }
|
|
if ($line -match '^\s*destination_map_y\s*:\s*(.+)$') { $current.destination_map_y = To-IntOrNull $matches[1]; continue }
|
|
if ($line -match '^\s*source_map_id\s*:\s*(.+)$') { $current.source_map_id = To-IntOrNull $matches[1]; continue }
|
|
if ($line -match '^\s*source_map_x\s*:\s*(.+)$') { $current.source_map_x = To-IntOrNull $matches[1]; continue }
|
|
if ($line -match '^\s*source_map_y\s*:\s*(.+)$') { $current.source_map_y = To-IntOrNull $matches[1]; continue }
|
|
if ($line -match '^\s*type\s*:\s*(.+)$') { $current.type = To-IntOrNull $matches[1]; continue }
|
|
}
|
|
if ($current) { $portals += $current }
|
|
}
|
|
|
|
# -------- npcs --------
|
|
Get-ChildItem (Join-Path $configPath 'map_npc_placement') -File -ErrorAction SilentlyContinue | ForEach-Object {
|
|
$lines = Read-NonCommentLines $_.FullName
|
|
$mapId = $null
|
|
$current = $null
|
|
foreach ($line in $lines) {
|
|
if ($line -match '^\s*map_id\s*:\s*(.+)$') { $mapId = To-IntOrNull $matches[1]; continue }
|
|
if ($line -match '^\s*-\s*map_npc_id\s*:\s*(.+)$') {
|
|
if ($current) { $npcs += $current }
|
|
$current = [ordered]@{ map_id=$mapId; map_npc_id=To-IntOrNull $matches[1]; vnum=$null; pos_x=$null; pos_y=$null; effect_vnum=$null; effect_delay=$null; dialog_id=$null; direction_facing=$null }
|
|
continue
|
|
}
|
|
if (-not $current) { continue }
|
|
if ($line -match '^\s*vnum\s*:\s*(.+)$') { $current.vnum = To-IntOrNull $matches[1]; continue }
|
|
if ($line -match '^\s*pos_x\s*:\s*(.+)$') { $current.pos_x = To-IntOrNull $matches[1]; continue }
|
|
if ($line -match '^\s*pos_y\s*:\s*(.+)$') { $current.pos_y = To-IntOrNull $matches[1]; continue }
|
|
if ($line -match '^\s*effect_vnum\s*:\s*(.+)$') { $current.effect_vnum = To-IntOrNull $matches[1]; continue }
|
|
if ($line -match '^\s*effect_delay\s*:\s*(.+)$') { $current.effect_delay = To-IntOrNull $matches[1]; continue }
|
|
if ($line -match '^\s*dialog_id\s*:\s*(.+)$') { $current.dialog_id = To-IntOrNull $matches[1]; continue }
|
|
if ($line -match '^\s*direction_facing\s*:\s*(.+)$') { $current.direction_facing = To-IntOrNull $matches[1]; continue }
|
|
}
|
|
if ($current) { $npcs += $current }
|
|
}
|
|
|
|
# -------- monsters --------
|
|
Get-ChildItem (Join-Path $configPath 'map_monster_placement') -File -ErrorAction SilentlyContinue | ForEach-Object {
|
|
$lines = Read-NonCommentLines $_.FullName
|
|
$mapId = $null
|
|
$current = $null
|
|
foreach ($line in $lines) {
|
|
if ($line -match '^\s*map_id\s*:\s*(.+)$') { $mapId = To-IntOrNull $matches[1]; continue }
|
|
if ($line -match '^\s*-\s*map_monster_id\s*:\s*(.+)$') {
|
|
if ($current) { $monsters += $current }
|
|
$current = [ordered]@{ map_id=$mapId; map_monster_id=To-IntOrNull $matches[1]; vnum=$null; map_x=$null; map_y=$null; position=$null; can_move=$null }
|
|
continue
|
|
}
|
|
if (-not $current) { continue }
|
|
if ($line -match '^\s*vnum\s*:\s*(.+)$') { $current.vnum = To-IntOrNull $matches[1]; continue }
|
|
if ($line -match '^\s*map_x\s*:\s*(.+)$') { $current.map_x = To-IntOrNull $matches[1]; continue }
|
|
if ($line -match '^\s*map_y\s*:\s*(.+)$') { $current.map_y = To-IntOrNull $matches[1]; continue }
|
|
if ($line -match '^\s*position\s*:\s*(.+)$') { $current.position = To-IntOrNull $matches[1]; continue }
|
|
if ($line -match '^\s*can_move\s*:\s*(.+)$') { $current.can_move = ($matches[1].Trim().ToLower() -eq 'true'); continue }
|
|
}
|
|
if ($current) { $monsters += $current }
|
|
}
|
|
|
|
$sql = New-Object System.Text.StringBuilder
|
|
[void]$sql.AppendLine("BEGIN;")
|
|
[void]$sql.AppendLine(@"
|
|
DROP TABLE IF EXISTS server_map_flags;
|
|
DROP TABLE IF EXISTS server_maps;
|
|
DROP TABLE IF EXISTS map_portals;
|
|
DROP TABLE IF EXISTS map_npcs;
|
|
DROP TABLE IF EXISTS map_monsters;
|
|
|
|
CREATE TABLE server_maps (
|
|
map_id INT PRIMARY KEY,
|
|
map_vnum INT,
|
|
map_name_id INT,
|
|
map_music_id INT
|
|
);
|
|
CREATE TABLE server_map_flags (
|
|
map_id INT NOT NULL,
|
|
flag TEXT NOT NULL,
|
|
PRIMARY KEY (map_id, flag)
|
|
);
|
|
CREATE TABLE map_portals (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
destination_map_id INT,
|
|
destination_map_x INT,
|
|
destination_map_y INT,
|
|
source_map_id INT,
|
|
source_map_x INT,
|
|
source_map_y INT,
|
|
type INT
|
|
);
|
|
CREATE TABLE map_npcs (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
map_npc_id INT,
|
|
map_id INT,
|
|
vnum INT,
|
|
pos_x INT,
|
|
pos_y INT,
|
|
effect_vnum INT,
|
|
effect_delay INT,
|
|
dialog_id INT,
|
|
direction_facing INT
|
|
);
|
|
CREATE TABLE map_monsters (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
map_monster_id INT,
|
|
map_id INT,
|
|
vnum INT,
|
|
map_x INT,
|
|
map_y INT,
|
|
position INT,
|
|
can_move BOOLEAN
|
|
);
|
|
"@)
|
|
|
|
foreach ($m in $maps | Where-Object { $null -ne $_.map_id }) {
|
|
[void]$sql.AppendLine("INSERT INTO server_maps(map_id,map_vnum,map_name_id,map_music_id) VALUES ($(SqlNum $m.map_id),$(SqlNum $m.map_vnum),$(SqlNum $m.map_name_id),$(SqlNum $m.map_music_id));")
|
|
}
|
|
foreach ($f in $mapFlags | Where-Object { $null -ne $_.map_id -and -not [string]::IsNullOrWhiteSpace($_.flag) }) {
|
|
[void]$sql.AppendLine("INSERT INTO server_map_flags(map_id,flag) VALUES ($(SqlNum $f.map_id),$(SqlEsc $f.flag));")
|
|
}
|
|
foreach ($p in $portals) {
|
|
[void]$sql.AppendLine("INSERT INTO map_portals(destination_map_id,destination_map_x,destination_map_y,source_map_id,source_map_x,source_map_y,type) VALUES ($(SqlNum $p.destination_map_id),$(SqlNum $p.destination_map_x),$(SqlNum $p.destination_map_y),$(SqlNum $p.source_map_id),$(SqlNum $p.source_map_x),$(SqlNum $p.source_map_y),$(SqlNum $p.type));")
|
|
}
|
|
foreach ($n in $npcs | Where-Object { $null -ne $_.map_npc_id }) {
|
|
[void]$sql.AppendLine("INSERT INTO map_npcs(map_npc_id,map_id,vnum,pos_x,pos_y,effect_vnum,effect_delay,dialog_id,direction_facing) VALUES ($(SqlNum $n.map_npc_id),$(SqlNum $n.map_id),$(SqlNum $n.vnum),$(SqlNum $n.pos_x),$(SqlNum $n.pos_y),$(SqlNum $n.effect_vnum),$(SqlNum $n.effect_delay),$(SqlNum $n.dialog_id),$(SqlNum $n.direction_facing));")
|
|
}
|
|
foreach ($m in $monsters | Where-Object { $null -ne $_.map_monster_id }) {
|
|
$mv = if ($null -eq $m.can_move) { 'NULL' } elseif ($m.can_move) { 'TRUE' } else { 'FALSE' }
|
|
[void]$sql.AppendLine("INSERT INTO map_monsters(map_monster_id,map_id,vnum,map_x,map_y,position,can_move) VALUES ($(SqlNum $m.map_monster_id),$(SqlNum $m.map_id),$(SqlNum $m.vnum),$(SqlNum $m.map_x),$(SqlNum $m.map_y),$(SqlNum $m.position),$mv);")
|
|
}
|
|
|
|
[void]$sql.AppendLine("COMMIT;")
|
|
|
|
$tmpSql = Join-Path $env:TEMP "parser_import.sql"
|
|
[System.IO.File]::WriteAllText($tmpSql, $sql.ToString())
|
|
|
|
Get-Content -Raw $tmpSql | docker exec -i $DbContainer psql -v ON_ERROR_STOP=1 -U $DbUser -d $DbName | Out-Host
|
|
|
|
Write-Host "Imported maps=$($maps.Count) flags=$($mapFlags.Count) portals=$($portals.Count) npcs=$($npcs.Count) monsters=$($monsters.Count)" -ForegroundColor Green
|