Table of Contents
— Hilmi 2022/07/27 16:46
You can search by source code name to know more about it!
PHP SCRIPT EXPLAINATION
This is the first time we work with php scripts, it's a lot of fun! I will post all my php source code at the end of this page!
Pardon all my code, my time frame to complete this project is so tight, so I'm not using proper programming (law) as you can said.
so you would be mad for a lot of shortcut I'm using in my code… PARDON! Nonetheless enjoy!
GetUsers.php
I use this script to fetch all the users in my database, why? because easier for me to create a scoreboard ingame. I also use this list to make comparison for me to get logged in user credientials such as score
Login.php
Login will ask two parameter one is username and password, here we will detect if users are verified or not, also for password we use PHP passwordencrypt. So we are not comparing the password directly.
Register.php
We will ask username, password, email, and OTP that have been random generated in C# password send into database will be encrypted. we also will check if username and email are already taken. if the registration success we will send VERIFICATION EMAIL into their mailbox.
SendOTP.php
This is used to send OTP to user email, everytime user try to login with unverified account. OTP IS ENCRYPTED! :D
VerifyOTP.php
Verify of OTP are the same, using password_verify($row["otp"], $otp); to check if value are true or false.
ResetPassword.php
Request password reset, sended to user email.
VerifyOTP.php
ResetPasswordVerfiy, new password sended to user.
ChangePassword.php
User change password ingame
LoginRegistration.cs
Full Script
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Networking; using TMPro; using ES3Internal; using UnityEngine.UI; using System.Text.RegularExpressions; using System; public class LoginRegistration : MonoBehaviour { public TMP_InputField usernameInput; public TMP_InputField passwordInput; public TMP_InputField usernameRegister; public TMP_InputField passwordRegister; public TMP_InputField emailRegister; public TMP_InputField emailForgotPassword; public PopUpSystem popUp; public Toggle toggle; public bool toggleOn = true; private void Start() { ifToggleOn(); } private void ifToggleOn() { if (!toggleOn) { toggle.isOn = false; usernameInput.text = ""; passwordInput.text = ""; } else { toggle.isOn = true; } } public void toggleButton() { if (toggle.isOn) { toggleOn = true; } if (!toggle.isOn) { toggleOn = false; } ES3AutoSaveMgr.Current.Save(); } public void ButtonLogin() { bool isMistake = false; string mistakes = ""; if (usernameInput.text.Equals("") || passwordInput.text.Equals("")) { // POPUP CANNOT BE EMPTY mistakes += "Username and Password field cannot be empty. \n"; isMistake = true; } if (usernameInput.text.Length <= 6) { //mistakes += "Username must be more than 6 character. \n"; //isMistake = true; } if (passwordInput.text.Length <= 6) { //mistakes += "Password must be more than 6 character. \n"; //isMistake = true; } if (usernameInput.text.Contains(" ") || passwordInput.text.Contains(" ")) { mistakes += "Empty spaces are not allowed. \n"; isMistake = true; } if (isMistake == false) { StartCoroutine(Login(usernameInput.text, passwordInput.text)); ES3AutoSaveMgr.Current.Save(); return; } popUp.OpenPopUp("ERROR!", mistakes); } public void ButtonRegister() { bool isMistake = false; string mistakes = ""; if (usernameRegister.text.Equals("") || passwordRegister.text.Equals("")) { // POPUP CANNOT BE EMPTY mistakes += "Username and Password field cannot be empty. \n"; isMistake = true; } if (usernameRegister.text.Length <= 6) { mistakes += "Username must be more than 6 character. \n"; isMistake = true; } if (passwordRegister.text.Length <= 6) { mistakes += "Password must be more than 6 character. \n"; isMistake = true; } if (usernameRegister.text.Length >= 16) { mistakes += "Username cannot be more than 15 character. \n"; isMistake = true; } if (passwordRegister.text.Length >= 26) { mistakes += "Password cannot be more than 25 character. \n"; isMistake = true; } if (usernameRegister.text.Contains(" ") || passwordRegister.text.Contains(" ")) { mistakes += "Empty spaces are not allowed. \n"; isMistake = true; } if (!IsValidEmail(emailRegister.text)) { mistakes += "Wrong Email Format. \n"; isMistake = true; } if (!IsValidUsername(usernameRegister.text)) { mistakes += "Username should only contains letters and numbers. \n"; isMistake = true; } if (isMistake == false) { System.Random rd = new System.Random(); int otp = rd.Next(100000, 999999); StartCoroutine(Register(usernameRegister.text, passwordRegister.text, emailRegister.text, otp)); ES3AutoSaveMgr.Current.Save(); return; } popUp.OpenPopUp("ERROR!", mistakes); } bool IsValidEmail(string email) { string pattern = @"\A(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)\Z"; if (Regex.IsMatch(email, pattern)) { return true; } else { return false; } } bool IsValidUsername(string username) { if (Regex.IsMatch(username, @"^[\p{L}\p{N}]+$")) { return true; } else { return false; } } public bool VerificationResetPasswordIsAvailable = true; public void ButtonForgotPassword() { if (!IsValidEmail(emailForgotPassword.text)) { popUp.OpenPopUp("ERROR!", "Invalid Email Format."); } else { if (VerificationResetPasswordIsAvailable == true) { StartCoroutine(ForgotPassword(emailForgotPassword.text)); StartCoroutine(StartCoolDownPasswordReset()); } else { popUp.OpenPopUp("BE PATIENT MY FRIEND!", "Yes I know, But please don't spam... Wait a moment sir.. "); } } } public IEnumerator StartCoolDownVerification() { VerificationIsAvailable = false; yield return new WaitForSeconds(60); VerificationIsAvailable = true; } public IEnumerator StartCoolDownPasswordReset() { VerificationResetPasswordIsAvailable = false; yield return new WaitForSeconds(5); VerificationResetPasswordIsAvailable = true; } #region PHP_REQUEST_POST_METHOD public bool VerificationIsAvailable = true; IEnumerator Login(string username, string password) { WWWForm form = new WWWForm(); form.AddField("loginUser", username); form.AddField("loginPass", password); using (UnityWebRequest www = UnityWebRequest.Post("-------- HIDDEN ---------", form)) { yield return www.SendWebRequest(); if (www.result != UnityWebRequest.Result.Success) { popUp.OpenPopUp("ERROR!", www.error); } else { if (www.downloadHandler.text.Equals("Login Failed.")) { popUp.OpenPopUp("ERROR!", "Login Failed. Double check your credientals."); } else if (www.downloadHandler.text.Equals("Login permited.")) { popUp.OpenPopUp("SUCCESS!", "Login permited."); var player_information = new PlayerInformation(); player_information.SetUsername(usernameInput.text.ToLower()); FindObjectOfType<AtanSceneController>().NextScene(); } else { if (VerificationIsAvailable == true) { popUp.OpenPopUp("ERROR!", "Your account is unverified, please verify your account. New OTP has been sended to you. ( CHECK YOUR SPAM FOLDER IT MIGHT BE THERE! ) " + www.downloadHandler.text); StartCoroutine(ResendVerification(usernameInput.text)); StartCoroutine(StartCoolDownVerification()); } else { popUp.OpenPopUp("BE PATIENT MY FRIEND!", "Your account is unverified, PLEASE WAIT A MOMENT!! OTP Cooldown, Relax Chill.. and go watch Mat Kilau Movie. ( CHECK YOUR SPAM FOLDER IT MIGHT BE THERE! )" + www.downloadHandler.text); } } } } } IEnumerator Register(string username, string password, string email, int otp) { WWWForm form = new WWWForm(); form.AddField("registerUser", username.ToLower()); form.AddField("registerPass", password); form.AddField("registerEmail", email.ToLower()); form.AddField("registerOTP", otp.ToString()); using (UnityWebRequest www = UnityWebRequest.Post("-------- HIDDEN ---------", form)) { yield return www.SendWebRequest(); if (www.result != UnityWebRequest.Result.Success) { popUp.OpenPopUp("ERROR!", www.error); } else { if (www.downloadHandler.text.Equals("Username is already taken.")) { popUp.OpenPopUp("ERROR!", "Username is already taken."); } if (www.downloadHandler.text.Equals("Email is already taken.")) { popUp.OpenPopUp("ERROR!", "Email is already taken."); } if (www.downloadHandler.text.Equals("Register sucess.")) { popUp.OpenPopUp("CONGRATS!", "Register sucess. \nAn email verification has been sended on your email account \n ( CHECK YOUR SPAM FOLDER IT MIGHT BE THERE! )" + emailRegister.text); } if (www.downloadHandler.text.Equals("Register Error.")) { popUp.OpenPopUp("ERROR!", "Register Error. If you get this error please contact admin@gementar.com"); } } } } IEnumerator ResendVerification(string username) { WWWForm form = new WWWForm(); form.AddField("userToPost", username); using (UnityWebRequest www = UnityWebRequest.Post("-------- HIDDEN ---------", form)) { yield return www.SendWebRequest(); if (www.result != UnityWebRequest.Result.Success) { popUp.OpenPopUp("ERROR!", www.error); } else { if (www.downloadHandler.text.Equals("The Email Message was successfully sent.")) { popUp.OpenPopUp("SUCCESS!", "The Email Verification Message was successfully sent. "); } } } } IEnumerator ForgotPassword(string email) { WWWForm form = new WWWForm(); form.AddField("emailUser", email); using (UnityWebRequest www = UnityWebRequest.Post("-------- HIDDEN ---------", form)) { yield return www.SendWebRequest(); if (www.result != UnityWebRequest.Result.Success) { popUp.OpenPopUp("ERROR!", www.error); } else { if (www.downloadHandler.text.Equals("Password Reset Email Verification Sended.")) { popUp.OpenPopUp("SUCCESS!", "The Email Verification Message was successfully sent. "); } if (www.downloadHandler.text.Equals("No Registered Password With That Email.")) { popUp.OpenPopUp("ERROR!", "Email doesn't exist, are you sure you put the right email?. "); } } } } #endregion }
private void ifToggleOn() & public void toggleButton()
This method is used and called from toggle (REMEMBER ME BUTTON)
public void ButtonLogin()
This button will process login. Before we send login credentials to php, we do client-side credentials validator. this will check if string empty, length, contains spaces, email format valid or not.
public void ButtonRegister()
This button will process register. Before we send login credentials to php, we do client-side credentials validator. this will check if string empty, lenght, contains spaces, email format valid or not. This is also where we set user OTP code.
IsValidEmail(string email) & IsValidUsername(string username)
Using regex we see if email and username valid or not.
IEnumerator Login(string username, string password)
By using unity build in UnityWebRequest class we can post parameter into php. This is how we post and we retrieve back strings to check if it's valid or not. IF ALL SUCCESS, WE WILL FIND USERS FROM USER List<string>() THAT HAVE BEEN GENERATED in SandBoxRequest.cs
IEnumerator StartCooldown()
If user not yet validate their account Login will automatically re-send OTP to their email, to avoid abuse we create a OTP cooldown.
Register(string username, string password, string email, int otp)
By using unity build in UnityWebRequest class we can post get parameter into php. This register is mostly the same with login method.
IEnumerator ResendVerification(string username)
method to resent verification
IEnumerator ButtonForgotPassword(string username)
method to run forgotpassword method
IEnumerator ForgotPassword(string email)
Forgot Password Logic! It will send the user email to validate, when they click that email, they will receive new password with that email, they can change password later ingame.
SandBoxRequestPHP.cs
Full Script
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Networking; public class SandBoxRequestPHP : MonoBehaviour { public static List<string> userList = new List<string>(); private string unformatedListUser = ""; void Start() { StartCoroutine(GetAllUsers("-------- HIDDEN ---------")); } IEnumerator GetAllUsers(string uri) { using (UnityWebRequest webRequest = UnityWebRequest.Get(uri)) { // Request and wait for the desired page. yield return webRequest.SendWebRequest(); string[] pages = uri.Split('/'); int page = pages.Length - 1; switch (webRequest.result) { case UnityWebRequest.Result.ConnectionError: case UnityWebRequest.Result.DataProcessingError: Debug.LogError(pages[page] + ": Error: " + webRequest.error); break; case UnityWebRequest.Result.ProtocolError: Debug.LogError(pages[page] + ": HTTP Error: " + webRequest.error); break; case UnityWebRequest.Result.Success: unformatedListUser = webRequest.downloadHandler.text; string[] SplitByUser = unformatedListUser.Split('-'); foreach (var item in SplitByUser) { userList.Add(item); } break; } } } public List<string> getPlayerList() { return userList; } }
IEnumerator GetAllUsers(string uri)
Get all users and put it into a list... this is usefull to get user credientals and create a leaderboard later.
List<string
getPlayerList() > List getter
PHP SCRIPT LIST
dokuwiki doesn't support php syntax in their wiki, I will link it to pastebin!
GetUsers.php - https://pastebin.com/5CvV2Vdb
Login.php - https://pastebin.com/X4hrRfw6
Register.php - https://pastebin.com/t5FLz8Hm
SendOTP.php - https://pastebin.com/3MrHNt3s
VerifyOTP.php - https://pastebin.com/qewV2HPQ