287 lines
10 KiB
C#
287 lines
10 KiB
C#
|
|
using UnityEngine;
|
|||
|
|
using UnityEngine.Networking;
|
|||
|
|
using System.Collections;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using System.IO;
|
|||
|
|
using System;
|
|||
|
|
using TMPro;
|
|||
|
|
using UnityEngine.UI;
|
|||
|
|
|
|||
|
|
// Класс для десериализации данных от сервера
|
|||
|
|
[Serializable]
|
|||
|
|
public class LevelEntry
|
|||
|
|
{
|
|||
|
|
public string id; // Guid с сервера придет как строка
|
|||
|
|
public string name;
|
|||
|
|
public string hash;
|
|||
|
|
public string uploadDate;
|
|||
|
|
public string authorName;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//public class accountData
|
|||
|
|
// {
|
|||
|
|
// public Guid id;
|
|||
|
|
// public int CompleteLevels;
|
|||
|
|
// public int CompleteCenter;
|
|||
|
|
// public int CompleteRight;
|
|||
|
|
// public int CompleteLeft;
|
|||
|
|
// public List<int> CollectAchievements;
|
|||
|
|
// public List<int> HaveSword;
|
|||
|
|
// public List<int> HaveHead;
|
|||
|
|
// public List<int> HaveSkins;
|
|||
|
|
// public List<int> EntityKilled;
|
|||
|
|
// public List<int> OtherStat;
|
|||
|
|
// public List<int> HaveOther;
|
|||
|
|
// }
|
|||
|
|
[System.Serializable]
|
|||
|
|
public class account
|
|||
|
|
{
|
|||
|
|
public Guid id;
|
|||
|
|
public string name ;
|
|||
|
|
public int level ;
|
|||
|
|
public List<string> levels ;
|
|||
|
|
public int CompletedLevels ;
|
|||
|
|
public int HaveSkins ;//20
|
|||
|
|
public int HaveMoneys ;
|
|||
|
|
public string password ;
|
|||
|
|
public DateTime CreateDate ;
|
|||
|
|
public int HaveMetall ;
|
|||
|
|
public bool disabled ;
|
|||
|
|
public int status ;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Обертка для JSON-массива (Unity не умеет парсить чистые массивы через JsonUtility)
|
|||
|
|
[Serializable]
|
|||
|
|
public class LevelListWrapper
|
|||
|
|
{
|
|||
|
|
public List<LevelEntry> levels;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public class ServerClient : MonoBehaviour
|
|||
|
|
{
|
|||
|
|
public GameObject Canv;
|
|||
|
|
public List<Button> starts;
|
|||
|
|
public GameObject LevelOpener;
|
|||
|
|
public List<GameObject> Openers;
|
|||
|
|
public RectTransform LevelList;
|
|||
|
|
public List<Button.ButtonClickedEvent> Open;
|
|||
|
|
public List<Button> AuthorAcc;
|
|||
|
|
public List<Button> Delete;
|
|||
|
|
|
|||
|
|
public Image AuthIcon;
|
|||
|
|
public TMP_Text AuthName;
|
|||
|
|
public TMP_Text AuthLevelsCount;
|
|||
|
|
// public TransferScript TS;
|
|||
|
|
|
|||
|
|
void Start()
|
|||
|
|
{GetPublicLevels((levels) => {
|
|||
|
|
// Внутри этих скобок переменная 'data' — это и есть твой «просто лист»
|
|||
|
|
List<LevelEntry> myLocalList = levels;
|
|||
|
|
Debug.Log("Получили список из " + myLocalList.Count + " элементов");
|
|||
|
|
for(int i = 0; i < myLocalList.Count; i++)
|
|||
|
|
{
|
|||
|
|
print($"{levels[i].name}, {levels[i].hash}, {levels[i].id}");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for (int i = 0; i < myLocalList.Count; i++)
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
int num = i;
|
|||
|
|
Openers.Add(Instantiate(LevelOpener, LevelOpener.transform.parent));
|
|||
|
|
Openers[i].GetComponent<RectTransform>().position -= new Vector3(0, i * LevelOpener.GetComponent<RectTransform>().rect.height* Canv.transform.localScale.y*1.1f, 0);
|
|||
|
|
Openers[i].GetComponentsInChildren<TMP_Text>()[0].text = levels[i].name;
|
|||
|
|
Openers[i].GetComponentsInChildren<TMP_Text>()[1].text = levels[i].authorName;
|
|||
|
|
starts.Add(Openers[i].GetComponentInChildren<Button>());
|
|||
|
|
print(starts.IndexOf(starts[i]));
|
|||
|
|
Open.Add(new Button.ButtonClickedEvent { });
|
|||
|
|
Open[i].AddListener(() => DownloadLevel(levels[num].id));
|
|||
|
|
print(i);
|
|||
|
|
starts[i].onClick.AddListener(() => DownloadLevel(levels[num].id));
|
|||
|
|
AuthorAcc.Add(Openers[i].GetComponentsInChildren<Button>()[1]);
|
|||
|
|
AuthorAcc[i].onClick.AddListener(() => GetAuthor(levels[num].authorName));
|
|||
|
|
//Delete.Add(Openers[i].GetComponentsInChildren<Button>()[2]);
|
|||
|
|
//Delete[i].onClick.AddListener(() => Dellvl(levels[num].id));
|
|||
|
|
//upload.Add(Openers[i].transform.GetChild(1).GetComponent<Button>());
|
|||
|
|
//uplo.Add(new Button.ButtonClickedEvent { });
|
|||
|
|
//uplo[i].AddListener(() => Upl(num));
|
|||
|
|
//upload[i].onClick.AddListener(() => Upl(num));
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
LevelList.sizeDelta = new Vector2(0, myLocalList.Count * LevelOpener.GetComponent<RectTransform>().sizeDelta.y*1.1f);});
|
|||
|
|
}
|
|||
|
|
private string baseUrl = "http://mc1.live-on.pro:64096/api/levels/";
|
|||
|
|
void PlayOpen(string ID)
|
|||
|
|
{
|
|||
|
|
Buttons bb = new Buttons();
|
|||
|
|
print(ID);
|
|||
|
|
TransferScript TS = GameObject.Find("Tobj").GetComponent<TransferScript>();
|
|||
|
|
DontDestroyOnLoad(TS);
|
|||
|
|
TS.string1 = Application.persistentDataPath + "/" +ID;
|
|||
|
|
bb.OpenScene("ImportLevel");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
// --- 1. ЗАГРУЗКА (Твой существующий код, немного подправленный) ---
|
|||
|
|
public void SendLevelToServer(string filePath, string levelName, string fileHash, string existingId = null)
|
|||
|
|
{
|
|||
|
|
StartCoroutine(UploadRoutine(filePath, levelName, fileHash, existingId));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private IEnumerator UploadRoutine(string filePath, string levelName, string fileHash, string existingId)
|
|||
|
|
{
|
|||
|
|
if (!File.Exists(filePath)) yield break;
|
|||
|
|
|
|||
|
|
byte[] fileData = File.ReadAllBytes(filePath);
|
|||
|
|
WWWForm form = new WWWForm();
|
|||
|
|
form.AddBinaryData("file", fileData, Path.GetFileName(filePath), "application/octet-stream");
|
|||
|
|
form.AddField("name", levelName);
|
|||
|
|
form.AddField("hash", fileHash);
|
|||
|
|
|
|||
|
|
// Если мы обновляем старый уровень, передаем его ID
|
|||
|
|
if (!string.IsNullOrEmpty(existingId))
|
|||
|
|
form.AddField("existingId", existingId);
|
|||
|
|
|
|||
|
|
using (UnityWebRequest www = UnityWebRequest.Post(baseUrl + "upload", form))
|
|||
|
|
{
|
|||
|
|
yield return www.SendWebRequest();
|
|||
|
|
if (www.result == UnityWebRequest.Result.Success)
|
|||
|
|
Debug.Log("Уровень успешно на сервере: " + www.downloadHandler.text);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// --- 2. ПОЛУЧЕНИЕ СПИСКА (Для Игрока Б) ---
|
|||
|
|
public void GetPublicLevels(Action<List<LevelEntry>> callback)
|
|||
|
|
{
|
|||
|
|
StartCoroutine(GetLevelsRoutine(callback));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private IEnumerator GetLevelsRoutine(Action<List<LevelEntry>> callback)
|
|||
|
|
{
|
|||
|
|
using (UnityWebRequest www = UnityWebRequest.Get(baseUrl + "list"))
|
|||
|
|
{
|
|||
|
|
yield return www.SendWebRequest();
|
|||
|
|
|
|||
|
|
if (www.result == UnityWebRequest.Result.Success)
|
|||
|
|
{
|
|||
|
|
// Магия: превращаем [{},{}] в {"levels":[{},{}]} чтобы Unity понял
|
|||
|
|
string rawJson = www.downloadHandler.text;
|
|||
|
|
string processedJson = "{\"levels\":" + rawJson + "}";
|
|||
|
|
|
|||
|
|
LevelListWrapper wrapper = JsonUtility.FromJson<LevelListWrapper>(processedJson);
|
|||
|
|
callback?.Invoke(wrapper.levels);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
Debug.LogError("Не удалось получить список: " + www.error);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// --- 3. СКАЧИВАНИЕ ФАЙЛА (Для Игрока Б) ---
|
|||
|
|
public void DownloadLevel(string levelId)
|
|||
|
|
{
|
|||
|
|
StartCoroutine(DownloadRoutine(levelId));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private IEnumerator DownloadRoutine(string levelId)
|
|||
|
|
{
|
|||
|
|
string url = baseUrl + "download/" + levelId;
|
|||
|
|
// Путь, куда сохраняем на телефоне/ПК
|
|||
|
|
string savePath = Path.Combine(Application.persistentDataPath, levelId + ".lpjl");
|
|||
|
|
|
|||
|
|
using (UnityWebRequest www = UnityWebRequest.Get(url))
|
|||
|
|
{
|
|||
|
|
yield return www.SendWebRequest();
|
|||
|
|
|
|||
|
|
if (www.result == UnityWebRequest.Result.Success)
|
|||
|
|
{
|
|||
|
|
// Записываем байты в файл
|
|||
|
|
File.WriteAllBytes(savePath, www.downloadHandler.data);
|
|||
|
|
Debug.Log($"Уровень скачан и сохранен в: {savePath}");
|
|||
|
|
ServerClient SC = new ServerClient();
|
|||
|
|
SC.PlayOpen(levelId);
|
|||
|
|
// ТУТ ВЫЗЫВАЙ СВОЙ ИМПОРТ УРОВНЯ В ИГРУ
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
Debug.LogError("Ошибка при скачивании: " + www.error);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void Dellvl(string levelId)
|
|||
|
|
{
|
|||
|
|
StartCoroutine(DeleteLevel(levelId));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private IEnumerator DeleteLevel(string levelId)
|
|||
|
|
{
|
|||
|
|
string url = baseUrl + "delete/" + levelId;
|
|||
|
|
// Путь, куда сохраняем на телефоне/ПК
|
|||
|
|
|
|||
|
|
using (UnityWebRequest www = UnityWebRequest.Delete(url))
|
|||
|
|
{
|
|||
|
|
yield return www.SendWebRequest();
|
|||
|
|
|
|||
|
|
if (www.result == UnityWebRequest.Result.Success)
|
|||
|
|
{
|
|||
|
|
Debug.Log("Level deleted, id:" + levelId);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
Debug.LogError("Ошибка при удалении: " + www.error);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void SendAccountData(string filePath, string levelName, string fileHash, string existingId = null)
|
|||
|
|
{
|
|||
|
|
//accountData AD = new accountData;
|
|||
|
|
//AD.id =
|
|||
|
|
StartCoroutine(UploadRoutine(filePath, levelName, fileHash, existingId));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public IEnumerator UploadData(string filePath, string levelName, string fileHash, string existingId)
|
|||
|
|
{
|
|||
|
|
if (!File.Exists(filePath)) yield break;
|
|||
|
|
|
|||
|
|
byte[] fileData = File.ReadAllBytes(filePath);
|
|||
|
|
WWWForm form = new WWWForm();
|
|||
|
|
form.AddBinaryData("file", fileData, Path.GetFileName(filePath), "application/octet-stream");
|
|||
|
|
form.AddField("name", levelName);
|
|||
|
|
form.AddField("hash", fileHash);
|
|||
|
|
|
|||
|
|
// Если мы обновляем старый уровень, передаем его ID
|
|||
|
|
if (!string.IsNullOrEmpty(existingId))
|
|||
|
|
form.AddField("existingId", existingId);
|
|||
|
|
|
|||
|
|
using (UnityWebRequest www = UnityWebRequest.Post(baseUrl + "upload", form))
|
|||
|
|
{
|
|||
|
|
yield return www.SendWebRequest();
|
|||
|
|
if (www.result == UnityWebRequest.Result.Success)
|
|||
|
|
Debug.Log("Уровень успешно на сервере: " + www.downloadHandler.text);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
public void GetAuthor(string name)
|
|||
|
|
{
|
|||
|
|
StartCoroutine(GetA(name));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public IEnumerator GetA(string name)
|
|||
|
|
{
|
|||
|
|
string basetUrl = "http://mc1.live-on.pro:64096/api/accounts/GetA/";
|
|||
|
|
using(UnityWebRequest www = UnityWebRequest.Get(basetUrl + name))
|
|||
|
|
{
|
|||
|
|
yield return www.SendWebRequest();
|
|||
|
|
|
|||
|
|
string json = www.downloadHandler.text;
|
|||
|
|
print(json);
|
|||
|
|
account acc = JsonUtility.FromJson<account>(json);
|
|||
|
|
AuthName.text = acc.name;
|
|||
|
|
Debug.Log(acc.levels);
|
|||
|
|
AuthLevelsCount.text = (acc.levels.Count).ToString();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|