2021-02-15 14:42:14 +01:00
|
|
|
using System.Collections;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.IO;
|
2021-02-22 16:29:17 +01:00
|
|
|
using System.Linq;
|
2021-02-15 14:42:14 +01:00
|
|
|
using System.Security.Cryptography.X509Certificates;
|
|
|
|
using System.Text;
|
|
|
|
using System.Threading;
|
|
|
|
using Google.Apis.Auth.OAuth2;
|
|
|
|
using Google.Apis.Services;
|
|
|
|
using Google.Apis.Sheets.v4;
|
|
|
|
using Google.Apis.Util.Store;
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
|
|
#region Editor
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
using UnityEditor;
|
|
|
|
|
|
|
|
public static partial class DialogueDatabase
|
|
|
|
{
|
2021-02-19 17:26:15 +01:00
|
|
|
|
2021-02-15 14:42:14 +01:00
|
|
|
public static string EDITOR_DialogueFile =>
|
|
|
|
Path.Combine(Application.dataPath, "Data", "Dialogue", DIALOGUE_FILENAME);
|
|
|
|
|
|
|
|
// TODO: neither of these should be in the repository! ideally, move them behind secure
|
|
|
|
// gitlab variables before there is too much data at risk
|
|
|
|
private const string SPREADSHEET_ID = "1H42653xGbKLxbsDzz7CSR0iaNMz1hU42LX5hWiFtn-Y";
|
|
|
|
private const string API_KEY = "AIzaSyD-tKzeKpAj5sFnbXbj2k4H2RQxipw8B8s";
|
|
|
|
private const string SERVICE_ACCOUNT_EMAIL = "gitlab-runner-dialogue-import@revival-304616.iam.gserviceaccount.com";
|
|
|
|
private const string CERTIFICATE_NAME = "revival-304616-7f150d13c408.p12";
|
|
|
|
|
|
|
|
private static string _workFolder => Path.Combine(Application.dataPath, "Data", "Dialogue");
|
|
|
|
private static string _certificateFile => Path.Combine(_workFolder, CERTIFICATE_NAME);
|
|
|
|
|
|
|
|
// makes a web request via google
|
|
|
|
// returns 0 on success
|
|
|
|
public static int Import()
|
|
|
|
{
|
|
|
|
var certificate = new X509Certificate2(_certificateFile, "notasecret", X509KeyStorageFlags.Exportable);
|
|
|
|
|
|
|
|
var credential = new ServiceAccountCredential(
|
|
|
|
new ServiceAccountCredential.Initializer(SERVICE_ACCOUNT_EMAIL)
|
|
|
|
{
|
|
|
|
Scopes = new[] {SheetsService.Scope.SpreadsheetsReadonly}
|
|
|
|
}.FromCertificate(certificate));
|
|
|
|
|
|
|
|
var service = new SheetsService(new BaseClientService.Initializer()
|
|
|
|
{
|
|
|
|
HttpClientInitializer = credential,
|
|
|
|
ApplicationName = "Kernel Panic - Revival Dialogue Importer",
|
|
|
|
ApiKey = API_KEY
|
|
|
|
});
|
|
|
|
|
|
|
|
// first two columns, ignore first row
|
|
|
|
var range = "Sheet1!A2:B";
|
|
|
|
var request = service.Spreadsheets.Values.Get(SPREADSHEET_ID, range);
|
|
|
|
|
|
|
|
var response = request.Execute();
|
|
|
|
var values = response.Values;
|
|
|
|
|
|
|
|
if (values == null || values.Count == 0)
|
|
|
|
{
|
|
|
|
Debug.LogError("no data");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2021-02-16 00:11:29 +01:00
|
|
|
Debug.Log($":: importing dialogue");
|
2021-02-19 17:26:15 +01:00
|
|
|
var sb = new StringBuilder();
|
2021-02-16 00:26:42 +01:00
|
|
|
var lines = 0;
|
2021-02-15 14:42:14 +01:00
|
|
|
foreach (var row in values)
|
|
|
|
{
|
2021-02-23 14:05:42 +01:00
|
|
|
if (row.Count != 2)
|
|
|
|
{
|
|
|
|
Debug.Log($":: skipping non-matching line: {lines}: {(row.Count == 0 ? "empty" : string.Join(",", row))}");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2021-02-19 17:26:15 +01:00
|
|
|
sb.AppendLine($"{row[0]}{SPLIT_CHAR}{row[1]}");
|
2021-02-16 00:26:42 +01:00
|
|
|
lines++;
|
2021-02-15 14:42:14 +01:00
|
|
|
}
|
2021-02-19 17:26:15 +01:00
|
|
|
Debug.Log($":: imported {lines} lines of dialogue\n{sb}");
|
2021-02-15 14:42:14 +01:00
|
|
|
|
2021-02-19 17:26:15 +01:00
|
|
|
File.WriteAllText(EDITOR_DialogueFile, sb.ToString());
|
2021-02-15 14:42:14 +01:00
|
|
|
if (!File.Exists(EDITOR_DialogueFile))
|
|
|
|
{
|
|
|
|
Debug.LogError($":: import failed: file doesn't exist: {EDITOR_DialogueFile}");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
[MenuItem("ktyl/Import Dialogue")]
|
|
|
|
private static void ImportDialogueMenuItem()
|
|
|
|
{
|
|
|
|
Import();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
public static partial class DialogueDatabase
|
|
|
|
{
|
2021-02-19 17:26:15 +01:00
|
|
|
private const char SPLIT_CHAR = '|';
|
|
|
|
|
|
|
|
public const string DIALOGUE_FILENAME = "dialogue.data";
|
2021-02-15 14:42:14 +01:00
|
|
|
|
|
|
|
public static string DialogueFile
|
|
|
|
{
|
|
|
|
get
|
|
|
|
{
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
// ensure file exists and run import if necessary
|
|
|
|
if (!File.Exists(EDITOR_DialogueFile) && Import() != 0) return null;
|
|
|
|
|
|
|
|
return EDITOR_DialogueFile;
|
|
|
|
#else
|
|
|
|
return Path.Combine(Application.dataPath, DIALOGUE_FILENAME);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static DialogueDatabase()
|
|
|
|
{
|
|
|
|
Debug.Log($":: building dialogue database from file at {DialogueFile}");
|
|
|
|
|
|
|
|
int count = 0;
|
|
|
|
foreach (var line in File.ReadLines(DialogueFile))
|
|
|
|
{
|
2021-02-19 17:26:15 +01:00
|
|
|
var parts = line.Split(SPLIT_CHAR);
|
2021-02-15 14:42:14 +01:00
|
|
|
|
|
|
|
var key = parts[0];
|
|
|
|
var text = parts[1];
|
|
|
|
if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(text))
|
|
|
|
{
|
|
|
|
Debug.LogWarning($"bad line in csv: {line}");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2021-04-16 17:26:42 +02:00
|
|
|
_dict[key] = text.Replace( "\\n", "\n" );
|
2021-02-15 14:42:14 +01:00
|
|
|
count++;
|
|
|
|
}
|
|
|
|
|
|
|
|
Debug.Log($":: imported {count} lines of dialogue");
|
|
|
|
}
|
|
|
|
|
|
|
|
private static readonly Dictionary<string, string> _dict = new Dictionary<string, string>();
|
|
|
|
|
2021-02-22 16:29:17 +01:00
|
|
|
public static string[] Keys => _dict.Keys.ToArray();
|
|
|
|
|
2021-02-15 14:42:14 +01:00
|
|
|
public static string ReadDialogue(string key)
|
|
|
|
{
|
|
|
|
return _dict.ContainsKey(key)
|
|
|
|
? _dict[key]
|
|
|
|
: $"<color=\"red\">MISSING[{key}]</color>";
|
|
|
|
}
|
|
|
|
}
|