463 lines
15 KiB
C#
463 lines
15 KiB
C#
using System;
|
|
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using Newtonsoft.Json;
|
|
using UnityEngine;
|
|
using UnityEngine.Events;
|
|
using UnityEngine.Networking;
|
|
using System.Net;
|
|
using System.Net.Sockets;
|
|
public class DBmanager : MonoBehaviour
|
|
{
|
|
public static string phpRoot = "http://38.242.232.13/upf/";
|
|
|
|
public static string username = null;
|
|
|
|
private static float level = 0;
|
|
private static int xp = 0;
|
|
private static int coins = 0;
|
|
private static int gems = 0;
|
|
private static int metal = 0;
|
|
private static int oxygen = 0;
|
|
private static List<int> expPassCollected = new List<int>();
|
|
public static List<BuildingState> buildingStates = new List<BuildingState>();
|
|
public static UnityEvent OnStateChanged = new UnityEvent();
|
|
|
|
public static int Xp => xp;
|
|
public static int Coins => coins;
|
|
public static int Gems => gems;
|
|
public static int Metal => metal;
|
|
public static int Oxygen => oxygen;
|
|
public static float Level => level;
|
|
public static int LevelInt => Mathf.CeilToInt(level);
|
|
public static List<int> ExpPassCollected => expPassCollected;
|
|
|
|
|
|
public static bool LoggedIn { get { return username != null; } }
|
|
public static void LogOut()
|
|
{
|
|
username = null;
|
|
}
|
|
|
|
public static async Task<DateTime> GetNetworkTime()
|
|
{
|
|
int unixTime = 0;
|
|
using (UnityWebRequest www = UnityWebRequest.Get(phpRoot + "get_time.php"))
|
|
{
|
|
var operation = www.SendWebRequest();
|
|
while (!operation.isDone)
|
|
{
|
|
await Task.Yield();
|
|
}
|
|
try{
|
|
unixTime = int.Parse(www.downloadHandler.text);
|
|
}catch{
|
|
Debug.Log("Invalid response from server : " + www.downloadHandler.text);
|
|
}
|
|
}
|
|
|
|
if(unixTime> 0){
|
|
return DateTimeOffset.FromUnixTimeSeconds(unixTime).UtcDateTime;
|
|
}
|
|
|
|
//default Windows time server
|
|
const string ntpServer = "time.windows.com";
|
|
|
|
// NTP message size - 16 bytes of the digest (RFC 2030)
|
|
var ntpData = new byte[48];
|
|
|
|
//Setting the Leap Indicator, Version Number and Mode values
|
|
ntpData[0] = 0x1B; //LI = 0 (no warning), VN = 3 (IPv4 only), Mode = 3 (Client Mode)
|
|
|
|
var addresses = Dns.GetHostEntry(ntpServer).AddressList;
|
|
|
|
//The UDP port number assigned to NTP is 123
|
|
var ipEndPoint = new IPEndPoint(addresses[0], 123);
|
|
//NTP uses UDP
|
|
|
|
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
|
|
{
|
|
socket.Connect(ipEndPoint);
|
|
|
|
//Stops code hang if NTP is blocked
|
|
socket.ReceiveTimeout = 3000;
|
|
|
|
socket.Send(ntpData);
|
|
socket.Receive(ntpData);
|
|
socket.Close();
|
|
}
|
|
|
|
//Offset to get to the "Transmit Timestamp" field (time at which the reply
|
|
//departed the server for the client, in 64-bit timestamp format."
|
|
const byte serverReplyTime = 40;
|
|
|
|
//Get the seconds part
|
|
ulong intPart = BitConverter.ToUInt32(ntpData, serverReplyTime);
|
|
|
|
//Get the seconds fraction
|
|
ulong fractPart = BitConverter.ToUInt32(ntpData, serverReplyTime + 4);
|
|
|
|
//Convert From big-endian to little-endian
|
|
intPart = SwapEndianness(intPart);
|
|
fractPart = SwapEndianness(fractPart);
|
|
|
|
var milliseconds = (intPart * 1000) + ((fractPart * 1000) / 0x100000000L);
|
|
|
|
//**UTC** time
|
|
var networkDateTime = (new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc)).AddMilliseconds((long)milliseconds);
|
|
|
|
return networkDateTime.ToLocalTime();
|
|
}
|
|
|
|
|
|
static uint SwapEndianness(ulong x)
|
|
{
|
|
return (uint)(((x & 0x000000ff) << 24) +
|
|
((x & 0x0000ff00) << 8) +
|
|
((x & 0x00ff0000) >> 8) +
|
|
((x & 0xff000000) >> 24));
|
|
}
|
|
|
|
public async static Task SetXp(int newValue, bool justOffline = false)
|
|
{
|
|
WWWForm form = new WWWForm();
|
|
form.AddField("name", username);
|
|
form.AddField("xp", newValue);
|
|
if (justOffline) { xp = newValue; }
|
|
else
|
|
{
|
|
using (UnityWebRequest www = UnityWebRequest.Post(phpRoot + "set_xp.php", form))
|
|
{
|
|
var operation = www.SendWebRequest();
|
|
while (!operation.isDone)
|
|
{
|
|
await Task.Yield();
|
|
}
|
|
|
|
if (www.downloadHandler.text == "0")
|
|
{
|
|
xp = newValue;
|
|
// Debug
|
|
}
|
|
else
|
|
{
|
|
Debug.Log("Response : " + www.downloadHandler.text);
|
|
Debug.LogWarning("Failed to set xp to " + newValue);
|
|
}
|
|
}
|
|
}
|
|
|
|
// for(int i =0; i < xp / 100; i++){
|
|
// i
|
|
// }
|
|
|
|
level = (Mathf.Sqrt((float)Mathf.Clamp(xp,100,float.PositiveInfinity) / 100f));
|
|
if(level == LevelInt){
|
|
level-=0.1f;
|
|
}
|
|
Debug.Log("Level : " + (float)xp / 100f + " : " + level + " : " + LevelInt);
|
|
GameManagerInstance.gameManager.RefreshData();
|
|
OnStateChanged.Invoke();
|
|
}
|
|
|
|
public async static Task SetCoins(int newValue, bool justOffline = false)
|
|
{
|
|
WWWForm form = new WWWForm();
|
|
form.AddField("name", username);
|
|
form.AddField("coins", newValue);
|
|
coins = newValue;
|
|
if (justOffline) { return; }
|
|
using (UnityWebRequest www = UnityWebRequest.Post(phpRoot + "set_coins.php", form))
|
|
{
|
|
var operation = www.SendWebRequest();
|
|
while (!operation.isDone)
|
|
{
|
|
await Task.Yield();
|
|
}
|
|
|
|
if (www.downloadHandler.text == "0")
|
|
{
|
|
coins = newValue;
|
|
}
|
|
else
|
|
{
|
|
Debug.Log("Response : " + www.downloadHandler.text);
|
|
Debug.LogWarning("Failed to set coins to " + newValue);
|
|
}
|
|
}
|
|
|
|
GameManagerInstance.gameManager.RefreshData();
|
|
OnStateChanged.Invoke();
|
|
}
|
|
|
|
public async static void SetGems(int newValue, bool justOffline = false)
|
|
{
|
|
WWWForm form = new WWWForm();
|
|
form.AddField("name", username);
|
|
form.AddField("gems", newValue);
|
|
if (justOffline) { gems = newValue; return; }
|
|
using (UnityWebRequest www = UnityWebRequest.Post(phpRoot + "set_gems.php", form))
|
|
{
|
|
var operation = www.SendWebRequest();
|
|
while (!operation.isDone)
|
|
{
|
|
await Task.Yield();
|
|
}
|
|
|
|
if (www.downloadHandler.text == "0")
|
|
{
|
|
gems = newValue;
|
|
}
|
|
else
|
|
{
|
|
Debug.Log("Response : " + www.downloadHandler.text);
|
|
Debug.LogWarning("Failed to set gems to " + newValue);
|
|
}
|
|
}
|
|
|
|
GameManagerInstance.gameManager.RefreshData();
|
|
OnStateChanged.Invoke();
|
|
}
|
|
|
|
public async static void SetMetal(int newValue, bool justOffline = false)
|
|
{
|
|
WWWForm form = new WWWForm();
|
|
form.AddField("name", username);
|
|
form.AddField("metal", newValue);
|
|
if (justOffline) { metal = newValue; return; }
|
|
using (UnityWebRequest www = UnityWebRequest.Post(phpRoot + "set_metal.php", form))
|
|
{
|
|
var operation = www.SendWebRequest();
|
|
while (!operation.isDone)
|
|
{
|
|
await Task.Yield();
|
|
}
|
|
|
|
if (www.downloadHandler.text == "0")
|
|
{
|
|
metal = newValue;
|
|
}
|
|
else
|
|
{
|
|
Debug.Log("Response : " + www.downloadHandler.text);
|
|
Debug.LogWarning("Failed to set metal to " + newValue);
|
|
}
|
|
}
|
|
|
|
GameManagerInstance.gameManager.RefreshData();
|
|
OnStateChanged.Invoke();
|
|
}
|
|
|
|
public async static void SetOxygen(int newValue, bool justOffline = false)
|
|
{
|
|
WWWForm form = new WWWForm();
|
|
form.AddField("name", username);
|
|
form.AddField("oxygen", newValue);
|
|
if (justOffline) { oxygen = newValue; return; }
|
|
using (UnityWebRequest www = UnityWebRequest.Post(phpRoot + "set_oxygen.php", form))
|
|
{
|
|
var operation = www.SendWebRequest();
|
|
while (!operation.isDone)
|
|
{
|
|
await Task.Yield();
|
|
}
|
|
|
|
if (www.downloadHandler.text == "0")
|
|
{
|
|
oxygen = newValue;
|
|
}
|
|
else
|
|
{
|
|
Debug.Log("Response : " + www.downloadHandler.text);
|
|
Debug.LogWarning("Failed to set oxygen to " + newValue);
|
|
}
|
|
}
|
|
|
|
GameManagerInstance.gameManager.RefreshData();
|
|
OnStateChanged.Invoke();
|
|
}
|
|
|
|
public static void SetExpPassCollected(string rawData, bool justOffline = false)
|
|
{
|
|
try{
|
|
string[] data = rawData.Split(',');
|
|
expPassCollected = new List<int>();
|
|
foreach(string item in data){
|
|
try{
|
|
int itemVal = int.Parse(item);
|
|
expPassCollected.Add(itemVal);
|
|
}catch {
|
|
|
|
}
|
|
}
|
|
|
|
GameManagerInstance.gameManager.RefreshData();
|
|
OnStateChanged.Invoke();
|
|
}catch{
|
|
|
|
}
|
|
}
|
|
|
|
public async static void AddCollectedExpPass(int newPassLevel)
|
|
{
|
|
expPassCollected.Add(newPassLevel);
|
|
string output = "";
|
|
for(int i =0;i < expPassCollected.Count;i++){
|
|
output += expPassCollected[i].ToString();
|
|
if(i < expPassCollected.Count -1){
|
|
output += ",";
|
|
}
|
|
}
|
|
|
|
WWWForm form = new WWWForm();
|
|
form.AddField("name", username);
|
|
form.AddField("expPass", output);
|
|
using (UnityWebRequest www = UnityWebRequest.Post(phpRoot + "set_expPassCollected.php", form))
|
|
{
|
|
var operation = www.SendWebRequest();
|
|
while (!operation.isDone)
|
|
{
|
|
await Task.Yield();
|
|
}
|
|
|
|
if (www.downloadHandler.text == "0")
|
|
{
|
|
Debug.Log("Success updating ExpPassCollected");
|
|
}
|
|
else
|
|
{
|
|
Debug.Log("Response : " + www.downloadHandler.text);
|
|
Debug.LogWarning("Failed to set exp_pass_collected to " + output);
|
|
}
|
|
}
|
|
|
|
GameManagerInstance.gameManager.RefreshData();
|
|
OnStateChanged.Invoke();
|
|
}
|
|
|
|
public static bool GetBuildingStates(string rawData)
|
|
{
|
|
bool success = false;
|
|
//try{
|
|
|
|
buildingStates = JsonConvert.DeserializeObject<List<BuildingState>>(rawData);
|
|
Debug.Log("Updating buildings data, isNull: " + (buildingStates == null).ToString());
|
|
if (buildingStates == null)
|
|
{
|
|
buildingStates = new List<BuildingState>();
|
|
}
|
|
success = true;
|
|
// }catch(Exception e){
|
|
// Debug.LogError(e.Message+'\n' + e.StackTrace);
|
|
//
|
|
// Debug.LogError("Error updating buildings from server, Response:" + rawData);
|
|
// success=false;
|
|
// }
|
|
|
|
OnStateChanged.Invoke();
|
|
return success;
|
|
}
|
|
|
|
public async static Task AddBuilding(BuildingData buildingData)
|
|
{
|
|
|
|
foreach (BuildingState buildingState in buildingStates)
|
|
{
|
|
if (buildingState.id == buildingData.buildingName)
|
|
{
|
|
Debug.LogError("Building already exists. Cannot add " + buildingState.id);
|
|
return;
|
|
}
|
|
}
|
|
Debug.Log("adding new building " + buildingData.buildingName);
|
|
buildingStates.Add(new BuildingState(buildingData.buildingName, 0, Vector3.zero,await GetNetworkTime()));
|
|
Debug.Log("Added new building " + buildingData.buildingName);
|
|
await UpdateBuildingsToServer();
|
|
OnStateChanged.Invoke();
|
|
SetXp(xp + buildingData.levels[0].xpGain);
|
|
}
|
|
|
|
public async static Task UpgradeBuilding(string id, int newLevel)
|
|
{
|
|
for (int i = 0; i < buildingStates.Count; i++)
|
|
{
|
|
if (buildingStates[i].id == id)
|
|
{
|
|
buildingStates[i].level = newLevel;
|
|
Debug.Log("Upgrading " + id + " to " + newLevel);
|
|
break;
|
|
}
|
|
}
|
|
|
|
await UpdateBuildingsToServer();
|
|
|
|
OnStateChanged.Invoke();
|
|
}
|
|
|
|
|
|
public async static Task CollectBuilding(string id)
|
|
{
|
|
for (int i = 0; i < buildingStates.Count; i++)
|
|
{
|
|
if (buildingStates[i].id == id)
|
|
{
|
|
buildingStates[i].lastCollectedTimestamp = await GetNetworkTime();
|
|
Debug.Log("Setting " + id + " last collected to " + buildingStates[i].lastCollectedTimestamp);
|
|
break;
|
|
}
|
|
}
|
|
|
|
await UpdateBuildingsToServer();
|
|
|
|
OnStateChanged.Invoke();
|
|
}
|
|
|
|
public async static Task RelocateBuilding(string id, Vector3 newPosition)
|
|
{
|
|
for (int i = 0; i < buildingStates.Count; i++)
|
|
{
|
|
if (buildingStates[i].id == id)
|
|
{
|
|
buildingStates[i].position = newPosition;
|
|
Debug.Log("Relocating " + id + " to " + newPosition);
|
|
// break;
|
|
}
|
|
}
|
|
Debug.Log("Going to update to server" + JsonConvert.SerializeObject(buildingStates));
|
|
await UpdateBuildingsToServer();
|
|
|
|
OnStateChanged.Invoke();
|
|
}
|
|
|
|
public async static Task UpdateBuildingsToServer()
|
|
{
|
|
string buildingsJson = JsonConvert.SerializeObject(buildingStates);
|
|
Debug.Log(buildingsJson);
|
|
|
|
WWWForm form = new WWWForm();
|
|
form.AddField("name", username);
|
|
form.AddField("buildings", buildingsJson);
|
|
|
|
using (UnityWebRequest www = UnityWebRequest.Post(phpRoot + "set_buildings.php", form))
|
|
{
|
|
var operation = www.SendWebRequest();
|
|
while (!operation.isDone)
|
|
{
|
|
await Task.Yield();
|
|
}
|
|
|
|
if (www.downloadHandler.text == "0")
|
|
{
|
|
|
|
}
|
|
else
|
|
{
|
|
Debug.Log("Response : " + www.downloadHandler.text);
|
|
Debug.LogWarning("Failed to set buildings to " + buildingsJson);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|