PJ/Assets/scripts/UI/ServerClient.cs

287 lines
10 KiB
C#
Raw Permalink Normal View History

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();
}
}
}