BasicService.cs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. using System;
  2. using UnityEngine;
  3. using SimpleJSON;
  4. using System.Collections;
  5. namespace Newgrounds.Services {
  6. public class BasicService {
  7. // Types
  8. public delegate void ServiceCallback(BasicService __service);
  9. // Constants
  10. private const string API_URL = "http://www.ngads.com/gateway_v2.php";
  11. private const string RADIX_SET = "/g8236klvBQ#&|;Zb*7CEA59%s`Oue1wziFp$rDVY@TKxUPWytSaGHJ>dmoMR^<0~4qNLhc(I+fjn)X";
  12. // Instances
  13. private ServiceCallback callback;
  14. private WWWForm formData;
  15. private WWW serviceRequest;
  16. // Request data
  17. protected string commandId;
  18. protected bool isSecure;
  19. // Result data
  20. private bool _resultSuccess;
  21. private string _resultErrorMessage;
  22. private int _resultErrorCode;
  23. // ================================================================================================================
  24. // CONSTRUCTOR ----------------------------------------------------------------------------------------------------
  25. public BasicService(ServiceCallback __callback = null) {
  26. callback = __callback;
  27. setDefaultData();
  28. }
  29. // ================================================================================================================
  30. // PUBLIC INTERFACE -----------------------------------------------------------------------------------------------
  31. public void execute() {
  32. // Creates the service
  33. Debug.Log("executing service");
  34. IDictionaryEnumerator myEnumerator;
  35. formData = new WWWForm();
  36. Hashtable formDataHash = new Hashtable();
  37. // The command
  38. if (isSecure) {
  39. string seed = StringUtils.getRandomAlphanumericString(13);
  40. string seedMD5 = StringUtils.MD5(seed);
  41. // Everything in an ecrypted field
  42. Hashtable formDataSecureHash = new Hashtable();
  43. // Generate the data first
  44. addBasicFields(formDataSecureHash);
  45. formDataSecureHash.Add("seed", seed);
  46. JSONObject j = new JSONObject(JSONObject.Type.OBJECT);
  47. myEnumerator = formDataSecureHash.GetEnumerator();
  48. while (myEnumerator.MoveNext()) {
  49. if (myEnumerator.Value is int) {
  50. j.AddField((string)myEnumerator.Key, (int)myEnumerator.Value);
  51. // Debug.Log(" SECURE adding int => " + myEnumerator.Key + " = " + myEnumerator.Value);
  52. } else {
  53. j.AddField((string)myEnumerator.Key, (string)myEnumerator.Value);
  54. // Debug.Log(" SECURE adding string => " + myEnumerator.Key + " = " + myEnumerator.Value);
  55. }
  56. }
  57. string secureParameter = j.Print();
  58. string encryptionKey = API.encryptionKey;
  59. // For some reason, the request never works the string length is a multiple of 6 (when the seed has a length of 1 or 13 or ...)
  60. // The documentation is conflicting in this regard and it's hard to know the cause (probably number padding and alignment)
  61. // So just add a space in that case
  62. // Sizes that don't work: 174, 180
  63. // Sizes that work: 175, 176, 177, 178
  64. if (secureParameter.Length % 3 == 0) secureParameter += " ";
  65. Debug.Log("Secure param => (" + secureParameter.Length + ") " + secureParameter);
  66. // Encode all data with RC4
  67. string secureParameterHex = seedMD5 + StringUtils.convertBytesToString(StringUtils.encodeRC4(secureParameter, encryptionKey));
  68. // Testingh
  69. // Convert to baseN
  70. int pos = 0;
  71. string secureParameterBaseN = "";
  72. string hexString;
  73. int hexNumber;
  74. while (pos < secureParameterHex.Length) {
  75. hexString = secureParameterHex.Substring(pos, Math.Min(pos + 6, secureParameterHex.Length)-pos);
  76. hexNumber = Convert.ToInt32(hexString, 16);
  77. secureParameterBaseN += StringUtils.convertIntToCustomBase(hexNumber, RADIX_SET, 4);
  78. //secureParameterBaseN += StringUtils.convertIntToCustomBase(hexNumber, RADIX_SET, hexString.Length / 3 * 2);
  79. pos += 6;
  80. }
  81. // Add tail length
  82. secureParameterBaseN = (secureParameterBaseN.Length % 6) + secureParameterBaseN;
  83. // Add real fields
  84. formDataHash.Add("secure", secureParameterBaseN);
  85. formDataHash.Add("command_id", "securePacket");
  86. } else {
  87. // Everything in main request
  88. addBasicFields(formDataHash);
  89. }
  90. // The tracker ID of your game
  91. formDataHash.Add("tracker_id", API.apiId);
  92. // Generate form data
  93. myEnumerator = formDataHash.GetEnumerator();
  94. while (myEnumerator.MoveNext()) {
  95. if (myEnumerator.Value is int) {
  96. formData.AddField((string)myEnumerator.Key, (int)myEnumerator.Value);
  97. // Debug.Log(" adding int => " + myEnumerator.Key + " = " + myEnumerator.Value);
  98. } else {
  99. formData.AddField((string)myEnumerator.Key, (string)myEnumerator.Value);
  100. // Debug.Log(" adding string => " + myEnumerator.Key + " = " + myEnumerator.Value);
  101. }
  102. }
  103. // Send
  104. serviceRequest = new WWW(API_URL, formData);
  105. API.surrogate.doPost(serviceRequest, onDone);
  106. }
  107. // ================================================================================================================
  108. // ACCESSOR INTERFACE ---------------------------------------------------------------------------------------------
  109. public bool resultSuccess {
  110. get { return _resultSuccess; }
  111. }
  112. public string resultErrorMessage {
  113. get { return _resultErrorMessage; }
  114. }
  115. public int resultErrorCode {
  116. get { return _resultErrorCode; }
  117. }
  118. // ================================================================================================================
  119. // EXTENDED INTERFACE ---------------------------------------------------------------------------------------------
  120. protected virtual void setDefaultData() {
  121. // Extend
  122. commandId = "";
  123. isSecure = false;
  124. }
  125. protected virtual void addCustomFields(Hashtable __hash) {
  126. // Extend
  127. }
  128. protected virtual void parseSuccessResult(JSONNode __result) {
  129. // Extend
  130. }
  131. // ================================================================================================================
  132. // INTERNAL INTERFACE ---------------------------------------------------------------------------------------------
  133. private void addBasicFields(Hashtable __hash) {
  134. __hash.Add("command_id", commandId);
  135. if (API.connectionPublisherId != null) __hash.Add("publisher_id", API.connectionPublisherId);
  136. if (API.connectionSessionId != null) __hash.Add("session_id", API.connectionSessionId);
  137. //if (API.connectionUserId != null) __hash.AddField("user_id", API.connectionSessionId);
  138. addCustomFields(__hash);
  139. }
  140. private void onDone() {
  141. JSONNode result = JSON.Parse(serviceRequest.text);
  142. // {"error_msg":"You must be logged in or provide an e-mail address to use postScore().","error_code":7,"success":0,"command_id":"postScore"}
  143. if (result["success"].AsInt == 1) {
  144. // Success!
  145. _resultSuccess = true;
  146. parseSuccessResult(result);
  147. } else {
  148. // Error!
  149. _resultSuccess = false;
  150. _resultErrorMessage = result["error_msg"];
  151. _resultErrorCode = result["error_code"].AsInt;
  152. }
  153. if (callback != null) callback(this);
  154. }
  155. }
  156. }