Advertisement
Guest User

Untitled

a guest
Jul 18th, 2019
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 18.41 KB | None | 0 0
  1. using System.Text;
  2. using System.Collections.Generic;
  3. using SimpleJSON;
  4. using System.Text.RegularExpressions;
  5. using XRL.Language;
  6.  
  7. namespace HistoryKit
  8. {
  9.     public static class HistoricStringExpander
  10.     {
  11.         public static void SetVar(Dictionary<string, JSONNode> vars, string key, JSONNode val)
  12.         {
  13.             if (vars.ContainsKey(key))
  14.             {
  15.                 vars[key] = val;
  16.             }
  17.             else
  18.             {
  19.                 vars.Add(key, val);
  20.             }
  21.         }
  22.  
  23.         public static History nullHistory = new History(0);
  24.         public static string ExpandQuery(string query, HistoricEntitySnapshot entity, History history, Dictionary<string, string> vars, Dictionary<string, JSONNode> nodeVars)
  25.         {
  26.             string origQuery = query;
  27.             string ret = query;
  28.             string var = null;
  29.             bool bArticle = false;
  30.             bool bCapitalize = false;
  31.             bool bPossessive = false;
  32.             if (history == null)
  33.             {
  34.                 if (nullHistory == null) nullHistory = new History(0);
  35.                 history = nullHistory;
  36.             }
  37.  
  38.             if (query.Length > 0 && query[0] == '<')
  39.             {
  40.                 query = query.Substring(1, query.Length - 2);
  41.             }
  42.  
  43.             if (query.EndsWith(".capitalize"))
  44.             {
  45.                 query = query.Remove(query.Length - ".capitalize".Length);
  46.                 bCapitalize = true;
  47.             }
  48.  
  49.             if (query.EndsWith(".article"))
  50.             {
  51.                 query = query.Remove(query.Length - ".article".Length);
  52.                 bArticle = true;
  53.             }
  54.  
  55.             if (query.EndsWith(".possessive"))
  56.             {
  57.                 query = query.Remove(query.Length - ".possessive".Length);
  58.                 bPossessive = true;
  59.             }
  60.  
  61.             string[] parts = query.Split('.');
  62.             for (int x = 0; x < parts.Length; x++)
  63.             {
  64.                 if (vars.ContainsKey(parts[x])) parts[x] = vars[parts[x]];
  65.             }
  66.  
  67.             if (parts.Length < 2)
  68.             {
  69.                 string target = null;
  70.                 if (parts[0].Contains("="))
  71.                 {
  72.                     string[] varparts = parts[0].Split('=');
  73.                     parts[0] = varparts[1];
  74.                     var = varparts[0];
  75.                 }
  76.                 else
  77.                 {
  78.                     var = null;
  79.                 }
  80.                 target = parts[0];
  81.  
  82.                 if (nodeVars.ContainsKey(target))
  83.                 {
  84.                     ret = nodeVars[target].Value;
  85.                     goto done;
  86.                 }
  87.                 if (vars.ContainsKey(target))
  88.                 {
  89.                     ret = vars[target];
  90.                     goto done;
  91.                 }
  92.  
  93.                 ret = target;
  94.                 goto done;
  95.             }
  96.             else
  97.             {
  98.                 string target = null;
  99.  
  100.                 if (query.Contains("="))
  101.                 {
  102.                     string[] varparts = query.Split('=');
  103.                     var = varparts[0];
  104.                     parts[0] = varparts[1].Split('.')[0];
  105.                 }
  106.                 else
  107.                 {
  108.                     var = null;
  109.                 }
  110.                 target = parts[0];
  111.  
  112.                 if (target.StartsWith("spice") || target[0] == '$')
  113.                 {
  114.                     JSONNode spiceRoot;
  115.                     JSONNode originalSpiceRoot;
  116.                     if (target == "spice")
  117.                     {
  118.                         spiceRoot = HistoricSpice.root;
  119.                     }
  120.                     else
  121.                     {
  122.                         spiceRoot = nodeVars[target];
  123.                     }
  124.  
  125.                     // resolve spice link
  126.                     for (int x = 1; x < parts.Length; x++)
  127.                     {
  128.                         originalSpiceRoot = spiceRoot;
  129.                         // TODO
  130.                         if (parts[x] == "!random")
  131.                         {
  132.                             if (x == parts.Length - 1)
  133.                             {
  134.                                 JSONClass cl = spiceRoot as JSONClass;
  135.                                 if (cl != null)
  136.                                 {
  137.                                     List<string> keys = cl.GetKeys();
  138.                                     ret = keys[history.Random(0, keys.Count - 1)];
  139.                                     if (!string.IsNullOrEmpty(var) && var[0] == '$')
  140.                                     {
  141.                                         SetVar(nodeVars, var, keys[history.Random(0, keys.Count - 1)]);
  142.                                         return "";
  143.                                     }
  144.                                     goto done;
  145.                                 }
  146.  
  147.                                 JSONNode node = spiceRoot[history.Random(0, spiceRoot.Count - 1)];
  148.                                 if (!string.IsNullOrEmpty(var) && var[0] == '$')
  149.                                 {
  150.                                     SetVar(nodeVars, var, node);
  151.                                     return "";
  152.                                 }
  153.                                 ret = node.Value;
  154.                                 goto done;
  155.                             }
  156.                             else
  157.                             {
  158.                                 int n = 0;
  159.                                 n = history.Random(0, spiceRoot.Count - 1);
  160.  
  161.                                 spiceRoot = spiceRoot[n] as JSONNode;
  162.                                 if (spiceRoot == null)
  163.                                 {
  164.                                     UnityEngine.Debug.LogError("no spice root after random in " + origQuery);
  165.                                     return "";
  166.                                 }
  167.                             }
  168.                         }
  169.                         else
  170.                         {
  171.                             if (parts[x].StartsWith("entity$"))
  172.                             {
  173.                                 string[] subparts = parts[x].Split('$');
  174.  
  175.                                 if (subparts[1].Contains("["))
  176.                                 {
  177.                                     string[] listpropertyparts = subparts[1].Split('[');
  178.                                     listpropertyparts[1] = listpropertyparts[1].Replace("]", "");
  179.  
  180.                                     if (!entity.listProperties.ContainsKey(listpropertyparts[0]))
  181.                                     {
  182.                                         if (!entity.properties.ContainsKey(subparts[1]))
  183.                                         {
  184.                                             if (originalSpiceRoot["_failureredirect"] != null)
  185.                                             {
  186.                                                 StringBuilder newQuery = new StringBuilder(originalSpiceRoot["_failureredirect"]);
  187.                                                 for (int p = x; p < parts.Length; p++)
  188.                                                 {
  189.                                                     newQuery.Append(".");
  190.                                                     newQuery.Append(parts[p]);
  191.                                                 }
  192.                                                 return ExpandQuery(newQuery.ToString(), entity, history, vars, nodeVars);
  193.                                             }
  194.  
  195.                                             if (originalSpiceRoot["_staticfailureredirect"] != null)
  196.                                             {
  197.                                                 return ExpandQuery(originalSpiceRoot["_staticfailureredirect"], entity, history, vars, nodeVars);
  198.                                             }
  199.                                             return "<undefined entity property " + subparts[1] + ">";
  200.                                         }
  201.                                         return "<undefined entity list " + listpropertyparts[0] + ">";
  202.                                     }
  203.  
  204.                                     if (entity.GetList(listpropertyparts[0]).Count == 0) return "<empty entity list " + listpropertyparts[0] + ">";
  205.  
  206.                                     int n = 0;
  207.                                     if (listpropertyparts[1] == "random")
  208.                                     {
  209.                                         n = history.Random(0, entity.GetList(listpropertyparts[0]).Count - 1);
  210.                                     }
  211.                                     else
  212.                                     {
  213.                                         n = int.Parse(listpropertyparts[1]);
  214.                                     }
  215.  
  216.                                     spiceRoot = spiceRoot[entity.GetList(listpropertyparts[0])[n]] as JSONNode;
  217.                                 }
  218.                                 else
  219.                                 {
  220.                                     if (!entity.properties.ContainsKey(subparts[1]))
  221.                                     {
  222.                                         if (originalSpiceRoot["_failureredirect"] != null)
  223.                                         {
  224.                                             StringBuilder newQuery = new StringBuilder(originalSpiceRoot["_failureredirect"]);
  225.                                             for (int p = x; p < parts.Length; p++)
  226.                                             {
  227.                                                 newQuery.Append(".");
  228.                                                 newQuery.Append(parts[p]);
  229.                                             }
  230.                                             return ExpandQuery(newQuery.ToString(), entity, history, vars, nodeVars);
  231.                                         }
  232.  
  233.                                         if (originalSpiceRoot["_staticfailureredirect"] != null)
  234.                                         {
  235.                                             return ExpandQuery(originalSpiceRoot["_staticfailureredirect"], entity, history, vars, nodeVars);
  236.                                         }
  237.                                         return "<undefined entity property " + subparts[1] + ">";
  238.                                     }
  239.                                     spiceRoot = spiceRoot[entity.GetProperty(subparts[1])] as JSONNode;
  240.                                 }
  241.                             }
  242.                             else
  243.                             {
  244.                                 spiceRoot = spiceRoot[parts[x]] as JSONNode;
  245.                                 if (spiceRoot == null)
  246.                                 {
  247.                                     if (originalSpiceRoot["_failureredirect"] != null)
  248.                                     {
  249.                                         StringBuilder newQuery = new StringBuilder(originalSpiceRoot["_failureredirect"]);
  250.                                         for (int p = x; p < parts.Length; p++)
  251.                                         {
  252.                                             newQuery.Append(".");
  253.                                             newQuery.Append(parts[p]);
  254.                                         }
  255.                                         return ExpandQuery(newQuery.ToString(), entity, history, vars, nodeVars);
  256.                                     }
  257.  
  258.                                     if (originalSpiceRoot["_staticfailureredirect"] != null)
  259.                                     {
  260.                                         return ExpandQuery(originalSpiceRoot["_staticfailureredirect"], entity, history, vars, nodeVars);
  261.                                     }
  262.                                 }
  263.                             }
  264.                             if (spiceRoot == null)
  265.                             {
  266.                                 UnityEngine.Debug.LogError("spice reference " + parts[x] + " in " + origQuery + " wasn't a node");
  267.                                 return "";
  268.                             }
  269.  
  270.                             if (x == parts.Length - 1)
  271.                             {
  272.                                 ret = spiceRoot.Value;
  273.                                 if (!string.IsNullOrEmpty(var) && var[0] == '$')
  274.                                 {
  275.                                     SetVar(nodeVars, var, spiceRoot);
  276.                                     return "";
  277.                                 }
  278.                                 goto done;
  279.                             }
  280.                         }
  281.                     }
  282.                 }
  283.                 else
  284.                 if (target.StartsWith("entity"))
  285.                 {
  286.                     HistoricEntitySnapshot targetEntity = entity;
  287.                     if (target.StartsWith("entity["))
  288.                     {
  289.                         targetEntity = history.GetEntity(target.Split('[')[1].Replace("]", "")).GetSnapshotAtYear(history.currentYear);
  290.                     }
  291.  
  292.                     if (targetEntity == null) return "<unknown entity>";
  293.  
  294.                     // just a property
  295.                     if (parts.Length == 2)
  296.                     {
  297.                         if (parts[1].Contains("["))
  298.                         {
  299.                             string[] listpropertyparts = parts[1].Split('[');
  300.                             listpropertyparts[1] = listpropertyparts[1].Replace("]", "");
  301.  
  302.                             if (!entity.listProperties.ContainsKey(listpropertyparts[0])) return "<undefined entity list " + listpropertyparts[0] + ">";
  303.                             if (entity.GetList(listpropertyparts[0]).Count == 0) return "<empty entity list " + listpropertyparts[0] + ">";
  304.  
  305.                             int n = 0;
  306.                             if (listpropertyparts[1] == "random")
  307.                             {
  308.                                 n = history.Random(0, entity.GetList(listpropertyparts[0]).Count - 1);
  309.                             }
  310.                             else
  311.                             {
  312.                                 n = int.Parse(listpropertyparts[1]);
  313.                             }
  314.  
  315.                             ret = targetEntity.GetList(listpropertyparts[0])[n];
  316.                         }
  317.                         else
  318.                         {
  319.                             ret = targetEntity.GetProperty(parts[1]);
  320.                         }
  321.                         goto done;
  322.                     }
  323.                     else
  324.                     {
  325.                         return "<unknown format " + query + ">";
  326.                     }
  327.                 }
  328.                 else
  329.                 if (target.StartsWith("history"))
  330.                 {
  331.  
  332.                 }
  333.             }
  334.  
  335.             done:
  336.  
  337.             if (ret == " ") ret = "";
  338.             if (bArticle && ret.Length > 0)
  339.             {
  340.                 if (ret[0] == '=')
  341.                 {
  342.                     ret = (bCapitalize ? "=Article=" : "=article=") + ret;
  343.                 }
  344.                 else
  345.                 {
  346.                     ret = Grammar.A(ret, bCapitalize);
  347.                 }
  348.                 bCapitalize = false;
  349.             }
  350.             if (bCapitalize && ret.Length > 0)
  351.             {
  352.                 if( ret[0] == '<')
  353.                 {
  354.                     if( ret.Substring(ret.IndexOf('>')-".capitalize".Length) != ".capitalize")
  355.                     {
  356.                         ret = ret.Insert(ret.IndexOf('>'), ".capitalize");
  357.                     }
  358.                 }
  359.                 else
  360.                 if (ret[0] == '=')
  361.                 {
  362.                     ret = "=capitalize=" + ret;
  363.                 }
  364.                 else
  365.                 {
  366.                     ret = char.ToUpper(ret[0]) + ret.Substring(1);
  367.                 }
  368.             }
  369.  
  370.             if (var != null)
  371.             {
  372.                 if (vars.ContainsKey(var))
  373.                 {
  374.                     vars[var] = ret;
  375.                 }
  376.                 else
  377.                 {
  378.                     vars.Add(var, ret);
  379.                 }
  380.                 return "";
  381.             }
  382.  
  383.  
  384.             if (vars != null)
  385.             {
  386.                 foreach (var pair in vars)
  387.                 {
  388.                     int n = 0;
  389.                     while (ret.Contains(pair.Key) && n < 5)
  390.                     {
  391.                         ret.Replace(pair.Key, pair.Value);
  392.                         n++;
  393.                     }
  394.                 }
  395.             }
  396.  
  397.             return ret;
  398.         }
  399.  
  400.         public static string ExpandString(string input)
  401.         {
  402.             return ExpandString(input, null, null);
  403.         }
  404.  
  405.         public static string ExpandString(string input, HistoricEntitySnapshot entity, History history, Dictionary<string, string> vars = null)
  406.         {
  407.             if (string.IsNullOrEmpty(input)) return "";
  408.             if (history == null)
  409.             {
  410.                 if (nullHistory == null) nullHistory = new History(0);
  411.                 history = nullHistory;
  412.             }
  413.             HistoricSpice.Init();
  414.  
  415.             StringBuilder sb = new StringBuilder(input);
  416.  
  417.             if (vars == null) vars = new Dictionary<string, string>();
  418.             Dictionary<string, JSONNode> nodeVars = new Dictionary<string, JSONNode>();
  419.             Match HeaderMatches = Regex.Match(input, @"<.*?>");
  420.  
  421.             int n = 0;
  422.             while (HeaderMatches != null && !string.IsNullOrEmpty(HeaderMatches.Value))
  423.             {
  424.                 int pos = HeaderMatches.Groups[0].Index;
  425.                 int len = HeaderMatches.Groups[0].Length;
  426.  
  427.                 sb.Remove(pos, len);
  428.                 sb.Insert(pos, ExpandQuery(HeaderMatches.Groups[0].Value, entity, history, vars, nodeVars));
  429.                 if (sb.Equals(input)) break;
  430.                 n++;
  431.                 if (n > 25)
  432.                 {
  433.                     UnityEngine.Debug.LogError("Maximum recursion reached on " + input + " current " + sb.ToString());
  434.                     break;
  435.                 }
  436.                 HeaderMatches = Regex.Match(sb.ToString(), @"<.*?>");
  437.             }
  438.  
  439.             if (vars != null)
  440.             {
  441.                 foreach (var pair in vars)
  442.                 {
  443.                     n = 0;
  444.                     while (sb.Contains(pair.Key) && n < 5)
  445.                     {
  446.                         sb.Replace(pair.Key, pair.Value);
  447.                         n++;
  448.                     }
  449.                 }
  450.             }
  451.  
  452.             return sb.ToString();
  453.         }
  454.     }
  455. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement