135 lines
No EOL
5.3 KiB
C#
135 lines
No EOL
5.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using FluentValidation.Results;
|
|
using MoonSharp.Interpreter;
|
|
using Npgsql;
|
|
using PhoenixLib.Logging;
|
|
using Plugin.Raids.Scripting.Validator.Raid;
|
|
using WingsAPI.Scripting;
|
|
using WingsAPI.Scripting.Enum.Raid;
|
|
using WingsAPI.Scripting.LUA;
|
|
using WingsAPI.Scripting.Object.Raid;
|
|
using WingsAPI.Scripting.ScriptManager;
|
|
|
|
namespace Plugin.Raids.Scripting;
|
|
|
|
public sealed class RaidScriptManager : IRaidScriptManager
|
|
{
|
|
private readonly Dictionary<SRaidType, SRaid> _cache = new();
|
|
private readonly IScriptFactory _scriptFactory;
|
|
private readonly ScriptFactoryConfiguration _scriptFactoryConfiguration;
|
|
private readonly SRaidValidator _validator;
|
|
|
|
public RaidScriptManager(IScriptFactory scriptFactory, ScriptFactoryConfiguration scriptFactoryConfiguration, SRaidValidator validator)
|
|
{
|
|
_scriptFactory = scriptFactory;
|
|
_scriptFactoryConfiguration = scriptFactoryConfiguration;
|
|
_validator = validator;
|
|
}
|
|
|
|
public SRaid GetScriptedRaid(SRaidType raidType) => _cache.GetValueOrDefault(raidType);
|
|
|
|
public void Load()
|
|
{
|
|
EnsureRaidScriptsDirectoryHydrated();
|
|
Directory.CreateDirectory(_scriptFactoryConfiguration.RaidsDirectory);
|
|
|
|
IEnumerable<string> files = Directory.GetFiles(_scriptFactoryConfiguration.RaidsDirectory, "*.lua");
|
|
foreach (string file in files)
|
|
{
|
|
try
|
|
{
|
|
SRaid raid = _scriptFactory.LoadScript<SRaid>(file);
|
|
if (raid == null)
|
|
{
|
|
Log.Warn($"Failed to load raid script {file}");
|
|
continue;
|
|
}
|
|
|
|
ValidationResult result = _validator.Validate(raid);
|
|
if (!result.IsValid)
|
|
{
|
|
throw new InvalidScriptException(result.Errors.First().ErrorMessage);
|
|
}
|
|
|
|
Log.Warn($"[RAID_SCRIPT_MANAGER] Loaded {Path.GetFileName(file)} for raid: {raid.RaidType}");
|
|
_cache[raid.RaidType] = raid;
|
|
}
|
|
catch (InvalidScriptException e)
|
|
{
|
|
Log.Error($"[RAID_SCRIPT_MANAGER]InvalidScript: {file}", e);
|
|
}
|
|
catch (ScriptRuntimeException e)
|
|
{
|
|
Log.Error($"[RAID_SCRIPT_MANAGER][SCRIPT ERROR] {file}, {e.DecoratedMessage}", e);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Log.Error($"[RAID_SCRIPT_MANAGER][SCRIPT ERROR] {file}", e);
|
|
}
|
|
}
|
|
|
|
Log.Info($"Loaded {_cache.Count} raids from scripts");
|
|
}
|
|
|
|
private void EnsureRaidScriptsDirectoryHydrated()
|
|
{
|
|
bool dbFirst = string.Equals(Environment.GetEnvironmentVariable("DB_FIRST"), "true", StringComparison.OrdinalIgnoreCase)
|
|
|| string.Equals(Environment.GetEnvironmentVariable("RESOURCE_DB_FIRST"), "true", StringComparison.OrdinalIgnoreCase);
|
|
if (!dbFirst)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (Directory.Exists(_scriptFactoryConfiguration.RaidsDirectory))
|
|
{
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
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";
|
|
|
|
using var conn = new NpgsqlConnection($"Host={host};Port={port};Database={db};Username={user};Password={pass}");
|
|
conn.Open();
|
|
|
|
using var cmd = new NpgsqlCommand("SELECT relative_path, content FROM resource_files WHERE category='config_scripts' AND relative_path LIKE 'config/scripts/raids/%';", conn);
|
|
using var reader = cmd.ExecuteReader();
|
|
int count = 0;
|
|
while (reader.Read())
|
|
{
|
|
string relative = reader.GetString(0).Replace('/', Path.DirectorySeparatorChar);
|
|
byte[] bytes = (byte[])reader[1];
|
|
string fullPath = Path.Combine(Directory.GetCurrentDirectory(), relative);
|
|
Directory.CreateDirectory(Path.GetDirectoryName(fullPath) ?? _scriptFactoryConfiguration.RaidsDirectory);
|
|
File.WriteAllBytes(fullPath, bytes);
|
|
count++;
|
|
}
|
|
|
|
if (count > 0)
|
|
{
|
|
Log.Info($"[DB_FIRST] Hydrated {count} raid scripts from resource_files");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Error("[DB_FIRST] Could not hydrate raid scripts from database", ex);
|
|
}
|
|
}
|
|
} |