Skip to content

Instantly share code, notes, and snippets.

@iggyzuk
Last active January 12, 2020 13:16
Show Gist options
  • Save iggyzuk/08b19e6e9d50f60c408a496ac377489d to your computer and use it in GitHub Desktop.
Save iggyzuk/08b19e6e9d50f60c408a496ac377489d to your computer and use it in GitHub Desktop.
namespace Sheets
{
public class URL
{
const string googleDocsURL = "https://docs.google.com/spreadsheets/d";
const string docID = "1C4SUgFUkcUlmy27nJ2za-kI8DuEnhOKLo3mWyWH_0xw"; // your document ID
const string format = "tsv";
public static string WithSheet(int id)
{
return $"{googleDocsURL}/{docID}/export?gid={id}&format={format}";
}
}
public static class Downloader
{
public static void Download(string URL, Action<string> onSuccess, Action<string> onFail)
{
UnityWebRequest webRequest = UnityWebRequest.Get(URL);
webRequest.SendWebRequest().completed += op =>
{
if (webRequest.isNetworkError) onFail?.Invoke(webRequest.error);
else onSuccess?.Invoke(webRequest.downloadHandler.text);
webRequest.Dispose();
};
}
}
public class Sheet
{
public readonly int ID;
public readonly string FileName;
const string FolderName = "Sheets";
public Sheet(int ID, string fileName)
{
this.ID = ID;
this.FileName = fileName;
string folderPath = GetDataFolderPath();
if (!Directory.Exists(folderPath))
{
Directory.CreateDirectory(folderPath);
}
string filePath = GetFilePath(FileName);
if (!File.Exists(filePath))
{
TextAsset items = Resources.Load<TextAsset>($"{FolderName}/{RemoveExtension(FileName)}");
string versionText = string.Empty;
if (items != null) versionText = items.text;
Write(versionText);
}
}
public string[] Rows()
{
return Read().Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None);
}
public string Read()
{
return File.ReadAllText(GetFilePath(FileName));
}
public void Write(string data)
{
File.WriteAllText(GetFilePath(FileName), data);
}
public void Delete()
{
File.Delete(GetFilePath(FileName));
}
public void Download(Action<string> onSuccess = null)
{
Debug.Log($"Downloading: {FileName}");
Downloader.Download(
URL.WithSheet(ID),
data =>
{
Debug.Log($"Received: {FileName}:\n{data}");
Write(data);
onSuccess?.Invoke(data);
},
error => Debug.LogError(error)
);
}
public static string GetDataFolderPath()
{
return Path.Combine(Application.persistentDataPath, FolderName);
}
public static string GetFilePath(string file)
{
return Path.Combine(GetDataFolderPath(), file);
}
public static string RemoveExtension(string fileName)
{
if (!fileName.Contains(".")) return fileName;
return fileName.Substring(0, fileName.IndexOf("."));
}
}
}
namespace Model
{
public class Version
{
public string build;
public string sheets;
public static bool operator >(Version left, Version right) => left.CompareTo(right) > 0;
public static bool operator <(Version left, Version right) => left.CompareTo(right) < 0;
public static bool operator >=(Version left, Version right) => left.CompareTo(right) >= 0;
public static bool operator <=(Version left, Version right) => left.CompareTo(right) <= 0;
public int CompareTo(Version other)
{
var v1 = new System.Version(build);
var v2 = new System.Version(other.build);
return v1.CompareTo(v2);
}
}
public class Character
{
public string id;
public int damage;
public int health;
public string weapon;
public string power;
}
public class Language
{
public string name;
public Dictionary<string, Word> words = new Dictionary<string, Word>();
}
public class State
{
public Dictionary<string, Character> characters = new Dictionary<string, Character>();
public Dictionary<string, Language> languages = new Dictionary<string, Language>();
}
}
namespace Project
{
public static class Sheets
{
public static readonly VersionSheet version = new VersionSheet();
public static readonly CharactersSheet characters = new CharactersSheet();
public static readonly LangSheet languages = new LangSheet();
}
public class VersionSheet : Sheet
{
public VersionSheet() : base(1587936774, "version.txt") { }
public void Check(Action onUpdate)
{
Downloader.Download(
URL.WithSheet(ID),
data =>
{
Model.Version localVersion = Parse();
localVersion.build = Application.version;
Model.Version remoteVersion = Parse(data);
Debug.Log($"Local: {localVersion} | Remote: {remoteVersion}");
if (localVersion < remoteVersion) return;
if (localVersion.sheets == remoteVersion.sheets) return;
Sheets.version.Write(data);
onUpdate?.Invoke();
},
null
);
}
public Model.Version Parse() => Parse(Read());
public static Model.Version Parse(string data)
{
string[] columns = data.Split('\t');
Model.Version version = new Model.Version();
version.build = columns[0];
version.sheets = columns[1];
return version;
}
}
public class CharactersSheet : Sheet
{
public CharactersSheet() : base(0, "characters.txt") { }
public void Download(Action<Dictionary<string, Model.Character>> onSuccess)
{
base.Download(_ => onSuccess(Parse()));
}
public Dictionary<string, Model.Character> Parse()
{
Dictionary<string, Model.Character> characters = new Dictionary<string, Model.Character>();
string[] rows = Read().Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None);
for (int i = 1; i < rows.Length; i++)
{
string[] columns = rows[i].Split('\t');
Model.Character character = new Model.Character();
character.id = columns[0];
character.damage = int.Parse(columns[1]);
character.health = int.Parse(columns[2]);
character.weapon = columns[3];
character.power = columns[4];
characters.Add(character.id, character);
}
return characters;
}
}
public class LangSheet : Sheet
{
public LangSheet() : base(1834096039, "lang.txt") { }
public void Download(Action<Dictionary<string, Model.Language>> onSuccess)
{
base.Download(_ => onSuccess(Parse()));
}
public Dictionary<string, Model.Language> Parse()
{
Dictionary<string, Model.Language> languages = new Dictionary<string, Model.Language>();
string[] rows = Read().Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None);
string[] langNames = rows[0].Split('\t');
for (int i = 1; i < langNames.Length; i++)
{
Model.Language lang = new Model.Language();
lang.name = langNames[i];
languages.Add(lang.name, lang);
}
for (int i = 1; i < rows.Length; i++)
{
string[] columns = rows[i].Split('\t');
string id = columns[0];
for (int j = 1; j < columns.Length; j++)
{
Model.Word word = new Model.Word();
word.id = id;
word.text = columns[j];
languages[langNames[j]].words.Add(word.id, word);
}
}
return languages;
}
}
// place this somewhere to check version and update the state
sheets.version.Check(() =>
{
sheets.characters.Download(character => state.characters = character);
sheets.languages.Download(languages => state.languages = languages);
});
}
namespace Tools
{
public static class SheetUpdater
{
[MenuItem("Tools/Sheets/Update Sheets")]
public static void UpdateSheets()
{
DeleteSheet();
DownloadSheets();
}
[MenuItem("Tools/Sheets/Download Sheets")]
public static void DownloadSheets()
{
foreach (Sheet sheet in GetSheets())
{
sheet.Download(data =>
{
string path = $"{Application.dataPath}/Resources/Sheets/{sheet.FileName}";
Directory.CreateDirectory(Path.GetDirectoryName(path));
File.WriteAllText(path, data);
AssetDatabase.Refresh();
});
}
}
[MenuItem("Tools/Sheets/Delete Sheets")]
public static void DeleteSheet()
{
foreach (Sheet sheet in GetSheets())
{
sheet.Delete();
Debug.Log($"Deleted: {sheet.FileName}");
}
}
static List<Sheet> GetSheets()
{
return new List<Sheet>
{
new VersionSheet(),
new CharactersSheet(),
new LangSheet()
};
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment