SOLVED : How to scan and delete elements from a name/score array on a dreamlo database
Hello everyone,
Thanks to the following tutorials I can now upload and display scores with the dreamlo asset/service.
https://www.youtube.com/watch?v=KZuqEyxYZCc
https://www.youtube.com/watch?v=9jejKPPKomg&t=696s
Many thanks to Carmine Guida and Sebastian Lague for helping me get this far!
Sebastian's tutorial has introduced me to a variety of concepts I have not used before; namely IEnumerator and the WWW module.
(It seems those 2 things play an integral role in what I'm trying to accomplish and even thought I've been able to find some documentation on these I still cannot implement them successfully in my own scripts. My poor understanding of referencing and syntax have undoubtedly played a role :| )
I also noticed that Sebastian does not make use of the dreamloLeaderBoard.cs class that comes with the dreamlo asset package. (me thinks probably because it wasn't available at the time)
Following the tutorials, I reproduced this HiScores.cs class.
using UnityEngine;
using System.Collections;
public class HiScores : MonoBehaviour{
const string privateCode = "############# hiden for this post ###############";
const string publicCode = "58508f378af60311f8e8c911";
const string webURL = "http://dreamlo.com/lb/";
public Highscore[] highscoreList;
static HiScores instance;
DisplayHighscores highscoresDisplay;
void Awake(){
instance = this;
highscoresDisplay = GetComponent<DisplayHighscores> ();
}
public static void AddNewHighscore(string username, int score){
instance.StartCoroutine(instance.UploadNewHighscore(username,score));
}
IEnumerator UploadNewHighscore(string username, int score){
WWW www = new WWW(webURL + privateCode + "/add/" + WWW.EscapeURL(username) + "/" + score);
yield return www;
if (string.IsNullOrEmpty(www.error)){
print ("Upload Successfull");
DownloadHighscores();
}
else{
print("Error uploading: " + www.error);
}
}
public void DownloadHighscores(){
StartCoroutine("DownloadHighscoresFromDatabase");
}
IEnumerator DownloadHighscoresFromDatabase(){
WWW www = new WWW(webURL + publicCode + "/pipe/");
yield return www;
if (string.IsNullOrEmpty(www.error)){
FormatHighscores(www.text);
highscoresDisplay.OnHighscoresDownloaded(highscoreList);
}
else{
print("Error Downloading: " + www.error);
}
}
void FormatHighscores(string textStream){
string[] entries = textStream.Split(new char[]{'\n'}, System.StringSplitOptions.RemoveEmptyEntries);
highscoreList = new Highscore[entries.Length];
for (int i= 0; i <entries.Length; i++){
string[] entryInfo = entries[i].Split(new char[]{'|'});
string username = entryInfo[0];
int score = int.Parse(entryInfo[1]);
highscoreList[i] = new Highscore(username,score);
}
}
}
public struct Highscore{
public string username;
public int score;
public Highscore(string _username, int _score)
{ username = _username;
score = _score;
}
}
I also have an UiInputField.cs class that grabs the user's name from an input field and stores it in public text nameGrabber;
. This class also has the following SaveName() method that I use to upload the player's very first score of 1. (I should probably just assign a score of zero but I will explain why I decided to do it this way in a minute..)
public void SaveName(){
PlayPref.userName = nameGrabber.text;
PlayerPrefs.SetString("playerName", PlayPref.userName);
int score = 1;
string username = PlayerPrefs.GetString("playerName");
HiScores.AddNewHighscore(username,score);
}
The simple If statement bellow is in my StateSet.cs "game manager" and it uploads my player's best score to the database.
if (stillGuest == false)
{ int score = PlayerPrefs.GetInt("TopScore");
string username = PlayerPrefs.GetString("playerName");
HiScores.AddNewHighscore(username,score);
}
So far so good..
I am currently trying to accomplish 2 things:
1. Delete a username/score entry on the dreamlo DB when I reset the player's profile. I have a PlayPref.cs class that acts as a "wrapper" for PlayerPrefs. Inside I have a ProfileReset() method and would like for it to delete the username/score from the database.
On the dreamlo website Carmine says the following:
"Changes and updates to your leaderboard are made through simple http get requests using your private url...Delete Carmine's score":
http://dreamlo.com/lb/### private code #### hiden for this post ######/delete/Carmine
I tried putting the following code in my ProfileReset() method..
WWW www = new WWW("http://dreamlo.com/lb/## private code ## hiden for this post ###/delete/" + PlayerPrefs.GetString("playerName"));
Nothing happens. I'm sure it's not as "simple" as that. I don't know what to do this this new www variable. I feel like I'm missing something. To be safe, I even tried to include the dreamloLeaderBoard.cs class in my project but I don't think that has anything to do with it..
(I have a feeling the solution for this first task will also provide some insight as to how to approach the second one.)
2. Detect if a username already exists in the dreamlo DB to avoid duplicate names.
In my StateSet.cs class I have the following checkAvailability() method.
public void checkAvailability(){
if (PlayPref.nameTaken == true){
regUnavailableText.SetActive(true);
regCheckAvailButton.SetActive(false);
clearButton.SetActive(true);
}
if (PlayPref.nameTaken == false){
regAvailableText.SetActive(true);
regYesNoButtons.SetActive(true);
}
}
In other words, based on the PlayPref.nameTaken boolean I enable/disable the UI that allows the user to "confirm" or "search again."
It is in this method that I'm trying to search the database to look up (and temporarily store) the score for the UserName that is inside the nameGrabber Text variable.
Then, if the score value for that username is not equal to zero it means that someone has already picked that name. This will set:
PlayPref.nameTaken = true;
if it is 0, or less than 1, the name is available and so:
PlayPref.nameTaken = false;
(I'm sure the whole set-initial-score-to-1 approach is unnecessarily complex but, based on the little that I know so far, it's the only solution I can think of.)
Thank you for taking the time to read all of this. As always, any help, suggestions, advice or direction you can offer on the subject will be enormously appreciated!
Best regards,
-Don
Ok, I figured out how to delete a username/score entry on the dreamlo database!
In my PlayPref.cs class I've added the following to my ProfileReset() method:
WWW www = new WWW("http://dreamlo.com/lb/###private code here####/delete/" + PlayerPrefs.GetString("playerName"));
StartCoroutine(WaitForRequest(www));
Later, in the same class, I added the following method:
IEnumerator WaitForRequest(WWW www)
{ yield return www;
if (www.error == null)
{ Debug.Log("WWW ok!:" + www.text);
}
else
{ Debug.Log("WWW error: " + www.error);
}
}
however, I did notice something peculiar; ( @car$$anonymous$$e, I thought I would mention this to you. Also, thank you so much for dreamlo!) if the user name has a space in it the entry will not be deleted and I get an Error uploading: 400 Bad Request
I'm not sure if this is a common thing. I wonder if it is my approach that is causing this and if there is a workaround. The only thing I can think of at the moment is to ask my users to not include spaces in their names or I could try to somehow disable the use of the space bar just to be safe.
I'm currently working on the second issue (Detect if a username already exists in the dreamlo DB to avoid duplicate names.) I've been trying different things and, as I'm starting to have a slightly better understanding of all this, I took the liberty of posting a new, more clear, Question Here earlier today. Of course I will make sure to post the solution in both places and would like to apologize in advance for the overlap.
Regarding the Space-in-Name issue I mentioned above: Car$$anonymous$$e mentioned the following " Because it's a URL encoded string, you may need to change a space to %20 or + The name is the "key" of the database. Ins$$anonymous$$d of storing the name there you could just put a GUID there and store the person's name in the extra text field." Now it's just a matter of figuring out how to do that. I will look into it after I've figured out how to search the database for a particular score.
Ok, even though Car$$anonymous$$e's reply shed some light on the "issue" with spaces in the name, implementing what he suggests sounds like it would open a whole new can of worms for me. I may have a work around.
I'll just ask the player to NOT include spaces in their name. Then I'll "scan" the name for spaces and replace them with.. NO spaces.
This previous Question seems to have presented a solution http://answers.unity3d.com/questions/574434/string-replace-with-in-c.html
.. so very close (I hope) to solving all this!:)
Rregarding searching the array for a name, I found this thread to be useful https://forum.unity3d.com/threads/string-get-specific-username-from-string-array.361470/ Then it should be a matter of comparing a couple of strings.
Getting close..
Answer by donimation · Jan 10, 2017 at 09:25 PM
Hello,
If you want nobody to answer your question --or If you want to, perhaps, get inspired to do some research on your own-- please feel free to use this thread as a template!;p :D:
For a solution to my 2 questions please read on:
2. Detect if a username already exists in the dreamlo DB to avoid duplicate names.
For this I posted a separate Question, and eventually my own solution, on another thread here.
1. Delete a username/score entry on the dreamlo DB when I reset the player's profile.
This was actually rather easy. I had it right all along, I just needed to include StartCoroutine(WaitForRequest(www)); right afterwards in my PlayPrefs.cs like this:
WWW www = new WWW("http://dreamlo.com/lb/######privateCodeHere#######/delete/" + PlayerPrefs.GetString("playerName")); StartCoroutine(WaitForRequest(www));
Oh yeah, and then set up the aforementioned WaitForRequest() later in this script like this:
IEnumerator WaitForRequest(WWW www)
{ yield return www;
if (www.error == null)
{ Debug.Log("WWW ok!:" + www.text);
}
else
{ Debug.Log("WWW error: " + www.error);
}
}
That's "basically" it!
Thanks for reading. Hope this helps someone.
Cheers, :D
Answer by leoggwp · Mar 11, 2018 at 04:37 PM
Why do I get an error in line 11 at: DisplayHighscores highscoresDisplay; ? The error: "The name 'DisplayHighscores does' not exist in the current context".
Your answer
![](https://koobas.hobune.stream/wayback/20220612103002im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
random question without repetition 0 Answers
how do i save player prefs? 1 Answer
Get value from array in unity: debug works, value's changing, but color not changing 0 Answers
ArguentOutOfRangeException: Argument is out of range. Parameter name:index 1 Answer
How can I save values in an array using PlayerPrefs? 0 Answers