· 6 years ago · Sep 29, 2019, 05:12 PM
1#define DEBUG
2
3#define PLUGIN_AUTHOR "SZOKOZ/EXE KL"
4#define PLUGIN_VERSION "1.00"
5#define MODULE_NAME "ASteamBot_BuyRank"
6
7#include <sourcemod>
8#include <sdktools>
9#include <ASteambot>
10#include <multicolors>
11
12#pragma semicolon 1
13#pragma newdecls required
14#pragma dynamic 131072
15
16#define ITEM_ID "itemID"
17#define ITEM_NAME "itemName"
18#define ITEM_VALUE "itemValue"
19#define ITEM_DONATED "itemDonated"
20#define RANKP_ITEMOPTS "items"
21#define RANKP_TIME "rankDuration"
22#define RANKP_NAME "packageName"
23#define RANKP_ID "id"
24#define RANKP_FLAGS "adminLevels"
25#define MAX_OPTION_ITEMS 8
26
27#define STRING(%1) %1,sizeof(%1)
28#define ISEMPTY(%1) !%1[0]
29
30char CREATE_TABLE[] = "CREATE TABLE IF NOT EXISTS `purchasedranks`"...
31 "("...
32 "`purchaseid` INT NOT NULL AUTO_INCREMENT, "...
33 "`id64` VARCHAR(64) NOT NULL, "...
34 "`flags` INT NOT NULL, "...
35 "`expires` INT NOT NULL, "...
36 "PRIMARY KEY(`purchaseid`)"...
37 ")"...
38 "ENGINE = InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;";
39
40char INSERT_PLAYER[] = "INSERT IGNORE INTO `purchasedranks`"...
41" (`id64`, `flags`, `expires`) VALUES ('%s', %d, %d)";
42
43char GET_PLAYER[] = "SELECT * FROM `purchasedranks` WHERE `id64` = '%s' AND `expires` > %d";
44
45ArrayList g_hRankPackages;
46ArrayList g_hTF2Items[MAXPLAYERS];
47ArrayList g_hCSGOItems[MAXPLAYERS];
48ArrayList g_hDOTA2Items[MAXPLAYERS];
49StringMap g_hPendingPackageActivation[MAXPLAYERS];
50Database g_hDb;
51
52public Plugin myinfo =
53{
54 name = "ASteamBot_BuyRank",
55 author = PLUGIN_AUTHOR,
56 description = "Buy Admin Levels via SteamBot",
57 version = PLUGIN_VERSION,
58 url = "szokoz.eu"
59};
60
61public void OnAllPluginsLoaded()
62{
63 //Ensure that there is not late-load problems.
64 if (LibraryExists("ASteambot"))
65 ASteambot_RegisterModule(MODULE_NAME);
66 else
67 SetFailState("ASteambot_Core is not present/not running. Plugin can't continue !");
68}
69
70public void OnPluginStart()
71{
72 Database.Connect(OnDbConnect, MODULE_NAME);
73
74 RegConsoleCmd("sm_donaterank", CMD_GetRank,
75 "Create a trade offer and send it to the player for VIP or Admin.");
76 RegConsoleCmd("sm_rangok", CMD_GetRank,
77 "Create a trade offer and send it to the player for VIP or Admin.");
78
79 g_hRankPackages = new ArrayList();
80 LoadTranslations("ASteambot.buyrank.phrases");
81}
82
83public void OnPluginEnd()
84{
85 ASteambot_RemoveModule();
86}
87
88public void OnConfigsExecuted()
89{
90 LoadRankPackages();
91}
92
93public void OnClientPostAdminFilter(int client)
94{
95 SQL_GetPlayerActivePackages(client, PostAdminFilter_SQLResult);
96}
97
98void PostAdminFilter_SQLResult(int client, StringMap rPackage)
99{
100 if (!IsClientValid(client))
101 {
102 PrintToServer("PAF:Client %d invalid.", client);
103 return;
104 }
105
106
107 if (rPackage == null)
108 {
109 PrintToServer("PAF:Package invalid.");
110 return;
111 }
112
113
114 int expires;
115 PrintToServer("Expires paf: %d", expires);
116 rPackage.GetValue(RANKP_TIME, expires);
117
118 if (expires >= GetTime())
119 return;
120
121 int flags;
122 rPackage.GetValue(RANKP_FLAGS, flags);
123 AddUserFlags(client, view_as<AdminFlag>(flags));
124 PrintToServer("Client %d has been given adminflag %d", client, flags);
125}
126
127public Action CMD_GetRank(int client, int args)
128{
129 if (!IsClientValid)
130 return Plugin_Handled;
131
132 if (!ASteambot_IsConnected())
133 {
134 CPrintToChat(client, "%s {fullred}%t", MODULE_NAME, "ASteambot_NotConnected");
135 return Plugin_Handled;
136 }
137
138 CPrintToChat(client, "%s {green}%t", MODULE_NAME, "TradeOffer_WaitItems");
139
140 SQL_GetPlayerActivePackages(client, OnCmdRank_SQLResult);
141
142 return Plugin_Handled;
143}
144
145void OnCmdRank_SQLResult(int client, StringMap packageMap)
146{
147 if (!IsClientValid(client))
148 {
149 return;
150 }
151
152 if (packageMap != null)
153 {
154 CPrintToChat(client, "%s {green}%s", MODULE_NAME, "You already have an active package!");
155 return;
156 }
157
158 char clientSteamID[40];
159 GetClientAuthId(client, AuthId_Steam2, clientSteamID, sizeof(clientSteamID));
160 ASteambot_SendMesssage(AS_SCAN_INVENTORY, clientSteamID);
161}
162
163void LoadRankPackages()
164{
165 KeyValues kv = CreateKeyValues("Rank_Packages");
166 if (!FileToKeyValues(kv, "addons/sourcemod/configs/rankpackages.cfg"))
167 {
168 SetFailState("%s Config File Cannot Be Accessed!", MODULE_NAME);
169 return;
170 }
171
172 static char rPackage[256];
173 static char flagString[256];
174 static char items[1024];
175 int ranktime;
176
177 kv.GotoFirstSubKey();
178 int i;
179 char id[4];
180 do
181 {
182 kv.GetSectionName(STRING(rPackage));
183 kv.GetString(RANKP_FLAGS, STRING(flagString));
184 kv.GetNum(RANKP_TIME);
185 kv.GetString(RANKP_ITEMOPTS, STRING(items));
186 ArrayList packageOptions = ParseItemString(items);
187 StringMap packageMap = new StringMap();
188 IntToString(i++, STRING(id));
189 packageMap.SetString(RANKP_ID, id);
190 packageMap.SetString(RANKP_NAME, rPackage);
191 packageMap.SetValue(RANKP_FLAGS, ParseFlagString(flagString));
192 packageMap.SetValue(RANKP_TIME, ranktime);
193 packageMap.SetValue(RANKP_ITEMOPTS, packageOptions);
194 g_hRankPackages.Push(packageMap);
195 }
196 while (KvGotoNextKey(kv));
197}
198
199int ParseFlagString(const char[] flags)
200{
201 char flagNames[32][16];
202 int flagCount = ExplodeString(flags, ",", flagNames, sizeof(flagNames), sizeof(flagNames[]));
203 int flag;
204 for (int i = 0; i < flagCount; i++)
205 {
206 AdminFlag admFlag;
207 bool success = FindFlagByName(flagNames[i], admFlag);
208 PrintToServer("Flag conversion %b, %s to %d", success, flagNames[i], admFlag);
209 flag |= view_as<int>(admFlag);
210 }
211
212 return flag;
213}
214
215ArrayList ParseItemString(const char[] items)
216{
217 ArrayList array = new ArrayList();
218 static char itemsoptions[4][256];
219 int options = ExplodeString(items, "|", itemsoptions, sizeof(itemsoptions), sizeof(itemsoptions[]));
220
221 for (int i = 0; i < options; i++)
222 {
223 static char itemsoption[MAX_OPTION_ITEMS][64];
224 int count =
225 ExplodeString(itemsoptions[i], ",", itemsoption, sizeof(itemsoption), sizeof(itemsoption[]));
226
227 ArrayList optionItems = new ArrayList(sizeof(itemsoption[]));
228 for (int j = 0; j < count; j++)
229 {
230 optionItems.PushString(itemsoption[j]);
231 }
232 array.Push(optionItems);
233 }
234
235 return array;
236}
237
238public void OnDbConnect(Database db, const char[] error, any data)
239{
240 if (db == null)
241 {
242 SetFailState("Unable to establish database connection to %s: %s", MODULE_NAME, error);
243 }
244 else
245 {
246 db.Query(OnTableCreate, CREATE_TABLE);
247 g_hDb = db;
248 }
249}
250
251void SQL_AddNewPurchase(int client, StringMap packageMap, Function callback)
252{
253 if (g_hDb == null)
254 return;
255
256 if (!IsClientValid(client))
257 return;
258
259 char id64[32];
260 GetClientAuthId(client, AuthId_SteamID64, STRING(id64));
261
262 int flags, time;
263 packageMap.GetValue(RANKP_FLAGS, flags);
264 packageMap.GetValue(RANKP_TIME, time);
265 static char query[512];
266 //expiry: current time in seconds plus days in seconds
267 Format(STRING(query), INSERT_PLAYER, id64, flags, GetTime()+(time*60*60*24));
268 DataPack dp = new DataPack();
269 dp.WriteCell(client);
270 dp.WriteCell(packageMap);
271 dp.WriteFunction(callback);
272 g_hDb.Query(OnInsertQuery, query, dp);
273 PrintToServer("Threaded Query Sent for Adding Purchase: Client %d", client);
274}
275
276void SQL_GetPlayerActivePackages(int client, Function callback)
277{
278 if (g_hDb == null)
279 return;
280
281 if (!IsClientValid(client))
282 return;
283
284 char id64[32];
285 GetClientAuthId(client, AuthId_SteamID64, STRING(id64));
286
287 static char query[512];
288 Format(STRING(query), GET_PLAYER, id64, GetTime());
289
290 DataPack dp = new DataPack();
291 dp.WriteCell(client);
292 dp.WriteFunction(callback);
293 g_hDb.Query(OnGetQuery, query, dp);
294}
295
296public void OnTableCreate(Database db, DBResultSet results, const char[] error, any data)
297{
298
299}
300
301public void OnInsertQuery(Database db, DBResultSet results, const char[] error, any data)
302{
303 DataPack dp = view_as<DataPack>(data);
304 dp.Reset();
305
306 int client = dp.ReadCell();
307 StringMap packageMap = dp.ReadCell();
308 Function callback = dp.ReadFunction();
309
310 delete dp;
311
312 if (!ISEMPTY(error))
313 {
314 PrintToServer("Error: %s", error);
315 return;
316 }
317
318
319 Call_StartFunction(INVALID_HANDLE, callback);
320 Call_PushCell(client);
321 Call_PushCell(packageMap);
322 Call_Finish();
323}
324
325public void OnGetQuery(Database db, DBResultSet results, const char[] error, any data)
326{
327 DataPack dp = view_as<DataPack>(data);
328 dp.Reset();
329
330 int client = dp.ReadCell();
331 Function callback = dp.ReadFunction();
332
333 delete dp;
334
335 if (!results.HasResults)
336 return;
337
338 if (!results.RowCount)
339 {
340 Call_StartFunction(INVALID_HANDLE, callback);
341 Call_PushCell(client);
342 Call_PushCell(0);
343 Call_Finish();
344 return;
345 }
346
347 while (results.FetchRow())
348 {
349 StringMap activePackage = new StringMap();
350 char id64[32];
351 results.FetchString(1, STRING(id64));
352 activePackage.SetString("id64", id64);
353 activePackage.SetValue("flags", results.FetchInt(2));
354 activePackage.SetValue("expires", results.FetchInt(3));
355 Call_StartFunction(INVALID_HANDLE, callback);
356 Call_PushCell(client);
357 Call_PushCell(activePackage);
358 Call_Finish();
359 }
360}
361
362public int ASteambot_Message(AS_MessageType MessageType, char[] message, const int messageSize)
363{
364 PrintToServer("MessageType: %d, Message:%s", MessageType, message);
365 char[][] parts = new char[4][messageSize];
366 char steamID[40];
367
368 ExplodeString(message, "/", parts, 4, messageSize);
369 Format(steamID, sizeof(steamID), parts[0]);
370
371 int client = ASteambot_FindClientBySteam64(steamID);
372
373 if (MessageType == AS_NOT_FRIENDS && client != -1)
374 {
375 CPrintToChat(client, "%s {green}%t", MODULE_NAME, "Steam_NotFriends");
376 char clientSteamID[30];
377
378 GetClientAuthId(client, AuthId_Steam2, clientSteamID, sizeof(clientSteamID));
379 ASteambot_SendMesssage(AS_FRIEND_INVITE, clientSteamID);
380
381 CPrintToChat(client, "%s {green}%t", MODULE_NAME, "Steam_FriendInvitSend");
382 }
383 else if (MessageType == AS_SCAN_INVENTORY && client != -1)
384 {
385 CPrintToChat(client, "%s {green}%t", MODULE_NAME, "TradeOffer_InventoryScanned");
386 PrepareInventories(client, parts[1], parts[2], parts[3], messageSize);
387 }
388 else if (MessageType == AS_TRADEOFFER_DECLINED && client != -1)
389 {
390 CPrintToChat(client, "%s {red}%t", MODULE_NAME, "TradeOffer_Declined");
391 g_hPendingPackageActivation[client] = null;
392 char packageName[256];
393 g_hPendingPackageActivation[client].GetString(RANKP_NAME, STRING(packageName));
394 char id64[32];
395 GetClientAuthId(client, AuthId_SteamID64, STRING(id64));
396 LogToFile("BuyRanksTradeLog.log", "Trade Offer for Package %s Denied by %N(%s)",
397 packageName, client, id64);
398 }
399 else if (MessageType == AS_TRADEOFFER_SUCCESS && client != -1)
400 {
401 /*char[] offerID = new char[messageSize];
402 char[] value = new char[messageSize];
403
404 Format(offerID, messageSize, parts[1]);
405 Format(value, messageSize, parts[2]);*/
406
407 char pName[45];
408 GetClientName(client, pName, sizeof(pName));
409 CPrintToChat(client, "%s {green}%t", MODULE_NAME, "TradeOffer_Success", pName);
410 PrintToServer("adding purchase to db for client %d", client);
411 char packageName[256];
412 g_hPendingPackageActivation[client].GetString(RANKP_NAME, STRING(packageName));
413 char id64[32];
414 GetClientAuthId(client, AuthId_SteamID64, STRING(id64));
415 LogToFile("BuyRanksTradeLog.log", "Trade Offer for Package %s Accepted by %N(%s)",
416 packageName, client, id64);
417 SQL_AddNewPurchase(client, g_hPendingPackageActivation[client], PostAdminFilter_SQLResult);
418
419 //ModVIP(client, "add", 0, VIPDuration[client] );
420 }
421}
422
423public void PrepareInventories(int client, const char[] tf2, const char[] csgo, const char[] dota2, int charSize)
424{
425 int tf2_icount = CountCharInString(tf2, ',') + 1;
426 int csgo_icount = CountCharInString(csgo, ',') + 1;
427 int dota2_icount = CountCharInString(dota2, ',') + 1;
428
429 g_hTF2Items[client] = CreateArray(tf2_icount);
430 g_hCSGOItems[client] = CreateArray(csgo_icount);
431 g_hDOTA2Items[client] = CreateArray(dota2_icount);
432
433 CreateInventory(client, tf2, tf2_icount, g_hTF2Items[client]);
434 CreateInventory(client, csgo, csgo_icount, g_hCSGOItems[client]);
435 CreateInventory(client, dota2, dota2_icount, g_hDOTA2Items[client]);
436
437 DisplayVIPPackageSelection(client);
438}
439
440public void CreateInventory(int client, const char[] strinventory, int itemCount, Handle inventory)
441{
442 if (!StrEqual(strinventory, "EMPTY"))
443 {
444 char[][] items = new char[itemCount][60];
445
446 ExplodeString(strinventory, ",", items, itemCount, 60);
447
448 for (int i = 0; i < itemCount; i++)
449 {
450 char itemInfos[3][30];
451 ExplodeString(items[i], "=", itemInfos, sizeof itemInfos, sizeof itemInfos[]);
452
453 Handle TRIE_Item = CreateTrie();
454 SetTrieString(TRIE_Item, ITEM_ID, itemInfos[0]);
455 SetTrieString(TRIE_Item, ITEM_NAME, itemInfos[1]);
456 SetTrieValue(TRIE_Item, ITEM_VALUE, StringToFloat(itemInfos[2]));
457 SetTrieValue(TRIE_Item, ITEM_DONATED, 0);
458 PushArrayCell(inventory, TRIE_Item);
459 }
460 }
461 else if (StrEqual(strinventory, "ERROR"))
462 {
463 CPrintToChat(client, "%s {fullred}%t", MODULE_NAME, "TradeOffer_ItemsError", strinventory);
464 }
465}
466
467public void DisplayVIPPackageSelection(int client)
468{
469 ArrayList viableClientPackages = ViableClientPackages(client);
470
471 if(viableClientPackages.Length == 0)
472 {
473 CPrintToChat(client, "%s {fullred}%t", MODULE_NAME, "VIP_NoPackageAvailable");
474 return;
475 }
476
477 CPrintToChat(client, "%s {green}%t", MODULE_NAME, "TradeOffer_SelectTradeOffer");
478
479 Menu menu = new Menu(MenuHandle_MainMenu);
480 menu.SetTitle("Select a VIP package :");
481
482 for (int i = 0; i < viableClientPackages.Length; i++)
483 {
484 StringMap packageMap = viableClientPackages.Get(i);
485 char pname[64];
486 char num[4];
487 packageMap.GetString(RANKP_ID, STRING(num));
488 packageMap.GetString(RANKP_NAME, STRING(pname));
489 menu.AddItem(num, pname);
490 }
491
492 menu.ExitBackButton = true;
493 menu.Display(client, MENU_TIME_FOREVER);
494}
495
496public ArrayList ViableClientPackages(int client)
497{
498 ArrayList viableClientPackages = new ArrayList();
499
500 for (int i = 0; i < g_hRankPackages.Length; i++)
501 {
502 StringMap packageMap = g_hRankPackages.Get(i);
503 ArrayList options;
504 int itemFound = 0;
505 char mainItemName[64];
506 char packageName[256];
507
508 GetTrieValue(packageMap, RANKP_ITEMOPTS, options);
509 GetTrieString(packageMap, RANKP_NAME, packageName, sizeof(packageName));
510
511 for (int j = 0; j < options.Length; j++)
512 {
513 ArrayList option = options.Get(j);
514 for (int k = 0; k < option.Length; k++)
515 {
516 option.GetString(k, STRING(mainItemName));
517 char itemID[30];
518 bool result = GetItemID(client, mainItemName, itemID, sizeof(itemID));
519
520 if(result && StrEqual(itemID, "NOT_FOUND") == false)
521 itemFound++;
522 }
523
524 if (itemFound == option.Length)
525 {
526 viableClientPackages.Push(packageMap);
527 break;
528 }
529
530 }
531
532 ResetInventories(client);
533 }
534
535 return viableClientPackages;
536}
537
538public int MenuHandle_MainMenu(Handle menu, MenuAction action, int client, int itemIndex)
539{
540 if (action == MenuAction_Select)
541 {
542 char description[32];
543 GetMenuItem(menu, itemIndex, description, sizeof(description));
544
545 ShowPackageMenu(client, StringToInt(description));
546 }
547 else if (action == MenuAction_End)
548 {
549 CloseHandle(menu);
550 }
551}
552
553public void ShowPackageMenu(int client, int packageID)
554{
555 ArrayList options;
556 char iname[50];
557 char itemID[30];
558 char packageName[55];
559 StringMap packageMap = g_hRankPackages.Get(packageID);
560
561 packageMap.GetString(RANKP_NAME, packageName, sizeof(packageName));
562 packageMap.GetValue(RANKP_ITEMOPTS, options);
563
564 Menu menu = new Menu(MenuHandle_PackageSelect);
565 menu.SetTitle(packageName);
566
567 for (int i = 0; i < options.Length; i++)
568 {
569 ArrayList option = options.Get(i);
570 for (int j = 0; j < option.Length; j++)
571 {
572 option.GetString(j, iname, sizeof(iname));
573 PrintToServer("%s zzz", iname);
574 if(GetItemID(client, iname, itemID, sizeof(itemID)))
575 {
576 PrintToServer("%s added to mofo menu", iname);
577 menu.AddItem(itemID, iname, ITEMDRAW_DEFAULT);
578 }
579 else
580 {
581 PrintToServer("heh?%d", j);
582 menu.RemoveAllItems();
583 break;
584 }
585 }
586
587 if (menu.ItemCount > 0)
588 {
589 g_hPendingPackageActivation[client] = packageMap;
590 break;
591 }
592 }
593
594 menu.AddItem("OK", "OK!");
595 menu.ExitBackButton = true;
596 menu.Display(client, MENU_TIME_FOREVER);
597}
598
599public int MenuHandle_PackageSelect(Handle menu, MenuAction action, int client, int itemIndex)
600{
601 if (action == MenuAction_Select)
602 {
603 char itemID[32];
604 GetMenuItem(menu, itemIndex, itemID, sizeof(itemID));
605 if(StrEqual(itemID, "OK"))
606 {
607 Handle items = CreateArray(100);
608 char itemList[512];
609 char itemName[64];
610 for (int i = 0; i < itemIndex; i++)
611 {
612 GetMenuItem(menu, i, itemID, sizeof(itemID), _, STRING(itemName));
613 PushArrayString(items, itemID);
614 StrCat(STRING(itemList), itemName);
615 }
616
617 ASteambot_CreateTradeOffer(client, items);
618 char packageName[256];
619 g_hPendingPackageActivation[client].GetString(RANKP_NAME, STRING(packageName));
620 char id64[32];
621 GetClientAuthId(client, AuthId_SteamID64, STRING(id64));
622 LogToFile("BuyRanksTradeLog.log", "%t to %N(%s) with the following items from package %s: %s",
623 "TradeOffer_Initiated", client, id64, packageName, itemList);
624 CPrintToChat(client, "%s {green}%t", MODULE_NAME, "TradeOffer_Created");
625 }
626 else
627 {
628 CPrintToChat(client, "%s {fullred}%t", MODULE_NAME, "VIP_Denied");
629 }
630 }
631 else if (action == MenuAction_End)
632 {
633 CloseHandle(menu);
634 }
635}
636
637public bool GetItemID(int client, const char[] mainItemName, char[] itemID, int itemIDsize)
638{
639 if(GetItemIDFromInventory(g_hTF2Items[client], mainItemName, itemID, itemIDsize))
640 return true;
641 else if(GetItemIDFromInventory(g_hCSGOItems[client], mainItemName, itemID, itemIDsize))
642 return true;
643 else if(GetItemIDFromInventory(g_hDOTA2Items[client], mainItemName, itemID, itemIDsize))
644 return true;
645
646 return false;
647}
648
649public bool GetItemIDFromInventory(Handle inventory, const char[] mainItemName, char[] itemID, int itemIDsize)
650{
651 char itemName[100];
652 for (int i = 0; i < GetArraySize(inventory); i++)
653 {
654 Handle t = GetArrayCell(inventory, i);
655 GetTrieString(t, ITEM_NAME, itemName, sizeof(itemName));
656
657 if (StrEqual(itemName, mainItemName))
658 {
659 int donated = -1;
660 GetTrieValue(t, ITEM_DONATED, donated);
661 if(donated == 0)
662 {
663 SetTrieValue(t, ITEM_DONATED, 1);
664 GetTrieString(t, ITEM_ID, itemID, itemIDsize);
665 return true;
666 }
667 }
668 }
669
670 return false;
671}
672
673public int CountCharInString(const char[] str, int c)
674{
675 int i = 0, count = 0;
676
677 while (str[i] != '\0')
678 {
679 if (str[i++] == c)
680 count++;
681 }
682
683 return count;
684}
685
686public void ResetInventory(Handle inventory)
687{
688 for (int i = 0; i < GetArraySize(inventory); i++)
689 {
690 Handle t = GetArrayCell(inventory, i);
691 SetTrieValue(t, ITEM_DONATED, 0);
692 }
693}
694
695public void ResetInventories(int client)
696{
697 ResetInventory(g_hTF2Items[client]);
698 ResetInventory(g_hCSGOItems[client]);
699 ResetInventory(g_hDOTA2Items[client]);
700}
701
702bool IsClientValid(int client)
703{
704 if (0 < client <= MaxClients)
705 {
706 return IsClientInGame(client);
707 }
708
709 return false;
710}