· 6 years ago · Nov 21, 2019, 11:02 PM
1/*
2
3 Smart CAD System
4 11/20/2019
5
6 GreenStaar - Digital Business Solutions
7
8 Made for Thin Blue Line RP
9*/
10
11/*
12 Pooled Strings
13*/
14util.AddNetworkString('smart_cad_menu');
15util.AddNetworkString('smart_cad_query');
16util.AddNetworkString('smart_cad_query_relay');
17util.AddNetworkString('smart_cad_user_action');
18
19
20/*
21 Cad Table
22*/
23
24local cad = {};
25
26/*
27 SQL Table
28*/
29
30cad.sql = include('plugins/sql.lua');
31
32/*
33 Print
34 String
35 Returns: Void
36*/
37function cad:Print(...)
38
39 if (smart_cad_cfg.debug) then
40 print('[SmartCAD]', ...);
41 end
42end
43
44/*
45 Verify Job List
46 Void / Nil
47 Returns: Void / Nil
48
49 Verify that all entries in the job whitelist are lowercase keys
50*/
51function cad:VerifyJobList()
52
53 local buffer = table.Copy(smart_cad_cfg.jobWhiteList);
54
55 for k,v in next, buffer do
56 buffer[k] = nil;
57 buffer[k:lower()] = v;
58 end
59
60 smart_cad_cfg.jobWhiteList = buffer;
61end
62cad:VerifyJobList();
63
64/*
65 Check Job Name
66 Player
67 Returns: bool
68
69 Checks the configured strings against given player's job name
70*/
71function cad:CheckJob(ply)
72
73 if (ply.getJobTable) then // check if this function exists
74
75 local jobTable = ply:getJobTable(); // grab job table
76 if (smart_cad_cfg.jobWhiteList[jobTable.name:lower()]) then // check if the job is in our whitelist, this is not case sensitive because we force lowercase everything
77 return true;
78 end
79 end
80
81 return false;
82end
83
84/*
85 Chat Commands
86 Player, String, Bool
87 Returns: String
88
89 Note: Check if the player is in a vehicle later
90*/
91function cad:ChatCommand(ply, str, bTeam)
92
93 local lower = str:lower();
94
95 if (lower == smart_cad_cfg.chatCommand) then
96 if (self:CheckJob(ply)) then
97
98 self.sql:Query([[
99 SELECT * FROM cases ORDER BY id DESC LIMIT 30
100 ]], function(q, data)
101
102 if (IsValid(ply)) then // Double check player validity
103
104 net.Start('smart_cad_menu');
105 net.WriteTable(data);
106 net.Send(ply);
107 end
108 end);
109
110 return '';
111 end
112 end
113end
114hook.Add('PlayerSay', 'cad_chat', function(ply, str, bTeam)
115
116 local ret = cad:ChatCommand(ply, str, bTeam);
117 if (ret) then
118 return ret;
119 end
120end);
121
122/*
123 Search Cases / Events
124 Player, String
125
126 Performs an SQL SELECT query and relays the data to the user requesting it
127*/
128function cad:SearchCases(ply, value)
129
130 local v = self.sql:Escape(value); // Escape & Shorten variable name
131
132 self.sql:Query([[
133 SELECT * FROM cases WHERE id=']] .. v .. [[' OR name=']] .. v .. [[' OR type=']] .. v .. [[' OR plate=']] .. v .. [[' OR weapon=']] .. v .. [[' OR charges=']] ..
134 v .. [[' OR felony=']] .. v .. [[' OR active=']] .. v .. [[' ORDER BY id DESC LIMIT 30
135 ]], function(q, data)
136
137 if (IsValid(ply)) then // Double check player validity
138
139 self:Print('Completed query for ', ply:Nick());
140
141 net.Start('smart_cad_query_relay');
142 net.WriteTable(data);
143 net.Send(ply);
144 end
145 end);
146end
147
148/*
149 Create Case / Event
150 Table, Callback
151 Returns: Void
152*/
153function cad:CreateCase(caseTable, callback)
154
155 local a = self.sql:EscapeTable(caseTable); // Shorten variable name and escape
156
157 self.sql:Query([[
158 INSERT INTO cases (`id`, `steamid`, `name`, `type`, `plate`, `weapon`, `charges`, `officers`, `felony`, `location`, `summary`, `active`)
159 VALUES ('', ']] .. a.steamID ..[[',']] .. a.name .. [[',']] .. a.type .. [[',']] .. a.plate .. [[',']] .. a.weapon .. [[',']] .. a.charges .. [[',']] ..
160 a.officers .. [[',']] .. a.felony .. [[',']] .. a.location .. [[',']] .. a.summary .. [[',']] .. a.active ..[[')
161 ]], function(q, data)
162
163 callback(data);
164 self:Print('Created Case: ', caseTable.name);
165 end);
166end
167
168/*
169 Edit Case / Event
170 Int, String, String
171 Returns: Void
172
173 Edits a single column in a case
174*/
175function cad:EditCase(caseID, column, value)
176
177 column = column:lower(); // Fool proofing, none of my column names ever use capitals
178
179 caseID = self.sql:Escape(caseID);
180 column = self.sql:Escape(column);
181 value = self.sql:Escape(value);
182
183 self.sql:Query([[
184 UPDATE cases WHERE id=']] .. caseID .. [[' SET ]] .. column .. [[=']] .. value .. [['
185 ]], function(q, data)
186
187 self:Print('Updated caseID:', caseID, 'column = ', column, 'value = ', value);
188 end);
189end
190
191/*
192 Full Edit Case / Event
193 Int, Table
194 Returns: Void
195
196 Edits a full table row (a full case / event)
197*/
198function cad:FullEditCase(caseID, caseTable)
199
200 caseID = self.sql:Escape(caseID);
201
202 local a = caseTable; // shorten variable name
203
204 self.sql:Query([[
205 UPDATE cases WHERE id=']] .. caseID .. [[' SET name=']] .. a.name .. [[',
206 type=']] .. a.type .. [[',
207 plate=']] .. a.plate .. [[',
208 weapon=']] .. a.weapon .. [[',
209 charges=']] .. a.charges .. [[',
210 officers=']] .. a.officers .. [[',
211 felony=']] .. a.felony .. [[',
212 location=']] .. a.location .. [[',
213 summary=']] .. a.summary .. [[',
214 active=']] .. a.active .. [['
215 ]], function(q, data)
216
217 self:Print('Fully Edited caseID: ' .. caseID);
218 end);
219end
220
221/*
222 Delete Case / Event
223*/
224function cad:DeleteCase(caseID)
225
226 caseID = self.sql:Escape(caseID);
227
228 self.sql:Query([[
229 DELETE FROM cases WHERE id=']] .. caseID .. [['
230 ]], function(q, data)
231
232 self:Print('Deleted caseID:', caseID);
233 end);
234end
235
236/*
237 SQL Startup
238 Void
239 Returns: Void
240
241 Creates the cases / events table if it doesn't exist
242*/
243function cad:SQLStartup()
244
245 self.sql:Query([[
246 CREATE TABLE IF NOT EXISTS cases(
247 id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
248 steamid VARCHAR(128) NOT NULL,
249 name VARCHAR(128) NOT NULL,
250 type VARCHAR(128) NOT NULL,
251 plate VARCHAR(128) NOT NULL,
252 weapon VARCHAR(128) NOT NULL,
253 charges VARCHAR(128) NOT NULL,
254 officers VARCHAR(256) NOT NULL,
255 felony VARCHAR(128) NOT NULL,
256 location VARCHAR(128) NOT NULL,
257 summary VARCHAR(128) NOT NULL,
258 active INT NOT NULL)
259 ]], function(q, data)
260
261 self:Print("DB Table Created!");
262 end);
263end
264cad:SQLStartup();
265
266/*
267 Client -> Server Networking
268 Receive net messages from clients and handle them
269
270 Note: Check for vehicle in the future
271*/
272
273// Process user actions
274net.Receive('smart_cad_action', function(len, ply)
275
276 if (!cad:CheckJob(ply)) then
277
278 cad:Print('smart_cad_action: User is not whitelisted!');
279 return;
280 end
281
282 local data = net.ReadTable();
283
284 if (data.action == nil) then cad:Print('smart_cad_action: action table element is not defined!') return end // Validate elements from the table
285
286 if (data.action == 'create') then
287
288 if (data.caseTable) then cad:Print('smart_cad_action (create): caseTable element is not defined!') return end // Validate just as above
289 cad:CreateCase(data.caseTable, function(data)
290 // Nothing for now
291 end);
292
293 elseif(data.action == 'edit') then
294
295 if (data.caseID == nil || data.column == nil || data.value == nil) then cad:Print('smart_cad_action (edit): caseID, column or value table element is undefined!') return end // Validate
296 cad:EditCase(data.caseID, data.column, data.value);
297
298 elseif(data.action == 'fullEdit') then
299
300 if (data.caseID == nil) then cad:Print('smart_cad_action (fullEdit): caseID table element is undefined!') return end
301 if (data.caseTable == nil) then cad:Print('smart_cad_action (fullEdit): caseTable element is undefined!') return end
302
303 cad:FullEditCase(data.caseID, data.caseTable);
304
305 elseif(data.action == 'delete') then
306
307 if (data.caseID == nil) then cad:Print('smart_cad_action (delete): caseID table element is undefined!') return end
308
309 cad:DeleteCase(data.caseID);
310 end
311end);
312
313// Process search queries
314net.Receive('smart_cad_query', function(len, ply)
315
316 if (!cad:CheckJob(ply)) then
317
318 cad:Print('smart_cad_query: User is not whitelisted!');
319 return;
320 end
321
322 local query = net.ReadString();
323 cad:SearchCases(ply, query);
324end);
325
326/*
327 Debug
328*/