· 7 years ago · Aug 17, 2018, 10:04 PM
1--Variables
2local baseURL = "http://api.gameanalytics.com/v2/"
3
4--Services
5local HTTP = game:GetService("HttpService")
6
7GA = {
8 PostFrequency = 15,
9
10 GameKey = nil,
11 SecretKey = nil,
12 SessionID = nil,
13 Queue = {},
14
15 EncodingModules = {},
16 Ready = false,
17}
18
19function GA:Init(GameKey, SecretKey)
20 baseURL = baseURL..GameKey.."/"
21
22 GA.GameKey = GameKey
23 GA.SecretKey = SecretKey
24 GA.SessionID = HTTP:GenerateGUID(false):lower()
25
26 --Encoding Modules
27 GA.EncodingModules.lockbox = require(script.lockbox)
28 GA.EncodingModules.lockbox.bit = require(script.bit).bit
29 GA.EncodingModules.array = require(GA.EncodingModules.lockbox.util.array)
30 GA.EncodingModules.stream = require(GA.EncodingModules.lockbox.util.stream)
31 GA.EncodingModules.base64 = require(GA.EncodingModules.lockbox.util.base64)
32 GA.EncodingModules.hmac = require(GA.EncodingModules.lockbox.mac.hmac)
33 GA.EncodingModules.sha256 = require(GA.EncodingModules.lockbox.digest.sha2_256)
34
35 GA.Base = {
36 ["device"] = "unknown",
37 ["v"] = 2,
38 ["user_id"] = "unknown",
39 ["client_ts"] = os.time(),
40 ["sdk_version"] = "rest api v2",
41 ["os_version"] = "windows 10",
42 ["manufacturer"] = "unknown",
43 ["platform"] = "windows",
44 ["session_id"] = GA.SessionID,
45 ["session_num"] = 1,
46 }
47
48 local Data = HTTP:JSONEncode({
49 ["platform"] = "unknown",
50 ["os_version"] = "unknown",
51 ["sdk_version"] = "rest api v2",
52 })
53
54 local Headers = {
55 Authorization = GA:Encode(Data)
56 }
57
58 local Response = HTTP:PostAsync(baseURL.."init", Data, Enum.HttpContentType.ApplicationJson, false, Headers)
59 Response = HTTP:JSONDecode(Response)
60
61 if not Response.enabled then
62 warn("GameAnalytics did not initialize properly!")
63 return
64 end
65
66 GA.Ready = true
67
68 spawn(function()
69 while true do
70 wait(GA.PostFrequency)
71 GA:Post()
72 end
73 end)
74end
75
76function GA:SendEvent(Data)
77 if not GA.Ready then
78 warn("GameAnalytics has not been initialized! Call :Init(GameKey, SecretKey) on the module before sending events!")
79 end
80
81 for i,v in pairs(GA.Base) do
82 Data[i] = Data[i] or v
83 end
84
85 table.insert(GA.Queue, Data)
86 return true
87end
88
89function GA:Post()
90 if not GA.Ready then
91 warn("GameAnalytics has not been initialized! Call :Init(GameKey, SecretKey) on the module before sending events!")
92 return
93 end
94
95 if #GA.Queue > 0 then
96 local Data = HTTP:JSONEncode(GA.Queue)
97 GA.Queue = {}
98
99 local Headers = {
100 ["Authorization"] = GA:Encode(Data)
101 }
102
103 local s,ret = pcall(function() return HTTP:PostAsync(baseURL.."events", Data, Enum.HttpContentType.ApplicationJson, false, Headers) end)
104
105 if s then
106 print("GameAnalytics: Posted!")
107 else
108 warn("GameAnalytics: Posting error.")
109 warn(ret)
110 end
111 end
112end
113
114function GA:Encode(body)
115 local secretKey = GA.SecretKey
116
117 local hmacBuilder = GA.EncodingModules.hmac()
118 .setBlockSize(64)
119 .setDigest(GA.EncodingModules.sha256)
120 .setKey(GA.EncodingModules.array.fromString(secretKey))
121 .init()
122 .update(GA.EncodingModules.stream.fromString(body))
123 .finish()
124 return GA.EncodingModules.base64.fromArray(hmacBuilder.asBytes())
125end
126
127return GA