adding in some needed packages
This commit is contained in:
parent
9e739f5dc8
commit
aba5310742
1012 changed files with 494191 additions and 1 deletions
8
Assets/LeaderboardCreator/Editor.meta
Executable file
8
Assets/LeaderboardCreator/Editor.meta
Executable file
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 6bd863986c5684e45b8f23f508c892f5
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
18
Assets/LeaderboardCreator/Editor/LeaderboardCreatorEditor.asmdef
Executable file
18
Assets/LeaderboardCreator/Editor/LeaderboardCreatorEditor.asmdef
Executable file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "LeaderboardCreatorEditor",
|
||||
"rootNamespace": "LeaderboardCreatorEditor",
|
||||
"references": [
|
||||
"GUID:b84cf0863fb105f47a726476f8d80bd8"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
7
Assets/LeaderboardCreator/Editor/LeaderboardCreatorEditor.asmdef.meta
Executable file
7
Assets/LeaderboardCreator/Editor/LeaderboardCreatorEditor.asmdef.meta
Executable file
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 638022afa367caf49b81e5b491548ae2
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
332
Assets/LeaderboardCreator/Editor/LeaderboardCreatorWindow.cs
Executable file
332
Assets/LeaderboardCreator/Editor/LeaderboardCreatorWindow.cs
Executable file
|
|
@ -0,0 +1,332 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Dan;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace LeaderboardCreatorEditor
|
||||
{
|
||||
public class LeaderboardCreatorWindow : EditorWindow
|
||||
{
|
||||
[System.Serializable]
|
||||
private class SavedLeaderboard
|
||||
{
|
||||
public string name, publicKey, secretKey;
|
||||
|
||||
public SavedLeaderboard(string name, string publicKey, string secretKey)
|
||||
{
|
||||
this.name = name;
|
||||
this.publicKey = publicKey;
|
||||
this.secretKey = secretKey;
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
private struct SavedLeaderboardList
|
||||
{
|
||||
public List<SavedLeaderboard> leaderboards;
|
||||
}
|
||||
|
||||
private const string ITCH_PAGE_URL = "https://danqzq.itch.io/leaderboard-creator";
|
||||
private const string AUTHOR_URL = "https://www.danqzq.games";
|
||||
private const string VERSION = "2.8";
|
||||
|
||||
private static bool _isAddLeaderboardMenuOpen;
|
||||
private static string _name, _publicKey, _secretKey;
|
||||
private static Vector2 _scrollPos;
|
||||
|
||||
private static SavedLeaderboardList _savedLeaderboardList;
|
||||
|
||||
private static GUIStyle _titleStyle;
|
||||
|
||||
private static int _menuOpened;
|
||||
|
||||
private static LeaderboardCreatorConfig Config => Resources.Load<LeaderboardCreatorConfig>("LeaderboardCreatorConfig");
|
||||
|
||||
[MenuItem("Leaderboard Creator/My Leaderboards")]
|
||||
private static void ShowWindow()
|
||||
{
|
||||
var window = GetWindow<LeaderboardCreatorWindow>();
|
||||
window.minSize = new Vector2(400, 475);
|
||||
window.titleContent = new GUIContent("Leaderboard Creator");
|
||||
window.Show();
|
||||
|
||||
CheckVersion();
|
||||
}
|
||||
|
||||
private static void CheckVersion()
|
||||
{
|
||||
var request = UnityEngine.Networking.UnityWebRequest.Get("https://lcv2-server.danqzq.games/version");
|
||||
var operation = request.SendWebRequest();
|
||||
Log("Checking for updates...");
|
||||
operation.completed += _ =>
|
||||
{
|
||||
if (request.responseCode != 200) return;
|
||||
var response = request.downloadHandler.text;
|
||||
if (response == VERSION)
|
||||
{
|
||||
Log("<color=green><b>Leaderboard Creator is up to date!</b></color>");
|
||||
return;
|
||||
}
|
||||
|
||||
Log("<color=red><b>There is a new version of Leaderboard Creator available!</b></color>");
|
||||
|
||||
var dialog = EditorUtility.DisplayDialog("Leaderboard Creator",
|
||||
"There is a new version of Leaderboard Creator available. Download it now?", "Yes", "No");
|
||||
if (!dialog) return;
|
||||
|
||||
Application.OpenURL(ITCH_PAGE_URL);
|
||||
};
|
||||
}
|
||||
|
||||
private void OnBecameVisible()
|
||||
{
|
||||
_titleStyle = new GUIStyle
|
||||
{
|
||||
fontSize = 20,
|
||||
fontStyle = FontStyle.Bold,
|
||||
normal = new GUIStyleState {textColor = Color.white}
|
||||
};
|
||||
_savedLeaderboardList = GetSavedLeaderboardList();
|
||||
}
|
||||
|
||||
private static SavedLeaderboardList GetSavedLeaderboardList()
|
||||
{
|
||||
var path = AssetDatabase.GetAssetPath(Config.editorOnlyLeaderboardsFile);
|
||||
var file = new System.IO.StreamReader(path);
|
||||
var json = file.ReadToEnd();
|
||||
file.Close();
|
||||
|
||||
if (string.IsNullOrEmpty(json))
|
||||
{
|
||||
SaveLeaderboardList();
|
||||
return new SavedLeaderboardList {leaderboards = new List<SavedLeaderboard>()};
|
||||
}
|
||||
|
||||
var savedLeaderboardList = JsonUtility.FromJson<SavedLeaderboardList>(json);
|
||||
return savedLeaderboardList;
|
||||
}
|
||||
|
||||
private static void SaveLeaderboardList()
|
||||
{
|
||||
_savedLeaderboardList.leaderboards ??= new List<SavedLeaderboard>();
|
||||
|
||||
var path = AssetDatabase.GetAssetPath(Config.editorOnlyLeaderboardsFile);
|
||||
var json = JsonUtility.ToJson(_savedLeaderboardList);
|
||||
|
||||
System.IO.File.WriteAllText(path, json);
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
_menuOpened = GUILayout.Toolbar(_menuOpened, new[] {"My Leaderboards", "Settings"});
|
||||
|
||||
switch (_menuOpened)
|
||||
{
|
||||
case 0:
|
||||
OnMyLeaderboardsGUI();
|
||||
break;
|
||||
case 1:
|
||||
OnSettingsGUI();
|
||||
break;
|
||||
}
|
||||
|
||||
DrawSeparator();
|
||||
|
||||
if (GUILayout.Button("<color=#2a9df4>Made by @danqzq</color>",
|
||||
new GUIStyle{alignment = TextAnchor.LowerRight, richText = true}))
|
||||
Application.OpenURL(AUTHOR_URL);
|
||||
|
||||
GUILayout.Label($"<color=white>v{VERSION}</color>", new GUIStyle{alignment = TextAnchor.LowerRight});
|
||||
}
|
||||
|
||||
private void OnMyLeaderboardsGUI()
|
||||
{
|
||||
DisplayLeaderboardsMenu();
|
||||
|
||||
if (!_isAddLeaderboardMenuOpen && GUILayout.Button("Enter New Leaderboard"))
|
||||
_isAddLeaderboardMenuOpen = true;
|
||||
|
||||
if (_isAddLeaderboardMenuOpen) DisplayEnterNewLeaderboardMenu();
|
||||
|
||||
if (GUILayout.Button("Save to C# Script"))
|
||||
SaveLeaderboardsToScript();
|
||||
|
||||
if (GUILayout.Button("Manage Leaderboards"))
|
||||
Application.OpenURL(ITCH_PAGE_URL);
|
||||
}
|
||||
|
||||
private void OnSettingsGUI()
|
||||
{
|
||||
GUILayout.Space(10);
|
||||
GUILayout.Label("Settings", _titleStyle);
|
||||
GUILayout.Space(10);
|
||||
|
||||
var oldAuthSaveMode = Config.authSaveMode;
|
||||
Config.authSaveMode = (AuthSaveMode) EditorGUILayout.EnumPopup("Authorization Save Mode", Config.authSaveMode);
|
||||
if (oldAuthSaveMode != Config.authSaveMode)
|
||||
EditorUtility.SetDirty(Config);
|
||||
|
||||
if (Config.authSaveMode == AuthSaveMode.PersistentDataPath)
|
||||
{
|
||||
var oldFileName = Config.fileName;
|
||||
Config.fileName = EditorGUILayout.TextField("File Name", Config.fileName);
|
||||
if (Config.fileName.Contains("/"))
|
||||
Config.fileName = Config.fileName.Replace("/", "");
|
||||
if (oldFileName != Config.fileName)
|
||||
EditorUtility.SetDirty(Config);
|
||||
if (Application.platform == RuntimePlatform.WebGLPlayer)
|
||||
EditorGUILayout.HelpBox("Saving to persistent data path may not work on WebGL builds.", MessageType.Warning);
|
||||
}
|
||||
|
||||
GUILayout.Space(20);
|
||||
|
||||
var oldIsUpdateLogsEnabled = Config.isUpdateLogsEnabled;
|
||||
Config.isUpdateLogsEnabled = GUILayout.Toggle(Config.isUpdateLogsEnabled, "Enable Update Logs");
|
||||
if (oldIsUpdateLogsEnabled != Config.isUpdateLogsEnabled)
|
||||
EditorUtility.SetDirty(Config);
|
||||
}
|
||||
|
||||
private static void DrawSeparator()
|
||||
{
|
||||
GUILayout.Space(10);
|
||||
var rect = EditorGUILayout.BeginHorizontal();
|
||||
Handles.color = Color.gray;
|
||||
Handles.DrawLine(new Vector2(rect.x - 15, rect.y), new Vector2(rect.width + 15, rect.y));
|
||||
EditorGUILayout.EndHorizontal();
|
||||
GUILayout.Space(10);
|
||||
}
|
||||
|
||||
private static void DisplayLeaderboardsMenu()
|
||||
{
|
||||
if (_savedLeaderboardList.leaderboards.Count == 0)
|
||||
{
|
||||
GUILayout.Label("You don't have any saved leaderboards.");
|
||||
return;
|
||||
}
|
||||
|
||||
_scrollPos = GUILayout.BeginScrollView(_scrollPos, GUILayout.Height(200));
|
||||
for (var i = 0; i < _savedLeaderboardList.leaderboards.Count; i++)
|
||||
{
|
||||
GUILayout.Space(10);
|
||||
GUILayout.Label("Leaderboard #" + (i + 1), EditorStyles.boldLabel);
|
||||
|
||||
var savedLeaderboard = _savedLeaderboardList.leaderboards[i];
|
||||
savedLeaderboard.name = EditorGUILayout.TextField("Name", savedLeaderboard.name);
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("Copy Public Key"))
|
||||
EditorGUIUtility.systemCopyBuffer = savedLeaderboard.publicKey;
|
||||
if (GUILayout.Button("Copy Secret Key"))
|
||||
EditorGUIUtility.systemCopyBuffer = savedLeaderboard.secretKey;
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
if (!GUILayout.Button("Forget Leaderboard"))
|
||||
continue;
|
||||
|
||||
_savedLeaderboardList.leaderboards.Remove(savedLeaderboard);
|
||||
SaveLeaderboardList();
|
||||
break;
|
||||
}
|
||||
|
||||
GUILayout.EndScrollView();
|
||||
}
|
||||
|
||||
private static void DisplayEnterNewLeaderboardMenu()
|
||||
{
|
||||
DrawSeparator();
|
||||
GUILayout.Label("Enter New Leaderboard", _titleStyle);
|
||||
|
||||
_name = EditorGUILayout.TextField("Name", _name);
|
||||
_publicKey = EditorGUILayout.TextField("Public Key", _publicKey);
|
||||
_secretKey = EditorGUILayout.TextField("Secret Key", _secretKey);
|
||||
|
||||
if (GUILayout.Button("Add Leaderboard"))
|
||||
EnterNewLeaderboard();
|
||||
|
||||
if (GUILayout.Button("Cancel"))
|
||||
_isAddLeaderboardMenuOpen = false;
|
||||
|
||||
DrawSeparator();
|
||||
}
|
||||
|
||||
private static void EnterNewLeaderboard()
|
||||
{
|
||||
if (string.IsNullOrEmpty(_publicKey) || string.IsNullOrEmpty(_secretKey))
|
||||
{
|
||||
EditorUtility.DisplayDialog("Leaderboard Creator Error", "Please fill all the fields.", "OK");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ValidateLeaderboardName(_name)) return;
|
||||
|
||||
_savedLeaderboardList = GetSavedLeaderboardList();
|
||||
if (_savedLeaderboardList.leaderboards.Exists(l => l.name == _name))
|
||||
{
|
||||
EditorUtility.DisplayDialog("Leaderboard Creator Error", "You already have a leaderboard with that name.", "OK");
|
||||
return;
|
||||
}
|
||||
|
||||
_savedLeaderboardList.leaderboards.Add(new SavedLeaderboard(_name, _publicKey, _secretKey));
|
||||
SaveLeaderboardList();
|
||||
|
||||
_name = _publicKey = _secretKey = "";
|
||||
}
|
||||
|
||||
private static bool ValidateLeaderboardName(string leaderboardName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(leaderboardName))
|
||||
{
|
||||
EditorUtility.DisplayDialog("Leaderboard Creator Error", "Please enter a name.", "OK");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Regex.IsMatch(leaderboardName, @"^[a-zA-Z0-9_]+$"))
|
||||
{
|
||||
EditorUtility.DisplayDialog("Leaderboard Creator Error", "The name can only contain alphabetical letters, numbers and underscores.", "OK");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Regex.IsMatch(leaderboardName, @"^[0-9]"))
|
||||
return true;
|
||||
|
||||
EditorUtility.DisplayDialog("Leaderboard Creator Error", "The name cannot start with a number.", "OK");
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void SaveLeaderboardsToScript()
|
||||
{
|
||||
if (_savedLeaderboardList.leaderboards.Any(savedLeaderboard => !ValidateLeaderboardName(savedLeaderboard.name)))
|
||||
return;
|
||||
|
||||
SaveLeaderboardList();
|
||||
|
||||
var path = AssetDatabase.GetAssetPath(Config.leaderboardsFile);
|
||||
var file = new System.IO.StreamWriter(path);
|
||||
|
||||
file.WriteLine("namespace Dan.Main");
|
||||
file.WriteLine("{");
|
||||
file.WriteLine(" public static class Leaderboards");
|
||||
file.WriteLine(" {");
|
||||
|
||||
foreach (var savedLeaderboard in _savedLeaderboardList.leaderboards)
|
||||
{
|
||||
file.WriteLine($" public static LeaderboardReference {savedLeaderboard.name} = " +
|
||||
$"new LeaderboardReference(\"{savedLeaderboard.publicKey}\");");
|
||||
}
|
||||
|
||||
file.WriteLine(" }");
|
||||
file.WriteLine("}");
|
||||
file.Close();
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
private static void Log(string message)
|
||||
{
|
||||
if (!Config.isUpdateLogsEnabled) return;
|
||||
Debug.Log($"[Leaderboard Creator] {message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/LeaderboardCreator/Editor/LeaderboardCreatorWindow.cs.meta
Executable file
3
Assets/LeaderboardCreator/Editor/LeaderboardCreatorWindow.cs.meta
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e80aaf6d96cc45b692e96e66380889ee
|
||||
timeCreated: 1693947366
|
||||
3
Assets/LeaderboardCreator/Resources.meta
Executable file
3
Assets/LeaderboardCreator/Resources.meta
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9dc78f1686d94215a156a0f58fdcd3c4
|
||||
timeCreated: 1693951712
|
||||
19
Assets/LeaderboardCreator/Resources/LeaderboardCreatorConfig.asset
Executable file
19
Assets/LeaderboardCreator/Resources/LeaderboardCreatorConfig.asset
Executable file
|
|
@ -0,0 +1,19 @@
|
|||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: f004774a7efa44eab4c0e289b68f484f, type: 3}
|
||||
m_Name: LeaderboardCreatorConfig
|
||||
m_EditorClassIdentifier:
|
||||
authSaveMode: 0
|
||||
fileName: leaderboard-creator-guid.txt
|
||||
isUpdateLogsEnabled: 1
|
||||
leaderboardsFile: {fileID: 11500000, guid: 8ff334e8988744eea42cf12786ee20d5, type: 3}
|
||||
editorOnlyLeaderboardsFile: {fileID: 4900000, guid: 5acfc3d506d9a854589cebec611a66e7, type: 3}
|
||||
8
Assets/LeaderboardCreator/Resources/LeaderboardCreatorConfig.asset.meta
Executable file
8
Assets/LeaderboardCreator/Resources/LeaderboardCreatorConfig.asset.meta
Executable file
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e5dcb9a6ab6c652448b9fe34a810dfd0
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/LeaderboardCreator/Scripts.meta
Executable file
8
Assets/LeaderboardCreator/Scripts.meta
Executable file
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 10b9fd2348cee4746a2d9cf74c22fac1
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
16
Assets/LeaderboardCreator/Scripts/Danqzq.LeaderboardCreator.asmdef
Executable file
16
Assets/LeaderboardCreator/Scripts/Danqzq.LeaderboardCreator.asmdef
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"name": "Danqzq.LeaderboardCreator",
|
||||
"rootNamespace": "Dan",
|
||||
"references": [
|
||||
"GUID:6055be8ebefd69e48b49212b09b47b2f"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
7
Assets/LeaderboardCreator/Scripts/Danqzq.LeaderboardCreator.asmdef.meta
Executable file
7
Assets/LeaderboardCreator/Scripts/Danqzq.LeaderboardCreator.asmdef.meta
Executable file
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b84cf0863fb105f47a726476f8d80bd8
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
3
Assets/LeaderboardCreator/Scripts/Enums.meta
Executable file
3
Assets/LeaderboardCreator/Scripts/Enums.meta
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9af4667ade994defb8e7ce8c2dd6c48c
|
||||
timeCreated: 1660484752
|
||||
15
Assets/LeaderboardCreator/Scripts/Enums/Routes.cs
Executable file
15
Assets/LeaderboardCreator/Scripts/Enums/Routes.cs
Executable file
|
|
@ -0,0 +1,15 @@
|
|||
namespace Dan.Enums
|
||||
{
|
||||
public enum Routes
|
||||
{
|
||||
Activate,
|
||||
Authorize,
|
||||
Get,
|
||||
None,
|
||||
Upload,
|
||||
UpdateUsername,
|
||||
DeleteEntry,
|
||||
GetPersonalEntry,
|
||||
GetEntryCount
|
||||
}
|
||||
}
|
||||
3
Assets/LeaderboardCreator/Scripts/Enums/Routes.cs.meta
Executable file
3
Assets/LeaderboardCreator/Scripts/Enums/Routes.cs.meta
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 72c5e1d220e94059b6b1cf3f7b99f95a
|
||||
timeCreated: 1660484888
|
||||
17
Assets/LeaderboardCreator/Scripts/Enums/StatusCode.cs
Executable file
17
Assets/LeaderboardCreator/Scripts/Enums/StatusCode.cs
Executable file
|
|
@ -0,0 +1,17 @@
|
|||
namespace Dan.Enums
|
||||
{
|
||||
public enum StatusCode
|
||||
{
|
||||
FailedToConnect = 0,
|
||||
Ok = 200,
|
||||
BadRequest = 400,
|
||||
Unauthorized = 401,
|
||||
Forbidden = 403,
|
||||
NotFound = 404,
|
||||
Conflict = 409,
|
||||
TooManyRequests = 429,
|
||||
InternalServerError = 500,
|
||||
NotImplemented = 501,
|
||||
ServiceUnavailable = 503
|
||||
}
|
||||
}
|
||||
3
Assets/LeaderboardCreator/Scripts/Enums/StatusCode.cs.meta
Executable file
3
Assets/LeaderboardCreator/Scripts/Enums/StatusCode.cs.meta
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 614196160841412b874fa7173e5a3c83
|
||||
timeCreated: 1660484853
|
||||
11
Assets/LeaderboardCreator/Scripts/Enums/TimePeriodType.cs
Executable file
11
Assets/LeaderboardCreator/Scripts/Enums/TimePeriodType.cs
Executable file
|
|
@ -0,0 +1,11 @@
|
|||
namespace Dan.Enums
|
||||
{
|
||||
public enum TimePeriodType
|
||||
{
|
||||
AllTime = 0,
|
||||
Today = 1,
|
||||
ThisWeek = 7,
|
||||
ThisMonth = 30,
|
||||
ThisYear = 365
|
||||
}
|
||||
}
|
||||
3
Assets/LeaderboardCreator/Scripts/Enums/TimePeriodType.cs.meta
Executable file
3
Assets/LeaderboardCreator/Scripts/Enums/TimePeriodType.cs.meta
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b9963a6d153c4971ab8b79eeb542e7bf
|
||||
timeCreated: 1679742430
|
||||
8
Assets/LeaderboardCreator/Scripts/Main.meta
Executable file
8
Assets/LeaderboardCreator/Scripts/Main.meta
Executable file
|
|
@ -0,0 +1,8 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 210cca2d87e75a948aee8beba1643210
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
323
Assets/LeaderboardCreator/Scripts/Main/LeaderboardCreator.cs
Executable file
323
Assets/LeaderboardCreator/Scripts/Main/LeaderboardCreator.cs
Executable file
|
|
@ -0,0 +1,323 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using Dan.Enums;
|
||||
using Dan.Models;
|
||||
using UnityEngine;
|
||||
|
||||
using static Dan.ConstantVariables;
|
||||
|
||||
namespace Dan.Main
|
||||
{
|
||||
public static class LeaderboardCreator
|
||||
{
|
||||
public static bool LoggingEnabled { get; set; } = true;
|
||||
|
||||
private static LeaderboardCreatorBehaviour _behaviour;
|
||||
|
||||
internal static string UserGuid;
|
||||
|
||||
private const string FORM_PUBLIC_KEY = "publicKey", FORM_USERNAME = "username", FORM_SCORE = "score",
|
||||
FORM_EXTRA = "extra", FORM_USER_GUID = "userGuid";
|
||||
|
||||
[RuntimeInitializeOnLoadMethod]
|
||||
private static void Initialize()
|
||||
{
|
||||
Log("Initializing...");
|
||||
_behaviour = new GameObject("[LeaderboardCreator]").AddComponent<LeaderboardCreatorBehaviour>();
|
||||
UnityEngine.Object.DontDestroyOnLoad(_behaviour.gameObject);
|
||||
|
||||
if (LeaderboardCreatorBehaviour.Config.authSaveMode != AuthSaveMode.Unhandled)
|
||||
_behaviour.Authorize(OnAuthorizationAttempted);
|
||||
}
|
||||
|
||||
private static void OnAuthorizationAttempted(string guid)
|
||||
{
|
||||
if (string.IsNullOrEmpty(guid))
|
||||
{
|
||||
Log("<b><color=#FF0000>Failed to connect to server, trying again...</color></b>");
|
||||
|
||||
IEnumerator Co()
|
||||
{
|
||||
yield return new WaitForSeconds(5f);
|
||||
_behaviour.Authorize(OnAuthorizationAttempted);
|
||||
}
|
||||
|
||||
_behaviour.StartCoroutine(Co());
|
||||
return;
|
||||
}
|
||||
SetUserGuid(guid);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requests a new unique identifier for the user from the server.
|
||||
/// NOTE: Use this function if you want to manually handle the user's unique identifier.
|
||||
/// IMPORTANT: Set the "Authorization Save Mode" to "Unhandled" in the Settings menu of the Leaderboard Creator window.
|
||||
/// </summary>
|
||||
/// <param name="userGuidCallback">A callback that returns the user's unique identifier.</param>
|
||||
public static void RequestUserGuid(Action<string> userGuidCallback)
|
||||
{
|
||||
_behaviour.Authorize(userGuidCallback);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the user's unique identifier to the given string value.
|
||||
/// </summary>
|
||||
/// <param name="userGuid">The user's unique identifier.</param>
|
||||
public static void SetUserGuid(string userGuid)
|
||||
{
|
||||
UserGuid = userGuid;
|
||||
Log("<b><color=#009900>Initialized!</color></b>");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pings the server to check if a connection can be established.
|
||||
/// </summary>
|
||||
/// <param name="isOnline">If true, the server is online, else connection failed.</param>
|
||||
public static void Ping(Action<bool> isOnline) => _behaviour.SendGetRequest(GetServerURL(), isOnline, null);
|
||||
|
||||
/// <summary>
|
||||
/// Fetches a leaderboard with the given public key.
|
||||
/// </summary>
|
||||
/// <param name="publicKey">The public key of the leaderboard
|
||||
/// (retrieve from https://danqzq.itch.io/leaderboard-creator).</param>
|
||||
/// <param name="callback">Returns entries of the leaderboard if the request was successful.</param>
|
||||
/// <param name="errorCallback">Returns an error message if the request failed.</param>
|
||||
public static void GetLeaderboard(string publicKey, Action<Entry[]> callback, Action<string> errorCallback = null) =>
|
||||
GetLeaderboard(publicKey, LeaderboardSearchQuery.Default, callback, errorCallback);
|
||||
|
||||
/// <summary>
|
||||
/// Fetches a leaderboard with the given public key.
|
||||
/// </summary>
|
||||
/// <param name="publicKey">The public key of the leaderboard
|
||||
/// (retrieve from https://danqzq.itch.io/leaderboard-creator).</param>
|
||||
/// <param name="isInAscendingOrder">If true, the leaderboard will be sorted in ascending order.</param>
|
||||
/// <param name="callback">Returns entries of the leaderboard if the request was successful.</param>
|
||||
/// <param name="errorCallback">Returns an error message if the request failed.</param>
|
||||
public static void GetLeaderboard(string publicKey, bool isInAscendingOrder, Action<Entry[]> callback, Action<string> errorCallback = null) =>
|
||||
GetLeaderboard(publicKey, isInAscendingOrder, LeaderboardSearchQuery.Default, callback, errorCallback);
|
||||
|
||||
/// <summary>
|
||||
/// Fetches a leaderboard with the given public key.
|
||||
/// </summary>
|
||||
/// <param name="publicKey">The public key of the leaderboard
|
||||
/// (retrieve from https://danqzq.itch.io/leaderboard-creator).</param>
|
||||
/// <param name="searchQuery">A struct with additional search parameters for filtering entries.</param>
|
||||
/// <param name="callback">Returns entries of the leaderboard if the request was successful.</param>
|
||||
/// <param name="errorCallback">Returns an error message if the request failed.</param>
|
||||
public static void GetLeaderboard(string publicKey, LeaderboardSearchQuery searchQuery, Action<Entry[]> callback, Action<string> errorCallback = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(publicKey))
|
||||
{
|
||||
LogError("Public key cannot be null or empty!");
|
||||
return;
|
||||
}
|
||||
|
||||
var query = $"?publicKey={publicKey}&userGuid={UserGuid}";
|
||||
query += searchQuery.ChainQuery();
|
||||
|
||||
_behaviour.SendGetRequest(GetServerURL(Routes.Get, query), callback, errorCallback);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches a leaderboard with the given public key.
|
||||
/// </summary>
|
||||
/// <param name="publicKey">The public key of the leaderboard
|
||||
/// (retrieve from https://danqzq.itch.io/leaderboard-creator).</param>
|
||||
/// <param name="isInAscendingOrder">If true, the leaderboard will be sorted in ascending order.</param>
|
||||
/// <param name="searchQuery">A struct with additional search parameters for filtering entries.</param>
|
||||
/// <param name="callback">Returns entries of the leaderboard if the request was successful.</param>
|
||||
/// <param name="errorCallback">Returns an error message if the request failed.</param>
|
||||
public static void GetLeaderboard(string publicKey, bool isInAscendingOrder, LeaderboardSearchQuery searchQuery, Action<Entry[]> callback, Action<string> errorCallback = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(publicKey))
|
||||
{
|
||||
LogError("Public key cannot be null or empty!");
|
||||
return;
|
||||
}
|
||||
|
||||
var query = $"?publicKey={publicKey}&userGuid={UserGuid}&isInAscendingOrder={(isInAscendingOrder ? 1 : 0)}";
|
||||
query += searchQuery.ChainQuery();
|
||||
|
||||
_behaviour.SendGetRequest(GetServerURL(Routes.Get, query), callback, errorCallback);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Uploads a new entry to the leaderboard with the given public key.
|
||||
/// </summary>
|
||||
/// <param name="publicKey">The public key of the leaderboard</param>
|
||||
/// <param name="username">The username of the player</param>
|
||||
/// <param name="score">The highscore of the player</param>
|
||||
/// <param name="callback">Returns true if the request was successful.</param>
|
||||
/// <param name="errorCallback">Returns an error message if the request failed.</param>
|
||||
public static void UploadNewEntry(string publicKey, string username, int score, Action<bool> callback = null, Action<string> errorCallback = null) =>
|
||||
UploadNewEntry(publicKey, username, score, " ", callback, errorCallback);
|
||||
|
||||
/// <summary>
|
||||
/// Uploads a new entry to the leaderboard with the given public key.
|
||||
/// </summary>
|
||||
/// <param name="publicKey">The public key of the leaderboard</param>
|
||||
/// <param name="username">The username of the player</param>
|
||||
/// <param name="score">The highscore of the player</param>
|
||||
/// <param name="extra">Extra data to be stored with the entry (max length of 100, unless using an advanced leaderboard)</param>
|
||||
/// <param name="callback">Returns true if the request was successful.</param>
|
||||
/// <param name="errorCallback">Returns an error message if the request failed.</param>
|
||||
public static void UploadNewEntry(string publicKey, string username, int score, string extra, Action<bool> callback = null, Action<string> errorCallback = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(publicKey))
|
||||
{
|
||||
LogError("Public key cannot be null or empty!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(username))
|
||||
{
|
||||
LogError("Username cannot be null or empty!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (username.Length > 127)
|
||||
{
|
||||
LogError("Username cannot be longer than 127 characters!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(UserGuid))
|
||||
{
|
||||
LogError("User GUID is null or empty! Please authorize the user before uploading an entry.");
|
||||
return;
|
||||
}
|
||||
|
||||
callback += isSuccessful =>
|
||||
{
|
||||
if (!isSuccessful)
|
||||
LogError("Uploading entry data failed!");
|
||||
else
|
||||
Log("Successfully uploaded entry data to leaderboard!");
|
||||
};
|
||||
|
||||
_behaviour.SendPostRequest(GetServerURL(Routes.Upload), Requests.Form(
|
||||
Requests.Field(FORM_PUBLIC_KEY, publicKey),
|
||||
Requests.Field(FORM_USERNAME, username),
|
||||
Requests.Field(FORM_SCORE, score.ToString()),
|
||||
Requests.Field(FORM_EXTRA, extra),
|
||||
Requests.Field(FORM_USER_GUID, UserGuid)), callback, errorCallback);
|
||||
}
|
||||
|
||||
[Obsolete("This function is deprecated and will be removed in the future.")]
|
||||
public static void UpdateEntryUsername(string publicKey, string username, Action<bool> callback = null, Action<string> errorCallback = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(publicKey))
|
||||
{
|
||||
LogError("Public key cannot be null or empty!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(username))
|
||||
{
|
||||
LogError("Username cannot be null or empty!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (username.Length > 127)
|
||||
{
|
||||
LogError("Username cannot be longer than 127 characters!");
|
||||
return;
|
||||
}
|
||||
|
||||
callback += isSuccessful =>
|
||||
{
|
||||
if (!isSuccessful)
|
||||
LogError("Updating entry's username failed!");
|
||||
else
|
||||
Log("Successfully updated player's username!");
|
||||
};
|
||||
|
||||
_behaviour.SendPostRequest(GetServerURL(Routes.UpdateUsername), Requests.Form(
|
||||
Requests.Field(FORM_PUBLIC_KEY, publicKey),
|
||||
Requests.Field(FORM_USERNAME, username),
|
||||
Requests.Field(FORM_USER_GUID, UserGuid)), callback, errorCallback);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the entry in a leaderboard, with the given public key.
|
||||
/// </summary>
|
||||
/// <param name="publicKey">Public key of the leaderboard.</param>
|
||||
/// <param name="callback">Returns true if the request was successful.</param>
|
||||
/// <param name="errorCallback">Returns an error message if the request failed.</param>
|
||||
public static void DeleteEntry(string publicKey, Action<bool> callback = null, Action<string> errorCallback = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(publicKey))
|
||||
{
|
||||
LogError("Public key cannot be null or empty!");
|
||||
return;
|
||||
}
|
||||
|
||||
callback += isSuccessful =>
|
||||
{
|
||||
if (!isSuccessful)
|
||||
LogError("Deleting entry failed!");
|
||||
else
|
||||
Log("Successfully deleted player's entry!");
|
||||
};
|
||||
|
||||
_behaviour.SendPostRequest(GetServerURL(Routes.DeleteEntry), Requests.Form(
|
||||
Requests.Field(FORM_PUBLIC_KEY, publicKey),
|
||||
Requests.Field(FORM_USER_GUID, UserGuid)), callback, errorCallback);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the entry data of the player in a leaderboard, with the given public key.
|
||||
/// </summary>
|
||||
/// <param name="publicKey">Public key of the leaderboard.</param>
|
||||
/// <param name="callback">Returns the entry data if request is successful</param>
|
||||
/// <param name="errorCallback">Returns an error message if the request failed.</param>
|
||||
public static void GetPersonalEntry(string publicKey, Action<Entry> callback, Action<string> errorCallback = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(publicKey))
|
||||
{
|
||||
LogError("Public key cannot be null or empty!");
|
||||
return;
|
||||
}
|
||||
|
||||
_behaviour.SendGetRequest(GetServerURL(Routes.GetPersonalEntry,
|
||||
$"?publicKey={publicKey}&userGuid={UserGuid}"), callback, errorCallback);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the total number of entries in a leaderboard, with the given public key.
|
||||
/// </summary>
|
||||
/// <param name="publicKey">Public key of the leaderboard.</param>
|
||||
/// <param name="callback">Returns the total number of entries in the leaderboard.</param>
|
||||
/// <param name="errorCallback">Returns an error message if the request failed.</param>
|
||||
public static void GetEntryCount(string publicKey, Action<int> callback, Action<string> errorCallback = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(publicKey))
|
||||
{
|
||||
LogError("Public key cannot be null or empty!");
|
||||
return;
|
||||
}
|
||||
|
||||
_behaviour.SendGetRequest(GetServerURL(Routes.GetEntryCount) + $"?publicKey={publicKey}", callback, errorCallback);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets a player's unique identifier and allows them to submit a new entry to the leaderboard.
|
||||
/// </summary>
|
||||
public static void ResetPlayer(Action onReset = null)
|
||||
{
|
||||
_behaviour.ResetAndAuthorize(OnAuthorizationAttempted, onReset);
|
||||
}
|
||||
|
||||
internal static void Log(string message)
|
||||
{
|
||||
if (!LoggingEnabled) return;
|
||||
Debug.Log($"[LeaderboardCreator] {message}");
|
||||
}
|
||||
|
||||
internal static void LogError(string message)
|
||||
{
|
||||
if (!LoggingEnabled) return;
|
||||
Debug.LogError($"[LeaderboardCreator] {message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/LeaderboardCreator/Scripts/Main/LeaderboardCreator.cs.meta
Executable file
3
Assets/LeaderboardCreator/Scripts/Main/LeaderboardCreator.cs.meta
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3dd7127c7a2c45bfa590eb249427722d
|
||||
timeCreated: 1660544476
|
||||
229
Assets/LeaderboardCreator/Scripts/Main/LeaderboardCreatorBehaviour.cs
Executable file
229
Assets/LeaderboardCreator/Scripts/Main/LeaderboardCreatorBehaviour.cs
Executable file
|
|
@ -0,0 +1,229 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Dan.Enums;
|
||||
using Dan.Models;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
using static Dan.ConstantVariables;
|
||||
|
||||
namespace Dan.Main
|
||||
{
|
||||
public sealed class LeaderboardCreatorBehaviour : MonoBehaviour
|
||||
{
|
||||
[Serializable]
|
||||
private struct EntryResponse
|
||||
{
|
||||
public Entry[] entries;
|
||||
}
|
||||
|
||||
internal static LeaderboardCreatorConfig Config =>
|
||||
Resources.Load<LeaderboardCreatorConfig>("LeaderboardCreatorConfig");
|
||||
|
||||
private static string GetError(UnityWebRequest request) =>
|
||||
$"{request.responseCode}: {request.downloadHandler.text}";
|
||||
|
||||
internal void Authorize(Action<string> callback)
|
||||
{
|
||||
var loadedGuid = LoadGuid();
|
||||
if (!string.IsNullOrEmpty(loadedGuid))
|
||||
{
|
||||
callback?.Invoke(loadedGuid);
|
||||
return;
|
||||
}
|
||||
|
||||
var request = UnityWebRequest.Get(GetServerURL(Routes.Authorize));
|
||||
StartCoroutine(HandleRequest(request, isSuccessful =>
|
||||
{
|
||||
if (!isSuccessful)
|
||||
{
|
||||
HandleError(request);
|
||||
callback?.Invoke(null);
|
||||
return;
|
||||
}
|
||||
|
||||
var guid = request.downloadHandler.text;
|
||||
SaveGuid(guid);
|
||||
callback?.Invoke(guid);
|
||||
}));
|
||||
}
|
||||
|
||||
internal void ResetAndAuthorize(Action<string> callback, Action onFinish)
|
||||
{
|
||||
callback += guid =>
|
||||
{
|
||||
if (string.IsNullOrEmpty(guid))
|
||||
return;
|
||||
onFinish?.Invoke();
|
||||
};
|
||||
DeleteGuid();
|
||||
Authorize(callback);
|
||||
}
|
||||
|
||||
internal void SendGetRequest(string url, Action<bool> callback, Action<string> errorCallback)
|
||||
{
|
||||
var request = UnityWebRequest.Get(url);
|
||||
StartCoroutine(HandleRequest(request, isSuccessful =>
|
||||
{
|
||||
if (!isSuccessful)
|
||||
{
|
||||
HandleError(request);
|
||||
callback?.Invoke(false);
|
||||
errorCallback?.Invoke(GetError(request));
|
||||
return;
|
||||
}
|
||||
callback?.Invoke(true);
|
||||
LeaderboardCreator.Log("Successfully retrieved leaderboard data!");
|
||||
}));
|
||||
}
|
||||
|
||||
internal void SendGetRequest(string url, Action<int> callback, Action<string> errorCallback)
|
||||
{
|
||||
var request = UnityWebRequest.Get(url);
|
||||
StartCoroutine(HandleRequest(request, isSuccessful =>
|
||||
{
|
||||
if (!isSuccessful)
|
||||
{
|
||||
HandleError(request);
|
||||
callback?.Invoke(0);
|
||||
errorCallback?.Invoke(GetError(request));
|
||||
return;
|
||||
}
|
||||
callback?.Invoke(int.Parse(request.downloadHandler.text));
|
||||
LeaderboardCreator.Log("Successfully retrieved leaderboard data!");
|
||||
}));
|
||||
}
|
||||
|
||||
internal void SendGetRequest(string url, Action<Entry> callback, Action<string> errorCallback)
|
||||
{
|
||||
var request = UnityWebRequest.Get(url);
|
||||
StartCoroutine(HandleRequest(request, isSuccessful =>
|
||||
{
|
||||
if (!isSuccessful)
|
||||
{
|
||||
HandleError(request);
|
||||
callback?.Invoke(new Entry());
|
||||
errorCallback?.Invoke(GetError(request));
|
||||
return;
|
||||
}
|
||||
var response = JsonUtility.FromJson<Entry>(request.downloadHandler.text);
|
||||
callback?.Invoke(response);
|
||||
LeaderboardCreator.Log("Successfully retrieved leaderboard data!");
|
||||
}));
|
||||
}
|
||||
|
||||
internal void SendGetRequest(string url, Action<Entry[]> callback, Action<string> errorCallback)
|
||||
{
|
||||
var request = UnityWebRequest.Get(url);
|
||||
StartCoroutine(HandleRequest(request, isSuccessful =>
|
||||
{
|
||||
if (!isSuccessful)
|
||||
{
|
||||
HandleError(request);
|
||||
callback?.Invoke(Array.Empty<Entry>());
|
||||
errorCallback?.Invoke(GetError(request));
|
||||
return;
|
||||
}
|
||||
var response = JsonUtility.FromJson<EntryResponse>($"{{\"entries\":{request.downloadHandler.text}}}");
|
||||
callback?.Invoke(response.entries);
|
||||
LeaderboardCreator.Log("Successfully retrieved leaderboard data!");
|
||||
}));
|
||||
}
|
||||
|
||||
internal void SendPostRequest(string url, List<IMultipartFormSection> form, Action<bool> callback = null, Action<string> errorCallback = null)
|
||||
{
|
||||
var request = UnityWebRequest.Post(url, form);
|
||||
StartCoroutine(HandleRequest(request, callback, errorCallback));
|
||||
}
|
||||
|
||||
#if UNITY_ANDROID
|
||||
private class ForceAcceptAll : CertificateHandler
|
||||
{
|
||||
protected override bool ValidateCertificate(byte[] certificateData) => true;
|
||||
}
|
||||
#endif
|
||||
private static IEnumerator HandleRequest(UnityWebRequest request, Action<bool> onComplete, Action<string> errorCallback = null)
|
||||
{
|
||||
#if UNITY_ANDROID
|
||||
request.certificateHandler = new ForceAcceptAll();
|
||||
#endif
|
||||
yield return request.SendWebRequest();
|
||||
|
||||
if (request.responseCode != 200)
|
||||
{
|
||||
onComplete.Invoke(false);
|
||||
errorCallback?.Invoke(GetError(request));
|
||||
request.downloadHandler.Dispose();
|
||||
request.Dispose();
|
||||
yield break;
|
||||
}
|
||||
|
||||
onComplete.Invoke(true);
|
||||
request.downloadHandler.Dispose();
|
||||
request.Dispose();
|
||||
}
|
||||
|
||||
private static void HandleError(UnityWebRequest request)
|
||||
{
|
||||
var message = Enum.GetName(typeof(StatusCode), (StatusCode) request.responseCode);
|
||||
message = string.IsNullOrEmpty(message) ? "Unknown" : message.SplitByUppercase();
|
||||
|
||||
var downloadHandler = request.downloadHandler;
|
||||
var text = downloadHandler.text;
|
||||
if (!string.IsNullOrEmpty(text))
|
||||
message = $"{message}: {text}";
|
||||
LeaderboardCreator.LogError(message);
|
||||
}
|
||||
|
||||
private static void SaveGuid(string guid)
|
||||
{
|
||||
switch (Config.authSaveMode)
|
||||
{
|
||||
case AuthSaveMode.PlayerPrefs:
|
||||
PlayerPrefs.SetString(GUID_KEY, guid);
|
||||
PlayerPrefs.Save();
|
||||
break;
|
||||
case AuthSaveMode.PersistentDataPath:
|
||||
var path = System.IO.Path.Combine(Application.persistentDataPath, Config.fileName);
|
||||
if (string.IsNullOrEmpty(path))
|
||||
return;
|
||||
System.IO.File.WriteAllText(path, guid);
|
||||
break;
|
||||
}
|
||||
LeaderboardCreator.UserGuid = guid;
|
||||
}
|
||||
|
||||
private static string LoadGuid()
|
||||
{
|
||||
switch (Config.authSaveMode)
|
||||
{
|
||||
case AuthSaveMode.PlayerPrefs:
|
||||
return PlayerPrefs.GetString(GUID_KEY, "");
|
||||
case AuthSaveMode.PersistentDataPath:
|
||||
var path = System.IO.Path.Combine(Application.persistentDataPath, Config.fileName);
|
||||
return System.IO.File.Exists(path) ? System.IO.File.ReadAllText(path) : "";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private static void DeleteGuid()
|
||||
{
|
||||
switch (Config.authSaveMode)
|
||||
{
|
||||
case AuthSaveMode.PlayerPrefs:
|
||||
PlayerPrefs.DeleteKey(GUID_KEY);
|
||||
PlayerPrefs.Save();
|
||||
break;
|
||||
case AuthSaveMode.PersistentDataPath:
|
||||
var path = System.IO.Path.Combine(Application.persistentDataPath, Config.fileName);
|
||||
if (string.IsNullOrEmpty(path) || !System.IO.File.Exists(path))
|
||||
return;
|
||||
System.IO.File.Delete(path);
|
||||
break;
|
||||
}
|
||||
LeaderboardCreator.UserGuid = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1844164b113842008a02b38fc49304f7
|
||||
timeCreated: 1660544772
|
||||
41
Assets/LeaderboardCreator/Scripts/Main/LeaderboardReference.cs
Executable file
41
Assets/LeaderboardCreator/Scripts/Main/LeaderboardReference.cs
Executable file
|
|
@ -0,0 +1,41 @@
|
|||
using System;
|
||||
using Dan.Models;
|
||||
|
||||
namespace Dan.Main
|
||||
{
|
||||
public class LeaderboardReference
|
||||
{
|
||||
public string PublicKey { get; }
|
||||
|
||||
public LeaderboardReference(string publicKey) => PublicKey = publicKey;
|
||||
|
||||
public void UploadNewEntry(string username, int score, Action<bool> callback = null, Action<string> errorCallback = null) =>
|
||||
LeaderboardCreator.UploadNewEntry(PublicKey, username, score, callback, errorCallback);
|
||||
|
||||
public void UploadNewEntry(string username, int score, string extraData, Action<bool> callback = null, Action<string> errorCallback = null) =>
|
||||
LeaderboardCreator.UploadNewEntry(PublicKey, username, score, extraData, callback, errorCallback);
|
||||
|
||||
public void GetEntries(Action<Entry[]> callback, Action<string> errorCallback = null) =>
|
||||
LeaderboardCreator.GetLeaderboard(PublicKey, callback, errorCallback);
|
||||
|
||||
public void GetEntries(bool isAscending, Action<Entry[]> callback, Action<string> errorCallback = null) =>
|
||||
LeaderboardCreator.GetLeaderboard(PublicKey, isAscending, callback, errorCallback);
|
||||
|
||||
public void GetEntries(LeaderboardSearchQuery query, Action<Entry[]> callback, Action<string> errorCallback = null) =>
|
||||
LeaderboardCreator.GetLeaderboard(PublicKey, query, callback, errorCallback);
|
||||
|
||||
public void GetEntries(bool isAscending, LeaderboardSearchQuery query, Action<Entry[]> callback, Action<string> errorCallback = null) =>
|
||||
LeaderboardCreator.GetLeaderboard(PublicKey, isAscending, query, callback, errorCallback);
|
||||
|
||||
public void GetPersonalEntry(Action<Entry> callback, Action<string> errorCallback = null) =>
|
||||
LeaderboardCreator.GetPersonalEntry(PublicKey, callback, errorCallback);
|
||||
|
||||
public void GetEntryCount(Action<int> callback, Action<string> errorCallback = null) =>
|
||||
LeaderboardCreator.GetEntryCount(PublicKey, callback, errorCallback);
|
||||
|
||||
public void DeleteEntry(Action<bool> callback = null, Action<string> errorCallback = null) =>
|
||||
LeaderboardCreator.DeleteEntry(PublicKey, callback, errorCallback);
|
||||
|
||||
public void ResetPlayer(Action onReset = null) => LeaderboardCreator.ResetPlayer(onReset);
|
||||
}
|
||||
}
|
||||
3
Assets/LeaderboardCreator/Scripts/Main/LeaderboardReference.cs.meta
Executable file
3
Assets/LeaderboardCreator/Scripts/Main/LeaderboardReference.cs.meta
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 237dfda88f2848018d42e238dec5b66c
|
||||
timeCreated: 1693950058
|
||||
7
Assets/LeaderboardCreator/Scripts/Main/Leaderboards.cs
Executable file
7
Assets/LeaderboardCreator/Scripts/Main/Leaderboards.cs
Executable file
|
|
@ -0,0 +1,7 @@
|
|||
namespace Dan.Main
|
||||
{
|
||||
public static class Leaderboards
|
||||
{
|
||||
public static LeaderboardReference YoumuLeaderboard = new LeaderboardReference("2b836767763cfa11c33d22e98dfbda369b0cb1eb2fc3f5418640676a518433d5");
|
||||
}
|
||||
}
|
||||
3
Assets/LeaderboardCreator/Scripts/Main/Leaderboards.cs.meta
Executable file
3
Assets/LeaderboardCreator/Scripts/Main/Leaderboards.cs.meta
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8ff334e8988744eea42cf12786ee20d5
|
||||
timeCreated: 1693949488
|
||||
3
Assets/LeaderboardCreator/Scripts/Models.meta
Executable file
3
Assets/LeaderboardCreator/Scripts/Models.meta
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2c8fa39508ba479592eefc448fcf4573
|
||||
timeCreated: 1660482071
|
||||
39
Assets/LeaderboardCreator/Scripts/Models/Entry.cs
Executable file
39
Assets/LeaderboardCreator/Scripts/Models/Entry.cs
Executable file
|
|
@ -0,0 +1,39 @@
|
|||
using Dan.Main;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Dan.Models
|
||||
{
|
||||
[System.Serializable]
|
||||
public struct Entry
|
||||
{
|
||||
public string Username;
|
||||
public int Score;
|
||||
public ulong Date;
|
||||
public string Extra;
|
||||
public int Rank;
|
||||
[SerializeField] internal string UserGuid;
|
||||
[field: System.NonSerialized] internal string NewUsername { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether the entry is the current user's entry.
|
||||
/// </summary>
|
||||
public bool IsMine() => UserGuid == LeaderboardCreator.UserGuid;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the rank of the entry with its suffix.
|
||||
/// </summary>
|
||||
/// <returns>Rank + suffix (e.g. 1st, 2nd, 3rd, 4th, 5th, etc.).</returns>
|
||||
public string RankSuffix()
|
||||
{
|
||||
var rank = Rank;
|
||||
var lastDigit = rank % 10;
|
||||
var lastTwoDigits = rank % 100;
|
||||
|
||||
var suffix = lastDigit == 1 && lastTwoDigits != 11 ? "st" :
|
||||
lastDigit == 2 && lastTwoDigits != 12 ? "nd" :
|
||||
lastDigit == 3 && lastTwoDigits != 13 ? "rd" : "th";
|
||||
|
||||
return $"{rank}{suffix}";
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/LeaderboardCreator/Scripts/Models/Entry.cs.meta
Executable file
3
Assets/LeaderboardCreator/Scripts/Models/Entry.cs.meta
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e9f6f4e4968841efa3dc6efbeeffd447
|
||||
timeCreated: 1660484221
|
||||
52
Assets/LeaderboardCreator/Scripts/Models/LeaderboardSearchQuery.cs
Executable file
52
Assets/LeaderboardCreator/Scripts/Models/LeaderboardSearchQuery.cs
Executable file
|
|
@ -0,0 +1,52 @@
|
|||
using Dan.Enums;
|
||||
|
||||
namespace Dan.Models
|
||||
{
|
||||
public struct LeaderboardSearchQuery
|
||||
{
|
||||
public int Skip { get; set; }
|
||||
public int Take { get; set; }
|
||||
public string Username { get; set; }
|
||||
public TimePeriodType TimePeriod { get; set; }
|
||||
|
||||
private string Query => $"skip={Skip}&take={Take}&username={Username}&timePeriod={(int) TimePeriod}";
|
||||
|
||||
public string GetQuery() => "?" + Query;
|
||||
|
||||
public string ChainQuery() => "&" + Query;
|
||||
|
||||
public static LeaderboardSearchQuery Default => new LeaderboardSearchQuery
|
||||
{
|
||||
Skip = 0,
|
||||
Take = 0,
|
||||
Username = "",
|
||||
TimePeriod = TimePeriodType.AllTime
|
||||
};
|
||||
|
||||
public static LeaderboardSearchQuery Paginated(int skip, int take) =>
|
||||
ByUsernameAndTimePaginated("", TimePeriodType.AllTime, skip, take);
|
||||
|
||||
public static LeaderboardSearchQuery ByUsername(string username) =>
|
||||
ByUsernamePaginated(username, 5, 5);
|
||||
|
||||
public static LeaderboardSearchQuery ByUsernamePaginated(string username, int prev, int next) =>
|
||||
ByUsernameAndTimePaginated(username, TimePeriodType.AllTime, prev, next);
|
||||
|
||||
public static LeaderboardSearchQuery ByTimePeriod(TimePeriodType timePeriod) =>
|
||||
ByTimePeriodPaginated(timePeriod, 0, 0);
|
||||
|
||||
public static LeaderboardSearchQuery ByTimePeriodPaginated(TimePeriodType timePeriod, int skip, int take) =>
|
||||
ByUsernameAndTimePaginated("", timePeriod, skip, take);
|
||||
|
||||
public static LeaderboardSearchQuery ByUsernameAndTime(string username, TimePeriodType timePeriod) =>
|
||||
ByUsernameAndTimePaginated(username, timePeriod, 0, 0);
|
||||
|
||||
public static LeaderboardSearchQuery ByUsernameAndTimePaginated(string username, TimePeriodType timePeriod, int skip, int take) => new LeaderboardSearchQuery
|
||||
{
|
||||
Skip = skip,
|
||||
Take = take,
|
||||
Username = username,
|
||||
TimePeriod = timePeriod
|
||||
};
|
||||
}
|
||||
}
|
||||
3
Assets/LeaderboardCreator/Scripts/Models/LeaderboardSearchQuery.cs.meta
Executable file
3
Assets/LeaderboardCreator/Scripts/Models/LeaderboardSearchQuery.cs.meta
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 29284a0880dd4054ac8294cc917db6f8
|
||||
timeCreated: 1679736989
|
||||
3
Assets/LeaderboardCreator/Scripts/Utils.meta
Executable file
3
Assets/LeaderboardCreator/Scripts/Utils.meta
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8889c8935b154ff4b70b2fcf3c719412
|
||||
timeCreated: 1660491089
|
||||
22
Assets/LeaderboardCreator/Scripts/Utils/ConstantVariables.cs
Executable file
22
Assets/LeaderboardCreator/Scripts/Utils/ConstantVariables.cs
Executable file
|
|
@ -0,0 +1,22 @@
|
|||
using Dan.Enums;
|
||||
|
||||
namespace Dan
|
||||
{
|
||||
internal static class ConstantVariables
|
||||
{
|
||||
internal const string GUID_KEY = "LEADERBOARD_CREATOR___LOCAL_GUID";
|
||||
|
||||
internal static string GetServerURL(Routes route = Routes.None, string extra = "")
|
||||
{
|
||||
return SERVER_URL + (route == Routes.Authorize ? "/authorize" :
|
||||
route == Routes.Get ? "/get" :
|
||||
route == Routes.Upload ? "/entry/upload" :
|
||||
route == Routes.UpdateUsername ? "/entry/update-username" :
|
||||
route == Routes.DeleteEntry ? "/entry/delete" :
|
||||
route == Routes.GetPersonalEntry ? "/entry/get" :
|
||||
route == Routes.GetEntryCount ? "/entry/count" : "/") + extra;
|
||||
}
|
||||
|
||||
private const string SERVER_URL = "https://lcv2-server.danqzq.games";
|
||||
}
|
||||
}
|
||||
3
Assets/LeaderboardCreator/Scripts/Utils/ConstantVariables.cs.meta
Executable file
3
Assets/LeaderboardCreator/Scripts/Utils/ConstantVariables.cs.meta
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8ba37bb8809248c793a754c692830a1b
|
||||
timeCreated: 1660731015
|
||||
10
Assets/LeaderboardCreator/Scripts/Utils/ExtensionMethods.cs
Executable file
10
Assets/LeaderboardCreator/Scripts/Utils/ExtensionMethods.cs
Executable file
|
|
@ -0,0 +1,10 @@
|
|||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Dan
|
||||
{
|
||||
public static class ExtensionMethods
|
||||
{
|
||||
public static string SplitByUppercase(this string str) =>
|
||||
Regex.Replace(str, @"(\B[A-Z]+?(?=[A-Z][^A-Z])|\B[A-Z]+?(?=[^A-Z]))", " $1");
|
||||
}
|
||||
}
|
||||
3
Assets/LeaderboardCreator/Scripts/Utils/ExtensionMethods.cs.meta
Executable file
3
Assets/LeaderboardCreator/Scripts/Utils/ExtensionMethods.cs.meta
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 07c46008f49546899a5404ae5730f8e5
|
||||
timeCreated: 1660647932
|
||||
23
Assets/LeaderboardCreator/Scripts/Utils/LeaderboardCreatorConfig.cs
Executable file
23
Assets/LeaderboardCreator/Scripts/Utils/LeaderboardCreatorConfig.cs
Executable file
|
|
@ -0,0 +1,23 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace Dan
|
||||
{
|
||||
public enum AuthSaveMode
|
||||
{
|
||||
PlayerPrefs,
|
||||
PersistentDataPath,
|
||||
Unhandled
|
||||
}
|
||||
|
||||
public class LeaderboardCreatorConfig : ScriptableObject
|
||||
{
|
||||
public AuthSaveMode authSaveMode = AuthSaveMode.PlayerPrefs;
|
||||
public string fileName = "leaderboard-creator-guid.txt";
|
||||
public bool isUpdateLogsEnabled = true;
|
||||
|
||||
public TextAsset leaderboardsFile;
|
||||
#if UNITY_EDITOR
|
||||
public TextAsset editorOnlyLeaderboardsFile;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
3
Assets/LeaderboardCreator/Scripts/Utils/LeaderboardCreatorConfig.cs.meta
Executable file
3
Assets/LeaderboardCreator/Scripts/Utils/LeaderboardCreatorConfig.cs.meta
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f004774a7efa44eab4c0e289b68f484f
|
||||
timeCreated: 1693951769
|
||||
23
Assets/LeaderboardCreator/Scripts/Utils/Requests.cs
Executable file
23
Assets/LeaderboardCreator/Scripts/Utils/Requests.cs
Executable file
|
|
@ -0,0 +1,23 @@
|
|||
using System.Collections.Generic;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace Dan
|
||||
{
|
||||
internal static partial class Requests
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a form section and adds the parameters to it.
|
||||
/// </summary>
|
||||
/// <returns>IMultipartFormSection object</returns>
|
||||
public static IMultipartFormSection Field(string fieldName, string data) =>
|
||||
new MultipartFormDataSection(fieldName, data);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a form out of the given parameters.
|
||||
/// </summary>
|
||||
/// <param name="formDataSections"></param>
|
||||
/// <returns>A list of IMultipartFormSection objects</returns>
|
||||
public static List<IMultipartFormSection> Form(params IMultipartFormSection[] formDataSections) =>
|
||||
new List<IMultipartFormSection>(formDataSections);
|
||||
}
|
||||
}
|
||||
3
Assets/LeaderboardCreator/Scripts/Utils/Requests.cs.meta
Executable file
3
Assets/LeaderboardCreator/Scripts/Utils/Requests.cs.meta
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 82185ae765074638b9962f5fbb356776
|
||||
timeCreated: 1651554086
|
||||
1
Assets/LeaderboardCreator/leaderboards.json
Executable file
1
Assets/LeaderboardCreator/leaderboards.json
Executable file
|
|
@ -0,0 +1 @@
|
|||
{"leaderboards":[{"name":"YoumuLeaderboard","publicKey":"2b836767763cfa11c33d22e98dfbda369b0cb1eb2fc3f5418640676a518433d5","secretKey":"6bfc44d54e77b92f860e95eb9d50ed3b7a7cc51684037922cf1c4aaa3d4ad86c77f6af5cb7bdbe321f2ba2471c4b8e2c1cda300b2acdd9dbea0eae45be9160973e1cad6f76eff4c13601dd0be47ee890259be5c6d495daddf5d2e9df45bef5e5feb98017b2f0fc079a060b88b0824220f1279b2fc39806d927cce67ee9d0501c"}]}
|
||||
7
Assets/LeaderboardCreator/leaderboards.json.meta
Executable file
7
Assets/LeaderboardCreator/leaderboards.json.meta
Executable file
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5acfc3d506d9a854589cebec611a66e7
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Loading…
Add table
Add a link
Reference in a new issue