· 7 years ago · Dec 10, 2018, 10:16 AM
1new Float:PlaneCoordsStart[][] = // Center Circle points. decrease raduis to make circle smaller
2{
3 { -8.3018,533.9124,499.0 } // Curcle one Red Country plane flyover start
4};
5
6new Float:PlaneCoordsFinish[][] = // Center Circle points. decrease raduis to make circle smaller
7{
8 { 1026.6929,-1184.2664,499.0, } // Curcle one Red Country plane flyover finish
9};
10
11new MySQL: Database, Corrupt_Check[MAX_PLAYERS];
12new PlaneNPCDriver;
13new PlaneNPCVehicle;
14
15forward OnPlayerDataCheck(playerid, corrupt_check); // Used for logging in MYSQL
16forward OnPlayerRegister(playerid);
17forward SettingUpSafeZone(); // Sets up the game
18forward EnteringPlayerIntoGame(); // Loops through eeryone in lobby putting them in game.
19forward CreatePlane(); // Creates and then destroys the plane at the start of the game
20
21main()
22{
23 print("\n----------------------------------");
24 print("San Andreas Battlegrounds -v1 ");
25 print("----------------------------------\n");
26}
27
28public OnGameModeInit()
29{
30 // Don't use these lines if it's a filterscript
31 SetGameModeText("SABG: RE-LOADED");
32 AddPlayerClass(0, 1958.3783, 1343.1572, 15.3746, 269.1425, 0, 0, 0, 0, 0, 0);
33
34 new MySQLOpt: option_id = mysql_init_options();
35 mysql_set_option(option_id, AUTO_RECONNECT, true);
36 Database = mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS, MYSQL_DATABASE, option_id);
37 if(Database == MYSQL_INVALID_HANDLE || mysql_errno(Database) != 0)
38 {
39 print("I couldn't connect to the MySQL server, closing.");
40 SendRconCommand("exit"); // Sending console command to shut down server.
41 return 1;
42 }
43 print("I have connected to the MySQL server.");
44 mysql_tquery(Database, "CREATE TABLE IF NOT EXISTS `PLAYERS` (`ID` int(11) NOT NULL AUTO_INCREMENT,`USERNAME` varchar(24) NOT NULL,`PASSWORD` char(65) NOT NULL,`SALT` char(11) NOT NULL,`SCORE` mediumint(7), `KILLS` mediumint(7), `BP` mediumint(7) NOT NULL DEFAULT '0',`DEATHS` mediumint(7) NOT NULL DEFAULT '0', PRIMARY KEY (`ID`), UNIQUE KEY `USERNAME` (`USERNAME`))");
45
46 ServerInfo[GameInProgress] = false; // Game is not in progress when gamemode first starts.
47 ServerInfo[Players] = 0; // no players on server when gamemode first starts.
48 ServerInfo[SafeZone] = random(MAX_SAFEZONES);
49 printf("Safezone: %d selected for first game.",ServerInfo[SafeZone]);
50 return 1;
51}
52
53public OnGameModeExit()
54{
55 mysql_close(Database);
56 return 1;
57}
58
59public OnPlayerRequestClass(playerid, classid)
60{
61 SetPlayerPos(playerid,398.4077,2540.5049,19.6311);
62 SetPlayerCameraPos(playerid,398.4077,2530.5049,19.6311);
63 SetPlayerCameraLookAt(playerid,398.4077,2540.5049,19.6311);
64 SetPlayerFacingAngle(playerid, 180.0);
65 return 1;
66}
67
68public OnPlayerConnect(playerid)
69{
70 new DB_Query[115];
71
72 GetPlayerName(playerid, PlayerInfo[playerid][pName], MAX_PLAYER_NAME); // Getting the player's name.
73 Corrupt_Check[playerid]++;
74
75 mysql_format(Database, DB_Query, sizeof(DB_Query), "SELECT * FROM `PLAYERS` WHERE `USERNAME` = '%e' LIMIT 1", PlayerInfo[playerid][pName]);
76 mysql_tquery(Database, DB_Query, "OnPlayerDataCheck", "ii", playerid, Corrupt_Check[playerid]);
77
78 PlayAudioStreamForPlayer(playerid, "https://vocaroo.com/media_command.php?media=s1ABYrVrLJxY&command=download_mp3");
79 ClearChat(playerid);
80 return 1;
81}
82
83public OnPlayerDisconnect(playerid, reason)
84{
85 Corrupt_Check[playerid]++;
86
87 new DB_Query[256];
88 //Running a query to save the player's data using the stored stuff.
89 mysql_format(Database, DB_Query, sizeof(DB_Query), "UPDATE `PLAYERS` SET `SCORE` = %d, `BP` = %d, `KILLS` = %d, `DEATHS` = %d WHERE `ID` = %d LIMIT 1",
90 PlayerInfo[playerid][Score], PlayerInfo[playerid][BP], PlayerInfo[playerid][Kills], PlayerInfo[playerid][Deaths], PlayerInfo[playerid][ID]);
91
92 mysql_tquery(Database, DB_Query);
93
94 if(cache_is_valid(PlayerInfo[playerid][Player_Cache])) //Checking if the player's cache ID is valid.
95 {
96 cache_delete(PlayerInfo[playerid][Player_Cache]); // Deleting the cache.
97 PlayerInfo[playerid][Player_Cache] = MYSQL_INVALID_CACHE; // Setting the stored player Cache as invalid.
98 }
99
100 PlayerInfo[playerid][LoggedIn] = false;
101 print("OnPlayerDisconnect has been called."); // Sending message once OnPlayerDisconnect is called.
102
103 return 1;
104}
105
106public OnPlayerSpawn(playerid)
107{
108 StopAudioStreamForPlayer(playerid);
109
110 if(ServerInfo[GameInProgress] == false) // ENTERING PLAYER INTO LOBBY
111 {
112 GameTextForPlayer(playerid,"~g~Game starting shortly.",4000,1);
113
114 PlayerInfo[playerid][InLobby] = true;
115
116 SetPlayerPos(playerid,371.6907,-2045.3824,7.6719); // Spawn point in lobby. (PIER)
117 SetPlayerFacingAngle(playerid,313.6174);
118 ResetPlayerWeapons(playerid);
119 SetPlayerVirtualWorld(playerid,0);
120 TogglePlayerControllable(playerid,1);
121 TogglePlayerSpectating(playerid,0);
122
123 if(ServerInfo[Players] >= MINIMUM_PLAYERS_BEFORE_GAME_BEGINS)
124 {
125 SetTimerEx("EnteringPlayerIntoGame",LOBBY_TIMER,false,"i",playerid);
126 }
127 }
128 else if(ServerInfo[GameInProgress] == true)
129 {
130 if(PlayerInfo[playerid][InsidePlane] == true)
131 {
132 new Float:pX,Float:pY,Float:pZ;
133 FCNPC_GetPosition(PlaneNPCDriver, pX,pY,pZ);
134
135 TogglePlayerSpectating(playerid,0);
136 SetPlayerPos(playerid,pX,pY,pZ-5);
137 SetCameraBehindPlayer(playerid);
138 GivePlayerWeapon(playerid,46,1);
139 PlayerInfo[playerid][InsidePlane] = false;
140 }
141 }
142 return 1;
143}
144
145
146public OnPlayerDeath(playerid, killerid, reason)
147{
148 return 1;
149}
150
151public OnVehicleSpawn(vehicleid)
152{
153 return 1;
154}
155
156public OnVehicleDeath(vehicleid, killerid)
157{
158 return 1;
159}
160
161public OnPlayerText(playerid, text[])
162{
163 return 1;
164}
165
166public OnPlayerCommandText(playerid, cmdtext[])
167{
168 if (strcmp("/mycommand", cmdtext, true, 10) == 0)
169 {
170 // Do something here
171 return 1;
172 }
173 return 0;
174}
175
176public OnPlayerEnterVehicle(playerid, vehicleid, ispassenger)
177{
178 return 1;
179}
180
181public OnPlayerExitVehicle(playerid, vehicleid)
182{
183 return 1;
184}
185
186public OnPlayerStateChange(playerid, newstate, oldstate)
187{
188 return 1;
189}
190
191public OnPlayerEnterCheckpoint(playerid)
192{
193 return 1;
194}
195
196public OnPlayerLeaveCheckpoint(playerid)
197{
198 return 1;
199}
200
201public OnPlayerEnterRaceCheckpoint(playerid)
202{
203 return 1;
204}
205
206public OnPlayerLeaveRaceCheckpoint(playerid)
207{
208 return 1;
209}
210
211public OnRconCommand(cmd[])
212{
213 return 1;
214}
215
216public OnPlayerRequestSpawn(playerid)
217{
218 if(PlayerInfo[playerid][LoggedIn] == false) return 0; // Ignoring the request incase player isn't logged in.
219 return 1;
220}
221
222public OnObjectMoved(objectid)
223{
224 return 1;
225}
226
227public OnPlayerObjectMoved(playerid, objectid)
228{
229 return 1;
230}
231
232public OnPlayerPickUpPickup(playerid, pickupid)
233{
234 return 1;
235}
236
237public OnVehicleMod(playerid, vehicleid, componentid)
238{
239 return 1;
240}
241
242public OnVehiclePaintjob(playerid, vehicleid, paintjobid)
243{
244 return 1;
245}
246
247public OnVehicleRespray(playerid, vehicleid, color1, color2)
248{
249 return 1;
250}
251
252public OnPlayerSelectedMenuRow(playerid, row)
253{
254 return 1;
255}
256
257public OnPlayerExitedMenu(playerid)
258{
259 return 1;
260}
261
262public OnPlayerInteriorChange(playerid, newinteriorid, oldinteriorid)
263{
264 return 1;
265}
266
267public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
268{
269 if(PlayerInfo[playerid][InsidePlane] == true)
270 {
271 if ((newkeys & KEY_FIRE) && !(oldkeys & KEY_FIRE))
272 {
273 OnPlayerSpawn(playerid);
274 }
275 }
276 return 1;
277}
278
279public OnRconLoginAttempt(ip[], password[], success)
280{
281 return 1;
282}
283
284public OnPlayerUpdate(playerid)
285{
286 return 1;
287}
288
289public OnPlayerStreamIn(playerid, forplayerid)
290{
291 return 1;
292}
293
294public OnPlayerStreamOut(playerid, forplayerid)
295{
296 return 1;
297}
298
299public OnVehicleStreamIn(vehicleid, forplayerid)
300{
301 return 1;
302}
303
304public OnVehicleStreamOut(vehicleid, forplayerid)
305{
306 return 1;
307}
308
309public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
310{
311 switch (dialogid)
312 {
313 case DIALOG_LOGIN:
314 {
315 if(!response) return Kick(playerid);
316
317 new Salted_Key[65];
318 SHA256_PassHash(inputtext, PlayerInfo[playerid][Salt], Salted_Key, 65);
319
320 if(strcmp(Salted_Key, PlayerInfo[playerid][Password]) == 0)
321 {
322 // Now, password should be correct as well as the strings
323 // Matched with each other, so nothing is wrong until now.
324
325 // We will activate the cache of player to make use of it e.g.
326 // Retrieve their data.
327
328 cache_set_active(PlayerInfo[playerid][Player_Cache]);
329
330 // Okay, we are retrieving the information now..
331 cache_get_value_int(0, "ID", PlayerInfo[playerid][ID]);
332
333 cache_get_value_int(0, "KILLS", PlayerInfo[playerid][Kills]);
334 cache_get_value_int(0, "DEATHS", PlayerInfo[playerid][Deaths]);
335
336 cache_get_value_int(0, "SCORE", PlayerInfo[playerid][Score]);
337 cache_get_value_int(0, "BP", PlayerInfo[playerid][BP]);
338
339 SetPlayerScore(playerid, PlayerInfo[playerid][Score]);
340
341 ResetPlayerMoney(playerid);
342 GivePlayerMoney(playerid, PlayerInfo[playerid][BP]);
343
344 // So, we have successfully retrieved data? Now deactivating the cache.
345
346 cache_delete(PlayerInfo[playerid][Player_Cache]);
347 PlayerInfo[playerid][Player_Cache] = MYSQL_INVALID_CACHE;
348
349 PlayerInfo[playerid][LoggedIn] = true;
350 SendClientMessage(playerid, 0x00FF00FF, "Logged in to the account.");
351 }
352 else
353 {
354 new String[150];
355
356 PlayerInfo[playerid][PasswordFails] += 1;
357 printf("%s has been failed to login. (%d)", PlayerInfo[playerid][pName], PlayerInfo[playerid][PasswordFails]);
358 // Printing the message that someone has failed to login to his account.
359
360 if (PlayerInfo[playerid][PasswordFails] >= 3) // If the fails exceeded the limit we kick the player.
361 {
362 format(String, sizeof(String), "%s has been kicked Reason: {FF0000}(%d/3) Login fails.", PlayerInfo[playerid][pName], PlayerInfo[playerid][PasswordFails]);
363 SendClientMessageToAll(0x969696FF, String);
364 Kick(playerid);
365 }
366 else
367 {
368 // If the player didn't exceed the limits we send him a message that the password is wrong.
369 format(String, sizeof(String), "Wrong password, you have %d out of 3 tries.", PlayerInfo[playerid][PasswordFails]);
370 SendClientMessage(playerid, 0xFF0000FF, String);
371
372 format(String, sizeof(String), "{FFFFFF}Welcome back, %s.\n\n{0099FF}This account is already registered.\n\
373 {0099FF}Please, input your password below to proceed to the game.\n\n", PlayerInfo[playerid][pName]);
374 ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_PASSWORD, "Login System", String, "Login", "Leave");
375 }
376 }
377 }
378 case DIALOG_REGISTER:
379 {
380 if(!response) return Kick(playerid);
381
382 if(strlen(inputtext) <= 5 || strlen(inputtext) > 60)
383 {
384 // If the password length is less than or equal to 5 and more than 60
385 // It repeats the process and shows error message as seen below.
386
387 SendClientMessage(playerid, 0x969696FF, "Invalid password length, should be 5 - 60.");
388
389 new String[150];
390
391 format(String, sizeof(String), "{FFFFFF}Welcome %s.\n\n{0099FF}This account is not registered.\n\
392 {0099FF}Please, input your password below to proceed.\n\n", PlayerInfo[playerid][pName]);
393 ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_PASSWORD, "Registration System", String, "Register", "Leave");
394 }
395 else
396 {
397
398 // Salting the player's password using SHA256 for a better security.
399
400 for (new i = 0; i < 10; i++)
401 {
402 PlayerInfo[playerid][Salt][i] = random(79) + 47;
403 }
404
405 PlayerInfo[playerid][Salt][10] = 0;
406 SHA256_PassHash(inputtext, PlayerInfo[playerid][Salt], PlayerInfo[playerid][Password], 65);
407
408 new DB_Query[225];
409
410 // Storing player's information if everything goes right.
411 mysql_format(Database, DB_Query, sizeof(DB_Query), "INSERT INTO `PLAYERS` (`USERNAME`, `PASSWORD`, `SALT`, `SCORE`, `KILLS`, `BP`, `DEATHS`)\
412 VALUES ('%e', '%s', '%e', '20', '0', '0', '0')", PlayerInfo[playerid][pName], PlayerInfo[playerid][Password], PlayerInfo[playerid][Salt]);
413 mysql_tquery(Database, DB_Query, "OnPlayerRegister", "d", playerid);
414 }
415 }
416 }
417 return 1;
418}
419
420public OnPlayerClickPlayer(playerid, clickedplayerid, source)
421{
422 return 1;
423}
424
425public OnPlayerRegister(playerid)
426{
427 // This gets called only when the player registers a new account.
428 SendClientMessage(playerid, 0x00FF00FF, "You are now registered and has been logged in.");
429 PlayerInfo[playerid][LoggedIn] = true;
430 return 1;
431}
432
433
434public OnPlayerDataCheck(playerid, corrupt_check)
435{
436 if (corrupt_check != Corrupt_Check[playerid]) return Kick(playerid);
437 // You'd have asked already what's corrput_check and how it'd benefit me?
438 // Well basically MySQL query takes long, incase a player leaves while its not proceeded
439 // With ID 1 for example, then another player comes as ID 1 it'll basically corrupt the data
440 // So, once the query is done, the player will have the wrong data assigned for himself.
441
442 new String[150];
443
444 if(cache_num_rows() > 0)
445 {
446 // If the player exists, everything is okay and nothing is wrongly detected
447 // The player's password and Saltion key gets stored as seen below
448 // So we won't have to get a headache just to match player's password.
449
450 cache_get_value(0, "PASSWORD", PlayerInfo[playerid][Password], 65);
451 cache_get_value(0, "SALT", PlayerInfo[playerid][Salt], 11);
452
453 PlayerInfo[playerid][Player_Cache] = cache_save();
454 // ^ Storing the cache ID of the player for further use later.
455
456 format(String, sizeof(String), "{FFFFFF}Welcome back, %s.\n\n{0099FF}This account is already registered.\n\
457 {0099FF}Please, input your password below to proceed to the game.\n\n", PlayerInfo[playerid][pName]);
458 ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_PASSWORD, "Login System", String, "Login", "Leave");
459 }
460 else
461 {
462 format(String, sizeof(String), "{FFFFFF}Welcome %s.\n\n{0099FF}This account is not registered.\n\
463 {0099FF}Please, input your password below to proceed to the game.\n\n", PlayerInfo[playerid][pName]);
464 ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_PASSWORD, "Registration System", String, "Register", "Leave");
465 }
466 return 1;
467}
468
469public SettingUpSafeZone()
470{
471 if(ServerInfo[SafeZone] == 0)
472 {
473 if(ServerInfo[SafeZoneStage] == 0)
474 {
475 // CREATE THE VEHICLES AND LOOT REFER TO OLD GM
476 }
477 }
478 return 1;
479}
480forward EnteringPlayerIntoGame();
481
482public EnteringPlayerIntoGame()
483{
484 ServerInfo[GameInProgress] = true;
485 CreatePlane(); // Creates the plane
486 for(new i; i < sizeof(PlayerInfo); i++)
487 {
488 if(PlayerInfo[i][InLobby] == true) // Only moves players in lobby into game
489 {
490 PlayerInfo[i][InsidePlane] = true;
491 PlayerInfo[i][InGame] = true;
492
493 ServerInfo[Players] ++;
494
495 SetPlayerVirtualWorld(i, 0);
496 SetPlayerInterior(i,0);
497 TogglePlayerSpectating(i, 1);
498 PlayerSpectateVehicle(i, PlaneNPCVehicle);
499 }
500 }
501 return 1;
502}
503
504public CreatePlane()
505{
506 FCNPC_Destroy(PlaneNPCDriver);
507 DestroyVehicle(PlaneNPCVehicle);
508 if(ServerInfo[PlaneCreated] == false)
509 {
510
511 PlaneNPCDriver = FCNPC_Create("PlanePilot");
512 FCNPC_Spawn(PlaneNPCDriver, 98, 0, 0, 5);
513 FCNPC_SetVirtualWorld(PlaneNPCDriver, 0);
514
515 PlaneNPCVehicle = AddStaticVehicle(592,PlaneCoordsStart[SafeZone][0],PlaneCoordsStart[SafeZone][1],PlaneCoordsStart[SafeZone][2], 0, 0, 1);
516
517 FCNPC_PutInVehicle(PlaneNPCDriver, PlaneNPCVehicle, 0);
518 FCNPC_GoTo(PlaneNPCDriver,PlaneCoordsFinish[SafeZone][0],PlaneCoordsFinish[SafeZone][1],PlaneCoordsFinish[SafeZone][2], FCNPC_MOVE_TYPE_DRIVE, 2.5);
519
520// SetTimer("DestroyPlaneNPC",60000,false);
521// SetTimer("DealDamageToPlayersNotInCircle",OUTSIDE_CIRCLE_TIMER,true); // CANCEL AT THE END OF THE GAME (NEEDS DOING)
522 ServerInfo[PlaneCreated] = true;
523 }
524 return 1;
525}