server-master/srcs/_plugins/Plugin.QuestImpl/Managers/QuestPostgresSync.cs

203 lines
8.4 KiB
C#

using System;
using System.Collections.Generic;
using Npgsql;
using PhoenixLib.Logging;
using WingsEmu.DTOs.Quests;
namespace Plugin.QuestImpl.Managers
{
public static class QuestPostgresSync
{
private static bool Enabled => !string.Equals(Environment.GetEnvironmentVariable("PARSER_DB_SYNC"), "false", StringComparison.OrdinalIgnoreCase);
private static string BuildConnectionString()
{
string host = Environment.GetEnvironmentVariable("DATABASE_IP")
?? Environment.GetEnvironmentVariable("POSTGRES_DATABASE_IP")
?? "127.0.0.1";
string port = Environment.GetEnvironmentVariable("DATABASE_PORT")
?? Environment.GetEnvironmentVariable("POSTGRES_DATABASE_PORT")
?? "5432";
string db = Environment.GetEnvironmentVariable("DATABASE_NAME")
?? Environment.GetEnvironmentVariable("POSTGRES_DATABASE_NAME")
?? "game";
string user = Environment.GetEnvironmentVariable("DATABASE_USER")
?? Environment.GetEnvironmentVariable("POSTGRES_DATABASE_USER")
?? "postgres";
string pass = Environment.GetEnvironmentVariable("DATABASE_PASSWORD")
?? Environment.GetEnvironmentVariable("POSTGRES_DATABASE_PASSWORD")
?? "postgres";
return $"Host={host};Port={port};Database={db};Username={user};Password={pass}";
}
public static void Sync(IReadOnlyList<QuestDto> quests, IReadOnlyList<TutorialDto> tutorials, IReadOnlyList<QuestNpcDto> questNpcs)
{
if (!Enabled) return;
try
{
using var conn = new NpgsqlConnection(BuildConnectionString());
conn.Open();
using var tx = conn.BeginTransaction();
using (var cmd = new NpgsqlCommand(@"
CREATE TABLE IF NOT EXISTS quests (
id BIGSERIAL PRIMARY KEY,
quest_id INT,
name TEXT,
description TEXT,
auto_finish BOOLEAN,
dialog_starting INT,
dialog_finish INT,
dialog_during INT,
min_level INT,
max_level INT,
next_quest_id INT,
quest_type INT,
required_quest_id INT,
talker_vnum INT,
target_map_id INT,
target_map_x INT,
target_map_y INT,
unknown1 INT,
is_blue BOOLEAN
);
CREATE TABLE IF NOT EXISTS quest_objectives (
id BIGSERIAL PRIMARY KEY,
quest_id INT,
data0 INT,
data1 INT,
data2 INT,
data3 INT,
objective_index INT
);
CREATE TABLE IF NOT EXISTS quest_prizes (
id BIGSERIAL PRIMARY KEY,
quest_id INT,
reward_type INT,
data0 INT,
data1 INT,
data2 INT,
data3 INT,
data4 INT
);
CREATE TABLE IF NOT EXISTS tutorials (
id BIGSERIAL PRIMARY KEY,
tutorial_id INT,
data INT,
script_id INT,
script_index INT,
type INT
);
CREATE TABLE IF NOT EXISTS quest_npcs (
id BIGSERIAL PRIMARY KEY,
quest_npc_id INT,
quest_id INT,
npc_vnum INT,
level INT,
starting_script INT,
required_completed_script INT,
is_main_quest BOOLEAN,
map_id INT
);", conn, tx)) cmd.ExecuteNonQuery();
using (var cmd = new NpgsqlCommand("TRUNCATE TABLE quests, quest_objectives, quest_prizes, tutorials, quest_npcs RESTART IDENTITY;", conn, tx)) cmd.ExecuteNonQuery();
foreach (QuestDto q in quests)
{
using (var cmd = new NpgsqlCommand(@"INSERT INTO quests(quest_id,name,description,auto_finish,dialog_starting,dialog_finish,dialog_during,min_level,max_level,next_quest_id,quest_type,required_quest_id,talker_vnum,target_map_id,target_map_x,target_map_y,unknown1,is_blue)
VALUES (@id,@name,@desc,@auto,@ds,@df,@dd,@min,@max,@next,@qt,@req,@talk,@tmid,@tmx,@tmy,@u1,@blue);", conn, tx))
{
cmd.Parameters.AddWithValue("id", q.Id);
cmd.Parameters.AddWithValue("name", (object?)q.Name ?? DBNull.Value);
cmd.Parameters.AddWithValue("desc", (object?)q.Description ?? DBNull.Value);
cmd.Parameters.AddWithValue("auto", q.AutoFinish);
cmd.Parameters.AddWithValue("ds", q.DialogStarting);
cmd.Parameters.AddWithValue("df", q.DialogFinish);
cmd.Parameters.AddWithValue("dd", q.DialogDuring);
cmd.Parameters.AddWithValue("min", q.MinLevel);
cmd.Parameters.AddWithValue("max", q.MaxLevel);
cmd.Parameters.AddWithValue("next", q.NextQuestId);
cmd.Parameters.AddWithValue("qt", (int)q.QuestType);
cmd.Parameters.AddWithValue("req", q.RequiredQuestId);
cmd.Parameters.AddWithValue("talk", q.TalkerVnum);
cmd.Parameters.AddWithValue("tmid", q.TargetMapId);
cmd.Parameters.AddWithValue("tmx", q.TargetMapX);
cmd.Parameters.AddWithValue("tmy", q.TargetMapY);
cmd.Parameters.AddWithValue("u1", q.Unknown1);
cmd.Parameters.AddWithValue("blue", q.IsBlue);
cmd.ExecuteNonQuery();
}
if (q.Objectives != null)
{
foreach (QuestObjectiveDto o in q.Objectives)
{
using var cmd = new NpgsqlCommand(@"INSERT INTO quest_objectives(quest_id,data0,data1,data2,data3,objective_index)
VALUES (@qid,@d0,@d1,@d2,@d3,@idx);", conn, tx);
cmd.Parameters.AddWithValue("qid", q.Id);
cmd.Parameters.AddWithValue("d0", o.Data0);
cmd.Parameters.AddWithValue("d1", o.Data1);
cmd.Parameters.AddWithValue("d2", o.Data2);
cmd.Parameters.AddWithValue("d3", o.Data3);
cmd.Parameters.AddWithValue("idx", o.ObjectiveIndex);
cmd.ExecuteNonQuery();
}
}
if (q.Prizes != null)
{
foreach (QuestPrizeDto p in q.Prizes)
{
using var cmd = new NpgsqlCommand(@"INSERT INTO quest_prizes(quest_id,reward_type,data0,data1,data2,data3,data4)
VALUES (@qid,@rt,@d0,@d1,@d2,@d3,@d4);", conn, tx);
cmd.Parameters.AddWithValue("qid", q.Id);
cmd.Parameters.AddWithValue("rt", p.RewardType);
cmd.Parameters.AddWithValue("d0", p.Data0);
cmd.Parameters.AddWithValue("d1", p.Data1);
cmd.Parameters.AddWithValue("d2", p.Data2);
cmd.Parameters.AddWithValue("d3", p.Data3);
cmd.Parameters.AddWithValue("d4", p.Data4);
cmd.ExecuteNonQuery();
}
}
}
foreach (TutorialDto t in tutorials)
{
using var cmd = new NpgsqlCommand("INSERT INTO tutorials(tutorial_id,data,script_id,script_index,type) VALUES (@id,@data,@sid,@sidx,@type);", conn, tx);
cmd.Parameters.AddWithValue("id", t.Id);
cmd.Parameters.AddWithValue("data", t.Data);
cmd.Parameters.AddWithValue("sid", t.ScriptId);
cmd.Parameters.AddWithValue("sidx", t.ScriptIndex);
cmd.Parameters.AddWithValue("type", (int)t.Type);
cmd.ExecuteNonQuery();
}
foreach (QuestNpcDto n in questNpcs)
{
using var cmd = new NpgsqlCommand(@"INSERT INTO quest_npcs(quest_npc_id,quest_id,npc_vnum,level,starting_script,required_completed_script,is_main_quest,map_id)
VALUES (@id,@qid,@npc,@lvl,@start,@req,@main,@map);", conn, tx);
cmd.Parameters.AddWithValue("id", n.Id);
cmd.Parameters.AddWithValue("qid", (object?)n.QuestId ?? DBNull.Value);
cmd.Parameters.AddWithValue("npc", n.NpcVnum);
cmd.Parameters.AddWithValue("lvl", n.Level);
cmd.Parameters.AddWithValue("start", n.StartingScript);
cmd.Parameters.AddWithValue("req", n.RequiredCompletedScript);
cmd.Parameters.AddWithValue("main", n.IsMainQuest);
cmd.Parameters.AddWithValue("map", n.MapId);
cmd.ExecuteNonQuery();
}
tx.Commit();
Log.Info($"[PARSER_DB_SYNC] Synced quests={quests.Count} tutorials={tutorials.Count} quest_npcs={questNpcs.Count}");
}
catch (Exception ex)
{
Log.Error("[PARSER_DB_SYNC] Failed to sync quests", ex);
}
}
}
}