├── Assets ├── Data.meta ├── Data │ ├── MySpreadSheet.asset │ ├── MySpreadSheet.asset.meta │ ├── Test.prefab │ └── Test.prefab.meta ├── Editor.meta ├── Editor │ ├── GDataDB.meta │ ├── GDataDB │ │ ├── GDataDB.Linq.meta │ │ ├── GDataDB.Linq │ │ │ ├── ITableExtensions.cs │ │ │ ├── ITableExtensions.cs.meta │ │ │ ├── Impl.meta │ │ │ └── Impl │ │ │ │ ├── Evaluator.cs │ │ │ │ ├── Evaluator.cs.meta │ │ │ │ ├── ExpressionVisitor.cs │ │ │ │ ├── ExpressionVisitor.cs.meta │ │ │ │ ├── GDataDBQueryProvider.cs │ │ │ │ ├── GDataDBQueryProvider.cs.meta │ │ │ │ ├── OrderTranslator.cs │ │ │ │ ├── OrderTranslator.cs.meta │ │ │ │ ├── Query.cs │ │ │ │ ├── Query.cs.meta │ │ │ │ ├── QueryProvider.cs │ │ │ │ ├── QueryProvider.cs.meta │ │ │ │ ├── QueryTranslator.cs │ │ │ │ ├── QueryTranslator.cs.meta │ │ │ │ ├── TypeSystem.cs │ │ │ │ ├── TypeSystem.cs.meta │ │ │ │ ├── WhereTranslator.cs │ │ │ │ └── WhereTranslator.cs.meta │ │ ├── GDataDB.meta │ │ ├── GDataDB │ │ │ ├── DatabaseClient.cs │ │ │ ├── DatabaseClient.cs.meta │ │ │ ├── IDatabase.cs │ │ │ ├── IDatabase.cs.meta │ │ │ ├── IDatabaseClient.cs │ │ │ ├── IDatabaseClient.cs.meta │ │ │ ├── IRow.cs │ │ │ ├── IRow.cs.meta │ │ │ ├── ITable.cs │ │ │ ├── ITable.cs.meta │ │ │ ├── Impl.meta │ │ │ ├── Impl │ │ │ │ ├── .svn │ │ │ │ │ ├── all-wcprops │ │ │ │ │ ├── entries │ │ │ │ │ └── text-base │ │ │ │ │ │ ├── Database.cs.meta.svn-base │ │ │ │ │ │ ├── Database.cs.svn-base │ │ │ │ │ │ ├── Row.cs.meta.svn-base │ │ │ │ │ │ ├── Row.cs.svn-base │ │ │ │ │ │ ├── Serializer.cs.meta.svn-base │ │ │ │ │ │ ├── Serializer.cs.svn-base │ │ │ │ │ │ ├── Table.cs.meta.svn-base │ │ │ │ │ │ └── Table.cs.svn-base │ │ │ │ ├── Database.cs │ │ │ │ ├── Database.cs.meta │ │ │ │ ├── Row.cs │ │ │ │ ├── Row.cs.meta │ │ │ │ ├── Serializer.cs │ │ │ │ ├── Serializer.cs.meta │ │ │ │ ├── Table.cs │ │ │ │ └── Table.cs.meta │ │ │ ├── Order.cs │ │ │ ├── Order.cs.meta │ │ │ ├── Query.cs │ │ │ └── Query.cs.meta │ │ ├── README.md │ │ ├── README.md.meta │ │ ├── license.txt │ │ └── license.txt.meta │ ├── Google.meta │ ├── Google │ │ ├── Google.GData.AccessControl.DLL │ │ ├── Google.GData.AccessControl.DLL.meta │ │ ├── Google.GData.Client.dll │ │ ├── Google.GData.Client.dll.meta │ │ ├── Google.GData.Documents.dll │ │ ├── Google.GData.Documents.dll.meta │ │ ├── Google.GData.Extensions.dll │ │ ├── Google.GData.Extensions.dll.meta │ │ ├── Google.GData.Spreadsheets.dll │ │ └── Google.GData.Spreadsheets.dll.meta │ ├── Util.meta │ └── Util │ │ ├── CustomAssetUtility.cs │ │ └── CustomAssetUtility.cs.meta ├── Scene.meta ├── Scene │ ├── Test.unity │ └── Test.unity.meta ├── Script.meta └── Script │ ├── Data.meta │ ├── Data │ ├── Editor.meta │ ├── Editor │ │ ├── GoogleDataAssetUtility.cs │ │ ├── GoogleDataAssetUtility.cs.meta │ │ ├── MySpreadSheetEditor.cs │ │ └── MySpreadSheetEditor.cs.meta │ ├── Runtime.meta │ └── Runtime │ │ ├── MySpreadSheet.cs │ │ └── MySpreadSheet.cs.meta │ ├── GDataPlugin.meta │ ├── GDataPlugin │ ├── Editor.meta │ ├── Editor │ │ ├── BaseEditor.cs │ │ ├── BaseEditor.cs.meta │ │ ├── ExposeProperties.cs │ │ ├── ExposeProperties.cs.meta │ │ ├── GoogleDataSettings.asset │ │ ├── GoogleDataSettings.asset.meta │ │ ├── GoogleDataSettings.cs │ │ ├── GoogleDataSettings.cs.meta │ │ ├── GoogleDataSettingsEditor.cs │ │ └── GoogleDataSettingsEditor.cs.meta │ ├── Runtime.meta │ └── Runtime │ │ ├── BaseDatabase.cs │ │ ├── BaseDatabase.cs.meta │ │ ├── ExposePropertyAttribute.cs │ │ └── ExposePropertyAttribute.cs.meta │ ├── Test.meta │ ├── Test │ ├── Test.cs │ └── Test.cs.meta │ ├── Util.meta │ └── Util │ ├── Cloner.cs │ ├── Cloner.cs.meta │ ├── CsvParser.cs │ ├── CsvParser.cs.meta │ ├── Singleton.cs │ └── Singleton.cs.meta ├── ProjectSettings ├── AudioManager.asset ├── DynamicsManager.asset ├── EditorBuildSettings.asset ├── EditorSettings.asset ├── InputManager.asset ├── NavMeshLayers.asset ├── NetworkManager.asset ├── ProjectSettings.asset ├── QualitySettings.asset ├── TagManager.asset └── TimeManager.asset ├── README.md └── images ├── connect.png ├── connect02.png ├── download.png ├── gdata_cells.png ├── gdata_title.png └── gdata_worksheet.png /Assets/Data.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: dbbbba98bfc3c4e2eaa3f4b65ffc4046 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Data/MySpreadSheet.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kimsama/Unity-GoogleData/09acc58f0c2fb6be41f8d8189b00784436850628/Assets/Data/MySpreadSheet.asset -------------------------------------------------------------------------------- /Assets/Data/MySpreadSheet.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e257710642b8c4b228b8e38e462bb1f3 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Data/Test.prefab: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kimsama/Unity-GoogleData/09acc58f0c2fb6be41f8d8189b00784436850628/Assets/Data/Test.prefab -------------------------------------------------------------------------------- /Assets/Data/Test.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 93ddec517ced04a5aad01114eb7098f4 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 325cf23ee6d094e7b96c2067ef0f2f99 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Editor/GDataDB.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 932da3dfaa46f45ab8abd672c6991f14 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB.Linq.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c0daa3662364c96498be5dfc3ed3a465 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB.Linq/ITableExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using GDataDB.Linq.Impl; 3 | 4 | namespace GDataDB.Linq { 5 | public static class ITableExtensions { 6 | public static IQueryable AsQueryable(this ITable t) { 7 | return new Query(new GDataDBQueryProvider(t)); 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB.Linq/ITableExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 83bfee35edbe9d546af8c7ca651b7f02 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB.Linq/Impl.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6adafc9a696233f4cae0972c63f0dedf 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB.Linq/Impl/Evaluator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq.Expressions; 4 | 5 | namespace GDataDB.Linq.Impl { 6 | /// 7 | /// From http://blogs.msdn.com/mattwar/archive/2007/08/01/linq-building-an-iqueryable-provider-part-iii.aspx 8 | /// 9 | public static class Evaluator { 10 | /// 11 | /// Performs evaluation & replacement of independent sub-trees 12 | /// 13 | /// The root of the expression tree. 14 | /// A function that decides whether a given expression node can be part of the local function. 15 | /// A new tree with sub-trees evaluated and replaced. 16 | public static Expression PartialEval(Expression expression, Func fnCanBeEvaluated) { 17 | return new SubtreeEvaluator(new Nominator(fnCanBeEvaluated).Nominate(expression)).Eval(expression); 18 | } 19 | 20 | 21 | /// 22 | /// Performs evaluation & replacement of independent sub-trees 23 | /// 24 | /// The root of the expression tree. 25 | /// A new tree with sub-trees evaluated and replaced. 26 | public static Expression PartialEval(Expression expression) { 27 | return PartialEval(expression, CanBeEvaluatedLocally); 28 | } 29 | 30 | 31 | private static bool CanBeEvaluatedLocally(Expression expression) { 32 | return expression.NodeType != ExpressionType.Parameter; 33 | } 34 | 35 | 36 | /// 37 | /// Evaluates & replaces sub-trees when first candidate is reached (top-down) 38 | /// 39 | private class SubtreeEvaluator : ExpressionVisitor { 40 | private readonly HashSet candidates; 41 | 42 | 43 | internal SubtreeEvaluator(HashSet candidates) { 44 | this.candidates = candidates; 45 | } 46 | 47 | 48 | internal Expression Eval(Expression exp) { 49 | return Visit(exp); 50 | } 51 | 52 | 53 | protected override Expression Visit(Expression exp) { 54 | if (exp == null) { 55 | return null; 56 | } 57 | 58 | if (candidates.Contains(exp)) { 59 | return Evaluate(exp); 60 | } 61 | 62 | return base.Visit(exp); 63 | } 64 | 65 | 66 | private Expression Evaluate(Expression e) { 67 | if (e.NodeType == ExpressionType.Constant) { 68 | return e; 69 | } 70 | 71 | LambdaExpression lambda = Expression.Lambda(e); 72 | 73 | Delegate fn = lambda.Compile(); 74 | 75 | return Expression.Constant(fn.DynamicInvoke(null), e.Type); 76 | } 77 | } 78 | 79 | 80 | /// 81 | /// Performs bottom-up analysis to determine which nodes can possibly 82 | /// be part of an evaluated sub-tree. 83 | /// 84 | private class Nominator : ExpressionVisitor { 85 | private readonly Func fnCanBeEvaluated; 86 | 87 | private HashSet candidates; 88 | 89 | private bool cannotBeEvaluated; 90 | 91 | 92 | internal Nominator(Func fnCanBeEvaluated) { 93 | this.fnCanBeEvaluated = fnCanBeEvaluated; 94 | } 95 | 96 | 97 | internal HashSet Nominate(Expression expression) { 98 | candidates = new HashSet(); 99 | 100 | Visit(expression); 101 | 102 | return candidates; 103 | } 104 | 105 | 106 | protected override Expression Visit(Expression expression) { 107 | if (expression != null) { 108 | bool saveCannotBeEvaluated = cannotBeEvaluated; 109 | 110 | cannotBeEvaluated = false; 111 | 112 | base.Visit(expression); 113 | 114 | if (!cannotBeEvaluated) { 115 | if (fnCanBeEvaluated(expression)) { 116 | candidates.Add(expression); 117 | } else { 118 | cannotBeEvaluated = true; 119 | } 120 | } 121 | 122 | cannotBeEvaluated |= saveCannotBeEvaluated; 123 | } 124 | 125 | return expression; 126 | } 127 | } 128 | } 129 | } -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB.Linq/Impl/Evaluator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d1d631e8a699e9043af266d2931b61a8 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB.Linq/Impl/ExpressionVisitor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.ObjectModel; 4 | using System.Linq.Expressions; 5 | 6 | namespace GDataDB.Linq.Impl { 7 | /// 8 | /// From http://blogs.msdn.com/mattwar/archive/2007/07/31/linq-building-an-iqueryable-provider-part-ii.aspx 9 | /// 10 | public abstract class ExpressionVisitor { 11 | protected virtual Expression Visit(Expression exp) { 12 | if (exp == null) 13 | return exp; 14 | switch (exp.NodeType) { 15 | case ExpressionType.Negate: 16 | case ExpressionType.NegateChecked: 17 | case ExpressionType.Not: 18 | case ExpressionType.Convert: 19 | case ExpressionType.ConvertChecked: 20 | case ExpressionType.ArrayLength: 21 | case ExpressionType.Quote: 22 | case ExpressionType.TypeAs: 23 | return VisitUnary((UnaryExpression) exp); 24 | case ExpressionType.Add: 25 | case ExpressionType.AddChecked: 26 | case ExpressionType.Subtract: 27 | case ExpressionType.SubtractChecked: 28 | case ExpressionType.Multiply: 29 | case ExpressionType.MultiplyChecked: 30 | case ExpressionType.Divide: 31 | case ExpressionType.Modulo: 32 | case ExpressionType.And: 33 | case ExpressionType.AndAlso: 34 | case ExpressionType.Or: 35 | case ExpressionType.OrElse: 36 | case ExpressionType.LessThan: 37 | case ExpressionType.LessThanOrEqual: 38 | case ExpressionType.GreaterThan: 39 | case ExpressionType.GreaterThanOrEqual: 40 | case ExpressionType.Equal: 41 | case ExpressionType.NotEqual: 42 | case ExpressionType.Coalesce: 43 | case ExpressionType.ArrayIndex: 44 | case ExpressionType.RightShift: 45 | case ExpressionType.LeftShift: 46 | case ExpressionType.ExclusiveOr: 47 | return VisitBinary((BinaryExpression) exp); 48 | case ExpressionType.TypeIs: 49 | return VisitTypeIs((TypeBinaryExpression) exp); 50 | case ExpressionType.Conditional: 51 | return VisitConditional((ConditionalExpression) exp); 52 | case ExpressionType.Constant: 53 | return VisitConstant((ConstantExpression) exp); 54 | case ExpressionType.Parameter: 55 | return VisitParameter((ParameterExpression) exp); 56 | case ExpressionType.MemberAccess: 57 | return VisitMemberAccess((MemberExpression) exp); 58 | case ExpressionType.Call: 59 | return VisitMethodCall((MethodCallExpression) exp); 60 | case ExpressionType.Lambda: 61 | return VisitLambda((LambdaExpression) exp); 62 | case ExpressionType.New: 63 | return VisitNew((NewExpression) exp); 64 | case ExpressionType.NewArrayInit: 65 | case ExpressionType.NewArrayBounds: 66 | return VisitNewArray((NewArrayExpression) exp); 67 | case ExpressionType.Invoke: 68 | return VisitInvocation((InvocationExpression) exp); 69 | case ExpressionType.MemberInit: 70 | return VisitMemberInit((MemberInitExpression) exp); 71 | case ExpressionType.ListInit: 72 | return VisitListInit((ListInitExpression) exp); 73 | default: 74 | throw new Exception(string.Format("Unhandled expression type: '{0}'", exp.NodeType)); 75 | } 76 | } 77 | 78 | protected virtual MemberBinding VisitBinding(MemberBinding binding) { 79 | switch (binding.BindingType) { 80 | case MemberBindingType.Assignment: 81 | return VisitMemberAssignment((MemberAssignment) binding); 82 | case MemberBindingType.MemberBinding: 83 | return VisitMemberMemberBinding((MemberMemberBinding) binding); 84 | case MemberBindingType.ListBinding: 85 | return VisitMemberListBinding((MemberListBinding) binding); 86 | default: 87 | throw new Exception(string.Format("Unhandled binding type '{0}'", binding.BindingType)); 88 | } 89 | } 90 | 91 | protected virtual ElementInit VisitElementInitializer(ElementInit initializer) { 92 | ReadOnlyCollection arguments = VisitExpressionList(initializer.Arguments); 93 | if (arguments != initializer.Arguments) { 94 | return Expression.ElementInit(initializer.AddMethod, arguments); 95 | } 96 | return initializer; 97 | } 98 | 99 | protected virtual Expression VisitUnary(UnaryExpression u) { 100 | Expression operand = Visit(u.Operand); 101 | if (operand != u.Operand) { 102 | return Expression.MakeUnary(u.NodeType, operand, u.Type, u.Method); 103 | } 104 | return u; 105 | } 106 | 107 | protected virtual Expression VisitBinary(BinaryExpression b) { 108 | Expression left = Visit(b.Left); 109 | Expression right = Visit(b.Right); 110 | Expression conversion = Visit(b.Conversion); 111 | if (left != b.Left || right != b.Right || conversion != b.Conversion) { 112 | if (b.NodeType == ExpressionType.Coalesce && b.Conversion != null) 113 | return Expression.Coalesce(left, right, conversion as LambdaExpression); 114 | return Expression.MakeBinary(b.NodeType, left, right, b.IsLiftedToNull, b.Method); 115 | } 116 | return b; 117 | } 118 | 119 | protected virtual Expression VisitTypeIs(TypeBinaryExpression b) { 120 | Expression expr = Visit(b.Expression); 121 | if (expr != b.Expression) { 122 | return Expression.TypeIs(expr, b.TypeOperand); 123 | } 124 | return b; 125 | } 126 | 127 | protected virtual Expression VisitConstant(ConstantExpression c) { 128 | return c; 129 | } 130 | 131 | protected virtual Expression VisitConditional(ConditionalExpression c) { 132 | Expression test = Visit(c.Test); 133 | Expression ifTrue = Visit(c.IfTrue); 134 | Expression ifFalse = Visit(c.IfFalse); 135 | if (test != c.Test || ifTrue != c.IfTrue || ifFalse != c.IfFalse) { 136 | return Expression.Condition(test, ifTrue, ifFalse); 137 | } 138 | return c; 139 | } 140 | 141 | protected virtual Expression VisitParameter(ParameterExpression p) { 142 | return p; 143 | } 144 | 145 | protected virtual Expression VisitMemberAccess(MemberExpression m) { 146 | Expression exp = Visit(m.Expression); 147 | if (exp != m.Expression) { 148 | return Expression.MakeMemberAccess(exp, m.Member); 149 | } 150 | return m; 151 | } 152 | 153 | protected virtual Expression VisitMethodCall(MethodCallExpression m) { 154 | Expression obj = Visit(m.Object); 155 | IEnumerable args = VisitExpressionList(m.Arguments); 156 | if (obj != m.Object || args != m.Arguments) { 157 | return Expression.Call(obj, m.Method, args); 158 | } 159 | return m; 160 | } 161 | 162 | protected virtual ReadOnlyCollection VisitExpressionList(ReadOnlyCollection original) { 163 | List list = null; 164 | for (int i = 0, n = original.Count; i < n; i++) { 165 | Expression p = Visit(original[i]); 166 | if (list != null) { 167 | list.Add(p); 168 | } else if (p != original[i]) { 169 | list = new List(n); 170 | for (int j = 0; j < i; j++) { 171 | list.Add(original[j]); 172 | } 173 | list.Add(p); 174 | } 175 | } 176 | if (list != null) { 177 | return list.AsReadOnly(); 178 | } 179 | return original; 180 | } 181 | 182 | protected virtual MemberAssignment VisitMemberAssignment(MemberAssignment assignment) { 183 | Expression e = Visit(assignment.Expression); 184 | if (e != assignment.Expression) { 185 | return Expression.Bind(assignment.Member, e); 186 | } 187 | return assignment; 188 | } 189 | 190 | protected virtual MemberMemberBinding VisitMemberMemberBinding(MemberMemberBinding binding) { 191 | IEnumerable bindings = VisitBindingList(binding.Bindings); 192 | if (bindings != binding.Bindings) { 193 | return Expression.MemberBind(binding.Member, bindings); 194 | } 195 | return binding; 196 | } 197 | 198 | protected virtual MemberListBinding VisitMemberListBinding(MemberListBinding binding) { 199 | IEnumerable initializers = VisitElementInitializerList(binding.Initializers); 200 | if (initializers != binding.Initializers) { 201 | return Expression.ListBind(binding.Member, initializers); 202 | } 203 | return binding; 204 | } 205 | 206 | protected virtual IEnumerable VisitBindingList(ReadOnlyCollection original) { 207 | List list = null; 208 | for (int i = 0, n = original.Count; i < n; i++) { 209 | MemberBinding b = VisitBinding(original[i]); 210 | if (list != null) { 211 | list.Add(b); 212 | } else if (b != original[i]) { 213 | list = new List(n); 214 | for (int j = 0; j < i; j++) { 215 | list.Add(original[j]); 216 | } 217 | list.Add(b); 218 | } 219 | } 220 | if (list != null) 221 | return list; 222 | return original; 223 | } 224 | 225 | protected virtual IEnumerable VisitElementInitializerList(ReadOnlyCollection original) { 226 | List list = null; 227 | for (int i = 0, n = original.Count; i < n; i++) { 228 | ElementInit init = VisitElementInitializer(original[i]); 229 | if (list != null) { 230 | list.Add(init); 231 | } else if (init != original[i]) { 232 | list = new List(n); 233 | for (int j = 0; j < i; j++) { 234 | list.Add(original[j]); 235 | } 236 | list.Add(init); 237 | } 238 | } 239 | if (list != null) 240 | return list; 241 | return original; 242 | } 243 | 244 | protected virtual Expression VisitLambda(LambdaExpression lambda) { 245 | Expression body = Visit(lambda.Body); 246 | if (body != lambda.Body) { 247 | return Expression.Lambda(lambda.Type, body, lambda.Parameters); 248 | } 249 | return lambda; 250 | } 251 | 252 | protected virtual NewExpression VisitNew(NewExpression nex) { 253 | IEnumerable args = VisitExpressionList(nex.Arguments); 254 | if (args != nex.Arguments) { 255 | if (nex.Members != null) 256 | return Expression.New(nex.Constructor, args, nex.Members); 257 | return Expression.New(nex.Constructor, args); 258 | } 259 | return nex; 260 | } 261 | 262 | protected virtual Expression VisitMemberInit(MemberInitExpression init) { 263 | NewExpression n = VisitNew(init.NewExpression); 264 | IEnumerable bindings = VisitBindingList(init.Bindings); 265 | if (n != init.NewExpression || bindings != init.Bindings) { 266 | return Expression.MemberInit(n, bindings); 267 | } 268 | return init; 269 | } 270 | 271 | protected virtual Expression VisitListInit(ListInitExpression init) { 272 | NewExpression n = VisitNew(init.NewExpression); 273 | IEnumerable initializers = VisitElementInitializerList(init.Initializers); 274 | if (n != init.NewExpression || initializers != init.Initializers) { 275 | return Expression.ListInit(n, initializers); 276 | } 277 | return init; 278 | } 279 | 280 | protected virtual Expression VisitNewArray(NewArrayExpression na) { 281 | IEnumerable exprs = VisitExpressionList(na.Expressions); 282 | if (exprs != na.Expressions) { 283 | if (na.NodeType == ExpressionType.NewArrayInit) { 284 | return Expression.NewArrayInit(na.Type.GetElementType(), exprs); 285 | } 286 | return Expression.NewArrayBounds(na.Type.GetElementType(), exprs); 287 | } 288 | return na; 289 | } 290 | 291 | protected virtual Expression VisitInvocation(InvocationExpression iv) { 292 | IEnumerable args = VisitExpressionList(iv.Arguments); 293 | Expression expr = Visit(iv.Expression); 294 | if (args != iv.Arguments || expr != iv.Expression) { 295 | return Expression.Invoke(expr, args); 296 | } 297 | return iv; 298 | } 299 | } 300 | } -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB.Linq/Impl/ExpressionVisitor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2a618029a4798c847870da8e33f2cfa0 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB.Linq/Impl/GDataDBQueryProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Linq.Expressions; 4 | 5 | namespace GDataDB.Linq.Impl { 6 | public class GDataDBQueryProvider : QueryProvider { 7 | private readonly ITable table; 8 | 9 | public GDataDBQueryProvider(ITable table) { 10 | this.table = table; 11 | } 12 | 13 | public override Query GetQuery(Expression expression) { 14 | expression = Evaluator.PartialEval(expression); 15 | return new QueryTranslator().Translate(expression); 16 | } 17 | 18 | public override object Execute(Expression expression) { 19 | return table.Find(GetQuery(expression)).Select(r => r.Element); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB.Linq/Impl/GDataDBQueryProvider.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9039df8209d16de4fb45a277a45f018d 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB.Linq/Impl/OrderTranslator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | 4 | namespace GDataDB.Linq.Impl { 5 | public class OrderTranslator : ExpressionVisitor { 6 | private string columnName; 7 | private bool descending; 8 | 9 | public Order Translate(Expression e) { 10 | Visit(e); 11 | if (columnName == null) 12 | return null; 13 | return new Order {ColumnName = columnName, Descending = descending}; 14 | } 15 | 16 | protected override Expression VisitMethodCall(MethodCallExpression m) { 17 | if (m.Arguments.Count > 2) 18 | throw new NotSupportedException("OrderBy with comparer is not supported"); 19 | if (m.Method.Name == "OrderBy") { 20 | Visit(m.Arguments[1]); 21 | } else if (m.Method.Name == "OrderByDescending") { 22 | descending = true; 23 | Visit(m.Arguments[1]); 24 | } 25 | return m; 26 | } 27 | 28 | protected override Expression VisitMemberAccess(MemberExpression m) { 29 | columnName = m.Member.Name.ToLowerInvariant(); 30 | return m; 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB.Linq/Impl/OrderTranslator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fa806d201eff6ce40a3649f5240c8d55 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB.Linq/Impl/Query.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Linq.Expressions; 6 | 7 | namespace GDataDB.Linq.Impl { 8 | /// 9 | /// From http://blogs.msdn.com/mattwar/archive/2007/07/30/linq-building-an-iqueryable-provider-part-i.aspx 10 | /// 11 | /// 12 | public class Query : IOrderedQueryable { 13 | private readonly QueryProvider provider; 14 | private readonly Expression expression; 15 | 16 | public Query(QueryProvider provider) { 17 | if (provider == null) { 18 | throw new ArgumentNullException("provider"); 19 | } 20 | this.provider = provider; 21 | expression = Expression.Constant(this); 22 | } 23 | 24 | public Query(QueryProvider provider, Expression expression) { 25 | if (provider == null) { 26 | throw new ArgumentNullException("provider"); 27 | } 28 | if (expression == null) { 29 | throw new ArgumentNullException("expression"); 30 | } 31 | if (!typeof (IQueryable).IsAssignableFrom(expression.Type)) { 32 | throw new ArgumentOutOfRangeException("expression"); 33 | } 34 | this.provider = provider; 35 | this.expression = expression; 36 | } 37 | 38 | Expression IQueryable.Expression { 39 | get { return expression; } 40 | } 41 | 42 | Type IQueryable.ElementType { 43 | get { return typeof (T); } 44 | } 45 | 46 | IQueryProvider IQueryable.Provider { 47 | get { return provider; } 48 | } 49 | 50 | public IEnumerator GetEnumerator() { 51 | return ((IEnumerable) provider.Execute(expression)).GetEnumerator(); 52 | } 53 | 54 | public override string ToString() { 55 | return ToQuery().StructuredQuery; 56 | } 57 | 58 | public Query ToQuery() { 59 | return provider.GetQuery(expression); 60 | } 61 | 62 | IEnumerator IEnumerable.GetEnumerator() { 63 | return GetEnumerator(); 64 | } 65 | } 66 | } -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB.Linq/Impl/Query.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8b3c7a9f093498044a39ef0b26a3fd1f 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB.Linq/Impl/QueryProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Linq.Expressions; 4 | using System.Reflection; 5 | 6 | namespace GDataDB.Linq.Impl { 7 | /// 8 | /// From http://blogs.msdn.com/mattwar/archive/2007/07/30/linq-building-an-iqueryable-provider-part-i.aspx 9 | /// 10 | public abstract class QueryProvider : IQueryProvider { 11 | IQueryable IQueryProvider.CreateQuery(Expression expression) { 12 | return new Query(this, expression); 13 | } 14 | 15 | IQueryable IQueryProvider.CreateQuery(Expression expression) { 16 | Type elementType = TypeSystem.GetElementType(expression.Type); 17 | try { 18 | return (IQueryable) Activator.CreateInstance(typeof (Query<>).MakeGenericType(elementType), new object[] {this, expression}); 19 | } catch (TargetInvocationException tie) { 20 | throw tie.InnerException; 21 | } 22 | } 23 | 24 | public abstract Query GetQuery(Expression expression); 25 | public abstract object Execute(Expression expression); 26 | 27 | public TResult Execute(Expression expression) { 28 | return (TResult) Execute(expression); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB.Linq/Impl/QueryProvider.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c31f8498ad9b84e43a30702be2471e54 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB.Linq/Impl/QueryTranslator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | 4 | namespace GDataDB.Linq.Impl { 5 | public class QueryTranslator : ExpressionVisitor { 6 | private readonly Query q = new Query(); 7 | 8 | public Query Translate(Expression e) { 9 | Visit(e); 10 | return q; 11 | } 12 | 13 | protected override Expression VisitMethodCall(MethodCallExpression m) { 14 | Visit(m.Arguments[0]); 15 | switch (m.Method.Name) { 16 | case "Where": 17 | q.StructuredQuery = new WhereTranslator().Translate(m); 18 | break; 19 | case "OrderBy": 20 | case "OrderByDescending": 21 | q.Order = new OrderTranslator().Translate(m); 22 | break; 23 | case "Take": 24 | q.Count = (int)((ConstantExpression)m.Arguments[1]).Value; 25 | break; 26 | case "Skip": 27 | q.Start = (int)((ConstantExpression)m.Arguments[1]).Value+1; 28 | break; 29 | default: 30 | throw new NotSupportedException(string.Format("Method {0} not supported", m.Method.Name)); 31 | } 32 | return m; 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB.Linq/Impl/QueryTranslator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 02d94f44794cb354b98e6a800cb6f058 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB.Linq/Impl/TypeSystem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace GDataDB.Linq.Impl { 5 | /// 6 | /// From http://blogs.msdn.com/mattwar/archive/2007/07/30/linq-building-an-iqueryable-provider-part-i.aspx 7 | /// 8 | internal static class TypeSystem { 9 | internal static Type GetElementType(Type seqType) { 10 | Type ienum = FindIEnumerable(seqType); 11 | if (ienum == null) return seqType; 12 | return ienum.GetGenericArguments()[0]; 13 | } 14 | 15 | private static Type FindIEnumerable(Type seqType) { 16 | if (seqType == null || seqType == typeof (string)) 17 | return null; 18 | if (seqType.IsArray) 19 | return typeof (IEnumerable<>).MakeGenericType(seqType.GetElementType()); 20 | if (seqType.IsGenericType) { 21 | foreach (var arg in seqType.GetGenericArguments()) { 22 | Type ienum = typeof (IEnumerable<>).MakeGenericType(arg); 23 | if (ienum.IsAssignableFrom(seqType)) { 24 | return ienum; 25 | } 26 | } 27 | } 28 | Type[] ifaces = seqType.GetInterfaces(); 29 | if (ifaces != null && ifaces.Length > 0) { 30 | foreach (var iface in ifaces) { 31 | Type ienum = FindIEnumerable(iface); 32 | if (ienum != null) return ienum; 33 | } 34 | } 35 | if (seqType.BaseType != null && seqType.BaseType != typeof (object)) { 36 | return FindIEnumerable(seqType.BaseType); 37 | } 38 | return null; 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB.Linq/Impl/TypeSystem.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bda6aa3f72177614393eac35b259f235 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB.Linq/Impl/WhereTranslator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | using System.Text; 4 | 5 | namespace GDataDB.Linq.Impl { 6 | public class WhereTranslator : ExpressionVisitor { 7 | private readonly StringBuilder sb = new StringBuilder(); 8 | 9 | public string Translate(Expression e) { 10 | Visit(e); 11 | return sb.ToString(); 12 | } 13 | 14 | protected override Expression VisitMethodCall(MethodCallExpression m) { 15 | if (m.Method.Name == "Where") { 16 | Visit(m.Arguments[1]); 17 | } 18 | return m; 19 | } 20 | 21 | protected override Expression VisitBinary(BinaryExpression b) { 22 | sb.Append("("); 23 | switch (b.NodeType) { 24 | case ExpressionType.And: 25 | case ExpressionType.AndAlso: 26 | Visit(b.Left); 27 | sb.Append("&&"); 28 | Visit(b.Right); 29 | break; 30 | case ExpressionType.Or: 31 | case ExpressionType.OrElse: 32 | Visit(b.Left); 33 | sb.Append("||"); 34 | Visit(b.Right); 35 | break; 36 | case ExpressionType.Equal: 37 | Visit(b.Left); 38 | sb.Append("="); 39 | Visit(b.Right); 40 | break; 41 | case ExpressionType.NotEqual: 42 | Visit(b.Left); 43 | sb.Append("!="); 44 | Visit(b.Right); 45 | break; 46 | case ExpressionType.LessThan: 47 | Visit(b.Left); 48 | sb.Append("<"); 49 | Visit(b.Right); 50 | break; 51 | case ExpressionType.GreaterThan: 52 | Visit(b.Left); 53 | sb.Append(">"); 54 | Visit(b.Right); 55 | break; 56 | case ExpressionType.LessThanOrEqual: 57 | Visit(Expression.Or(Expression.LessThan(b.Left, b.Right), Expression.Equal(b.Left, b.Right))); 58 | break; 59 | case ExpressionType.GreaterThanOrEqual: 60 | Visit(Expression.Or(Expression.GreaterThan(b.Left, b.Right), Expression.Equal(b.Left, b.Right))); 61 | break; 62 | default: 63 | throw new NotSupportedException(string.Format("The binary operator '{0}' is not supported", b.NodeType)); 64 | } 65 | sb.Append(")"); 66 | return b; 67 | } 68 | 69 | protected override Expression VisitMemberAccess(MemberExpression m) { 70 | if (m.Expression != null && m.Expression.NodeType == ExpressionType.Parameter) { 71 | sb.Append(m.Member.Name.ToLowerInvariant()); 72 | return m; 73 | } 74 | throw new NotSupportedException(string.Format("The member '{0}' is not supported", m.Member.Name)); 75 | } 76 | 77 | protected override Expression VisitConstant(ConstantExpression c) { 78 | if (c.Value is string) 79 | sb.AppendFormat("\"{0}\"", c.Value); 80 | else 81 | sb.Append(c.Value.ToString()); 82 | return c; 83 | } 84 | } 85 | } -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB.Linq/Impl/WhereTranslator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 55f8b5099068ae74ca9eaf9584869912 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 65c3ebc1434ca37428411dc4e4a5c6fb 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB/DatabaseClient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using GDataDB.Impl; 4 | using Google.GData.Client; 5 | using Google.GData.Documents; 6 | using Google.GData.Spreadsheets; 7 | using SpreadsheetQuery=Google.GData.Documents.SpreadsheetQuery; 8 | 9 | namespace GDataDB { 10 | public class DatabaseClient : IDatabaseClient { 11 | private readonly IService documentService; 12 | private readonly IService spreadsheetService; 13 | 14 | public IService DocumentService 15 | { 16 | get { return documentService; } 17 | } 18 | 19 | public IService SpreadsheetService 20 | { 21 | get { return spreadsheetService; } 22 | } 23 | 24 | public DatabaseClient(string username, string password) { 25 | var docService = new DocumentsService("database"); 26 | docService.setUserCredentials(username, password); 27 | documentService = docService; 28 | 29 | var ssService = new SpreadsheetsService("database"); 30 | ssService.setUserCredentials(username, password); 31 | spreadsheetService = ssService; 32 | } 33 | 34 | public IDatabase CreateDatabase(string name) { 35 | using (var ms = new MemoryStream()) { 36 | using (var sw = new StreamWriter(ms)) { 37 | sw.WriteLine(",,,"); 38 | var spreadSheet = DocumentService.Insert(new Uri(DocumentsListQuery.documentsBaseUri), ms, "text/csv", name); 39 | return new Database(this, spreadSheet); 40 | } 41 | } 42 | } 43 | 44 | public IDatabase GetDatabase(string name) { 45 | var feed = DocumentService.Query(new SpreadsheetQuery {TitleExact = true, Title = name }); 46 | if (feed.Entries.Count == 0) 47 | return null; 48 | return new Database(this, feed.Entries[0]); 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB/DatabaseClient.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d4c9eaa6ce6f8964bab6d1129aefa2d7 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB/IDatabase.cs: -------------------------------------------------------------------------------- 1 | namespace GDataDB { 2 | /// 3 | /// Spreadsheet document 4 | /// 5 | public interface IDatabase { 6 | /// 7 | /// Creates a new worksheet in this document 8 | /// 9 | /// 10 | /// 11 | /// 12 | ITable CreateTable(string name); 13 | 14 | /// 15 | /// Gets an existing worksheet in this document. 16 | /// 17 | /// 18 | /// 19 | /// Searched worksheet or null if not found 20 | ITable GetTable(string name); 21 | 22 | /// 23 | /// Deletes this spreadsheet document 24 | /// 25 | void Delete(); 26 | } 27 | } -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB/IDatabase.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 788d4b3fe2e790c43a2082552de3c353 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB/IDatabaseClient.cs: -------------------------------------------------------------------------------- 1 | using Google.GData.Client; 2 | 3 | namespace GDataDB { 4 | /// 5 | /// Google spreadsheet service entry point 6 | /// 7 | public interface IDatabaseClient { 8 | 9 | IService DocumentService { get; } 10 | IService SpreadsheetService { get; } 11 | 12 | /// 13 | /// Creates a new (spreadsheet document) 14 | /// 15 | /// 16 | /// 17 | IDatabase CreateDatabase(string name); 18 | 19 | /// 20 | /// Gets an existing (spreadsheet document) 21 | /// 22 | /// 23 | /// IDocument instance or null if not found 24 | IDatabase GetDatabase(string name); 25 | } 26 | } -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB/IDatabaseClient.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5a7e5eb4d75bb7341b2d4e1f0b71cb9f 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB/IRow.cs: -------------------------------------------------------------------------------- 1 | namespace GDataDB { 2 | /// 3 | /// Row in the spreadsheet 4 | /// 5 | /// 6 | public interface IRow { 7 | /// 8 | /// Element stored in the row 9 | /// 10 | T Element { get; set; } 11 | 12 | /// 13 | /// Updates the row in the spreadsheet using the current 14 | /// 15 | void Update(); 16 | 17 | /// 18 | /// Deletes this row 19 | /// 20 | void Delete(); 21 | } 22 | } -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB/IRow.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ad52f3dc30c4b9f4aaa578d3f8dfc699 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB/ITable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace GDataDB { 5 | /// 6 | /// Worksheet in a spreadsheet document 7 | /// 8 | /// 9 | public interface ITable { 10 | /// 11 | /// Deletes this worksheet 12 | /// 13 | void Delete(); 14 | 15 | /// 16 | /// Adds a new row 17 | /// 18 | /// Object to store 19 | /// Row stored 20 | IRow Add(T e); 21 | 22 | /// 23 | /// Gets a row by index number 24 | /// 25 | /// 26 | /// 27 | IRow Get(int rowNumber); 28 | 29 | /// 30 | /// Gets all stored rows in this worksheet 31 | /// 32 | /// 33 | IList> FindAll(); 34 | 35 | /// 36 | /// Gets all stored rows in this worksheet, paged 37 | /// 38 | /// 39 | /// 40 | /// 41 | IList> FindAll(int start, int count); 42 | 43 | /// 44 | /// Free text row search 45 | /// 46 | /// text to search 47 | /// Matching rows 48 | IList> Find(string query); 49 | 50 | /// 51 | /// Searches rows using a structured query 52 | /// Syntax: http://code.google.com/apis/spreadsheets/data/2.0/reference.html#ListParameters 53 | /// 54 | /// structured query 55 | /// Matching rows 56 | IList> FindStructured(string query); 57 | 58 | /// 59 | /// Searches rows using a structured query, paged 60 | /// Syntax: http://code.google.com/apis/spreadsheets/data/2.0/reference.html#ListParameters 61 | /// 62 | /// 63 | /// 64 | /// 65 | /// Matching rows 66 | IList> FindStructured(string query, int start, int count); 67 | 68 | /// 69 | /// Searches rows 70 | /// 71 | /// query parameters 72 | /// Matching rows 73 | IList> Find(Query q); 74 | 75 | 76 | Uri GetFeedUrl(); 77 | } 78 | } -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB/ITable.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 75e47bc892ac4aa4286dace5bd7bbd9b 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB/Impl.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4fe0b3f6bed7fcf4c9d52ed1dbfea1a2 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB/Impl/.svn/all-wcprops: -------------------------------------------------------------------------------- 1 | K 25 2 | svn:wc:ra_dav:version-url 3 | V 70 4 | /svn/G9_Canimal/!svn/ver/3357/Trunk/Assets/Editor/GDataDB/GDataDB/Impl 5 | END 6 | Row.cs.meta 7 | K 25 8 | svn:wc:ra_dav:version-url 9 | V 82 10 | /svn/G9_Canimal/!svn/ver/3357/Trunk/Assets/Editor/GDataDB/GDataDB/Impl/Row.cs.meta 11 | END 12 | Table.cs.meta 13 | K 25 14 | svn:wc:ra_dav:version-url 15 | V 84 16 | /svn/G9_Canimal/!svn/ver/3357/Trunk/Assets/Editor/GDataDB/GDataDB/Impl/Table.cs.meta 17 | END 18 | Serializer.cs.meta 19 | K 25 20 | svn:wc:ra_dav:version-url 21 | V 89 22 | /svn/G9_Canimal/!svn/ver/3357/Trunk/Assets/Editor/GDataDB/GDataDB/Impl/Serializer.cs.meta 23 | END 24 | Database.cs 25 | K 25 26 | svn:wc:ra_dav:version-url 27 | V 82 28 | /svn/G9_Canimal/!svn/ver/3357/Trunk/Assets/Editor/GDataDB/GDataDB/Impl/Database.cs 29 | END 30 | Row.cs 31 | K 25 32 | svn:wc:ra_dav:version-url 33 | V 77 34 | /svn/G9_Canimal/!svn/ver/3357/Trunk/Assets/Editor/GDataDB/GDataDB/Impl/Row.cs 35 | END 36 | Table.cs 37 | K 25 38 | svn:wc:ra_dav:version-url 39 | V 79 40 | /svn/G9_Canimal/!svn/ver/3357/Trunk/Assets/Editor/GDataDB/GDataDB/Impl/Table.cs 41 | END 42 | Database.cs.meta 43 | K 25 44 | svn:wc:ra_dav:version-url 45 | V 87 46 | /svn/G9_Canimal/!svn/ver/3357/Trunk/Assets/Editor/GDataDB/GDataDB/Impl/Database.cs.meta 47 | END 48 | Serializer.cs 49 | K 25 50 | svn:wc:ra_dav:version-url 51 | V 84 52 | /svn/G9_Canimal/!svn/ver/3357/Trunk/Assets/Editor/GDataDB/GDataDB/Impl/Serializer.cs 53 | END 54 | -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB/Impl/.svn/entries: -------------------------------------------------------------------------------- 1 | 10 2 | 3 | dir 4 | 3357 5 | http://office.gameus.co.kr:7001/svn/G9_Canimal/Trunk/Assets/Editor/GDataDB/GDataDB/Impl 6 | http://office.gameus.co.kr:7001/svn/G9_Canimal 7 | 8 | 9 | 10 | 2013-06-05T06:00:05.658445Z 11 | 3357 12 | hwpeterkim 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 69851156-2391-fc40-bb9f-d03dfa9181f8 28 | 29 | Row.cs.meta 30 | file 31 | 32 | 33 | 34 | 35 | 2013-03-29T09:21:42.000000Z 36 | 87ffcf3c8d470561956925e25cd3471a 37 | 2013-06-05T06:00:05.658445Z 38 | 3357 39 | hwpeterkim 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 178 62 | 63 | Table.cs.meta 64 | file 65 | 66 | 67 | 68 | 69 | 2013-03-29T09:21:42.000000Z 70 | 8e4e686f22b4cda8f292535af3cfd3b9 71 | 2013-06-05T06:00:05.658445Z 72 | 3357 73 | hwpeterkim 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 178 96 | 97 | Serializer.cs.meta 98 | file 99 | 100 | 101 | 102 | 103 | 2013-03-29T09:21:42.000000Z 104 | b6f7842b62565b49cc48caaf0492a0c2 105 | 2013-06-05T06:00:05.658445Z 106 | 3357 107 | hwpeterkim 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 178 130 | 131 | Database.cs 132 | file 133 | 134 | 135 | 136 | 137 | 2013-03-29T09:21:42.000000Z 138 | 6f18dcf20b380372b5d54323972a7267 139 | 2013-06-05T06:00:05.658445Z 140 | 3357 141 | hwpeterkim 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 2045 164 | 165 | Row.cs 166 | file 167 | 168 | 169 | 170 | 171 | 2013-03-29T09:21:42.000000Z 172 | fd43d120cffaf9c8c60407e52717d89e 173 | 2013-06-05T06:00:05.658445Z 174 | 3357 175 | hwpeterkim 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 530 198 | 199 | Table.cs 200 | file 201 | 202 | 203 | 204 | 205 | 2013-03-29T09:21:42.000000Z 206 | b7fae19566f5ca74feee66607145494e 207 | 2013-06-05T06:00:05.658445Z 208 | 3357 209 | hwpeterkim 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 3157 232 | 233 | Database.cs.meta 234 | file 235 | 236 | 237 | 238 | 239 | 2013-03-29T09:21:42.000000Z 240 | 668139f906e60424e68dd014e5af4664 241 | 2013-06-05T06:00:05.658445Z 242 | 3357 243 | hwpeterkim 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 178 266 | 267 | Serializer.cs 268 | file 269 | 270 | 271 | 272 | 273 | 2013-04-04T01:41:48.000000Z 274 | 51fece3a17cef4e0deb42310cde710d3 275 | 2013-06-05T06:00:05.658445Z 276 | 3357 277 | hwpeterkim 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 2315 300 | 301 | -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB/Impl/.svn/text-base/Database.cs.meta.svn-base: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 95dbd957c296755498c0bfc3f38ac355 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB/Impl/.svn/text-base/Database.cs.svn-base: -------------------------------------------------------------------------------- 1 | using System; 2 | using Google.GData.Client; 3 | using Google.GData.Documents; 4 | using Google.GData.Spreadsheets; 5 | 6 | namespace GDataDB.Impl { 7 | public class Database : IDatabase { 8 | private readonly IDatabaseClient client; 9 | private readonly AtomEntry entry; 10 | 11 | public Database(IDatabaseClient client, AtomEntry entry) { 12 | this.client = client; 13 | this.entry = entry; 14 | } 15 | 16 | public ITable CreateTable(string name) { 17 | var link = entry.Links.FindService(GDataSpreadsheetsNameTable.WorksheetRel, null); 18 | var wsFeed = (WorksheetFeed) client.SpreadsheetService.Query(new WorksheetQuery(link.HRef.ToString())); 19 | var length = typeof (T).GetProperties().Length; 20 | var ws = wsFeed.Insert(new WorksheetEntry(1, (uint) length, name)); 21 | var cellLink = new AtomLink(ws.CellFeedLink); 22 | var cFeed = client.SpreadsheetService.Query(new CellQuery(cellLink.HRef.ToString())); 23 | { 24 | uint c = 0; 25 | foreach (var p in typeof (T).GetProperties()) { 26 | var entry1 = new CellEntry(1, ++c, p.Name); 27 | cFeed.Insert(entry1); 28 | } 29 | } 30 | return new Table(client.SpreadsheetService, ws); 31 | } 32 | 33 | public ITable GetTable(string name) { 34 | var link = entry.Links.FindService(GDataSpreadsheetsNameTable.WorksheetRel, null); 35 | var wsFeed = (WorksheetFeed) client.SpreadsheetService.Query(new WorksheetQuery(link.HRef.ToString()) {Title = name, Exact = true}); 36 | if (wsFeed.Entries.Count == 0) 37 | return null; 38 | return new Table(client.SpreadsheetService, (WorksheetEntry) wsFeed.Entries[0]); 39 | } 40 | 41 | public void Delete() { 42 | // cannot call "entry.Delete()" directly after modification as the EditUri is invalid 43 | var feed = client.DocumentService.Query(new DocumentsListQuery(entry.SelfUri.ToString())); 44 | feed.Entries[0].Delete(); 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB/Impl/.svn/text-base/Row.cs.meta.svn-base: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6a5c6b56be3e37c4c939dd0b4527126d 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB/Impl/.svn/text-base/Row.cs.svn-base: -------------------------------------------------------------------------------- 1 | using Google.GData.Spreadsheets; 2 | 3 | namespace GDataDB.Impl { 4 | public class Row : IRow { 5 | public T Element { get; set; } 6 | private readonly ListEntry entry; 7 | private readonly Serializer serializer = new Serializer(); 8 | 9 | public Row(ListEntry entry) { 10 | this.entry = entry; 11 | } 12 | 13 | public void Update() { 14 | serializer.Serialize(Element, entry); 15 | entry.Update(); 16 | } 17 | 18 | public void Delete() { 19 | entry.Delete(); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB/Impl/.svn/text-base/Serializer.cs.meta.svn-base: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 667b9130d72e9ac4682c2694848ed56b 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB/Impl/.svn/text-base/Serializer.cs.svn-base: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | 4 | using System; 5 | using System.ComponentModel; 6 | using System.Reflection; 7 | using Google.GData.Spreadsheets; 8 | 9 | namespace GDataDB.Impl { 10 | /// 11 | /// (de)serializes an object into a spreadsheet row 12 | /// Uses only the object properties. 13 | /// Property names are used as column names in the spreadsheet 14 | /// 15 | /// 16 | public class Serializer { 17 | public ListEntry Serialize(T e) { 18 | return Serialize(e, new ListEntry()); 19 | } 20 | 21 | public ListEntry Serialize(T e, ListEntry record) { 22 | foreach (var p in typeof (T).GetProperties()) { 23 | if (p.CanRead) { 24 | record.Elements.Add(new ListEntry.Custom { 25 | LocalName = p.Name.ToLowerInvariant(), // for some reason this HAS to be lowercase or it throws 26 | Value = ToNullOrString(p.GetValue(e, null)), 27 | }); 28 | } 29 | } 30 | return record; 31 | } 32 | 33 | public string ToNullOrString(object o) { 34 | if (o == null) 35 | return null; 36 | return o.ToString(); 37 | } 38 | 39 | public object ConvertFrom(object value, Type t) { 40 | if (t.IsGenericType && t.GetGenericTypeDefinition().Equals(typeof (Nullable<>))) { 41 | var nc = new NullableConverter(t); 42 | return nc.ConvertFrom(value); 43 | } 44 | 45 | //HACK: modified to return enum. 46 | if (t.IsEnum) 47 | { 48 | return Enum.Parse(t, value.ToString(), true); 49 | } 50 | else 51 | return Convert.ChangeType(value, t); 52 | } 53 | 54 | public T Deserialize(ListEntry e) { 55 | var t = typeof (T); 56 | var r = (T) Activator.CreateInstance(t); 57 | foreach (ListEntry.Custom c in e.Elements) { 58 | var property = t.GetProperty(c.LocalName, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public); 59 | if (property == null) 60 | continue; 61 | if (property.CanWrite) { 62 | 63 | try 64 | { 65 | var value = ConvertFrom(c.Value, property.PropertyType); 66 | property.SetValue(r, value, null); 67 | } 68 | catch(Exception exc) 69 | { 70 | Debug.LogError ("GDataDB Serialization Exception: " + exc.Message + " ListEntry LocalName: " + c.LocalName); 71 | } 72 | } 73 | } 74 | return r; 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB/Impl/.svn/text-base/Table.cs.meta.svn-base: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 077c0760add2b3e4ebea39ece9adfdf8 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB/Impl/.svn/text-base/Table.cs.svn-base: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Google.GData.Client; 4 | using Google.GData.Spreadsheets; 5 | 6 | namespace GDataDB.Impl { 7 | public class Table : ITable { 8 | private readonly IService svc; 9 | private readonly WorksheetEntry entry; 10 | private readonly Serializer serializer = new Serializer(); 11 | 12 | public Table(IService svc, WorksheetEntry entry) { 13 | this.svc = svc; 14 | this.entry = entry; 15 | } 16 | 17 | public void Delete() { 18 | var wsFeed = (WorksheetFeed)svc.Query(new WorksheetQuery(entry.SelfUri.ToString())); 19 | wsFeed.Entries[0].Delete(); 20 | } 21 | 22 | private ListQuery GetQuery() { 23 | return new ListQuery(GetLink().HRef.Content); 24 | } 25 | 26 | private ListFeed GetFeed() { 27 | return (ListFeed) svc.Query(GetQuery()); 28 | } 29 | 30 | private AtomLink GetLink() { 31 | return entry.Links.FindService(GDataSpreadsheetsNameTable.ListRel, null); 32 | } 33 | 34 | public IRow Add(T e) { 35 | var feed = GetFeed(); 36 | var newEntry = serializer.Serialize(e); 37 | var rowEntry = feed.Insert(newEntry); 38 | return new Row((ListEntry) rowEntry) {Element = e}; 39 | } 40 | 41 | public IRow Get(int rowNumber) { 42 | var q = GetQuery(); 43 | q.StartIndex = rowNumber; 44 | q.NumberToRetrieve = 1; 45 | var results = Find(q); 46 | if (results.Count == 0) 47 | return null; 48 | return results[0]; 49 | } 50 | 51 | public IList> FindAll() { 52 | return Find(GetQuery()); 53 | } 54 | 55 | public IList> FindAll(int start, int count) { 56 | return Find(new Query { 57 | Start = start, 58 | Count = count, 59 | }); 60 | } 61 | 62 | public IList> Find(string query) { 63 | return Find(new Query {FreeQuery = query}); 64 | } 65 | 66 | public IList> FindStructured(string query) { 67 | return Find(new Query {StructuredQuery = query}); 68 | } 69 | 70 | public IList> FindStructured(string query, int start, int count) { 71 | return Find(new Query { 72 | StructuredQuery = query, 73 | Start = start, 74 | Count = count, 75 | }); 76 | } 77 | 78 | public IList> Find(Query q) { 79 | var fq = GetQuery(); 80 | fq.Query = q.FreeQuery; 81 | fq.SpreadsheetQuery = q.StructuredQuery; 82 | fq.StartIndex = q.Start; 83 | fq.NumberToRetrieve = q.Count; 84 | if (q.Order != null) { 85 | fq.OrderByColumn = q.Order.ColumnName; 86 | fq.Reverse = q.Order.Descending; 87 | } 88 | return Find(fq); 89 | } 90 | 91 | public Uri GetFeedUrl() { 92 | return new Uri(GetFeed().Feed); 93 | } 94 | 95 | private IList> Find(FeedQuery q) { 96 | var feed = (ListFeed) svc.Query(q); 97 | var l = new List>(); 98 | foreach (ListEntry e in feed.Entries) { 99 | l.Add(new Row(e) { Element = serializer.Deserialize(e) }); 100 | } 101 | return l; 102 | } 103 | } 104 | } -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB/Impl/Database.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Google.GData.Client; 3 | using Google.GData.Documents; 4 | using Google.GData.Spreadsheets; 5 | 6 | namespace GDataDB.Impl { 7 | public class Database : IDatabase { 8 | private readonly IDatabaseClient client; 9 | private readonly AtomEntry entry; 10 | 11 | public Database(IDatabaseClient client, AtomEntry entry) { 12 | this.client = client; 13 | this.entry = entry; 14 | } 15 | 16 | public ITable CreateTable(string name) { 17 | var link = entry.Links.FindService(GDataSpreadsheetsNameTable.WorksheetRel, null); 18 | var wsFeed = (WorksheetFeed) client.SpreadsheetService.Query(new WorksheetQuery(link.HRef.ToString())); 19 | var length = typeof (T).GetProperties().Length; 20 | var ws = wsFeed.Insert(new WorksheetEntry(1, (uint) length, name)); 21 | var cellLink = new AtomLink(ws.CellFeedLink); 22 | var cFeed = client.SpreadsheetService.Query(new CellQuery(cellLink.HRef.ToString())); 23 | { 24 | uint c = 0; 25 | foreach (var p in typeof (T).GetProperties()) { 26 | var entry1 = new CellEntry(1, ++c, p.Name); 27 | cFeed.Insert(entry1); 28 | } 29 | } 30 | return new Table(client.SpreadsheetService, ws); 31 | } 32 | 33 | public ITable GetTable(string name) { 34 | var link = entry.Links.FindService(GDataSpreadsheetsNameTable.WorksheetRel, null); 35 | var wsFeed = (WorksheetFeed) client.SpreadsheetService.Query(new WorksheetQuery(link.HRef.ToString()) {Title = name, Exact = true}); 36 | if (wsFeed.Entries.Count == 0) 37 | return null; 38 | return new Table(client.SpreadsheetService, (WorksheetEntry) wsFeed.Entries[0]); 39 | } 40 | 41 | public void Delete() { 42 | // cannot call "entry.Delete()" directly after modification as the EditUri is invalid 43 | var feed = client.DocumentService.Query(new DocumentsListQuery(entry.SelfUri.ToString())); 44 | feed.Entries[0].Delete(); 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB/Impl/Database.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 95dbd957c296755498c0bfc3f38ac355 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB/Impl/Row.cs: -------------------------------------------------------------------------------- 1 | using Google.GData.Spreadsheets; 2 | 3 | namespace GDataDB.Impl { 4 | public class Row : IRow { 5 | public T Element { get; set; } 6 | private readonly ListEntry entry; 7 | private readonly Serializer serializer = new Serializer(); 8 | 9 | public Row(ListEntry entry) { 10 | this.entry = entry; 11 | } 12 | 13 | public void Update() { 14 | serializer.Serialize(Element, entry); 15 | entry.Update(); 16 | } 17 | 18 | public void Delete() { 19 | entry.Delete(); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB/Impl/Row.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6a5c6b56be3e37c4c939dd0b4527126d 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB/Impl/Serializer.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | 4 | using System; 5 | using System.ComponentModel; 6 | using System.Reflection; 7 | using Google.GData.Spreadsheets; 8 | 9 | namespace GDataDB.Impl { 10 | /// 11 | /// (de)serializes an object into a spreadsheet row 12 | /// Uses only the object properties. 13 | /// Property names are used as column names in the spreadsheet 14 | /// 15 | /// 16 | public class Serializer { 17 | public ListEntry Serialize(T e) { 18 | return Serialize(e, new ListEntry()); 19 | } 20 | 21 | public ListEntry Serialize(T e, ListEntry record) { 22 | foreach (var p in typeof (T).GetProperties()) { 23 | if (p.CanRead) { 24 | record.Elements.Add(new ListEntry.Custom { 25 | LocalName = p.Name.ToLowerInvariant(), // for some reason this HAS to be lowercase or it throws 26 | Value = ToNullOrString(p.GetValue(e, null)), 27 | }); 28 | } 29 | } 30 | return record; 31 | } 32 | 33 | public string ToNullOrString(object o) { 34 | if (o == null) 35 | return null; 36 | return o.ToString(); 37 | } 38 | 39 | public object ConvertFrom(object value, Type t) { 40 | if (t.IsGenericType && t.GetGenericTypeDefinition().Equals(typeof (Nullable<>))) { 41 | var nc = new NullableConverter(t); 42 | return nc.ConvertFrom(value); 43 | } 44 | 45 | //HACK: modified to return enum. 46 | if (t.IsEnum) 47 | { 48 | return Enum.Parse(t, value.ToString(), true); 49 | } 50 | else 51 | return Convert.ChangeType(value, t); 52 | } 53 | 54 | public T Deserialize(ListEntry e) { 55 | var t = typeof (T); 56 | var r = (T) Activator.CreateInstance(t); 57 | foreach (ListEntry.Custom c in e.Elements) { 58 | var property = t.GetProperty(c.LocalName, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public); 59 | if (property == null) 60 | continue; 61 | if (property.CanWrite) { 62 | 63 | try 64 | { 65 | var value = ConvertFrom(c.Value, property.PropertyType); 66 | property.SetValue(r, value, null); 67 | } 68 | catch(Exception exc) 69 | { 70 | Debug.LogError ("GDataDB Serialization Exception: " + exc.Message + " ListEntry LocalName: " + c.LocalName); 71 | } 72 | } 73 | } 74 | return r; 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB/Impl/Serializer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 667b9130d72e9ac4682c2694848ed56b 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB/Impl/Table.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Google.GData.Client; 4 | using Google.GData.Spreadsheets; 5 | 6 | namespace GDataDB.Impl { 7 | public class Table : ITable { 8 | private readonly IService svc; 9 | private readonly WorksheetEntry entry; 10 | private readonly Serializer serializer = new Serializer(); 11 | 12 | public Table(IService svc, WorksheetEntry entry) { 13 | this.svc = svc; 14 | this.entry = entry; 15 | } 16 | 17 | public void Delete() { 18 | var wsFeed = (WorksheetFeed)svc.Query(new WorksheetQuery(entry.SelfUri.ToString())); 19 | wsFeed.Entries[0].Delete(); 20 | } 21 | 22 | private ListQuery GetQuery() { 23 | return new ListQuery(GetLink().HRef.Content); 24 | } 25 | 26 | private ListFeed GetFeed() { 27 | return (ListFeed) svc.Query(GetQuery()); 28 | } 29 | 30 | private AtomLink GetLink() { 31 | return entry.Links.FindService(GDataSpreadsheetsNameTable.ListRel, null); 32 | } 33 | 34 | public IRow Add(T e) { 35 | var feed = GetFeed(); 36 | var newEntry = serializer.Serialize(e); 37 | var rowEntry = feed.Insert(newEntry); 38 | return new Row((ListEntry) rowEntry) {Element = e}; 39 | } 40 | 41 | public IRow Get(int rowNumber) { 42 | var q = GetQuery(); 43 | q.StartIndex = rowNumber; 44 | q.NumberToRetrieve = 1; 45 | var results = Find(q); 46 | if (results.Count == 0) 47 | return null; 48 | return results[0]; 49 | } 50 | 51 | public IList> FindAll() { 52 | return Find(GetQuery()); 53 | } 54 | 55 | public IList> FindAll(int start, int count) { 56 | return Find(new Query { 57 | Start = start, 58 | Count = count, 59 | }); 60 | } 61 | 62 | public IList> Find(string query) { 63 | return Find(new Query {FreeQuery = query}); 64 | } 65 | 66 | public IList> FindStructured(string query) { 67 | return Find(new Query {StructuredQuery = query}); 68 | } 69 | 70 | public IList> FindStructured(string query, int start, int count) { 71 | return Find(new Query { 72 | StructuredQuery = query, 73 | Start = start, 74 | Count = count, 75 | }); 76 | } 77 | 78 | public IList> Find(Query q) { 79 | var fq = GetQuery(); 80 | fq.Query = q.FreeQuery; 81 | fq.SpreadsheetQuery = q.StructuredQuery; 82 | fq.StartIndex = q.Start; 83 | fq.NumberToRetrieve = q.Count; 84 | if (q.Order != null) { 85 | fq.OrderByColumn = q.Order.ColumnName; 86 | fq.Reverse = q.Order.Descending; 87 | } 88 | return Find(fq); 89 | } 90 | 91 | public Uri GetFeedUrl() { 92 | return new Uri(GetFeed().Feed); 93 | } 94 | 95 | private IList> Find(FeedQuery q) { 96 | var feed = (ListFeed) svc.Query(q); 97 | var l = new List>(); 98 | foreach (ListEntry e in feed.Entries) { 99 | l.Add(new Row(e) { Element = serializer.Deserialize(e) }); 100 | } 101 | return l; 102 | } 103 | } 104 | } -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB/Impl/Table.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 077c0760add2b3e4ebea39ece9adfdf8 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB/Order.cs: -------------------------------------------------------------------------------- 1 | namespace GDataDB { 2 | /// 3 | /// Sort order 4 | /// 5 | public class Order { 6 | public bool Descending { get; set; } 7 | public string ColumnName { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB/Order.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a6768b3551820c14596495b922ae947d 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB/Query.cs: -------------------------------------------------------------------------------- 1 | namespace GDataDB { 2 | /// 3 | /// Query parameters 4 | /// 5 | public class Query { 6 | /// 7 | /// Start index, for paging 8 | /// 9 | public int Start { get; set; } 10 | 11 | /// 12 | /// Record count to fetch, for paging 13 | /// 14 | public int Count { get; set; } 15 | 16 | /// 17 | /// Free text query 18 | /// 19 | public string FreeQuery { get; set; } 20 | 21 | /// 22 | /// Structured query 23 | /// 24 | public string StructuredQuery { get; set; } 25 | 26 | /// 27 | /// Sort order 28 | /// 29 | public Order Order { get; set; } 30 | } 31 | } -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/GDataDB/Query.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ca099168b2a2cab4d99be4b1e31c4e49 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/README.md: -------------------------------------------------------------------------------- 1 | This is an attempt at porting the python google spreadsheet data client 2 | 3 | Original source at: 4 | http://code.google.com/p/gdata-python-client/source/browse/src/gdata/spreadsheet/text_db.py 5 | 6 | [![Please donate](http://www.pledgie.com/campaigns/11248.png)](http://www.pledgie.com/campaigns/11248) -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 19cd0a60c7615e3468335ee3e9e0cb0e 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/license.txt: -------------------------------------------------------------------------------- 1 | GDataDB 2 | 3 | Copyright 2008-2012 Mauricio Scheffer 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | 17 | 18 | 19 | Apache License 20 | Version 2.0, January 2004 21 | http://www.apache.org/licenses/ 22 | 23 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 24 | 25 | 1. Definitions. 26 | 27 | "License" shall mean the terms and conditions for use, reproduction, 28 | and distribution as defined by Sections 1 through 9 of this document. 29 | 30 | "Licensor" shall mean the copyright owner or entity authorized by 31 | the copyright owner that is granting the License. 32 | 33 | "Legal Entity" shall mean the union of the acting entity and all 34 | other entities that control, are controlled by, or are under common 35 | control with that entity. For the purposes of this definition, 36 | "control" means (i) the power, direct or indirect, to cause the 37 | direction or management of such entity, whether by contract or 38 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 39 | outstanding shares, or (iii) beneficial ownership of such entity. 40 | 41 | "You" (or "Your") shall mean an individual or Legal Entity 42 | exercising permissions granted by this License. 43 | 44 | "Source" form shall mean the preferred form for making modifications, 45 | including but not limited to software source code, documentation 46 | source, and configuration files. 47 | 48 | "Object" form shall mean any form resulting from mechanical 49 | transformation or translation of a Source form, including but 50 | not limited to compiled object code, generated documentation, 51 | and conversions to other media types. 52 | 53 | "Work" shall mean the work of authorship, whether in Source or 54 | Object form, made available under the License, as indicated by a 55 | copyright notice that is included in or attached to the work 56 | (an example is provided in the Appendix below). 57 | 58 | "Derivative Works" shall mean any work, whether in Source or Object 59 | form, that is based on (or derived from) the Work and for which the 60 | editorial revisions, annotations, elaborations, or other modifications 61 | represent, as a whole, an original work of authorship. For the purposes 62 | of this License, Derivative Works shall not include works that remain 63 | separable from, or merely link (or bind by name) to the interfaces of, 64 | the Work and Derivative Works thereof. 65 | 66 | "Contribution" shall mean any work of authorship, including 67 | the original version of the Work and any modifications or additions 68 | to that Work or Derivative Works thereof, that is intentionally 69 | submitted to Licensor for inclusion in the Work by the copyright owner 70 | or by an individual or Legal Entity authorized to submit on behalf of 71 | the copyright owner. For the purposes of this definition, "submitted" 72 | means any form of electronic, verbal, or written communication sent 73 | to the Licensor or its representatives, including but not limited to 74 | communication on electronic mailing lists, source code control systems, 75 | and issue tracking systems that are managed by, or on behalf of, the 76 | Licensor for the purpose of discussing and improving the Work, but 77 | excluding communication that is conspicuously marked or otherwise 78 | designated in writing by the copyright owner as "Not a Contribution." 79 | 80 | "Contributor" shall mean Licensor and any individual or Legal Entity 81 | on behalf of whom a Contribution has been received by Licensor and 82 | subsequently incorporated within the Work. 83 | 84 | 2. Grant of Copyright License. Subject to the terms and conditions of 85 | this License, each Contributor hereby grants to You a perpetual, 86 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 87 | copyright license to reproduce, prepare Derivative Works of, 88 | publicly display, publicly perform, sublicense, and distribute the 89 | Work and such Derivative Works in Source or Object form. 90 | 91 | 3. Grant of Patent License. Subject to the terms and conditions of 92 | this License, each Contributor hereby grants to You a perpetual, 93 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 94 | (except as stated in this section) patent license to make, have made, 95 | use, offer to sell, sell, import, and otherwise transfer the Work, 96 | where such license applies only to those patent claims licensable 97 | by such Contributor that are necessarily infringed by their 98 | Contribution(s) alone or by combination of their Contribution(s) 99 | with the Work to which such Contribution(s) was submitted. If You 100 | institute patent litigation against any entity (including a 101 | cross-claim or counterclaim in a lawsuit) alleging that the Work 102 | or a Contribution incorporated within the Work constitutes direct 103 | or contributory patent infringement, then any patent licenses 104 | granted to You under this License for that Work shall terminate 105 | as of the date such litigation is filed. 106 | 107 | 4. Redistribution. You may reproduce and distribute copies of the 108 | Work or Derivative Works thereof in any medium, with or without 109 | modifications, and in Source or Object form, provided that You 110 | meet the following conditions: 111 | 112 | (a) You must give any other recipients of the Work or 113 | Derivative Works a copy of this License; and 114 | 115 | (b) You must cause any modified files to carry prominent notices 116 | stating that You changed the files; and 117 | 118 | (c) You must retain, in the Source form of any Derivative Works 119 | that You distribute, all copyright, patent, trademark, and 120 | attribution notices from the Source form of the Work, 121 | excluding those notices that do not pertain to any part of 122 | the Derivative Works; and 123 | 124 | (d) If the Work includes a "NOTICE" text file as part of its 125 | distribution, then any Derivative Works that You distribute must 126 | include a readable copy of the attribution notices contained 127 | within such NOTICE file, excluding those notices that do not 128 | pertain to any part of the Derivative Works, in at least one 129 | of the following places: within a NOTICE text file distributed 130 | as part of the Derivative Works; within the Source form or 131 | documentation, if provided along with the Derivative Works; or, 132 | within a display generated by the Derivative Works, if and 133 | wherever such third-party notices normally appear. The contents 134 | of the NOTICE file are for informational purposes only and 135 | do not modify the License. You may add Your own attribution 136 | notices within Derivative Works that You distribute, alongside 137 | or as an addendum to the NOTICE text from the Work, provided 138 | that such additional attribution notices cannot be construed 139 | as modifying the License. 140 | 141 | You may add Your own copyright statement to Your modifications and 142 | may provide additional or different license terms and conditions 143 | for use, reproduction, or distribution of Your modifications, or 144 | for any such Derivative Works as a whole, provided Your use, 145 | reproduction, and distribution of the Work otherwise complies with 146 | the conditions stated in this License. 147 | 148 | 5. Submission of Contributions. Unless You explicitly state otherwise, 149 | any Contribution intentionally submitted for inclusion in the Work 150 | by You to the Licensor shall be under the terms and conditions of 151 | this License, without any additional terms or conditions. 152 | Notwithstanding the above, nothing herein shall supersede or modify 153 | the terms of any separate license agreement you may have executed 154 | with Licensor regarding such Contributions. 155 | 156 | 6. Trademarks. This License does not grant permission to use the trade 157 | names, trademarks, service marks, or product names of the Licensor, 158 | except as required for reasonable and customary use in describing the 159 | origin of the Work and reproducing the content of the NOTICE file. 160 | 161 | 7. Disclaimer of Warranty. Unless required by applicable law or 162 | agreed to in writing, Licensor provides the Work (and each 163 | Contributor provides its Contributions) on an "AS IS" BASIS, 164 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 165 | implied, including, without limitation, any warranties or conditions 166 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 167 | PARTICULAR PURPOSE. You are solely responsible for determining the 168 | appropriateness of using or redistributing the Work and assume any 169 | risks associated with Your exercise of permissions under this License. 170 | 171 | 8. Limitation of Liability. In no event and under no legal theory, 172 | whether in tort (including negligence), contract, or otherwise, 173 | unless required by applicable law (such as deliberate and grossly 174 | negligent acts) or agreed to in writing, shall any Contributor be 175 | liable to You for damages, including any direct, indirect, special, 176 | incidental, or consequential damages of any character arising as a 177 | result of this License or out of the use or inability to use the 178 | Work (including but not limited to damages for loss of goodwill, 179 | work stoppage, computer failure or malfunction, or any and all 180 | other commercial damages or losses), even if such Contributor 181 | has been advised of the possibility of such damages. 182 | 183 | 9. Accepting Warranty or Additional Liability. While redistributing 184 | the Work or Derivative Works thereof, You may choose to offer, 185 | and charge a fee for, acceptance of support, warranty, indemnity, 186 | or other liability obligations and/or rights consistent with this 187 | License. However, in accepting such obligations, You may act only 188 | on Your own behalf and on Your sole responsibility, not on behalf 189 | of any other Contributor, and only if You agree to indemnify, 190 | defend, and hold each Contributor harmless for any liability 191 | incurred by, or claims asserted against, such Contributor by reason 192 | of your accepting any such warranty or additional liability. 193 | 194 | END OF TERMS AND CONDITIONS -------------------------------------------------------------------------------- /Assets/Editor/GDataDB/license.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 41705903b394e5d4f813d0714e94c8ef 3 | TextScriptImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Editor/Google.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 32c5807a363d4482793822434a439877 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Editor/Google/Google.GData.AccessControl.DLL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kimsama/Unity-GoogleData/09acc58f0c2fb6be41f8d8189b00784436850628/Assets/Editor/Google/Google.GData.AccessControl.DLL -------------------------------------------------------------------------------- /Assets/Editor/Google/Google.GData.AccessControl.DLL.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5bd4770df836dfa4cb7d79a5efb16d09 3 | MonoAssemblyImporter: 4 | serializedVersion: 1 5 | iconMap: {} 6 | executionOrder: {} 7 | userData: 8 | -------------------------------------------------------------------------------- /Assets/Editor/Google/Google.GData.Client.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kimsama/Unity-GoogleData/09acc58f0c2fb6be41f8d8189b00784436850628/Assets/Editor/Google/Google.GData.Client.dll -------------------------------------------------------------------------------- /Assets/Editor/Google/Google.GData.Client.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b684da2fb04dcbf448b763151b143173 3 | MonoAssemblyImporter: 4 | serializedVersion: 1 5 | iconMap: {} 6 | executionOrder: {} 7 | userData: 8 | -------------------------------------------------------------------------------- /Assets/Editor/Google/Google.GData.Documents.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kimsama/Unity-GoogleData/09acc58f0c2fb6be41f8d8189b00784436850628/Assets/Editor/Google/Google.GData.Documents.dll -------------------------------------------------------------------------------- /Assets/Editor/Google/Google.GData.Documents.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5be667ff94c69764f87ad41e6b2320ad 3 | MonoAssemblyImporter: 4 | serializedVersion: 1 5 | iconMap: {} 6 | executionOrder: {} 7 | userData: 8 | -------------------------------------------------------------------------------- /Assets/Editor/Google/Google.GData.Extensions.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kimsama/Unity-GoogleData/09acc58f0c2fb6be41f8d8189b00784436850628/Assets/Editor/Google/Google.GData.Extensions.dll -------------------------------------------------------------------------------- /Assets/Editor/Google/Google.GData.Extensions.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4af0bbad3fb48464d8c0e0151a37248f 3 | MonoAssemblyImporter: 4 | serializedVersion: 1 5 | iconMap: {} 6 | executionOrder: {} 7 | userData: 8 | -------------------------------------------------------------------------------- /Assets/Editor/Google/Google.GData.Spreadsheets.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kimsama/Unity-GoogleData/09acc58f0c2fb6be41f8d8189b00784436850628/Assets/Editor/Google/Google.GData.Spreadsheets.dll -------------------------------------------------------------------------------- /Assets/Editor/Google/Google.GData.Spreadsheets.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ae388cd5d2a6a624c8de7dc0aa004a1c 3 | MonoAssemblyImporter: 4 | serializedVersion: 1 5 | iconMap: {} 6 | executionOrder: {} 7 | userData: 8 | -------------------------------------------------------------------------------- /Assets/Editor/Util.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cfc0a3ec3e650419a9f9a48c777f8352 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Editor/Util/CustomAssetUtility.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | using System.IO; 4 | 5 | public static class CustomAssetUtility 6 | { 7 | public static void CreateAsset () where T : ScriptableObject 8 | { 9 | T asset = ScriptableObject.CreateInstance (); 10 | 11 | string path = AssetDatabase.GetAssetPath (Selection.activeObject); 12 | if (path == "") 13 | { 14 | path = "Assets"; 15 | } 16 | else if (Path.GetExtension (path) != "") 17 | { 18 | path = path.Replace (Path.GetFileName (AssetDatabase.GetAssetPath (Selection.activeObject)), ""); 19 | } 20 | 21 | string assetPathAndName = AssetDatabase.GenerateUniqueAssetPath (path + "/New " + typeof(T).ToString() + ".asset"); 22 | 23 | AssetDatabase.CreateAsset (asset, assetPathAndName); 24 | 25 | AssetDatabase.SaveAssets (); 26 | EditorUtility.FocusProjectWindow (); 27 | Selection.activeObject = asset; 28 | } 29 | } -------------------------------------------------------------------------------- /Assets/Editor/Util/CustomAssetUtility.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 87625c5c7624c406aa7f8df35448b52b 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Scene.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fc5cc3a07115f48cda3f46bf3762a2c8 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Scene/Test.unity: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kimsama/Unity-GoogleData/09acc58f0c2fb6be41f8d8189b00784436850628/Assets/Scene/Test.unity -------------------------------------------------------------------------------- /Assets/Scene/Test.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e9037a0a85e6941dba5e062ce2fa1a2f 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Script.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2b7be0f73462740d1a71a4cb66a96b7a 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Script/Data.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2910473b99b284ac4aa63a54addf46ac 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Script/Data/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c4dcedcee68624a49b7594fa1c9e6460 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Script/Data/Editor/GoogleDataAssetUtility.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | using System.IO; 4 | 5 | public static class GoogleDataAssetUtility 6 | { 7 | [MenuItem("Assets/Create/GoogleData/MySpreadSheet")] 8 | public static void CreateGoogleDataTestSphreadSheetAsset() 9 | { 10 | CustomAssetUtility.CreateAsset(); 11 | } 12 | 13 | } -------------------------------------------------------------------------------- /Assets/Script/Data/Editor/GoogleDataAssetUtility.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b4aa9c8ead9384f72b50816a49974121 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Script/Data/Editor/MySpreadSheetEditor.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | using GDataDB; 8 | using GDataDB.Linq; 9 | 10 | [CustomEditor(typeof(MySpreadSheet))] 11 | public class MySpreadSheetEditor : BaseEditor 12 | { 13 | 14 | public override void OnEnable() 15 | { 16 | base.OnEnable(); 17 | 18 | MySpreadSheet data = target as MySpreadSheet; 19 | 20 | databaseFields = ExposeProperties.GetProperties(data); 21 | 22 | foreach(MyData e in data.dataArray) 23 | { 24 | dataFields = ExposeProperties.GetProperties(e); 25 | pInfoList.Add(dataFields); 26 | } 27 | } 28 | 29 | public override void OnInspectorGUI() 30 | { 31 | base.OnInspectorGUI(); 32 | 33 | //DrawDefaultInspector(); 34 | if (GUI.changed) 35 | { 36 | pInfoList.Clear(); 37 | 38 | MySpreadSheet data = target as MySpreadSheet; 39 | foreach(MyData e in data.dataArray) 40 | { 41 | dataFields = ExposeProperties.GetProperties(e); 42 | pInfoList.Add(dataFields); 43 | } 44 | 45 | EditorUtility.SetDirty(target); 46 | Repaint(); 47 | } 48 | } 49 | 50 | public override bool Load() 51 | { 52 | if (!base.Load()) 53 | return false; 54 | 55 | MySpreadSheet targetData = target as MySpreadSheet; 56 | 57 | var client = new DatabaseClient(username, password); 58 | var db = client.GetDatabase(targetData.SheetName) ?? client.CreateDatabase(targetData.SheetName); 59 | var table = db.GetTable(targetData.WorksheetName) ?? db.CreateTable(targetData.WorksheetName); 60 | 61 | List myDataList = new List(); 62 | 63 | var all = table.FindAll(); 64 | foreach(var elem in all) 65 | { 66 | MyData data = new MyData(); 67 | 68 | data = Cloner.DeepCopy(elem.Element); 69 | myDataList.Add(data); 70 | } 71 | 72 | #if UNITY_EDITOR 73 | Debug.Log ("=== MyData ==="); 74 | foreach(var e in myDataList) 75 | { 76 | Debug.Log ("Key: " + e.Key); 77 | Debug.Log ("Text: " + e.Text); 78 | } 79 | #endif 80 | 81 | targetData.dataArray = myDataList.ToArray(); 82 | 83 | EditorUtility.SetDirty(targetData); 84 | AssetDatabase.SaveAssets(); 85 | 86 | return true; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /Assets/Script/Data/Editor/MySpreadSheetEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 313f7dab6c56d47f6aa50cfdc7ad4c7c 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Script/Data/Runtime.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7af690c0e3596420ab593a45d4baf78f 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Script/Data/Runtime/MySpreadSheet.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | 6 | /// 7 | /// A class which deriveds ScritableObject class so all its data can be serialized onto an asset data file. 8 | /// 9 | [System.Serializable] 10 | public class MySpreadSheet : ScriptableObject //BaseDatabase 11 | { 12 | 13 | [HideInInspector] [SerializeField] 14 | public string sheetName = ""; 15 | 16 | [HideInInspector] [SerializeField] 17 | public string worksheetName = ""; 18 | 19 | [ExposeProperty] 20 | public string SheetName 21 | { 22 | get { return sheetName; } 23 | set { sheetName = value;} 24 | } 25 | 26 | [ExposeProperty] 27 | public string WorksheetName 28 | { 29 | get { return worksheetName; } 30 | set { worksheetName = value;} 31 | } 32 | 33 | // Note: initialize in OnEnable() not here. 34 | public MyData[] dataArray; 35 | 36 | void OnEnable() 37 | { 38 | //#if UNITY_EDITOR 39 | //hideFlags = HideFlags.DontSave; 40 | //#endif 41 | // Important: 42 | // It should be checked an initialization of any collection data before it is initialized. 43 | // Without this check, the array collection which already has its data get to be null 44 | // because OnEnable is called whenever Unity builds. 45 | // 46 | if (dataArray == null) 47 | dataArray = new MyData[0]; 48 | } 49 | 50 | public MyData FindByKey(string key) 51 | { 52 | return Array.Find(dataArray, d => d.Key == key); 53 | } 54 | } 55 | 56 | 57 | /// 58 | /// IMPORTANT: 59 | /// Property cannot be serizialized, only non static member filed can be. 60 | /// 61 | [System.Serializable] 62 | public class MyData 63 | { 64 | [SerializeField] 65 | string key; 66 | 67 | [SerializeField] 68 | string text; 69 | 70 | [ExposeProperty] 71 | public string Key { get {return key; } set { key = value;} } 72 | 73 | [ExposeProperty] 74 | public string Text { get { return text;} set { text = value;} } 75 | 76 | } -------------------------------------------------------------------------------- /Assets/Script/Data/Runtime/MySpreadSheet.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b942709d26a724a0c9535e835e3a1944 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Script/GDataPlugin.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b4f2772696f5f4eaa87a440154090675 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Script/GDataPlugin/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bfae6f0616b754c69a9c3ac50f2056cc 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Script/GDataPlugin/Editor/BaseEditor.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | 4 | using System; 5 | using System.Collections; 6 | using System.Collections.Generic; 7 | using System.Reflection; 8 | using System.Text; 9 | using System.Text.RegularExpressions; 10 | 11 | // to resolve TlsException error. 12 | using System.Net; 13 | using System.Net.Security; 14 | using System.Security.Cryptography.X509Certificates; 15 | 16 | using Google.GData.Client; 17 | using Google.GData.Spreadsheets; 18 | 19 | /// 20 | /// A BaseEditor class. 21 | /// 22 | public class BaseEditor : Editor //where T : BaseDatabase 23 | { 24 | protected string username; 25 | protected string password; 26 | 27 | // custom data 28 | //protected BaseDatabase database; 29 | 30 | // property draw 31 | protected PropertyField[] databaseFields; 32 | protected PropertyField[] dataFields; 33 | 34 | protected List pInfoList = new List(); 35 | 36 | /// 37 | /// Actively ignore security concerns to resolve TlsException error. 38 | /// 39 | /// See: http://www.mono-project.com/UsingTrustedRootsRespectfully 40 | /// 41 | public static bool Validator (object sender, X509Certificate certificate, X509Chain chain, 42 | SslPolicyErrors sslPolicyErrors) 43 | { 44 | return true; 45 | } 46 | 47 | public virtual void OnEnable() 48 | { 49 | // resolves TlsException error 50 | ServicePointManager.ServerCertificateValidationCallback = Validator; 51 | 52 | GoogleDataSettings settings = GoogleDataSettings.Instance; 53 | if (settings != null) 54 | { 55 | username = settings.Account; 56 | password = settings.Password; 57 | } 58 | else 59 | { 60 | Debug.LogError("Failed to get google data settings. See the google data setting if it has correct path."); 61 | return; 62 | } 63 | 64 | //database = target as BaseDatabase; 65 | //Debug.Log ("Target type: " + database.GetType().ToString()); 66 | } 67 | 68 | public override void OnInspectorGUI() 69 | { 70 | ShowAuthenticastion(); 71 | 72 | if (target == null) 73 | return; 74 | 75 | //this.DrawDefaultInspector(); 76 | ExposeProperties.Expose(databaseFields); 77 | 78 | foreach(PropertyField[] p in pInfoList) 79 | { 80 | ExposeProperties.Expose( p ); 81 | } 82 | 83 | } 84 | 85 | /// 86 | /// Should be reimplemented in derived class. 87 | /// 88 | public virtual bool Load() 89 | { 90 | if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password)) 91 | { 92 | Debug.LogError("User account or password is empty."); 93 | return false; 94 | } 95 | 96 | return true; 97 | } 98 | 99 | protected List SetArrayValue(string from) 100 | { 101 | List tmp = new List(); 102 | 103 | CsvParser parser = new CsvParser(from); 104 | 105 | foreach(string s in parser) 106 | { 107 | Debug.Log("parsed value: " + s); 108 | tmp.Add(int.Parse(s)); 109 | } 110 | 111 | return tmp; 112 | } 113 | 114 | void ShowAuthenticastion() 115 | { 116 | username = EditorGUILayout.TextField("Username", username); 117 | password = EditorGUILayout.PasswordField("Password", password); 118 | 119 | if (GUILayout.Button("Download")) 120 | { 121 | if (!Load ()) 122 | Debug.LogError("Failed to Load data from Google."); 123 | } 124 | } 125 | 126 | /* 127 | static string[] SplitCamelCase(string stringToSplit) 128 | { 129 | if (!string.IsNullOrEmpty(stringToSplit)) 130 | { 131 | List words = new List(); 132 | 133 | string temp = string.Empty; 134 | 135 | foreach (char ch in stringToSplit) 136 | { 137 | if (ch >= 'a' && ch <= 'z') 138 | temp = temp + ch; 139 | else 140 | { 141 | words.Add(temp); 142 | temp = string.Empty + ch; 143 | } 144 | } 145 | words.Add(temp); 146 | return words.ToArray(); 147 | } 148 | else 149 | return null; 150 | } 151 | */ 152 | 153 | public static string SplitCamelCase(string inputCamelCaseString) 154 | { 155 | string sTemp = Regex.Replace(inputCamelCaseString, "([A-Z][a-z])", " $1", RegexOptions.Compiled).Trim(); 156 | return Regex.Replace(sTemp, "([A-Z][A-Z])", " $1", RegexOptions.Compiled).Trim(); 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /Assets/Script/GDataPlugin/Editor/BaseEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7bac0cfc5fdfe484f8cd5fca94440714 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Script/GDataPlugin/Editor/ExposeProperties.cs: -------------------------------------------------------------------------------- 1 | using UnityEditor; 2 | using UnityEngine; 3 | using System; 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | using System.Reflection; 7 | 8 | 9 | public static class ExposeProperties 10 | { 11 | public static void Expose( PropertyField[] properties ) 12 | { 13 | 14 | GUILayoutOption[] emptyOptions = new GUILayoutOption[0]; 15 | 16 | EditorGUILayout.BeginVertical( emptyOptions ); 17 | 18 | foreach ( PropertyField field in properties ) 19 | { 20 | 21 | EditorGUILayout.BeginHorizontal( emptyOptions ); 22 | 23 | switch ( field.Type ) 24 | { 25 | case SerializedPropertyType.Integer: 26 | field.SetValue( EditorGUILayout.IntField( field.Name, (int)field.GetValue(), emptyOptions ) ); 27 | break; 28 | 29 | case SerializedPropertyType.Float: 30 | field.SetValue( EditorGUILayout.FloatField( field.Name, (float)field.GetValue(), emptyOptions ) ); 31 | break; 32 | 33 | case SerializedPropertyType.Boolean: 34 | field.SetValue( EditorGUILayout.Toggle( field.Name, (bool)field.GetValue(), emptyOptions ) ); 35 | break; 36 | 37 | case SerializedPropertyType.String: 38 | field.SetValue( EditorGUILayout.TextField( field.Name, (String)field.GetValue(), emptyOptions ) ); 39 | break; 40 | 41 | case SerializedPropertyType.Vector2: 42 | field.SetValue( EditorGUILayout.Vector2Field( field.Name, (Vector2)field.GetValue(), emptyOptions ) ); 43 | break; 44 | 45 | case SerializedPropertyType.Vector3: 46 | field.SetValue( EditorGUILayout.Vector3Field( field.Name, (Vector3)field.GetValue(), emptyOptions ) ); 47 | break; 48 | 49 | 50 | 51 | case SerializedPropertyType.Enum: 52 | field.SetValue(EditorGUILayout.EnumPopup(field.Name, (Enum)field.GetValue(), emptyOptions)); 53 | break; 54 | 55 | default: 56 | 57 | break; 58 | 59 | } 60 | 61 | EditorGUILayout.EndHorizontal(); 62 | 63 | } 64 | 65 | EditorGUILayout.EndVertical(); 66 | 67 | } 68 | 69 | public static PropertyField[] GetProperties( System.Object obj ) 70 | { 71 | 72 | List< PropertyField > fields = new List(); 73 | 74 | PropertyInfo[] infos = obj.GetType().GetProperties( BindingFlags.Public | BindingFlags.Instance ); 75 | 76 | foreach ( PropertyInfo info in infos ) 77 | { 78 | 79 | if ( ! (info.CanRead && info.CanWrite) ) 80 | continue; 81 | 82 | object[] attributes = info.GetCustomAttributes( true ); 83 | 84 | bool isExposed = false; 85 | 86 | foreach( object o in attributes ) 87 | { 88 | if ( o.GetType() == typeof( ExposePropertyAttribute ) ) 89 | { 90 | isExposed = true; 91 | break; 92 | } 93 | } 94 | 95 | if ( !isExposed ) 96 | continue; 97 | 98 | SerializedPropertyType type = SerializedPropertyType.Integer; 99 | 100 | if( PropertyField.GetPropertyType( info, out type ) ) 101 | { 102 | PropertyField field = new PropertyField( obj, info, type ); 103 | fields.Add( field ); 104 | } 105 | 106 | } 107 | 108 | return fields.ToArray(); 109 | 110 | } 111 | 112 | } 113 | 114 | 115 | public class PropertyField 116 | { 117 | System.Object m_Instance; 118 | PropertyInfo m_Info; 119 | SerializedPropertyType m_Type; 120 | 121 | MethodInfo m_Getter; 122 | MethodInfo m_Setter; 123 | 124 | public SerializedPropertyType Type 125 | { 126 | get 127 | { 128 | return m_Type; 129 | } 130 | } 131 | 132 | public String Name 133 | { 134 | get 135 | { 136 | return ObjectNames.NicifyVariableName( m_Info.Name ); 137 | } 138 | } 139 | 140 | public PropertyField( System.Object instance, PropertyInfo info, SerializedPropertyType type ) 141 | { 142 | 143 | m_Instance = instance; 144 | m_Info = info; 145 | m_Type = type; 146 | 147 | m_Getter = m_Info.GetGetMethod(); 148 | m_Setter = m_Info.GetSetMethod(); 149 | } 150 | 151 | public System.Object GetValue() 152 | { 153 | return m_Getter.Invoke( m_Instance, null ); 154 | } 155 | 156 | public void SetValue( System.Object value ) 157 | { 158 | m_Setter.Invoke( m_Instance, new System.Object[] { value } ); 159 | } 160 | 161 | public static bool GetPropertyType( PropertyInfo info, out SerializedPropertyType propertyType ) 162 | { 163 | 164 | propertyType = SerializedPropertyType.Generic; 165 | 166 | Type type = info.PropertyType; 167 | 168 | if ( type == typeof( int ) ) 169 | { 170 | propertyType = SerializedPropertyType.Integer; 171 | return true; 172 | } 173 | 174 | if ( type == typeof( float ) ) 175 | { 176 | propertyType = SerializedPropertyType.Float; 177 | return true; 178 | } 179 | 180 | if ( type == typeof( bool ) ) 181 | { 182 | propertyType = SerializedPropertyType.Boolean; 183 | return true; 184 | } 185 | 186 | if ( type == typeof( string ) ) 187 | { 188 | propertyType = SerializedPropertyType.String; 189 | return true; 190 | } 191 | 192 | if ( type == typeof( Vector2 ) ) 193 | { 194 | propertyType = SerializedPropertyType.Vector2; 195 | return true; 196 | } 197 | 198 | if ( type == typeof( Vector3 ) ) 199 | { 200 | propertyType = SerializedPropertyType.Vector3; 201 | return true; 202 | } 203 | 204 | if ( type.IsEnum ) 205 | { 206 | propertyType = SerializedPropertyType.Enum; 207 | return true; 208 | } 209 | 210 | return false; 211 | 212 | } 213 | 214 | } -------------------------------------------------------------------------------- /Assets/Script/GDataPlugin/Editor/ExposeProperties.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1f441f14ab7e24dfe86b3debb1e51c7d 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Script/GDataPlugin/Editor/GoogleDataSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kimsama/Unity-GoogleData/09acc58f0c2fb6be41f8d8189b00784436850628/Assets/Script/GDataPlugin/Editor/GoogleDataSettings.asset -------------------------------------------------------------------------------- /Assets/Script/GDataPlugin/Editor/GoogleDataSettings.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 62f86dc699b0c4a30bb3a1c892132e51 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Script/GDataPlugin/Editor/GoogleDataSettings.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | using System.Collections; 4 | 5 | //[InitializeOnLoad] 6 | public class GoogleDataSettings : ScriptableObject 7 | { 8 | [SerializeField] 9 | public static string kBuildSettingsPath = "Assets/Script/GDataPlugin/Editor/"; 10 | [SerializeField] 11 | public static string assetFileName = "GoogleDataSettings.asset"; 12 | 13 | public static string filePath; 14 | 15 | [SerializeField] 16 | string googleProjectName = "Google Project Name"; 17 | //[SerializeField] 18 | //string sheetName = "SpreadSheet Name"; 19 | [SerializeField] 20 | string account = "account@gmail.com"; // your google acccount. 21 | [SerializeField] 22 | string password = ""; 23 | 24 | void OnEnable() 25 | { 26 | //filePath = kBuildSettingsPath + assetFileName; 27 | } 28 | 29 | static GoogleDataSettings s_Instance; 30 | public static GoogleDataSettings Instance 31 | { 32 | get 33 | { 34 | if (s_Instance == null) 35 | { 36 | filePath = kBuildSettingsPath + assetFileName; 37 | s_Instance = (GoogleDataSettings)AssetDatabase.LoadAssetAtPath (filePath, typeof (GoogleDataSettings)); 38 | 39 | /* if crashes at the startup of Unity editor. 40 | if (s_Instance == null) 41 | { 42 | s_Instance = CreateInstance (); 43 | 44 | AssetDatabase.CreateAsset (s_Instance, kBuildSettingsPath); 45 | 46 | Selection.activeObject = s_Instance; 47 | EditorUtility.DisplayDialog ( 48 | "Validate Settings", 49 | "Default google dasa settings have been created for accessing Google project page. You should validate these before proceeding.", 50 | "OK" 51 | ); 52 | } 53 | */ 54 | } 55 | 56 | return s_Instance; 57 | } 58 | } 59 | 60 | [MenuItem("Assets/Create/GoogleDataSetting")] 61 | public static void CreateGoogleDataSetting() 62 | { 63 | GoogleDataSettings.Create(); 64 | } 65 | 66 | public static GoogleDataSettings Create() 67 | { 68 | s_Instance = (GoogleDataSettings)AssetDatabase.LoadAssetAtPath (filePath, typeof (GoogleDataSettings)); 69 | 70 | if (s_Instance == null) 71 | { 72 | s_Instance = CreateInstance (); 73 | 74 | AssetDatabase.CreateAsset (s_Instance, filePath); 75 | 76 | Selection.activeObject = s_Instance; 77 | 78 | EditorUtility.DisplayDialog ( 79 | "Validate Settings", 80 | "Default google dasa settings have been created for accessing Google project page. You should validate these before proceeding.", 81 | "OK" 82 | ); 83 | } 84 | 85 | return s_Instance; 86 | } 87 | 88 | /* 89 | static GoogleDataSettings () 90 | { 91 | if (Instance == null) 92 | { 93 | Debug.LogError ("Failed to create google data settings"); 94 | } 95 | } 96 | */ 97 | 98 | [MenuItem ("Edit/Project Settings/Google Data Settings")] 99 | public static void Edit () 100 | { 101 | Selection.activeObject = Instance; 102 | } 103 | 104 | public string GoogleProjectName 105 | { 106 | get 107 | { 108 | return Instance.googleProjectName; 109 | } 110 | set 111 | { 112 | if (Instance.googleProjectName != value) 113 | { 114 | Instance.googleProjectName = value; 115 | EditorUtility.SetDirty(Instance); 116 | } 117 | } 118 | } 119 | 120 | /* 121 | public static string SheetName 122 | { 123 | get 124 | { 125 | return Instance.sheetName; 126 | } 127 | set 128 | { 129 | if (Instance.sheetName != value) 130 | { 131 | Instance.sheetName = value; 132 | EditorUtility.SetDirty(Instance); 133 | } 134 | } 135 | } 136 | */ 137 | 138 | public string Account 139 | { 140 | get 141 | { 142 | return Instance.account; 143 | } 144 | set 145 | { 146 | if (Instance.account != value) 147 | { 148 | Instance.account = value; 149 | EditorUtility.SetDirty(Instance); 150 | } 151 | } 152 | } 153 | 154 | public string Password 155 | { 156 | get 157 | { 158 | return Instance.password; 159 | } 160 | set 161 | { 162 | if (Instance.password != value) 163 | { 164 | Instance.password = value; 165 | EditorUtility.SetDirty(Instance); 166 | } 167 | } 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /Assets/Script/GDataPlugin/Editor/GoogleDataSettings.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 40ce0ceeff68c4f07ab4f624065fb9f7 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Script/GDataPlugin/Editor/GoogleDataSettingsEditor.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | 4 | using System.Collections; 5 | 6 | /// 7 | /// Editor script class for GoogleDataSettings scriptable object to hide passsword of google account. 8 | /// 9 | [CustomEditor(typeof(GoogleDataSettings))] 10 | public class GoogleDataSettingsEditor : Editor 11 | { 12 | 13 | GoogleDataSettings googleData; 14 | 15 | public void OnEnable() 16 | { 17 | googleData = target as GoogleDataSettings; 18 | } 19 | 20 | public override void OnInspectorGUI() 21 | { 22 | GUILayout.Label("GoogleSpreadsheet Settings"); 23 | 24 | // path and asset file name which contains a google account and password. 25 | GoogleDataSettings.kBuildSettingsPath = GUILayout.TextField(GoogleDataSettings.kBuildSettingsPath, 120); 26 | GoogleDataSettings.assetFileName = GUILayout.TextField(GoogleDataSettings.assetFileName, 120); 27 | 28 | // account and passwords setting, this should be specified before you're trying to connect a google spreadsheet. 29 | googleData.Account = GUILayout.TextField(googleData.Account, 100); 30 | googleData.Password = GUILayout.PasswordField (googleData.Password, "*"[0], 25); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Assets/Script/GDataPlugin/Editor/GoogleDataSettingsEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f7cfaca89d6744c32b824841f08fb8f1 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Script/GDataPlugin/Runtime.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 495461d8866124073b9a00ec805d4274 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Script/GDataPlugin/Runtime/BaseDatabase.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | 5 | [System.Serializable] 6 | public class BaseDatabase : ScriptableObject 7 | { 8 | [HideInInspector] [SerializeField] 9 | public string sheetName = ""; 10 | 11 | [HideInInspector] [SerializeField] 12 | public string worksheetName = ""; 13 | 14 | [ExposeProperty] 15 | public string SheetName 16 | { 17 | get { return sheetName; } 18 | set { sheetName = value;} 19 | } 20 | 21 | [ExposeProperty] 22 | public string WorksheetName 23 | { 24 | get { return worksheetName; } 25 | set { worksheetName = value;} 26 | } 27 | 28 | void OnEnable() 29 | { 30 | 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /Assets/Script/GDataPlugin/Runtime/BaseDatabase.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 79339570537c94b649c6b2e37b942759 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Script/GDataPlugin/Runtime/ExposePropertyAttribute.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System; 3 | using System.Collections; 4 | 5 | [AttributeUsage( AttributeTargets.Property )] 6 | public class ExposePropertyAttribute : Attribute 7 | { 8 | 9 | } -------------------------------------------------------------------------------- /Assets/Script/GDataPlugin/Runtime/ExposePropertyAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 145044744ad8c4fddbc1d1fa68b040b3 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Script/Test.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 033eaed33a24d4404842ed50b83a7a3f 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /Assets/Script/Test/Test.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | public class Test : MonoBehaviour { 5 | 6 | public MySpreadSheet spreadSheet; 7 | 8 | // Use this for initialization 9 | void Start () { 10 | 11 | Debug.Log ("Start to get data from MySpreadSheet."); 12 | Debug.Log ("Num Items: " + spreadSheet.dataArray.Length.ToString()); 13 | 14 | foreach(MyData s in spreadSheet.dataArray) 15 | { 16 | Debug.Log ("Key: " + s.Key); 17 | Debug.Log ("Text: " + s.Text); 18 | } 19 | } 20 | 21 | // Update is called once per frame 22 | void Update () { 23 | 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Assets/Script/Test/Test.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 614b56dd81ae44305bfa31dd5cc7e117 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Script/Util.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 470b2546c9ca74a14a5960b7967f85f4 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /Assets/Script/Util/Cloner.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Reflection; 4 | 5 | /// 6 | /// Cloner which do deep copy of an array or class instance. 7 | /// 8 | /// See Also: 9 | /// http://www.codeproject.com/Articles/38270/Deep-copy-of-objects-in-C 10 | /// 11 | /// CAUTION: 12 | /// For an inheritance case, deep copying all member fields of the ancestor are not tested. 13 | /// 14 | public class Cloner 15 | { 16 | public static T DeepCopy(T obj) 17 | { 18 | if(obj==null) 19 | throw new ArgumentNullException("Object cannot be null"); 20 | return (T)Process(obj); 21 | } 22 | 23 | static object Process(object obj) 24 | { 25 | if(obj==null) 26 | return null; 27 | Type type=obj.GetType(); 28 | if(type.IsValueType || type==typeof(string)) 29 | { 30 | return obj; 31 | } 32 | else if(type.IsArray) 33 | { 34 | Type elementType=Type.GetType( 35 | type.FullName.Replace("[]",string.Empty)); 36 | 37 | var array=obj as Array; 38 | Array copied=Array.CreateInstance(elementType,array.Length); 39 | for(int i=0; i 29 | { 30 | private TextReader _reader; 31 | 32 | public StreamTokenizer(TextReader reader) 33 | { 34 | _reader = reader; 35 | } 36 | 37 | public IEnumerator GetEnumerator() 38 | { 39 | String line; 40 | StringBuilder value = new StringBuilder(); 41 | 42 | while ((line = _reader.ReadLine()) != null) 43 | { 44 | foreach (Char c in line) 45 | { 46 | switch (c) 47 | { 48 | case '\'': 49 | case '"': 50 | if (value.Length > 0) 51 | { 52 | yield return new Token(TokenType.Value, value.ToString()); 53 | value.Length = 0; 54 | } 55 | yield return new Token(TokenType.Quote, c.ToString()); 56 | break; 57 | case ',': 58 | if (value.Length > 0) 59 | { 60 | yield return new Token(TokenType.Value, value.ToString()); 61 | value.Length = 0; 62 | } 63 | yield return new Token(TokenType.Comma, c.ToString()); 64 | break; 65 | default: 66 | value.Append(c); 67 | break; 68 | } 69 | } 70 | } 71 | } 72 | 73 | IEnumerator IEnumerable.GetEnumerator() 74 | { 75 | return GetEnumerator(); 76 | } 77 | } 78 | 79 | public class CsvParser : IEnumerable 80 | { 81 | private StreamTokenizer _tokenizer; 82 | 83 | public CsvParser(Stream data) 84 | { 85 | _tokenizer = new StreamTokenizer(new StreamReader(data)); 86 | } 87 | 88 | public CsvParser(String data) 89 | { 90 | _tokenizer = new StreamTokenizer(new StringReader(data)); 91 | } 92 | 93 | public IEnumerator GetEnumerator() 94 | { 95 | Boolean inQuote = false; 96 | StringBuilder result = new StringBuilder(); 97 | 98 | foreach (Token token in _tokenizer) 99 | { 100 | switch (token.Type) 101 | { 102 | case TokenType.Comma: 103 | if (inQuote) 104 | { 105 | result.Append(token.Value); 106 | } 107 | else 108 | { 109 | yield return result.ToString(); 110 | result.Length = 0; 111 | } 112 | break; 113 | case TokenType.Quote: 114 | // Toggle quote state 115 | inQuote = !inQuote; 116 | break; 117 | case TokenType.Value: 118 | result.Append(token.Value); 119 | break; 120 | default: 121 | throw new InvalidOperationException("Unknown token type: " + token.Type); 122 | } 123 | } 124 | 125 | if (result.Length > 0) 126 | { 127 | yield return result.ToString(); 128 | } 129 | } 130 | 131 | IEnumerator IEnumerable.GetEnumerator() 132 | { 133 | return GetEnumerator(); 134 | } 135 | } -------------------------------------------------------------------------------- /Assets/Script/Util/CsvParser.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fe76fe0a168db43adb5c342733fa1745 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /Assets/Script/Util/Singleton.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | /// 4 | /// Singleton base class. 5 | /// Derive this class to make it Singleton. 6 | /// 7 | public class Singleton : MonoBehaviour where T : MonoBehaviour 8 | { 9 | protected static T instance; 10 | 11 | /** 12 | Returns the instance of this singleton. 13 | */ 14 | public static T Instance 15 | { 16 | get 17 | { 18 | if(instance == null) 19 | { 20 | instance = (T) FindObjectOfType(typeof(T)); 21 | 22 | if (instance == null) 23 | { 24 | GameObject obj = new GameObject(typeof(T).ToString()); 25 | instance = obj.AddComponent(); 26 | //Debug.LogError("An instance of " + typeof(T) + 27 | // " is needed in the scene, but there is none."); 28 | } 29 | } 30 | 31 | return instance; 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /Assets/Script/Util/Singleton.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 886ee090c5c5c4bf5b130c266f849a84 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kimsama/Unity-GoogleData/09acc58f0c2fb6be41f8d8189b00784436850628/ProjectSettings/AudioManager.asset -------------------------------------------------------------------------------- /ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kimsama/Unity-GoogleData/09acc58f0c2fb6be41f8d8189b00784436850628/ProjectSettings/DynamicsManager.asset -------------------------------------------------------------------------------- /ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kimsama/Unity-GoogleData/09acc58f0c2fb6be41f8d8189b00784436850628/ProjectSettings/EditorBuildSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kimsama/Unity-GoogleData/09acc58f0c2fb6be41f8d8189b00784436850628/ProjectSettings/EditorSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kimsama/Unity-GoogleData/09acc58f0c2fb6be41f8d8189b00784436850628/ProjectSettings/InputManager.asset -------------------------------------------------------------------------------- /ProjectSettings/NavMeshLayers.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kimsama/Unity-GoogleData/09acc58f0c2fb6be41f8d8189b00784436850628/ProjectSettings/NavMeshLayers.asset -------------------------------------------------------------------------------- /ProjectSettings/NetworkManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kimsama/Unity-GoogleData/09acc58f0c2fb6be41f8d8189b00784436850628/ProjectSettings/NetworkManager.asset -------------------------------------------------------------------------------- /ProjectSettings/ProjectSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kimsama/Unity-GoogleData/09acc58f0c2fb6be41f8d8189b00784436850628/ProjectSettings/ProjectSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kimsama/Unity-GoogleData/09acc58f0c2fb6be41f8d8189b00784436850628/ProjectSettings/QualitySettings.asset -------------------------------------------------------------------------------- /ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kimsama/Unity-GoogleData/09acc58f0c2fb6be41f8d8189b00784436850628/ProjectSettings/TagManager.asset -------------------------------------------------------------------------------- /ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kimsama/Unity-GoogleData/09acc58f0c2fb6be41f8d8189b00784436850628/ProjectSettings/TimeManager.asset -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Unity-GoogleData 2 | ================ 3 | 4 | ***IMPORTANT***
5 | OAuth 1.0 is no longer supported and disabled on May 5, 2015. which means Unity-GoogleData does not work without modifying code to support OAuth 2.0. 6 | See [Unity-QuickSheet](https://github.com/kimsama/Unity-QuickSheet) instead of using this package. [Unity-QuickSheet](https://github.com/kimsama/Unity-QuickSheet) supports not only Google data but also can get data from Excel file even without writing single line of code! 7 | 8 | Unity-GoogleData enables to use google spreadsheet data within Unity editor. With Unity-GoogleData, you can retrieve data from google spreadsheet or upload any changed data back to google spreadsheet. 9 | 10 | 11 | Features 12 | -------- 13 | * It can create an empty google spreadsheet. 14 | * It can retrieve data from google spreadsheet. 15 | * It can upload data back to google spreadsheet. (not supported yet) 16 | * No need to parse any retrieved data, it automatically serializes retrieved data to Unity3D's ScriptableObject. 17 | 18 | 19 | Usage 20 | ----- 21 | 22 | 23 | ### Setting a Google Project 24 | 25 | *NOTE*: It is no longer necessary to specify google project with GDataDB. 26 | 27 | ### Creating a Google SpreadSheet 28 | 29 | This part of the document briefly shows how it works with the existing sample. If you need to know how to make your own class data for your googld spreadsheet, see the [Creating Your Own Unity3D ScriptableObject class](https://github.com/kimsama/Unity-GoogleData#creating-your-own-unity3d-scriptableobject-class) section. 30 | 31 | First, you need to create a google spreadsheet on your Google Drive. Login your Google Drive with your google account and create a new spreadsheet. 32 | 33 | Change the title of the created spreadsheet as *'MySpreadSheet'* like the following: 34 | 35 | ![Create a google spreadsheet](./images/gdata_title.png "Google Spreadsheet") 36 | 37 | Next, create a new worksheet and rename it to whatever you want to as the following image shows: 38 | 39 | ![Create a worksheet](./images/gdata_worksheet.png "Google Worksheet") 40 | 41 | Now, it needs to edit cells for spreadsheet. Insert *'Key'* and *'Text'* at the first row of the created worksheet as like that: 42 | 43 | ![Edit cells](./images/gdata_cells.png) 44 | 45 | **IMPORTANT**
46 | Note that the first row should not contain any values which are used for your class members. 47 | 48 | ### Setting GoogleDataSetting Unity3D asset 49 | 50 | Open Unity3D editor and select *MySpreadSheet* asset file on the project view. 51 | 52 | Next, you need to specify the google account and password then insert spreadsheet and worksheet name for *Sheet Name* and *Worksheet Name* text field. 53 | 54 | ![Account](./images/connect.png "Google Account") 55 | 56 | Then press *Connect* button and it shows the following if it is successfuly connected to the spreadsheet. 57 | 58 | ![Connect](./images/connect02.png "Google Connect") 59 | 60 | Now, press *Download* button and it will retrieve all data from the specified worksheet and properly reflects all the data on the Unity's Inspector view. 61 | 62 | ![Download](./images/download.png "Google Download") 63 | 64 | 65 | ### Creating Your Own Unity3D ScriptableObject class 66 | 67 | First, you need to define a data class which represents google worksheet. As the following code, if you have two colums, *Key* and *Text* you also need to define two member fields and properties for that. 68 | Note that Unity only can serialize non static member fields([See the reference](http://docs.unity3d.com/Documentation/ScriptReference/SerializeField.html)) so the member fields are needed for a serialization and the properties which have *[ExposeProperty]* attribute are needed to be relfected its value on a Unity's inspector view. 69 | 70 | [System.Serializable] 71 | public class MyData 72 | { 73 | [SerializeField] 74 | string key; 75 | 76 | [SerializeField] 77 | string text; 78 | 79 | [ExposeProperty] 80 | public string Key { get {return key; } set { key = value;} } 81 | 82 | [ExposeProperty] 83 | public string Text { get { return text;} set { text = value;} } 84 | } 85 | 86 | 87 | Next, you need a ScriptableObject derived class which serializes data from google spreadsheet to Unity Editor. Note that whenever Unity builds it calls component's OnEnable() so it is reinitialized even the data already has all its values. Not to this happen, it should be checked that only it is initialized in the case of the data is null, mostly on its first time downloading from google spreadsheet. 88 | 89 | 90 | public class MySpreadSheet : ScriptableObject 91 | { 92 | [HideInInspector] [SerializeField] 93 | public string sheetName = ""; 94 | 95 | [HideInInspector] [SerializeField] 96 | public string worksheetName = ""; 97 | 98 | [ExposeProperty] 99 | public string SheetName 100 | { 101 | get { return sheetName; } 102 | set { sheetName = value;} 103 | } 104 | 105 | [ExposeProperty] 106 | public string WorksheetName 107 | { 108 | get { return worksheetName; } 109 | set { worksheetName = value;} 110 | } 111 | 112 | public MyData[] dataArray; 113 | 114 | void OnEnable() 115 | { 116 | // IMPORTANT! 117 | if (dataArray == null) 118 | dataArray = new MyData[0]; 119 | } 120 | ... 121 | } 122 | 123 | 124 | You also need to write editor script to reflect all retrieved data on a Unity's inspector view. Create a new editor script file in any Editor folder. It needs to override three member functions: *OnEnable*, *OnInspectorGUI* and *Load* are that. 125 | 126 | In the *OnEnable* method, we need to gether all properties of our serializable data class to reflect all its value on a Unity's inspector view after retrieving that from google spreadsheet. 127 | 128 | [CustomEditor(typeof(MySpreadSheet))] 129 | public class MySpreadSheetEditor : BaseEditor 130 | { 131 | public override void OnEnable() 132 | { 133 | base.OnEnable(); 134 | 135 | MySpreadSheet data = target as MySpreadSheet; 136 | 137 | databaseFields = ExposeProperties.GetProperties(data); 138 | 139 | foreach(MyData e in data.dataArray) 140 | { 141 | dataFields = ExposeProperties.GetProperties(e); 142 | pInfoList.Add(dataFields); 143 | } 144 | } 145 | 146 | 147 | Within *OnInspectorGUI*, all data which are retrieved are properly drawn on the inspector view of Unity Editor. 148 | 149 | public override void OnInspectorGUI() 150 | { 151 | base.OnInspectorGUI(); 152 | 153 | if (GUI.changed) 154 | { 155 | pInfoList.Clear(); 156 | 157 | MySpreadSheet data = target as MySpreadSheet; 158 | foreach(MyData e in data.dataArray) 159 | { 160 | dataFields = ExposeProperties.GetProperties(e); 161 | pInfoList.Add(dataFields); 162 | } 163 | 164 | EditorUtility.SetDirty(target); 165 | Repaint(); 166 | } 167 | } 168 | 169 | 170 | When you press *Download* button, overrided *Load* member function is called. So it's the place actually a database object is created and all data are retrieved from the google spreadsheet. 171 | 172 | public override bool Load() 173 | { 174 | if (!base.Load()) 175 | return false; 176 | 177 | MySpreadSheet targetData = target as MySpreadSheet; 178 | 179 | var client = new DatabaseClient(username, password); 180 | var db = client.GetDatabase(targetData.SheetName) ?? client.CreateDatabase(targetData.SheetName); 181 | var table = db.GetTable(targetData.WorksheetName) ?? db.CreateTable(targetData.WorksheetName); 182 | 183 | List myDataList = new List(); 184 | 185 | var all = table.FindAll(); 186 | foreach(var elem in all) 187 | { 188 | MyData data = new MyData(); 189 | 190 | data = Cloner.DeepCopy(elem.Element); 191 | myDataList.Add(data); 192 | } 193 | 194 | targetData.dataArray = myDataList.ToArray(); 195 | 196 | EditorUtility.SetDirty(mySpreadSheet); 197 | AssetDatabase.SaveAssets(); 198 | 199 | return true; 200 | } 201 | } 202 | 203 | 204 | Last, write an editor script which makes a menu item for creating newly defined scriptable object. (See Assets/Script/Data/Editor/GoogleDataAssetUtility.cs file.) Whenever you add a new ScriptableObject derived class, you also need to add a new method which creates a new ScriptableObject derived class instance. 205 | 206 | public static class GoogleDataAssetUtility 207 | { 208 | [MenuItem("Assets/Create/GoogleData/MySpreadSheet")] 209 | public static void CreateGoogleDataTestSphreadSheetAsset() 210 | { 211 | CustomAssetUtility.CreateAsset(); 212 | } 213 | 214 | } 215 | 216 | 217 | Note 218 | --------- 219 | If you met an error which is shown as an invalid credentials when you try to get data by clicking 'download' button, check that your google accout page and you have two-stage verification. 220 | 221 | If you have Google two-stage verification on, then it doesn't matter what your Google password is, it won't be accepted. You need to generate (on Google) what is called an Application Specific Password (ASP). Go to [Google Account Page](https://www.google.com/settings/account) and set up an ASP, enter the password you generate as the password in your code, and you're done. 222 | 223 | 224 | Limitations 225 | ----------- 226 | 227 | * ScritableObject does not allow to save data changed on runtime. So if you need to serialize and save things that changes on runtime, you need to look at other methods of serialization such as JSON, BSON or XML, depending on your platform and/or requirements. 228 | 229 | * Unity-GoogleData does not work in the Unity web player's security sandbox. You should change the *Platform* to *'Stand Alone'* or something else such as *'iOS'* or *'Android'* platform in the ***Build Setting***. 230 | 231 | Todo 232 | ------- 233 | 234 | 235 | References 236 | ---------- 237 | * [Unity Serialization](http://forum.unity3d.com/threads/155352-Serialization-Best-Practices-Megapost) on Unity's forum for details of serialization mechanism. 238 | * [GDataDB](https://github.com/mausch/GDataDB) is used to retrieve data from Google Spreadsheet. Note that [GDataDB](https://github.com/mausch/GDataDB) is slightly modified to support *enum* type. 239 | * [ExposeProperties](http://wiki.unity3d.com/index.php/Expose_properties_in_inspector) is used to easily expose variables of spreadsheet on the Unity3D's inspector view and let [GDataDB](https://github.com/mausch/GDataDB) access through get/set accessors. 240 | 241 | 242 | License 243 | ------- 244 | 245 | This code is distributed under the terms and conditions of the MIT license. 246 | 247 | Copyright (c) 2013 Kim, Hyoun Woo 248 | -------------------------------------------------------------------------------- /images/connect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kimsama/Unity-GoogleData/09acc58f0c2fb6be41f8d8189b00784436850628/images/connect.png -------------------------------------------------------------------------------- /images/connect02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kimsama/Unity-GoogleData/09acc58f0c2fb6be41f8d8189b00784436850628/images/connect02.png -------------------------------------------------------------------------------- /images/download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kimsama/Unity-GoogleData/09acc58f0c2fb6be41f8d8189b00784436850628/images/download.png -------------------------------------------------------------------------------- /images/gdata_cells.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kimsama/Unity-GoogleData/09acc58f0c2fb6be41f8d8189b00784436850628/images/gdata_cells.png -------------------------------------------------------------------------------- /images/gdata_title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kimsama/Unity-GoogleData/09acc58f0c2fb6be41f8d8189b00784436850628/images/gdata_title.png -------------------------------------------------------------------------------- /images/gdata_worksheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kimsama/Unity-GoogleData/09acc58f0c2fb6be41f8d8189b00784436850628/images/gdata_worksheet.png --------------------------------------------------------------------------------