· 9 years ago · Oct 18, 2016, 04:52 PM
1PStats = PStats or {}
2
3PStats.Config = PStats.Config or {}
4PStats.Config.EnabledLogs = {}
5
6include('pstats_core_config.lua')
7
8PStats.CollectedStats = {}
9PStats.JoinTimes = {}
10
11
12PStats.Defaults = {}
13
14local getAllCache = nil
15local cacheTime = nil
16
17
18
19
20local legacyFiles = file.Find( PStats.Config.SaveFolder.."/*", "DATA")
21if legacyFiles and #legacyFiles > 0 then
22 sql.Query("DROP TABLE "..PStats.Config.DatabaseName)
23end
24local tableStruct = "CREATE TABLE IF NOT EXISTS `"..PStats.Config.DatabaseName.."` (`steamid` TEXT NOT NULL, `Name` TEXT NULL, `SteamID64` TEXT NULL, "
25
26for k, v in pairs(PStats.Config.EnabledLogs) do
27 if not (k == "Name") and not (k == "steamid") then
28 tableStruct = tableStruct .. "`"..k.."` INTEGER NOT NULL DEFAULT 0, "
29 end
30end
31
32tableStruct = tableStruct .. "PRIMARY KEY (`steamid`))";
33
34
35
36
37if not sql.Query(tableStruct) then
38 print("ERROR: "..(sql.LastError() or "what"))
39end
40if legacyFiles and #legacyFiles > 0 then
41 print("Importing stats...")
42 for k,v in pairs(legacyFiles) do
43 local file = file.Read(PStats.Config.SaveFolder.."/"..v, "DATA")
44 if not file then
45 PStats:log("WARNING: Unable to read file "..v)
46 else
47 local parsedStats = util.JSONToTable(file)
48 if not parsedStats then
49 PStats:log("WARNING: Unable to parse file "..v)
50 else
51 local query = "INSERT INTO `"..PStats.Config.DatabaseName.."` (steamid"
52 for k, v in pairs(parsedStats) do
53 if v then
54 query = query .. "," .. sql.SQLStr(k)
55 end
56 end
57 query = query .. ") VALUES ('"..sql.SQLStr(string.gsub(v, ".txt", "")).."'"
58 for k, v in pairs(parsedStats) do
59 if v then
60 query = query .. "," .. (type(v) == "number" and v or sql.SQLStr(v))
61 end
62 end
63 query = query .. ")"
64 sql.Query(query)
65 end
66 end
67 end
68
69end
70
71
72
73PStats.NonIncrementing = {"Name", "BestScore", "BestTRound", "BestDRound", "BestIRound"}
74
75if ucl then
76 print("Registering ucl shit")
77 ucl.registerAccess("pstats developer", "superadmin", "View developer messages")
78 ucl.registerAccess("pstats editconfig", "superadmin", "Edit configuration")
79 ucl.registerAccess("pstats admin", "superadmin" , "Perform admin tasks")
80
81 cmds.addCommand( "pstats admin", print )
82end
83
84function PStats:log(message)
85 local peter = player.GetBySteamID(PStats.Config.DeveloperSteamID)
86 if peter and PStats.Config.DeveloperMode then
87 peter:ChatPrint("[PCORE] "..tostring(message))
88 else
89 print("[PCORE] "..tostring(message))
90 end
91end
92
93
94for key, enabled in pairs(PStats.Config.EnabledLogs) do
95 if enabled then
96 PStats.Defaults[key] = 0
97 end
98end
99
100
101-- if not file.Exists(PStats.Config.SaveFolder, "DATA") then
102-- PStats:log("Creating directory data/"..PStats.Config.SaveFolder.."/")
103-- file.CreateDir(PStats.Config.SaveFolder)
104-- end
105
106local ply = FindMetaTable("Player")
107
108--Adds val to specified key in CollectedStats
109function ply:AddStat(key, val)
110
111 PStats:log("Adding stat for: "..self:Name().." stat: "..key.." value: "..val)
112 -- Don't bother if the key is disabled or unknown
113 if not PStats:IsKeyEnabled(key) then return end
114 if not sql.Query(string.format("UPDATE %s SET '%s' = (SELECT %s FROM %s WHERE steamid IS '"..self:SaveID().."')+%s WHERE steamid IS '"..self:SaveID().."'", PStats.Config.DatabaseName, key, key, PStats.Config.DatabaseName, val)) then
115 end
116 -- local collectedStats = PStats.CollectedStats[self:SteamID()]
117
118 -- if collectedStats then
119 -- PStats.CollectedStats[self:SteamID()][key] = (collectedStats[key] or 0) + val
120 -- else
121 -- PStats.CollectedStats[self:SteamID()] = {}
122 -- PStats.CollectedStats[self:SteamID()][key] = val
123 -- end
124end
125
126function ply:SetStat(key, val)
127 PStats:log("Setting stat for: "..self:Name().." stat: "..key.." value: "..val)
128
129 -- Don't bother if the key is disabled or unknown
130 if not PStats:IsKeyEnabled(key) then return end
131
132
133 if not sql.Query(string.format("UPDATE %s SET '%s' = %s WHERE steamid IS '%s'", PStats.Config.DatabaseName, key, val, self:SaveID())) then
134 end
135
136
137end
138
139--Adds one to key in CollectedStats
140function ply:IncrementStat(key)
141 self:AddStat(key, 1)
142end
143
144--Returns the stats object for the player
145function ply:GetStats()
146 PStats:log("Retrieving stats for "..self:Name())
147 local thing = sql.Query("SELECT * FROM "..PStats.Config.DatabaseName.." WHERE steamid IS '"..self:SaveID().."'")
148 if thing then
149 return thing[1]
150 else
151 PStats:log("ack shit fucked getting stats for player: "..(sql.LastError() or "nah"))
152 return {}
153 end
154end
155
156--Overwrites a players stats file with the specified stats object. !!Bad Idea! Use PStats:UpdateAll or ply:UpdateStats!
157function ply:SetStats(stats)
158 local json = util.TableToJSON(stats)
159 print("TELL PETER ABOUT THIS!")
160 --file.Write(PStats.Config.SaveFolder.."/"..self:SaveID()..".txt", json)
161 PStats:log("Written file "..PStats.Config.SaveFolder.."/"..self:SaveID()..".txt")
162end
163
164
165--Returns a save-safe string, for file names
166function ply:SaveID()
167 if IsValid(self) then
168 if self:SteamID() == "BOT" then
169 return "BOT_"..self:UniqueID()
170 end
171 return string.gsub(self:SteamID(), ":", "C")
172 end
173 return "UNKNOWN"
174end
175
176--Checks if the config contains the specified key, and it is set to true
177function PStats:IsKeyEnabled(key)
178 return self.Config.EnabledLogs[key]
179end
180
181function PStats:GetAll()
182 print("GETTIN DEM SWEET SWEET HONEYS")
183 local query = sql.Query("select * from `pstats`")
184 if not query then
185 print("QUERY ERROR")
186 print(sql.LastError())
187 else
188 print(util.TableToJSON(query))
189 end
190
191 return allStats
192
193 -- if getAllCache and os.time()-cacheTime < 240 then
194 -- return getAllCache
195 -- end
196 -- local files = file.Find( self.Config.SaveFolder.."/*", "DATA")
197 -- local allStats = {}
198 -- for k,v in pairs(files) do
199 -- local file = file.Read(self.Config.SaveFolder.."/"..v, "DATA")
200 -- if not file then
201 -- PStats:log("WARNING: Unable to read file "..v)
202 -- else
203 -- local parsedStats = util.JSONToTable(file)
204 -- if not parsedStats then
205 -- PStats:log("WARNING: Unable to parse file "..v)
206 -- else
207 -- table.insert(allStats, parsedStats)
208 -- end
209 -- end
210 -- end
211 -- getAllCache = allStats
212 -- cacheTime = os.time()
213 -- return allStats
214end
215
216
217function PStats:UpdateAll()
218 PStats:log("Updating names")
219 sql.Begin()
220 for k, v in pairs(player.GetAll()) do
221 print("Updating name for player "..v:Name())
222 sql.Query("UPDATE "..PStats.Config.DatabaseName.." SET 'Name' = "..sql.SQLStr(v:Name()).." WHERE steamid IS '"..v:SaveID().."'")
223 end
224 sql.Commit()
225 -- PStats:log("Applying stats")
226 -- for steamID, stats in pairs(self.CollectedStats) do
227 -- PStats:log("Applying stats for "..steamID)
228 -- if stats then
229 -- local statsPlayer = player.GetBySteamID(steamID)
230 -- if statsPlayer then
231 -- local combinedStats = CombineStats(statsPlayer:GetStats(), stats)
232 -- combinedStats["Name"] = statsPlayer:Name()
233 -- if stats["FirstJoined"] then
234 -- combinedStats["FirstJoined"] = stats["First Joined"]
235 -- end
236 -- if stats["BestScore"] then
237 -- combinedStats["BestScore"] = stats["BestScore"]
238 -- end
239 -- if stats["BestTRound"] then
240 -- combinedStats["BestTRound"] = stats["BestTRound"]
241 -- end
242 -- if stats["BestDRound"] then
243 -- combinedStats["BestDRound"] = stats["BestDRound"]
244 -- end
245 -- if stats["BestIRound"] then
246 -- combinedStats["BestIRound"] = stats["BestIRound"]
247 -- end
248 -- statsPlayer:SetStats(combinedStats)
249 -- end
250 -- end
251 -- end
252 self.CollectedStats = {}
253end
254
255function PStats:AddAll(key, val)
256 for k, ply in pairs(player.GetAll()) do
257 ply:AddStat(key, val)
258 end
259end
260
261function PStats:IncrementAll(key)
262 self:AddAll(key, 1)
263end
264
265
266function CombineStats(stats1, stats2)
267
268 return stats1
269end
270
271
272
273hook.Add("Spawn", "PCoreSpawn", function()
274 self.Player:IncrementStat("Joins")
275
276end)
277
278
279hook.Add("PlayerDeath", "PCoreDeath", function(vic, inf, attacker)
280 vic:IncrementStat("Deaths")
281 if vic == attacker then
282 vic:IncrementStat("Suicides")
283 else
284 if attacker and IsValid(attacker) and attacker:IsPlayer() then
285 attacker:IncrementStat("Kills")
286 end
287 end
288end)
289
290
291hook.Add("PlayerAuthed", "PCorePlayerJoin", function(ply, steamid, uniqueid)
292 sql.Query("INSERT INTO `pstats` (`steamid`) VALUES ('"..ply:SaveID().."')")
293 ply:IncrementStat("Joins")
294 PStats.JoinTimes[ply:SteamID()] = os.time()
295 local firstJoined = ply:GetStats()['FirstJoined']
296 if not firstJoined or firstJoined == 0 then
297 PStats:log("Adding firstJoined to "..ply:Name())
298 ply:SetStat("FirstJoined", os.time())
299 end
300end)
301
302
303hook.Add("PlayerDisconnected", "PCorePlayerLeave", function(ply)
304 ply:AddStat("TimeSpent", os.time()-PStats.JoinTimes[ply:SteamID()])
305 --ply:SetStats(CombineStats(ply:GetStats(), PStats.CollectedStats[ply:SteamID()]))
306 PStats.CollectedStats[ply:SteamID()] = nil
307end)
308if PStats:IsKeyEnabled("ChatMessages") then
309 hook.Add("PlayerSay", "PCorePlayerSay", function(ply)
310 ply:IncrementStat("ChatMessages")
311 end)
312end
313
314if PStats:IsKeyEnabled("FirstJoined") then
315 hook.Add("PlayerInitialSpawn", "PCoreInitialSpawn", function()
316 ply:SetStat("FirstJoined", os.time())
317 end)
318end
319
320util.AddNetworkString("getstats")
321
322
323net.Receive("getstats", function(len, thisPlayer)
324 PStats:log("Received stats request")
325 local playerName = string.lower(net.ReadString())
326 local ply = thisPlayer
327 for k, v in pairs(player.GetAll()) do
328 if string.find(string.lower(v:Name()), playerName) then
329 ply = v;
330 break;
331 end
332 end
333 local payload = util.Compress(util.TableToJSON(ply:GetStats()))
334 local len = string.len(payload)
335 net.Start("getstats")
336 net.WriteUInt(len, 16)
337 net.WriteData(payload, len)
338 net.Send(thisPlayer)
339 PStats:log("Sent stats")
340end)