· 7 years ago · Dec 20, 2018, 01:22 AM
1#include <sourcemod>
2#include <sdktools>
3
4#define DBNAME "storage-local"
5#define CREATE_TABLE_WEDDING "CREATE TABLE IF NOT EXISTS `weddings_marriages` \
6 (`source_name` varchar(64) NOT NULL, \
7 `source_id` varchar(64) NOT NULL, \
8 `partner_name` varchar(64) NOT NULL, \
9 `partner_id` varchar(64) NOT NULL, \
10 `timestamp` UNSIGNED INTEGER NOT NULL DEFAULT '0'\
11 `score` UNSIGNED INTEGER NOT NULL DEFAULT '0');"
12
13#define CREATE_TABLE_PROPOSAL "CREATE TABLE IF NOT EXISTS `weddings_proposals` \
14 (`source_name` varchar(64) NOT NULL, \
15 `source_id` varchar(64) NOT NULL PRIMARY KEY, \
16 `target_name` varchar(64) NOT NULL, \
17 `target_id` varchar(64));"
18
19#define ADD_PROPOSAL "INSERT INTO `weddings_proposals` VALUES ('%s', '%s', '%s', '%s');"
20#define DEL_PROPOSAL_SRC "DELETE FROM `weddings_proposals` WHERE `source_id` = '%s';"
21#define DEL_PROPOSAL_TAR "DELETE FROM `weddings_proposals` WHERE `target_id` = '%s';"
22#define GET_PROPOSALS "SELECT `source_name`, `source_id` FROM `wedding_proposals` WHERE `target_id` = '%s';"
23#define ADD_MARRIAGE "INSERT INTO `weddings_marriages` VALUES ('%s', '%s', '%s', '%s', '%d', '%d');"
24#define DEL_MARRIAGE "DELETE FROM `weddings_marriages` WHERE `source_id` = '%s' OR `target_id` = '%s';"
25#define UPDATE_SCORE "UPDATE `weddings_marriages` SET `score` = '%s' WHERE `source_id` = '%s' OR `target_id` = '%s';"
26#define GET_SCORE "SELECT `score` FROM `wedding_proposals` WHERE `source_id` = '%s' OR `target_id` = '%s';"
27
28Database g_hDB;
29
30bool g_bMarried[MAXPLAYERS + 1];
31int g_iScore[MAXPLAYERS + 1];
32int g_iMarriages[MAXPLAYERS + 1];
33
34public void OnPluginStart() {
35 Database.Connect(SQL_OnConnect, DBNAME);
36 RegConsoleCmd("sm_marry", Command_Marry, "Opens menu of all single users.")
37 RegConsoleCmd("sm_proposals", Command_Proposals, "Opens menu of proposals");
38 CreateTimer(60.0, Timer_AddScore, _, TIMER_REPEAT);
39}
40
41public Action Timer_AddScore(Handle timer) {
42 for (int client = 1; client <= MaxClients; client++) {
43 if (PartnerConnected(client)) {
44 g_iScore[client] += 1;
45 }
46 }
47 return Plugin_Continue;
48}
49
50public Action Command_Marry(int client, int args) {
51 Menu menu = new Menu(MenuHandler_Marry);
52 menu.SetTitle("Marry a single");
53 for (int i = 1; i <= MaxClients; i++) {
54 if (CanBeMarried(i)) {
55 char steamid[64], name[MAX_NAME_LENGTH];
56 GetClientAuthId(i, AuthId_Steam2, steamid, sizeof(steamid));
57 GetClientName(i, name, sizeof(name));
58 menu.AddItem(steamid, name);
59 }
60 }
61 if (menu.ItemCount > 0) {
62 menu.Display(client, MENU_TIME_FOREVER);
63 } else {
64 ReplyToCommand(client, "[Weddings] There are no singles on the server.");
65 }
66 return Plugin_Handled;
67}
68
69public int MenuHandler_Marry(Menu menu, MenuAction action, int param1, int param2) {
70 if (action == MenuAction_Select) {
71 char targetName[MAX_NAME_LENGTH], targetId[64];
72 if (menu.GetItem(param2, targetId, sizeof(targetId), _, targetName, sizeof(targetName))) {
73 char sourceName[MAX_NAME_LENGTH], sourceId[64];
74 GetClientName(param1, sourceName, sizeof(sourceName));
75 GetClientAuthId(param1, AuthId_Steam2, sourceId, sizeof(sourceId));
76 SendProposalQuery(sourceName, sourceId, targetName, targetId);
77 PrintToChat(param1, "[Weddings] You sent a proposal to %s.", targetName);
78 int target = GetClientByAuthId(targetId);
79 if (target != 0) {
80 PrintToChat(target, "[Weddings] You received a proposal from %s.", sourceName);
81 }
82 }
83 } else if (action == MenuAction_End) {
84 delete menu;
85 }
86}
87
88int GetClientByAuthId(const char[] auth) {
89 for (int i = 1; i <= MaxClients; i++) {
90 char tempAuth[64];
91 GetClientAuthId(i, AuthId_Steam2, tempAuth, sizeof(tempAuth));
92 if (StrEqual(auth, tempAuth)) {
93 return i;
94 }
95 }
96 return 0;
97}
98
99void SendProposalQuery(char[] sourceName, char[] sourceId, char[] targetName, char[] targetId) {
100 char proposal[512];
101 Format(proposal, sizeof(proposal), ADD_PROPOSAL, sourceName, sourceId, targetName, targetId);
102 g_hDB.Query(SQL_NewProposal, proposal);
103}
104
105public void SQL_NewProposal(Database db, DBResultSet results, const char[] error, any data) {
106 if (strlen(error) > 0) {
107 LogError("[Weddings] Query failed in SQL_NewProposal >> %s", error);
108 }
109}
110
111public Action Command_Proposals(int client, int args) {
112 DisplayProposalMenu(client);
113 return Plugin_Handled;
114}
115
116void DisplayProposalMenu(int client) {
117 char targetAuth[64], query[512];
118 GetClientAuthId(client, AuthId_Steam2, targetAuth, sizeof(targetAuth));
119 Format(query, sizeof(query), targetAuth);
120 g_hDB.Query(SQL_GetProposals, query, client);
121}
122
123// Receive a steam id through datapack
124public void SQL_GetProposals(Database db, DBResultSet results, const char[] error, any client) {
125 if (strlen(error) > 0) {
126 LogError("[Weddings] Query failed in SQL_GetProposals >> %s", error);
127 } else if (results.RowCount == 0) {
128 if (IsClientConnected(client)) {
129 PrintToChat(client, "[Weddings] You have no proposals.");
130 }
131 } else {
132 Menu menu = new Menu(MenuHandler_Proposals);
133 menu.SetTitle("Incoming proposals");
134 while (results.FetchRow()) {
135 char sourceId[64], sourceName[MAX_NAME_LENGTH];
136 int nameIndex, idIndex;
137 if (results.FieldNameToNum("source_name", nameIndex) && results.FieldNameToNum("source_id", idIndex)) {
138 results.FetchString(nameIndex, sourceName, sizeof(sourceName));
139 results.FetchString(idIndex, sourceId, sizeof(sourceId));
140 menu.AddItem(sourceId, sourceName);
141 }
142 }
143 menu.Display(client, MENU_TIME_FOREVER);
144 }
145}
146
147public int MenuHandler_Proposals(Menu menu, MenuAction action, int param1, int param2) {
148 if (action == MenuAction_Select) {
149 char sourceId[64], sourceName[MAX_NAME_LENGTH];
150 if (menu.GetItem(param2, sourceId, sizeof(sourceId), _, sourceName, sizeof(sourceName))) {
151 char targetName[MAX_NAME_LENGTH], targetId[64];
152 GetClientName(param1, targetName, sizeof(targetName));
153 GetClientAuthId(param1, AuthId_Steam2, targetId, sizeof(targetId));
154 SendMarriageQuery(sourceName, sourceId, targetName, targetId, GetTime());
155 PrintToChat(param1, "[Weddings] You are now married to %s!", sourceName);
156 int target = GetClientByAuthId(sourceId);
157 if (target != 0) {
158 PrintToChat(target, "[Weddings] %N accepted your proposal, you are now married!", param1);
159 }
160 g_bMarried[param1] = true;
161 g_bMarried[target] = true;
162 g_iMarriages[param1] = target;
163 g_iMarriages[target] = param1;
164 }
165 } else if (action == MenuAction_End) {
166 delete menu;
167 }
168}
169
170void SendMarriageQuery(char[] sourceName, char[] sourceId, char[] targetName, char[] targetId, int timeStamp) {
171 char query[512];
172 Format(query, sizeof(query), ADD_MARRIAGE, sourceName, sourceId, targetName, targetId, timeStamp, 0);
173 g_hDB.Query(SQL_NewMarriage, query);
174}
175
176public void SQL_NewMarriage(Database db, DBResultSet results, const char[] error, any data) {
177 if (strlen(error) > 0) {
178 LogError("[Weddings] Query failed in SQL_NewMarriage >> %s", error);
179 }
180}
181
182public void OnClientAuthorized(int client, const char[] auth) {
183 g_bMarried[client] = false;
184 g_iMarriages[client] = 0;
185
186 DataPack data = new DataPack();
187 data.WriteString(auth);
188
189 char query[512];
190 Format(query, sizeof(query), GET_SCORE, auth, auth);
191 g_hDB.Query(SQL_GetScore, query, data);
192}
193
194public void SQL_GetScore(Database db, DBResultSet results, const char[] error, DataPack data) {
195 if (strlen(error) > 0) {
196 LogError("[Weddings] Query failed in SQL_GetScore >> %s", error);
197 } else {
198 if (results.FetchRow()) {
199 int scoreIndex;
200 if (results.FieldNameToNum("score", scoreIndex)) {
201 int score = results.FetchInt(scoreIndex);
202 char auth[64];
203 data.Reset();
204 data.ReadString(auth, sizeof(auth));
205 int client = GetClientByAuthId(auth);
206 if (client != 0) {
207 SetScores(client, score);
208 }
209 } else {
210 LogError("[Weddings] Failed to get field name \"score\" in SQL_GetScore.");
211 }
212 }
213 }
214}
215
216public void SQL_OnConnect(Database db, const char[] error, any data) {
217 if (db == null || strlen(error) > 0) {
218 SetFailState("Failed to connect to \"%s\" database config. Check your databases.cfg.", DBNAME);
219 }
220
221 g_hDB = db;
222 LogMessage("[Weddings] Successfully connected to database.");
223 g_hDB.Query(SQL_OnTableCreate, CREATE_TABLE_WEDDING, _, DBPrio_High);
224 g_hDB.Query(SQL_OnTableCreate, CREATE_TABLE_PROPOSAL, _, DBPrio_High);
225}
226
227public void SQL_OnTableCreate(Database db, DBResultSet results, const char[] error, any data) {
228 if (strlen(error) > 0) {
229 LogError("[Weddings] Query failed in SQL_OnTableCreate >> %s", error);
230 }
231}
232
233bool CanBeMarried(int client) {
234 return !g_bMarried[client] && IsClientConnected(client) && !IsFakeClient(client);
235}
236
237bool PartnerConnected(int client) {
238 return g_iMarriages[client] != 0;
239}
240
241int SetScores(int client, int score) {
242 g_iScore[client] = score;
243 if (g_iMarriages[client] != 0) {
244 g_iScore[g_iMarriages[client]] = score;
245 } else {
246 g_iScore[g_iMarriages[client]] = -1;
247 }
248}