UPF/Assets/Game/Scripts/DBmanager.cs
2022-10-06 23:45:04 +05:30

912 lines
28 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://vmi1005083.contaboserver.net/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 trophies = 0;
private static int mostTime=0;
private static int doubleKills,tripleKills,quadKills,pentaKills = 0;
private static DateTime lastCollectedDailyChest;
private static List<InventoryEntry> inventory;
private static List<int> expPassCollected = new List<int>();
private static List<string> skinsPurchased = new List<string>();
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 Trophies => trophies;
public static int MostTime=> mostTime;
public static int DoubleKills => doubleKills;
public static int TripleKills => tripleKills;
public static int QuadKills => quadKills;
public static int PentaKills => pentaKills;
public static DateTime LastCollectedDailyChest => lastCollectedDailyChest;
public static float Level => level;
public static int LevelInt => Mathf.CeilToInt(level);
public static List<int> ExpPassCollected => expPassCollected;
public static List<InventoryEntry> Inventory => inventory;
public static List<string> SkinsPurchased => skinsPurchased;
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);
GameManager.Refresh();
OnStateChanged.Invoke();
}
public static int XpForNextLevel(){
int nextLevel = Mathf.CeilToInt(level);
return (nextLevel*nextLevel) * 100;
}
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);
}
}
GameManager.Refresh();
OnStateChanged.Invoke();
}
public async static void SetGems(int newValue, bool justOffline = false)
{
WWWForm form = new WWWForm();
form.AddField("name", username);
form.AddField("gems", newValue);
int oldVal = Gems;
gems = newValue;
if (justOffline) {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);
gems = oldVal;
}
}
GameManager.Refresh();
OnStateChanged.Invoke();
}
public async static void SetMetal(int newValue, bool justOffline = false)
{
WWWForm form = new WWWForm();
form.AddField("name", username);
form.AddField("metal", newValue);
int oldVal = metal;
metal = newValue;
if (justOffline) { 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;
Debug.Log("Metal updated on "+ username);
}
else
{
Debug.Log("Response : " + www.downloadHandler.text);
Debug.LogWarning("Failed to set metal to " + newValue);
metal = oldVal;
}
}
GameManager.Refresh();
OnStateChanged.Invoke();
}
public async static void SetTrophies(int newValue, bool justOffline = false)
{
WWWForm form = new WWWForm();
form.AddField("name", username);
form.AddField("trophies", newValue);
if (justOffline) { trophies = newValue; return; }
using (UnityWebRequest www = UnityWebRequest.Post(phpRoot + "set_trophies.php", form))
{
var operation = www.SendWebRequest();
while (!operation.isDone)
{
await Task.Yield();
}
if (www.downloadHandler.text == "0")
{
trophies = newValue;
}
else
{
Debug.Log("Response : " + www.downloadHandler.text);
Debug.LogWarning("Failed to set trophies to " + newValue);
}
}
GameManager.Refresh();
OnStateChanged.Invoke();
}
public async static void SetMostTime(int newValue, bool justOffline = false)
{
WWWForm form = new WWWForm();
form.AddField("name", username);
form.AddField("mostTime", newValue);
int oldValue = mostTime;
mostTime = newValue;
if (justOffline) { return; }
using (UnityWebRequest www = UnityWebRequest.Post(phpRoot + "set_mostTime.php", form))
{
var operation = www.SendWebRequest();
while (!operation.isDone)
{
await Task.Yield();
}
if (www.downloadHandler.text == "0")
{
}
else
{
mostTime = oldValue;
Debug.Log("Response : " + www.downloadHandler.text);
Debug.LogWarning("Failed to set most time to " + newValue);
}
}
GameManager.Refresh();
OnStateChanged.Invoke();
}
public async static void SetDoubleKills(int newValue, bool justOffline = false)
{
WWWForm form = new WWWForm();
form.AddField("name", username);
form.AddField("value", newValue);
int oldValue = doubleKills;
doubleKills = newValue;
if (justOffline) { return; }
using (UnityWebRequest www = UnityWebRequest.Post(phpRoot + "set_double_kills.php", form))
{
var operation = www.SendWebRequest();
while (!operation.isDone)
{
await Task.Yield();
}
if (www.downloadHandler.text == "0")
{
}
else
{
doubleKills = oldValue;
Debug.Log("Response : " + www.downloadHandler.text);
Debug.LogWarning("Failed to set double kills to " + newValue);
}
}
GameManager.Refresh();
OnStateChanged.Invoke();
}
public async static void SetTripleKills(int newValue, bool justOffline = false)
{
WWWForm form = new WWWForm();
form.AddField("name", username);
form.AddField("value", newValue);
int oldValue = tripleKills;
tripleKills = newValue;
if (justOffline) { return; }
using (UnityWebRequest www = UnityWebRequest.Post(phpRoot + "set_triple_kills.php", form))
{
var operation = www.SendWebRequest();
while (!operation.isDone)
{
await Task.Yield();
}
if (www.downloadHandler.text == "0")
{
}
else
{
tripleKills = oldValue;
Debug.Log("Response : " + www.downloadHandler.text);
Debug.LogWarning("Failed to set triple kills to " + newValue);
}
}
GameManager.Refresh();
OnStateChanged.Invoke();
}
public async static void SetQuadKills(int newValue, bool justOffline = false)
{
WWWForm form = new WWWForm();
form.AddField("name", username);
form.AddField("value", newValue);
int oldValue = quadKills;
quadKills = newValue;
if (justOffline) { return; }
using (UnityWebRequest www = UnityWebRequest.Post(phpRoot + "set_quad_kills.php", form))
{
var operation = www.SendWebRequest();
while (!operation.isDone)
{
await Task.Yield();
}
if (www.downloadHandler.text == "0")
{
}
else
{
quadKills = oldValue;
Debug.Log("Response : " + www.downloadHandler.text);
Debug.LogWarning("Failed to set quad kills to " + newValue);
}
}
GameManager.Refresh();
OnStateChanged.Invoke();
}
public async static void SetPentaKills(int newValue, bool justOffline = false)
{
WWWForm form = new WWWForm();
form.AddField("name", username);
form.AddField("value", newValue);
int oldValue = pentaKills;
pentaKills = newValue;
if (justOffline) { return; }
using (UnityWebRequest www = UnityWebRequest.Post(phpRoot + "set_penta_kills.php", form))
{
var operation = www.SendWebRequest();
while (!operation.isDone)
{
await Task.Yield();
}
if (www.downloadHandler.text == "0")
{
}
else
{
pentaKills = oldValue;
Debug.Log("Response : " + www.downloadHandler.text);
Debug.LogWarning("Failed to set penta kills to " + newValue);
}
}
GameManager.Refresh();
OnStateChanged.Invoke();
}
public async static void SetLastCollectedDailyChest(string newValue, bool justOffline = false)
{
WWWForm form = new WWWForm();
form.AddField("name", username);
form.AddField("value", newValue);
DateTime oldValue = lastCollectedDailyChest;
lastCollectedDailyChest = DateTime.Parse(newValue);
Debug.Log(newValue + ":"+lastCollectedDailyChest);
if (justOffline) { return; }
using (UnityWebRequest www = UnityWebRequest.Post(phpRoot + "set_daily_chest_collected.php", form))
{
var operation = www.SendWebRequest();
while (!operation.isDone)
{
await Task.Yield();
}
if (www.downloadHandler.text == "0")
{
}
else
{
lastCollectedDailyChest = oldValue;
Debug.Log("Response : " + www.downloadHandler.text);
Debug.LogWarning("Failed to set lastCollectedDailyChest to " + newValue);
}
}
GameManager.Refresh();
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
{
}
}
GameManager.Refresh();
OnStateChanged.Invoke();
}
catch
{
}
}
public static void SetPurchasedSkins(string data){
skinsPurchased= new List<string>();
string[] skins = data.Split(',');
foreach(string skin in skins){
skinsPurchased.Add(skin);
}
}
public static void PurchaseSkin(SkinShopItemData data){
if(metal < data.price){
return;
}
SetMetal(metal-data.price);
AddSkin(data);
AudioManager.instnace.Spend();
}
public static void AddSkin(SkinShopItemData data){
skinsPurchased.Add(data.name);
UpdatePurchasedSkins();
}
public async static void UpdatePurchasedSkins(){
string output ="";
foreach(string skin in skinsPurchased){
if(skin.Length==0){continue;}
output += skin +",";
}
if(output.Length>0){output = output.Substring(0,output.Length-1);} // <-- Removes the last ','
WWWForm form = new WWWForm();
form.AddField("name", username);
form.AddField("skins", output);
using (UnityWebRequest www = UnityWebRequest.Post(phpRoot + "set_skins_purchased.php", form))
{
var operation = www.SendWebRequest();
while (!operation.isDone)
{
await Task.Yield();
}
if (www.downloadHandler.text == "0")
{
Debug.Log("Success updating PurchasedSkins");
}
else
{
Debug.Log("Response : " + www.downloadHandler.text);
Debug.LogWarning("Failed to set PurchasedSkins to " + output);
}
}
GameManager.Refresh();
OnStateChanged.Invoke();
}
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);
}
}
GameManager.Refresh();
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);
}
}
}
public static bool GetInventoryFromServer(string rawJson)
{
// try{
inventory = JsonConvert.DeserializeObject<List<InventoryEntry>>(rawJson);
// }catch{
// inventory = null;
// }
if(inventory==null){
Debug.Log("Failed to set inventory, server said : " + rawJson);
inventory= new List<InventoryEntry>();
}
return true;
}
public async static void AddInventoryItem(InventoryItem item)
{
bool exists = false;
if(inventory==null){inventory = new List<InventoryEntry>();}
foreach(InventoryEntry entry in inventory){
if(entry.Item == item.itemName){
entry.Count++;
exists=true;
break;
}
}
if(!exists){
inventory.Add(new InventoryEntry(item.itemName,1));
}
await UpdateInventoryToServer();
OnStateChanged.Invoke();
}
public async static void RemoveInventoryItem(string item)
{
List<InventoryEntry> temp_inventory = inventory;
inventory = new List<InventoryEntry>();
foreach(InventoryEntry entry in temp_inventory){
if(entry.Item == item){continue;}
inventory.Add(entry);
}
if(inventory.Count == temp_inventory.Count){Debug.LogError("No item was removed from inventory");}
await UpdateInventoryToServer();
OnStateChanged.Invoke();
}
public async static Task UpdateInventoryToServer()
{
string inventoryJson = JsonConvert.SerializeObject(inventory);
Debug.Log(inventoryJson);
WWWForm form = new WWWForm();
form.AddField("name", username);
form.AddField("inventory", inventoryJson);
using (UnityWebRequest www = UnityWebRequest.Post(phpRoot + "set_inventory.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 inventory to " + inventoryJson);
}
}
}
public async static Task SellItem(string item, int coins_amount, int gems_amount, int metals_amount, int oxygen_amount){
//Insert new trade entry to server
WWWForm form = new WWWForm();
form.AddField("name", username);
form.AddField("item", item);
form.AddField("coins", coins_amount);
form.AddField("gems", gems_amount);
form.AddField("metals", metals_amount);
form.AddField("oxygen", oxygen_amount);
using (UnityWebRequest www = UnityWebRequest.Post(phpRoot + "add_trade.php", form))
{
var operation = www.SendWebRequest();
while (!operation.isDone)
{
await Task.Yield();
}
if (www.downloadHandler.text == "0")
{
RemoveInventoryItem(item);
}
else
{
Debug.Log("Response : " + www.downloadHandler.text);
Debug.LogWarning("Failed to add trade entry");
}
}
OnStateChanged.Invoke();
}
public async static Task<List<LeaderboardUserData>> GetLeaderboard()
{
WWWForm form = new WWWForm();
List<LeaderboardUserData> leaderboard = new List<LeaderboardUserData>();
using (UnityWebRequest www = UnityWebRequest.Post(phpRoot + "get_leaderboard.php", form))
{
var operation = www.SendWebRequest();
while (!operation.isDone)
{
await Task.Yield();
}
try{
string[] split = {"<td>"};
string[] players = www.downloadHandler.text.Split(split, StringSplitOptions.RemoveEmptyEntries);
foreach(string player in players){
leaderboard.Add(JsonConvert.DeserializeObject<LeaderboardUserData>(player));
}
}catch{
Debug.Log("Failed fetching Leaderboard");
Debug.Log("Response : " + www.downloadHandler.text);
}
}
return leaderboard;
}
}
public class LeaderboardUserData{
public string username;
public int trophies;
public int position;
}