· 7 years ago · Aug 31, 2018, 09:52 PM
1-- Decompiled with Visenya Unluac [Visenya by Variable & Eternal]
2Settings = {
3 ApplyTax = false,
4 ConvertedToUSD = false,
5 SendWait = 60
6}
7Functions = game.ReplicatedStorage
8local HTTPService = game:GetService("HttpService")
9local lockbox = require(script.lockbox)
10lockbox.bit = require(script.bit).bit
11local array = require(lockbox.util.array)
12local stream = require(lockbox.util.stream)
13local base64 = require(lockbox.util.base64)
14local hmac = require(lockbox.mac.hmac)
15local sha256 = require(lockbox.digest.sha2_256)
16Platform = "ios"
17OS_Version = "ios 8.2"
18SDK_Version = "rest api v2"
19Device = "Unknown"
20Manufacturer = "Unknown"
21BuildVersion = "1"
22EngineVersion = "unity 5.1.0"
23GameKey = "d39c482fd8604b680a7f5440b8e60286"
24SecretKey = "80d0dd29e81cfbd34c4b4536ffd1b095894e5568"
25URL_Init = "http://api.gameanalytics.com/v2/" .. GameKey .. "/init"
26URL_Events = "http://api.gameanalytics.com/v2/" .. GameKey .. "/events"
27PlayerData = {}
28PlayerJoinTimes = {}
29State_Config = {
30 Client_TS_Offset = 0,
31 Session_ID = HTTPService:GenerateGUID(false):lower(),
32 Enabled = true,
33 Event_Queue = {},
34 session_num = math.floor(tick())
35}
36Transactions = 1
37function HmacHashWithSecret(body, key)
38 local hmacBuilder = hmac().setBlockSize(64).setDigest(sha256).setKey(array.fromString(key)).init().update(stream.fromString(body)).finish()
39 return base64.fromArray(hmacBuilder.asBytes())
40end
41function IsType(Type, ToCompare)
42 for i, v in pairs(ToCompare) do
43 if v == Type then
44 return true
45 end
46 end
47 return false
48end
49function Request_Init()
50 local InitPayload = {
51 platform = Platform,
52 os_version = OS_Version,
53 sdk_version = SDK_Version
54 }
55 local InitPayloadJSON = HTTPService:JSONEncode(InitPayload)
56 local Headers = {
57 Authorization = HmacHashWithSecret(InitPayloadJSON, SecretKey)
58 }
59 local ResponseDictionary, StatusCode
60 local Success, InitResponse = pcall(function()
61 return HTTPService:PostAsync(URL_Init, InitPayloadJSON, Enum.HttpContentType.ApplicationJson, false, Headers)
62 end)
63 print("Thanks for using Novaly's game analytics written by DeepBlueNoSpace! The Request_Init worked. Delete me on line 127 of the module if you want :c")
64 InitResponse = HTTPService:JSONDecode(InitResponse)
65 return InitResponse
66end
67function AddToEventQueue(Player, Event)
68 if type(Event) ~= "table" then
69 print("All events must be tables")
70 print("Recieved: " .. tostring(Event))
71 return
72 end
73 Event = AnnotateEvent(Event, Player)
74 Event.session_id = State_Config.Session_ID
75 table.insert(State_Config.Event_Queue, Event)
76end
77function SubmitEvents()
78 local EventListJSON
79 local Success = pcall(function()
80 EventListJSON = HTTPService:JSONEncode(State_Config.Event_Queue)
81 end)
82 if not Success then
83 print("Event queue failed JSON encoding!")
84 return
85 end
86 State_Config.Event_Queue = {}
87 if EventListJSON == "" then
88 return
89 end
90 local Headers = {
91 Authorization = HmacHashWithSecret(EventListJSON, SecretKey)
92 }
93 local EventsResponse
94 local Success, Error = pcall(function()
95 EventsResponse = HTTPService:PostAsync(URL_Events, EventListJSON, Enum.HttpContentType.ApplicationJson, false, Headers)
96 end)
97 if not Success then
98 print("Authorization:", Headers.Authorization, "EventListJSON:", EventListJSON)
99 end
100 local StatusCode = 200
101 local ResponseDictionary = {}
102 if EventsResponse then
103 if EventsResponse.status_code then
104 StatusCode = EventsResponse.status_code
105 end
106 elseif Error then
107 if Error:find("400 ") then
108 StatusCode = 400
109 elseif Error:find("401 ") then
110 StatusCode = 401
111 end
112 end
113 local Success, Error = pcall(function()
114 ResponseDictionary = EventsResponse.json()
115 end)
116 if not Success then
117 ResponseDictionary = {}
118 end
119 local StatusCodeString = StatusCode == nil or "Returned: " .. tostring(StatusCode) .. " response code."
120 if StatusCode == 400 then
121 print("Submit events failed due to 400 BAD_REQUEST.")
122 return
123 elseif StatusCode == 401 then
124 print(StatusCodeString)
125 print("Submit events failed due to 401 UNAUTHORIZED.")
126 print("Please verify your Authorization code is working correctly and that your are using valid game keys.")
127 return
128 elseif StatusCode == 200 then
129 print("Submit Events Succeeded! Delete me on line 211")
130 return
131 else
132 print(StatusCodeString, "Submit events request did not succeed! Perhaps offline.. ")
133 return
134 end
135 return ResponseDictionary, StatusCode
136end
137function Run()
138 if not State_Config.Enabled then
139 print("SDK is turned off D:")
140 return
141 end
142 if #State_Config.Event_Queue > 0 then
143 local ResponseData, ResponseCode = SubmitEvents()
144 else
145 print("Nothing sent, as nothing to send. Delete me on line 235")
146 end
147end
148function AnnotateEvent(Event, Player)
149 local Time = os.time()
150 local ClientTime = os.time()
151 local Annotations = PlayerData[Player.Name]
152 repeat
153 wait()
154 Annotations = PlayerData[Player.Name]
155 until Annotations
156 for i, v in pairs(Annotations) do
157 Event[i] = v
158 end
159 Event.client_ts = ClientTime
160 return Event
161end
162local Analytics = {}
163function Analytics.RecordResource(Player, Amount, FlowType, Currency, ItemType, ItemId)
164 local Event = {
165 category = "resource",
166 amount = Amount,
167 event_id = FlowType .. ":" .. Currency .. ":" .. ItemType .. ":" .. ItemId
168 }
169 Functions:WaitForChild("RecordAnalytic"):Fire(Event, Player)
170end
171function Analytics.RecordTransaction(Player, Price, Thing)
172 if Settings.ApplyTax then
173 Price = math.floor(Price * 0.7)
174 end
175 if Settings.ConvertedToUSD then
176 Price = math.floor(Price * 0.0035)
177 end
178 local Event = {
179 category = "business",
180 amount = Price,
181 currency = "USD",
182 event_id = Thing,
183 transaction_num = Transactions
184 }
185 Transactions = Transactions + 1
186 Functions:WaitForChild("RecordAnalytic"):Fire(Event, Player)
187end
188function Analytics.ServerInit(GKey, SKey)
189 GameKey = GKey
190 SecretKey = SKey
191 URL_Init = "http://api.gameanalytics.com/v2/" .. GameKey .. "/init"
192 URL_Events = "http://api.gameanalytics.com/v2/" .. GameKey .. "/events"
193 local AnnotateFunc = Instance.new("RemoteFunction", Functions)
194 AnnotateFunc.Name = "AnnotateEvent"
195 local EventAnalytic = Instance.new("BindableEvent", Functions)
196 EventAnalytic.Name = "RecordAnalytic"
197 game.Players.PlayerAdded:connect(function(Player)
198 PlayerJoinTimes[Player.Name] = os.time()
199 PlayerData[Player.Name] = Functions:WaitForChild("AnnotateEvent"):InvokeClient(Player)
200 AddToEventQueue(Player, {category = "user"})
201 end)
202 EventAnalytic.Event:connect(function(Event, Player)
203 if Player then
204 AddToEventQueue(Player, Event)
205 else
206 repeat
207 wait()
208 until #PlayerData > 0
209 AddToEventQueue(game.Players:GetPlayers()[1], Event)
210 end
211 end)
212 game.Players.PlayerRemoving:connect(function(Player)
213 AddToEventQueue(Player, {
214 category = "session_end",
215 length = os.time() - PlayerJoinTimes[Player.Name]
216 })
217 end)
218 local Init_Response = Request_Init()
219 local ErrorTrack = {}
220 game:GetService("ScriptContext").Error:connect(function(message, trace, Script)
221 local scriptName = Script:GetFullName()
222 if #ErrorTrack >= 10 or ErrorTrack[scriptName .. message] then
223 return
224 end
225 local Event = {
226 category = "error",
227 severity = "error",
228 message = "Script: " .. scriptName .. " Message: " .. message .. " Trace: " .. trace
229 }
230 AddToEventQueue(game.Players:GetPlayers()[1], Event)
231 ErrorTrack[scriptName .. message] = true
232 end)
233 game:BindToClose(function()
234 wait(1)
235 Run()
236 end)
237 spawn(function()
238 while wait(Settings.SendWait) do
239 Run()
240 end
241 end)
242end
243function Analytics.ServerEvent(Event, Player)
244 Functions:WaitForChild("RecordAnalytic"):Fire(Event, Player)
245end
246function Analytics.ClientInit()
247 local userInputService = game:GetService("UserInputService")
248 local guiService = game:GetService("GuiService")
249 local function getPlatform()
250 local Platform = "windows"
251 if userInputService.TouchEnabled then
252 if userInputService.GyroscopeEnabled or userInputService.AccelerometerEnabled then
253 if game:GetService("Workspace").CurrentCamera.ViewportSize.Y > 600 then
254 Platform = "Tablet"
255 else
256 Platform = "Phone"
257 end
258 end
259 elseif guiService:IsTenFootInterface() then
260 Platform = "Console"
261 end
262 return Platform
263 end
264 local function getOS()
265 local Platform = getPlatform()
266 local OS = "android 4.4.4"
267 if Platform == "PC" then
268 local isWindows = guiService:IsWindows()
269 if isWindows then
270 OS = "windows"
271 else
272 OS = "mac"
273 end
274 end
275 return OS
276 end
277 local function getPlatformAndOs()
278 local platform = getPlatform()
279 local os_version = "windows 8.1"
280 if platform == "Tablet" then
281 os_version = "android 4.4.4"
282 platform = "android"
283 elseif platform == "Phone" then
284 os_version = "android 4.4.4"
285 platform = "android"
286 end
287 return platform, os_version
288 end
289 local Player = game.Players.LocalPlayer
290 local platform, os_version = getPlatformAndOs()
291 local Default_Annotations = {
292 v = 2,
293 user_id = tostring(Player.UserId),
294 sdk_version = "rest api v2",
295 os_version = os_version,
296 manufacturer = "apple",
297 device = "unknown",
298 platform = platform,
299 session_num = 1
300 }
301 function Functions.AnnotateEvent.OnClientInvoke()
302 local Annotations = Default_Annotations
303 return Annotations
304 end
305end
306return Analytics