init
This commit is contained in:
310
Assets/TcgEngine/Scripts/Tools/AudioTool.cs
Normal file
310
Assets/TcgEngine/Scripts/Tools/AudioTool.cs
Normal file
@@ -0,0 +1,310 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TcgEngine
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Main audio script, allow to play sounds by channel
|
||||
/// </summary>
|
||||
|
||||
public class AudioTool : MonoBehaviour
|
||||
{
|
||||
private static AudioTool instance;
|
||||
|
||||
private Dictionary<string, AudioSource> channels_sfx = new Dictionary<string, AudioSource>();
|
||||
private Dictionary<string, AudioSource> channels_music = new Dictionary<string, AudioSource>();
|
||||
private Dictionary<string, float> channels_volume = new Dictionary<string, float>();
|
||||
private Dictionary<string, float> tchannels_volume = new Dictionary<string, float>();
|
||||
|
||||
[HideInInspector] public float master_vol = 1f;
|
||||
[HideInInspector] public float sfx_vol = 1f;
|
||||
[HideInInspector] public float music_vol = 1f;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
LoadPrefs();
|
||||
RefreshVolume();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
foreach (KeyValuePair<string, AudioSource> pair in channels_music)
|
||||
{
|
||||
if (pair.Value.isPlaying)
|
||||
{
|
||||
float tvol = tchannels_volume[pair.Key];
|
||||
float vol = channels_volume[pair.Key];
|
||||
vol = Mathf.MoveTowards(vol, tvol, 0.5f * Time.deltaTime);
|
||||
channels_volume[pair.Key] = vol;
|
||||
pair.Value.volume = vol * music_vol;
|
||||
|
||||
if (vol < 0.01f && tvol < 0.01f)
|
||||
StopMusic(pair.Key);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<string, AudioSource> pair in channels_sfx)
|
||||
{
|
||||
if (pair.Value.isPlaying)
|
||||
{
|
||||
float tvol = tchannels_volume[pair.Key];
|
||||
float vol = channels_volume[pair.Key];
|
||||
vol = Mathf.MoveTowards(vol, tvol, 0.5f * Time.deltaTime);
|
||||
channels_volume[pair.Key] = vol;
|
||||
pair.Value.volume = vol * sfx_vol;
|
||||
|
||||
if (vol < 0.01f && tvol < 0.01f)
|
||||
StopSFX(pair.Key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//channel: Two sounds on the same channel will never play at the same time, sounds on different channel will play at the same time.
|
||||
//priority: if false, will not play if a sound is already playing on the channel, if true, will replace current sound playing on channel
|
||||
public void PlaySFX(string channel, AudioClip sound, float vol = 0.6f, bool priority = true, bool loop = false)
|
||||
{
|
||||
if (string.IsNullOrEmpty(channel) || sound == null)
|
||||
return;
|
||||
|
||||
AudioSource source = GetChannel(channel);
|
||||
channels_volume[channel] = vol;
|
||||
tchannels_volume[channel] = vol;
|
||||
|
||||
if (source == null)
|
||||
{
|
||||
source = CreateChannel(channel);
|
||||
channels_sfx[channel] = source;
|
||||
}
|
||||
|
||||
if (source != null)
|
||||
{
|
||||
if (priority || !source.isPlaying)
|
||||
{
|
||||
source.clip = sound;
|
||||
source.volume = vol * sfx_vol;
|
||||
source.loop = loop;
|
||||
source.Play();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//channel: Two sounds on the same channel will never play at the same time, sounds on different channel will play at the same time.
|
||||
//If music is already playing on the same channel, new music will be played unless its the same one.(Won't restart in that case)
|
||||
public void PlayMusic(string channel, AudioClip music, float vol = 0.3f, bool loop = true)
|
||||
{
|
||||
if (string.IsNullOrEmpty(channel) || music == null)
|
||||
return;
|
||||
|
||||
AudioSource source = GetMusicChannel(channel);
|
||||
channels_volume[channel] = vol;
|
||||
tchannels_volume[channel] = vol;
|
||||
|
||||
if (source == null)
|
||||
{
|
||||
source = CreateChannel(channel);
|
||||
channels_music[channel] = source;
|
||||
}
|
||||
|
||||
if (source != null)
|
||||
{
|
||||
if (!source.isPlaying || source.clip != music)
|
||||
{
|
||||
source.clip = music;
|
||||
source.volume = vol * music_vol;
|
||||
source.loop = loop;
|
||||
source.Play();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Same as PlaySFX but takes random audio in array
|
||||
public void PlaySFX(string channel, AudioClip[] sounds, float vol = 0.6f, bool priority = true, bool loop = false)
|
||||
{
|
||||
if (sounds != null && sounds.Length > 0)
|
||||
{
|
||||
AudioClip sound = sounds[Random.Range(0, sounds.Length)];
|
||||
PlaySFX(channel, sound, vol, priority, loop);
|
||||
}
|
||||
}
|
||||
|
||||
//Same as PlayMusic but takes random audio in array
|
||||
public void PlayMusic(string channel, AudioClip[] musics, float vol = 0.6f, bool loop = false)
|
||||
{
|
||||
if (musics != null && musics.Length > 0)
|
||||
{
|
||||
AudioClip music = musics[Random.Range(0, musics.Length)];
|
||||
PlayMusic(channel, music, vol, loop);
|
||||
}
|
||||
}
|
||||
|
||||
public void StopSFX(string channel)
|
||||
{
|
||||
if (string.IsNullOrEmpty(channel))
|
||||
return;
|
||||
|
||||
AudioSource source = GetChannel(channel);
|
||||
if (source)
|
||||
{
|
||||
source.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
public void StopMusic(string channel)
|
||||
{
|
||||
if (string.IsNullOrEmpty(channel))
|
||||
return;
|
||||
|
||||
AudioSource source = GetMusicChannel(channel);
|
||||
if (source)
|
||||
{
|
||||
source.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
public void FadeOutMusic(string channel)
|
||||
{
|
||||
if (tchannels_volume.ContainsKey(channel))
|
||||
tchannels_volume[channel] = 0f;
|
||||
}
|
||||
|
||||
public void FadeOutSFX(string channel)
|
||||
{
|
||||
if (tchannels_volume.ContainsKey(channel))
|
||||
tchannels_volume[channel] = 0f;
|
||||
}
|
||||
|
||||
public void SetMasterVolume(float value)
|
||||
{
|
||||
master_vol = value;
|
||||
RefreshVolume();
|
||||
SavePrefs();
|
||||
}
|
||||
|
||||
public void SetMusicVolume(float value)
|
||||
{
|
||||
music_vol = value;
|
||||
RefreshVolume();
|
||||
SavePrefs();
|
||||
}
|
||||
|
||||
public void SetSFXVolume(float value)
|
||||
{
|
||||
sfx_vol = value;
|
||||
RefreshVolume();
|
||||
SavePrefs();
|
||||
}
|
||||
|
||||
public void LoadPrefs()
|
||||
{
|
||||
master_vol = PlayerPrefs.GetFloat("audio_master_volume", 1f);
|
||||
music_vol = PlayerPrefs.GetFloat("audio_music_volume", 1f);
|
||||
sfx_vol = PlayerPrefs.GetFloat("audio_sfx_volume", 1f);
|
||||
}
|
||||
|
||||
public void SavePrefs()
|
||||
{
|
||||
PlayerPrefs.SetFloat("audio_master_volume", master_vol);
|
||||
PlayerPrefs.SetFloat("audio_music_volume", music_vol);
|
||||
PlayerPrefs.SetFloat("audio_sfx_volume", sfx_vol);
|
||||
}
|
||||
|
||||
public void RefreshVolume()
|
||||
{
|
||||
|
||||
AudioListener.volume = master_vol;
|
||||
|
||||
foreach (KeyValuePair<string, AudioSource> pair in channels_sfx)
|
||||
{
|
||||
if (pair.Value != null)
|
||||
{
|
||||
float vol = channels_volume.ContainsKey(pair.Key) ? channels_volume[pair.Key] : 0.8f;
|
||||
pair.Value.volume = vol * sfx_vol;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<string, AudioSource> pair in channels_music)
|
||||
{
|
||||
if (pair.Value != null)
|
||||
{
|
||||
float vol = channels_volume.ContainsKey(pair.Key) ? channels_volume[pair.Key] : 0.4f;
|
||||
pair.Value.volume = vol * music_vol;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsMusicPlaying(string channel)
|
||||
{
|
||||
AudioSource source = GetMusicChannel(channel);
|
||||
if (source != null)
|
||||
return source.isPlaying;
|
||||
return false;
|
||||
}
|
||||
|
||||
public AudioSource CreateChannel(string channel, int priority = 128)
|
||||
{
|
||||
if (string.IsNullOrEmpty(channel))
|
||||
return null;
|
||||
|
||||
GameObject cobj = new GameObject("AudioChannel-" + channel);
|
||||
cobj.transform.SetParent(transform);
|
||||
AudioSource caudio = cobj.AddComponent<AudioSource>();
|
||||
caudio.playOnAwake = false;
|
||||
caudio.loop = false;
|
||||
caudio.priority = priority;
|
||||
return caudio;
|
||||
}
|
||||
|
||||
public AudioSource GetChannel(string channel)
|
||||
{
|
||||
if (channels_sfx.ContainsKey(channel))
|
||||
return channels_sfx[channel];
|
||||
return null;
|
||||
}
|
||||
|
||||
public AudioSource GetMusicChannel(string channel)
|
||||
{
|
||||
if (channels_music.ContainsKey(channel))
|
||||
return channels_music[channel];
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool DoesChannelExist(string channel)
|
||||
{
|
||||
return channels_sfx.ContainsKey(channel);
|
||||
}
|
||||
|
||||
public bool DoesMusicChannelExist(string channel)
|
||||
{
|
||||
return channels_music.ContainsKey(channel);
|
||||
}
|
||||
|
||||
public float GetMasterVolume()
|
||||
{
|
||||
return master_vol;
|
||||
}
|
||||
|
||||
public float GetSFXVolume()
|
||||
{
|
||||
return sfx_vol;
|
||||
}
|
||||
|
||||
public float GetMusicVolume()
|
||||
{
|
||||
return music_vol;
|
||||
}
|
||||
|
||||
public static AudioTool Get()
|
||||
{
|
||||
if (instance == null)
|
||||
{
|
||||
GameObject audio_system = new GameObject("AudioSystem");
|
||||
instance = audio_system.AddComponent<AudioTool>();
|
||||
DontDestroyOnLoad(audio_system);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
11
Assets/TcgEngine/Scripts/Tools/AudioTool.cs.meta
Normal file
11
Assets/TcgEngine/Scripts/Tools/AudioTool.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3ec345907b756324a859656ac2445bb1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
118
Assets/TcgEngine/Scripts/Tools/CameraResize.cs
Normal file
118
Assets/TcgEngine/Scripts/Tools/CameraResize.cs
Normal file
@@ -0,0 +1,118 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace TcgEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// Script that will resize the camera frame to a supported aspect ratio
|
||||
/// By default: only 16/9 and 16/10 are supported
|
||||
/// Black bars will appear on the side if the window is different
|
||||
/// </summary>
|
||||
|
||||
[RequireComponent(typeof(Camera))]
|
||||
public class CameraResize : MonoBehaviour
|
||||
{
|
||||
private Camera cam;
|
||||
private int sheight;
|
||||
private int swidth;
|
||||
|
||||
void Start()
|
||||
{
|
||||
cam = GetComponent<Camera>();
|
||||
sheight = Screen.height;
|
||||
swidth = Screen.width;
|
||||
UpdateSize();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (sheight != Screen.height || swidth != Screen.width)
|
||||
{
|
||||
sheight = Screen.height;
|
||||
swidth = Screen.width;
|
||||
UpdateSize();
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateSize()
|
||||
{
|
||||
float screenRatio = Screen.width / (float)Screen.height;
|
||||
float targetRatio = GetAspectRatio();
|
||||
|
||||
if (Mathf.Approximately(screenRatio, targetRatio))
|
||||
{
|
||||
// Screen or window is the target aspect ratio: use the whole area.
|
||||
cam.rect = new Rect(0, 0, 1, 1);
|
||||
}
|
||||
else if (screenRatio > targetRatio)
|
||||
{
|
||||
// Screen or window is wider than the target: pillarbox.
|
||||
float normalizedWidth = targetRatio / screenRatio;
|
||||
float barThickness = (1f - normalizedWidth) / 2f;
|
||||
cam.rect = new Rect(barThickness, 0, normalizedWidth, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Screen or window is narrower than the target: letterbox.
|
||||
float normalizedHeight = screenRatio / targetRatio;
|
||||
float barThickness = (1f - normalizedHeight) / 2f;
|
||||
cam.rect = new Rect(0, barThickness, 1, normalizedHeight);
|
||||
}
|
||||
|
||||
/*if (TheGame.IsMobile())
|
||||
{
|
||||
float size_min = GetCamSizeMin();
|
||||
float size_max = GetCamSizeMax();
|
||||
float value = GetAspectValue();
|
||||
float cam_size = value * size_min + (1f - value) * size_max;
|
||||
cam.orthographicSize = cam_size;
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
public static float GetAspectMin()
|
||||
{
|
||||
float min = 16f / 10f;
|
||||
return min;
|
||||
}
|
||||
|
||||
public static float GetAspectMax()
|
||||
{
|
||||
//bool allow_wide = TheGame.IsMobile() && TheGame.Get() != null;
|
||||
//float max = allow_wide ? 16f / 8f : 16f / 9f;
|
||||
float max = 16f / 9f;
|
||||
return max;
|
||||
}
|
||||
|
||||
public static float GetCamSizeMin()
|
||||
{
|
||||
//bool allow_wide = TheGame.IsMobile() && TheGame.Get() != null;
|
||||
//float max = allow_wide ? 4.2f : 4.5f;
|
||||
float max = 4.5f;
|
||||
return max;
|
||||
}
|
||||
|
||||
public static float GetCamSizeMax()
|
||||
{
|
||||
return 5f;
|
||||
}
|
||||
|
||||
public static float GetAspectRatio()
|
||||
{
|
||||
float max = GetAspectMax();
|
||||
float min = GetAspectMin();
|
||||
float screenRatio = Screen.width / (float)Screen.height;
|
||||
float targetRatio = Mathf.Clamp(screenRatio, min, max);
|
||||
return targetRatio;
|
||||
}
|
||||
|
||||
public static float GetAspectValue()
|
||||
{
|
||||
float max = GetAspectMax();
|
||||
float min = GetAspectMin();
|
||||
float aspect = GetAspectRatio();
|
||||
float value = (aspect - min) / (max - min);
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
11
Assets/TcgEngine/Scripts/Tools/CameraResize.cs.meta
Normal file
11
Assets/TcgEngine/Scripts/Tools/CameraResize.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0c9675c727e674447b6539e68147881e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
86
Assets/TcgEngine/Scripts/Tools/CardExporter.cs
Normal file
86
Assets/TcgEngine/Scripts/Tools/CardExporter.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using TcgEngine.UI;
|
||||
|
||||
namespace TcgEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// Use this export all your cards to png images (so they have the stats/ui on top of the card)
|
||||
/// </summary>
|
||||
|
||||
public class CardExporter : MonoBehaviour
|
||||
{
|
||||
public string export_path = "C:/CardsExport";
|
||||
public int width = 856;
|
||||
public int height = 1200;
|
||||
public VariantData variant;
|
||||
|
||||
[Header("References")]
|
||||
public Camera render_cam;
|
||||
public CardUI card_ui;
|
||||
|
||||
private RenderTexture texture;
|
||||
private Texture2D export_texture;
|
||||
|
||||
void Start()
|
||||
{
|
||||
if (variant == null)
|
||||
variant = VariantData.GetDefault();
|
||||
|
||||
GenerateAll();
|
||||
}
|
||||
|
||||
private async void GenerateAll()
|
||||
{
|
||||
QualitySettings.SetQualityLevel(QualitySettings.names.Length -1); //Set Max Quality level
|
||||
|
||||
texture = new RenderTexture(width, height, 0, RenderTextureFormat.ARGB32);
|
||||
export_texture = new Texture2D(width, height, TextureFormat.ARGB32, false);
|
||||
texture.filterMode = FilterMode.Point;
|
||||
export_texture.filterMode = FilterMode.Point;
|
||||
render_cam.targetTexture = texture;
|
||||
render_cam.orthographicSize = height / 2;
|
||||
|
||||
List<CardData> cards = CardData.GetAll();
|
||||
for (int i = 0; i < cards.Count; i++)
|
||||
{
|
||||
CardData card = cards[i];
|
||||
if (card.deckbuilding)
|
||||
{
|
||||
ShowText("Exporting: " + card.id);
|
||||
GenerateCard(card);
|
||||
await TimeTool.Delay(1);
|
||||
ExportCard(card);
|
||||
await TimeTool.Delay(2);
|
||||
}
|
||||
}
|
||||
|
||||
ShowText("Completed!");
|
||||
}
|
||||
|
||||
private void GenerateCard(CardData card)
|
||||
{
|
||||
card_ui.SetCard(card, variant);
|
||||
render_cam.Render();
|
||||
}
|
||||
|
||||
private void ExportCard(CardData card)
|
||||
{
|
||||
RenderTexture.active = texture;
|
||||
export_texture.ReadPixels(new Rect(0, 0, width, height), 0, 0);
|
||||
byte[] bytes = export_texture.EncodeToPNG();
|
||||
string file = card.id + ".png";
|
||||
File.WriteAllBytes(export_path + "/" + file, bytes);
|
||||
RenderTexture.active = null;
|
||||
}
|
||||
|
||||
private void ShowText(string txt)
|
||||
{
|
||||
Debug.Log(txt);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/TcgEngine/Scripts/Tools/CardExporter.cs.meta
Normal file
11
Assets/TcgEngine/Scripts/Tools/CardExporter.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 39f2a5200b7a2ba43a1233b77905c246
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
489
Assets/TcgEngine/Scripts/Tools/CardUploader.cs
Normal file
489
Assets/TcgEngine/Scripts/Tools/CardUploader.cs
Normal file
@@ -0,0 +1,489 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace TcgEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// Use this tool to upload your cards, packs and rewards to the Mongo Database (it will overwrite existing data)
|
||||
/// </summary>
|
||||
|
||||
public class CardUploader : MonoBehaviour
|
||||
{
|
||||
public string username = "admin";
|
||||
|
||||
[Header("References")]
|
||||
public InputField username_txt;
|
||||
public InputField password_txt;
|
||||
public Text msg_text;
|
||||
|
||||
[Header("Upload")]
|
||||
public bool upload_cards = true;
|
||||
public bool upload_packs = true;
|
||||
public bool upload_decks = true;
|
||||
public bool upload_variants = true;
|
||||
public bool upload_rewards = true;
|
||||
|
||||
void Start()
|
||||
{
|
||||
username_txt.text = username;
|
||||
msg_text.text = "";
|
||||
}
|
||||
|
||||
private async void Login()
|
||||
{
|
||||
LoginResponse res = await ApiClient.Get().Login(username_txt.text, password_txt.text);
|
||||
if (res.success && res.permission_level >= 10)
|
||||
{
|
||||
UploadAll();
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowText("Admin Login Failed");
|
||||
}
|
||||
}
|
||||
|
||||
private async void UploadAll()
|
||||
{
|
||||
//Delete previous data
|
||||
ShowText("Deleting previous data...");
|
||||
|
||||
if(upload_packs)
|
||||
await DeleteAllPacks();
|
||||
if (upload_cards)
|
||||
await DeleteAllCards();
|
||||
if (upload_variants)
|
||||
await DeleteAllVariants();
|
||||
if (upload_decks)
|
||||
await DeleteAllDecks();
|
||||
if (upload_rewards)
|
||||
await DeleteAllRewards();
|
||||
|
||||
//Packs
|
||||
if (upload_packs)
|
||||
{
|
||||
List<PackData> packs = PackData.GetAll();
|
||||
for (int i = 0; i < packs.Count; i++)
|
||||
{
|
||||
PackData pack = packs[i];
|
||||
if (pack.available)
|
||||
{
|
||||
ShowText("Uploading Packs: " + pack.id);
|
||||
UploadPack(pack);
|
||||
await TimeTool.Delay(100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Cards
|
||||
if (upload_cards)
|
||||
{
|
||||
List<CardData> cards = CardData.GetAll();
|
||||
for (int i = 0; i < cards.Count; i += 100)
|
||||
{
|
||||
List<CardData> list = GetCardGroup(cards, i, 100);
|
||||
ShowText("Uploading Cards: " + i + "-" + (i + 100 - 1));
|
||||
UploadCardList(list);
|
||||
await TimeTool.Delay(200);
|
||||
}
|
||||
}
|
||||
|
||||
//Variants
|
||||
if (upload_variants)
|
||||
{
|
||||
List<VariantData> variants = VariantData.GetAll();
|
||||
for (int i = 0; i < variants.Count; i++)
|
||||
{
|
||||
VariantData variant = variants[i];
|
||||
ShowText("Uploading Variant: " + variant.id);
|
||||
UploadVariant(variant);
|
||||
await TimeTool.Delay(100);
|
||||
}
|
||||
}
|
||||
|
||||
//Starter Decks
|
||||
if (upload_decks)
|
||||
{
|
||||
DeckData[] decks = GameplayData.Get().starter_decks;
|
||||
for (int i = 0; i < decks.Length; i++)
|
||||
{
|
||||
DeckData deck = decks[i];
|
||||
ShowText("Uploading Deck: " + deck.id);
|
||||
UploadDeck(deck);
|
||||
UploadDeckReward(deck);
|
||||
await TimeTool.Delay(100);
|
||||
}
|
||||
}
|
||||
|
||||
//Solo rewards
|
||||
if (upload_rewards)
|
||||
{
|
||||
List<LevelData> levels = LevelData.GetAll();
|
||||
for (int i = 0; i < levels.Count; i++)
|
||||
{
|
||||
LevelData level = levels[i];
|
||||
ShowText("Uploading Reward: " + level.id);
|
||||
UploadLevelReward(level);
|
||||
|
||||
if (level.reward_decks != null)
|
||||
{
|
||||
foreach (DeckData deck in level.reward_decks)
|
||||
UploadDeck(deck);
|
||||
}
|
||||
|
||||
await TimeTool.Delay(100);
|
||||
}
|
||||
}
|
||||
|
||||
//Custom rewards
|
||||
if (upload_rewards)
|
||||
{
|
||||
List<RewardData> rewards = RewardData.GetAll();
|
||||
for (int i = 0; i < rewards.Count; i++)
|
||||
{
|
||||
RewardData reward = rewards[i];
|
||||
ShowText("Uploading Reward: " + reward.id);
|
||||
UploadReward(reward);
|
||||
|
||||
foreach (DeckData deck in reward.decks)
|
||||
UploadDeck(deck);
|
||||
|
||||
await TimeTool.Delay(100);
|
||||
}
|
||||
}
|
||||
|
||||
ShowText("Completed!");
|
||||
ApiClient.Get().Logout();
|
||||
}
|
||||
|
||||
private async Task DeleteAllPacks()
|
||||
{
|
||||
string url = ApiClient.ServerURL + "/packs";
|
||||
await ApiClient.Get().SendRequest(url, WebRequest.METHOD_DELETE);
|
||||
}
|
||||
|
||||
private async Task DeleteAllCards()
|
||||
{
|
||||
string url = ApiClient.ServerURL + "/cards";
|
||||
await ApiClient.Get().SendRequest(url, WebRequest.METHOD_DELETE);
|
||||
}
|
||||
|
||||
private async Task DeleteAllVariants()
|
||||
{
|
||||
string url = ApiClient.ServerURL + "/variants";
|
||||
await ApiClient.Get().SendRequest(url, WebRequest.METHOD_DELETE);
|
||||
}
|
||||
|
||||
private async Task DeleteAllDecks()
|
||||
{
|
||||
string url = ApiClient.ServerURL + "/decks";
|
||||
await ApiClient.Get().SendRequest(url, WebRequest.METHOD_DELETE);
|
||||
}
|
||||
|
||||
private async Task DeleteAllRewards()
|
||||
{
|
||||
string url = ApiClient.ServerURL + "/rewards";
|
||||
await ApiClient.Get().SendRequest(url, WebRequest.METHOD_DELETE);
|
||||
}
|
||||
|
||||
private async void UploadPack(PackData pack)
|
||||
{
|
||||
PackAddRequest req = new PackAddRequest();
|
||||
req.tid = pack.id;
|
||||
req.cards = pack.cards;
|
||||
req.cost = pack.cost;
|
||||
req.random = pack.type == PackType.Random;
|
||||
|
||||
req.rarities_1st = new PackAddProbability[pack.rarities_1st.Length];
|
||||
req.rarities = new PackAddProbability[pack.rarities.Length];
|
||||
req.variants = new PackAddProbability[pack.variants.Length];
|
||||
|
||||
for (int i = 0; i < req.rarities_1st.Length; i++)
|
||||
req.rarities_1st[i] = AddPackRarity(pack.rarities_1st[i]);
|
||||
|
||||
for (int i = 0; i < req.rarities.Length; i++)
|
||||
req.rarities[i] = AddPackRarity(pack.rarities[i]);
|
||||
|
||||
for (int i = 0; i < req.variants.Length; i++)
|
||||
req.variants[i] = AddPackVariant(pack.variants[i]);
|
||||
|
||||
string url = ApiClient.ServerURL + "/packs/add";
|
||||
string json = ApiTool.ToJson(req);
|
||||
await ApiClient.Get().SendPostRequest(url, json);
|
||||
}
|
||||
|
||||
private PackAddProbability AddPackRarity(PackRarity rarity)
|
||||
{
|
||||
PackAddProbability add = new PackAddProbability();
|
||||
add.tid = rarity.rarity.id;
|
||||
add.value = rarity.probability;
|
||||
return add;
|
||||
}
|
||||
|
||||
private PackAddProbability AddPackVariant(PackVariant rarity)
|
||||
{
|
||||
PackAddProbability add = new PackAddProbability();
|
||||
add.tid = rarity.variant.id;
|
||||
add.value = rarity.probability;
|
||||
return add;
|
||||
}
|
||||
|
||||
private async void UploadCard(CardData card)
|
||||
{
|
||||
CardAddRequest req = new CardAddRequest();
|
||||
req.tid = card.id;
|
||||
req.type = card.GetTypeId();
|
||||
req.team = card.team.id;
|
||||
req.rarity = card.rarity.id;
|
||||
req.mana = card.mana;
|
||||
req.attack = card.attack;
|
||||
req.hp = card.hp;
|
||||
req.cost = card.cost;
|
||||
req.packs = new string[card.packs.Length];
|
||||
|
||||
for (int i = 0; i < req.packs.Length; i++)
|
||||
{
|
||||
req.packs[i] = card.packs[i].id;
|
||||
}
|
||||
|
||||
string url = ApiClient.ServerURL + "/cards/add";
|
||||
string json = ApiTool.ToJson(req);
|
||||
await ApiClient.Get().SendPostRequest(url, json);
|
||||
}
|
||||
|
||||
private async void UploadCardList(List<CardData> cards)
|
||||
{
|
||||
CardAddListRequest req = new CardAddListRequest();
|
||||
req.cards = new CardAddRequest[cards.Count];
|
||||
for(int i=0; i<cards.Count; i++)
|
||||
{
|
||||
CardData card = cards[i];
|
||||
CardAddRequest rcard = new CardAddRequest();
|
||||
rcard.tid = card.id;
|
||||
rcard.type = card.GetTypeId();
|
||||
rcard.team = card.team.id;
|
||||
rcard.rarity = card.rarity.id;
|
||||
rcard.mana = card.mana;
|
||||
rcard.attack = card.attack;
|
||||
rcard.hp = card.hp;
|
||||
rcard.cost = card.cost;
|
||||
rcard.packs = new string[card.packs.Length];
|
||||
for (int p = 0; p < card.packs.Length; p++)
|
||||
{
|
||||
rcard.packs[p] = card.packs[p].id;
|
||||
}
|
||||
req.cards[i] = rcard;
|
||||
}
|
||||
|
||||
string url = ApiClient.ServerURL + "/cards/add/list";
|
||||
string json = ApiTool.ToJson(req);
|
||||
await ApiClient.Get().SendPostRequest(url, json);
|
||||
}
|
||||
|
||||
private async void UploadVariant(VariantData variant)
|
||||
{
|
||||
VariantAddRequest req = new VariantAddRequest();
|
||||
req.tid = variant.id;
|
||||
req.cost_factor = variant.cost_factor;
|
||||
req.is_default = variant.is_default;
|
||||
|
||||
string url = ApiClient.ServerURL + "/variants/add";
|
||||
string json = ApiTool.ToJson(req);
|
||||
await ApiClient.Get().SendPostRequest(url, json);
|
||||
}
|
||||
|
||||
private async void UploadDeckReward(DeckData deck)
|
||||
{
|
||||
RewardAddRequest req = new RewardAddRequest();
|
||||
req.tid = deck.id;
|
||||
req.group = "starter_deck";
|
||||
req.decks = new string[1] { deck.id };
|
||||
|
||||
string url = ApiClient.ServerURL + "/rewards/add";
|
||||
string json = ApiTool.ToJson(req);
|
||||
await ApiClient.Get().SendPostRequest(url, json);
|
||||
}
|
||||
|
||||
private async void UploadDeck(DeckData deck)
|
||||
{
|
||||
UserDeckData req = new UserDeckData(deck);
|
||||
string url = ApiClient.ServerURL + "/decks/add";
|
||||
string json = ApiTool.ToJson(req);
|
||||
await ApiClient.Get().SendPostRequest(url, json);
|
||||
}
|
||||
|
||||
private async void UploadReward(RewardData reward)
|
||||
{
|
||||
RewardAddRequest req = new RewardAddRequest();
|
||||
req.tid = reward.id;
|
||||
req.group = "";
|
||||
req.coins = reward.coins;
|
||||
req.xp = reward.xp;
|
||||
req.repeat = reward.repeat;
|
||||
|
||||
if (reward.cards != null)
|
||||
{
|
||||
req.cards = new string[reward.cards.Length];
|
||||
for (int i = 0; i < reward.cards.Length; i++)
|
||||
{
|
||||
req.cards[i] = reward.cards[i].id;
|
||||
}
|
||||
}
|
||||
|
||||
if (reward.decks != null)
|
||||
{
|
||||
req.decks = new string[reward.decks.Length];
|
||||
for (int i = 0; i < reward.decks.Length; i++)
|
||||
{
|
||||
req.decks[i] = reward.decks[i].id;
|
||||
}
|
||||
}
|
||||
|
||||
if (reward.packs != null)
|
||||
{
|
||||
req.packs = new string[reward.packs.Length];
|
||||
for (int i = 0; i < reward.packs.Length; i++)
|
||||
{
|
||||
req.packs[i] = reward.packs[i].id;
|
||||
}
|
||||
}
|
||||
|
||||
string url = ApiClient.ServerURL + "/rewards/add";
|
||||
string json = ApiTool.ToJson(req);
|
||||
await ApiClient.Get().SendPostRequest(url, json);
|
||||
}
|
||||
|
||||
private async void UploadLevelReward(LevelData level)
|
||||
{
|
||||
RewardAddRequest req = new RewardAddRequest();
|
||||
req.tid = level.id;
|
||||
req.group = "";
|
||||
req.coins = level.reward_coins;
|
||||
req.xp = level.reward_xp;
|
||||
req.repeat = false;
|
||||
|
||||
if (level.reward_cards != null)
|
||||
{
|
||||
req.cards = new string[level.reward_cards.Length];
|
||||
for (int i = 0; i < level.reward_cards.Length; i++)
|
||||
{
|
||||
req.cards[i] = level.reward_cards[i].id;
|
||||
}
|
||||
}
|
||||
|
||||
if (level.reward_packs != null)
|
||||
{
|
||||
req.packs = new string[level.reward_packs.Length];
|
||||
for (int i = 0; i < level.reward_packs.Length; i++)
|
||||
{
|
||||
req.packs[i] = level.reward_packs[i].id;
|
||||
}
|
||||
}
|
||||
|
||||
if (level.reward_decks != null)
|
||||
{
|
||||
req.decks = new string[level.reward_decks.Length];
|
||||
for (int i = 0; i < level.reward_decks.Length; i++)
|
||||
{
|
||||
req.decks[i] = level.reward_decks[i].id;
|
||||
}
|
||||
}
|
||||
|
||||
string url = ApiClient.ServerURL + "/rewards/add";
|
||||
string json = ApiTool.ToJson(req);
|
||||
await ApiClient.Get().SendPostRequest(url, json);
|
||||
}
|
||||
|
||||
private List<CardData> GetCardGroup(List<CardData> all_cards, int start, int count)
|
||||
{
|
||||
List<CardData> list = new List<CardData>();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
int index = start + i;
|
||||
if (index < all_cards.Count)
|
||||
{
|
||||
CardData card = all_cards[index];
|
||||
if (card.deckbuilding)
|
||||
{
|
||||
list.Add(card);
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private void ShowText(string txt)
|
||||
{
|
||||
msg_text.text = txt;
|
||||
Debug.Log(txt);
|
||||
}
|
||||
|
||||
public void OnClickStart()
|
||||
{
|
||||
msg_text.text = "";
|
||||
Login();
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class CardAddListRequest
|
||||
{
|
||||
public CardAddRequest[] cards;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class CardAddRequest
|
||||
{
|
||||
public string tid;
|
||||
public string type;
|
||||
public string team;
|
||||
public string rarity;
|
||||
public int mana;
|
||||
public int attack;
|
||||
public int hp;
|
||||
public int cost;
|
||||
public string[] packs;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class PackAddRequest
|
||||
{
|
||||
public string tid;
|
||||
public int cards;
|
||||
public int cost;
|
||||
public bool random;
|
||||
public PackAddProbability[] rarities_1st;
|
||||
public PackAddProbability[] rarities;
|
||||
public PackAddProbability[] variants;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class PackAddProbability
|
||||
{
|
||||
public string tid;
|
||||
public int value;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class VariantAddRequest
|
||||
{
|
||||
public string tid;
|
||||
public int cost_factor;
|
||||
public bool is_default;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class RewardAddRequest
|
||||
{
|
||||
public string tid;
|
||||
public string group;
|
||||
public int coins;
|
||||
public int xp;
|
||||
public string[] packs;
|
||||
public string[] cards;
|
||||
public string[] decks;
|
||||
public bool repeat;
|
||||
}
|
||||
}
|
||||
11
Assets/TcgEngine/Scripts/Tools/CardUploader.cs.meta
Normal file
11
Assets/TcgEngine/Scripts/Tools/CardUploader.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 651d9a7ec841fde44b1cae9b97dfe0cd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
127
Assets/TcgEngine/Scripts/Tools/ChangePermission.cs
Normal file
127
Assets/TcgEngine/Scripts/Tools/ChangePermission.cs
Normal file
@@ -0,0 +1,127 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using TcgEngine.UI;
|
||||
|
||||
namespace TcgEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// Use this tool to upload your cards and packs to the Mongo Database (it will overwrite existing data)
|
||||
/// </summary>
|
||||
|
||||
public class ChangePermission : MonoBehaviour
|
||||
{
|
||||
public string username = "admin";
|
||||
|
||||
[Header("Login")]
|
||||
public InputField username_txt;
|
||||
public InputField password_txt;
|
||||
|
||||
[Header("Change Permission")]
|
||||
public UIPanel permission_panel;
|
||||
public InputField target_user_txt;
|
||||
public InputField target_perm_txt;
|
||||
public Text error;
|
||||
|
||||
private string logged_user;
|
||||
|
||||
void Start()
|
||||
{
|
||||
username_txt.text = username;
|
||||
error.text = "";
|
||||
}
|
||||
|
||||
private async void Login(string user, string pass)
|
||||
{
|
||||
LoginResponse res = await ApiClient.Get().Login(user, pass);
|
||||
if (res.success && res.permission_level >= 10)
|
||||
{
|
||||
logged_user = user;
|
||||
permission_panel.Show();
|
||||
}
|
||||
else if (res.success)
|
||||
{
|
||||
error.text = "Not an admin user";
|
||||
}
|
||||
else
|
||||
{
|
||||
error.text = res.error;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<string> GetUserID(string tuser)
|
||||
{
|
||||
string url = ApiClient.ServerURL + "/users/" + tuser;
|
||||
WebResponse res = await ApiClient.Get().SendGetRequest(url);
|
||||
UserData udata = ApiTool.JsonToObject<UserData>(res.data);
|
||||
if (!res.success)
|
||||
error.text = res.error;
|
||||
|
||||
return res.success ? udata.id : null;
|
||||
}
|
||||
|
||||
private async void SetPermission(string tuser, int permission)
|
||||
{
|
||||
string user_id = await GetUserID(tuser);
|
||||
if (user_id == null)
|
||||
return;
|
||||
|
||||
ChangePermissionRequest req = new ChangePermissionRequest();
|
||||
req.permission_level = permission;
|
||||
|
||||
string url = ApiClient.ServerURL + "/users/permission/edit/" + user_id;
|
||||
string json = ApiTool.ToJson(req);
|
||||
WebResponse res = await ApiClient.Get().SendPostRequest(url, json);
|
||||
|
||||
if (!res.success)
|
||||
error.text = res.error;
|
||||
|
||||
if (res.success)
|
||||
{
|
||||
error.text = "Success!";
|
||||
error.color = Color.green;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnClickLogin()
|
||||
{
|
||||
if (string.IsNullOrEmpty(username_txt.text))
|
||||
return;
|
||||
|
||||
if (string.IsNullOrEmpty(password_txt.text))
|
||||
return;
|
||||
|
||||
error.text = "";
|
||||
error.color = Color.red;
|
||||
Login(username_txt.text, password_txt.text);
|
||||
}
|
||||
|
||||
public void OnClickUpdate()
|
||||
{
|
||||
if (string.IsNullOrEmpty(target_user_txt.text))
|
||||
return;
|
||||
|
||||
bool success = int.TryParse(target_perm_txt.text, out int perm);
|
||||
if (!success)
|
||||
return;
|
||||
|
||||
if (logged_user == target_user_txt.text)
|
||||
return; //Prevent changing yourself
|
||||
|
||||
error.text = "";
|
||||
error.color = Color.red;
|
||||
SetPermission(target_user_txt.text, perm);
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class ChangePermissionRequest
|
||||
{
|
||||
public int permission_level;
|
||||
}
|
||||
|
||||
}
|
||||
11
Assets/TcgEngine/Scripts/Tools/ChangePermission.cs.meta
Normal file
11
Assets/TcgEngine/Scripts/Tools/ChangePermission.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 94523a4b844f81847b531581dcaa4976
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
25
Assets/TcgEngine/Scripts/Tools/DeviceVisibility.cs
Normal file
25
Assets/TcgEngine/Scripts/Tools/DeviceVisibility.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TcgEngine.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// Add to any UI component to make it visible or invisible based on the device
|
||||
/// </summary>
|
||||
|
||||
public class DeviceVisibility : MonoBehaviour
|
||||
{
|
||||
public bool desktop = true;
|
||||
public bool mobile = true;
|
||||
|
||||
void Start()
|
||||
{
|
||||
bool ismobile = GameTool.IsMobile();
|
||||
if (ismobile && !mobile)
|
||||
gameObject.SetActive(false);
|
||||
else if (!ismobile && !desktop)
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/TcgEngine/Scripts/Tools/DeviceVisibility.cs.meta
Normal file
11
Assets/TcgEngine/Scripts/Tools/DeviceVisibility.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0a63a5ee9a4546c45a76f94f44ce2411
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
72
Assets/TcgEngine/Scripts/Tools/FXTool.cs
Normal file
72
Assets/TcgEngine/Scripts/Tools/FXTool.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using TcgEngine.FX;
|
||||
using TcgEngine.Client;
|
||||
|
||||
namespace TcgEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// Static functions to spawn FX prefabs
|
||||
/// </summary>
|
||||
|
||||
public class FXTool : MonoBehaviour
|
||||
{
|
||||
public static GameObject DoFX(GameObject fx_prefab, Vector3 pos, float duration = 5f)
|
||||
{
|
||||
if (fx_prefab != null)
|
||||
{
|
||||
GameObject fx = Instantiate(fx_prefab, pos, GetFXRotation());
|
||||
Destroy(fx, duration);
|
||||
return fx;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static GameObject DoSnapFX(GameObject fx_prefab, Transform snap_target)
|
||||
{
|
||||
return DoSnapFX(fx_prefab, snap_target, Vector3.zero);
|
||||
}
|
||||
|
||||
public static GameObject DoSnapFX(GameObject fx_prefab, Transform snap_target, Vector3 offset)
|
||||
{
|
||||
if (fx_prefab != null && snap_target != null)
|
||||
{
|
||||
GameObject fx = Instantiate(fx_prefab, snap_target.transform.position + offset, GetFXRotation());
|
||||
SnapFX snap = fx.AddComponent<SnapFX>();
|
||||
snap.target = snap_target;
|
||||
snap.offset = offset;
|
||||
Destroy(fx, 5f);
|
||||
return fx;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static GameObject DoProjectileFX(GameObject fx_prefab, Transform source, Transform target, int damage)
|
||||
{
|
||||
if (fx_prefab != null && source != null && target != null)
|
||||
{
|
||||
GameObject fx = Instantiate(fx_prefab, source.position, GetFXRotation());
|
||||
Projectile projectile = fx.GetComponent<Projectile>();
|
||||
if (projectile == null)
|
||||
projectile = fx.AddComponent<Projectile>();
|
||||
|
||||
projectile.SetSource(source);
|
||||
projectile.SetTarget(target);
|
||||
projectile.damage = damage;
|
||||
projectile.DelayDamage();
|
||||
|
||||
Destroy(fx, projectile.duration);
|
||||
return fx;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Quaternion GetFXRotation()
|
||||
{
|
||||
GameBoard board = GameBoard.Get();
|
||||
Vector3 facing = board != null ? board.transform.forward : Vector3.forward;
|
||||
return Quaternion.LookRotation(facing, Vector3.up);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/TcgEngine/Scripts/Tools/FXTool.cs.meta
Normal file
11
Assets/TcgEngine/Scripts/Tools/FXTool.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8a7b1c65356269246bec79e006ee6565
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
133
Assets/TcgEngine/Scripts/Tools/GameTool.cs
Normal file
133
Assets/TcgEngine/Scripts/Tools/GameTool.cs
Normal file
@@ -0,0 +1,133 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.Rendering.Universal;
|
||||
|
||||
namespace TcgEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// Generic static functions for TcgEngine
|
||||
/// </summary>
|
||||
|
||||
public static class GameTool
|
||||
{
|
||||
private const string uid_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
private static System.Random random = new System.Random();
|
||||
|
||||
//Generate a random string to use as UID
|
||||
public static string GenerateRandomID(int min = 9, int max = 15)
|
||||
{
|
||||
int length = random.Next(min, max);
|
||||
string unique_id = "";
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
unique_id += uid_chars[random.Next(uid_chars.Length - 1)];
|
||||
}
|
||||
return unique_id;
|
||||
}
|
||||
|
||||
//Generate a random int
|
||||
public static int GenerateRandomInt()
|
||||
{
|
||||
return random.Next(int.MinValue, int.MaxValue);
|
||||
}
|
||||
|
||||
//Generate a random ulong
|
||||
public static ulong GenerateRandomUInt64()
|
||||
{
|
||||
ulong id = (uint)random.Next(int.MinValue, int.MaxValue); //Cast to uint before casting to ulong
|
||||
uint bid = (uint)random.Next(int.MinValue, int.MaxValue);
|
||||
id = id << 32;
|
||||
id = id | bid;
|
||||
return id;
|
||||
}
|
||||
|
||||
//Pick X random elements in a list (same cant be picked twice, unless it appears twice or more in the list)
|
||||
public static List<T> PickXRandom<T>(List<T> source, List<T> dest, int x)
|
||||
{
|
||||
if (source.Count <= x || x <= 0)
|
||||
return source; //No need to pick anything
|
||||
|
||||
if (dest.Count > 0)
|
||||
dest.Clear();
|
||||
|
||||
for (int i = 0; i < x; i++)
|
||||
{
|
||||
int r = random.Next(source.Count);
|
||||
dest.Add(source[r]);
|
||||
source.RemoveAt(r);
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
//Clone a list of string in most optimized way (avoiding as many Add/Remove as possible)
|
||||
public static void CloneList(List<string> source, List<string> dest)
|
||||
{
|
||||
for (int i = 0; i < source.Count; i++)
|
||||
{
|
||||
if (i < dest.Count)
|
||||
dest[i] = source[i];
|
||||
else
|
||||
dest.Add(source[i]);
|
||||
}
|
||||
|
||||
if (dest.Count > source.Count)
|
||||
dest.RemoveRange(source.Count, dest.Count - source.Count);
|
||||
}
|
||||
|
||||
//Clone a list in most optimized way, only the list is cloned, elements references are preserved
|
||||
public static void CloneListRef<T>(List<T> source, List<T> dest) where T : class
|
||||
{
|
||||
for (int i = 0; i < source.Count; i++)
|
||||
{
|
||||
if (i < dest.Count)
|
||||
dest[i] = source[i];
|
||||
else
|
||||
dest.Add(source[i]);
|
||||
}
|
||||
|
||||
if (dest.Count > source.Count)
|
||||
dest.RemoveRange(source.Count, dest.Count - source.Count);
|
||||
}
|
||||
|
||||
//Same a previous function, but elements could be null
|
||||
public static void CloneListRefNull<T>(List<T> source, ref List<T> dest) where T : class
|
||||
{
|
||||
//Source is null, set destination null
|
||||
if (source == null)
|
||||
{
|
||||
dest = null;
|
||||
return;
|
||||
}
|
||||
|
||||
//Dest is null
|
||||
if (dest == null)
|
||||
dest = new List<T>();
|
||||
|
||||
//Both arent null, clone
|
||||
CloneListRef(source, dest);
|
||||
}
|
||||
|
||||
//Check if current device is mobile device
|
||||
public static bool IsMobile()
|
||||
{
|
||||
#if UNITY_ANDROID || UNITY_IOS || UNITY_TIZEN
|
||||
return true;
|
||||
#else
|
||||
return UnityEngine.Device.Application.isMobilePlatform;
|
||||
#endif
|
||||
}
|
||||
|
||||
//Check if using Universal Render Pipeline
|
||||
//If this function return compile error (because URP isnt installed and you dont want it, you can simply comment the code and return false
|
||||
public static bool IsURP()
|
||||
{
|
||||
if (GraphicsSettings.renderPipelineAsset is UniversalRenderPipelineAsset)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
11
Assets/TcgEngine/Scripts/Tools/GameTool.cs.meta
Normal file
11
Assets/TcgEngine/Scripts/Tools/GameTool.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dfd2a611578d9e041a1be0c56f069c80
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
42
Assets/TcgEngine/Scripts/Tools/ListSwap.cs
Normal file
42
Assets/TcgEngine/Scripts/Tools/ListSwap.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TcgEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// Useful optimization tool, let you use arrays without instantiating new ones
|
||||
/// </summary>
|
||||
|
||||
public class ListSwap<T>
|
||||
{
|
||||
public List<T> swap1 = new List<T>();
|
||||
public List<T> swap2 = new List<T>();
|
||||
|
||||
//Return any array
|
||||
public List<T> Get()
|
||||
{
|
||||
swap1.Clear(); //Clear before using
|
||||
return swap1;
|
||||
}
|
||||
|
||||
//Return the OTHER array (because skip is already in use)
|
||||
public List<T> GetOther(List<T> skip)
|
||||
{
|
||||
if (skip == swap1)
|
||||
{
|
||||
swap2.Clear(); //Clear before using
|
||||
return swap2;
|
||||
}
|
||||
swap1.Clear(); //Clear before using
|
||||
return swap1;
|
||||
}
|
||||
|
||||
//Clear both
|
||||
public void Clear()
|
||||
{
|
||||
swap1.Clear();
|
||||
swap2.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/TcgEngine/Scripts/Tools/ListSwap.cs.meta
Normal file
11
Assets/TcgEngine/Scripts/Tools/ListSwap.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a33a9fa01d21c1e45bd72957e559fde2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
26
Assets/TcgEngine/Scripts/Tools/MobileResizeUI.cs
Normal file
26
Assets/TcgEngine/Scripts/Tools/MobileResizeUI.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TcgEngine.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// Add to any UI element to make it resize on mobile (some buttons should be bigger on mobile)
|
||||
/// </summary>
|
||||
|
||||
public class MobileResizeUI : MonoBehaviour
|
||||
{
|
||||
public Vector2 position_offset;
|
||||
public float size = 1f;
|
||||
|
||||
void Start()
|
||||
{
|
||||
if (GameTool.IsMobile())
|
||||
{
|
||||
RectTransform rect = GetComponent<RectTransform>();
|
||||
rect.anchoredPosition += position_offset;
|
||||
transform.localScale = transform.localScale * size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/TcgEngine/Scripts/Tools/MobileResizeUI.cs.meta
Normal file
11
Assets/TcgEngine/Scripts/Tools/MobileResizeUI.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1dc7e6d14aa7ae14fa896b16dd1de55e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
552
Assets/TcgEngine/Scripts/Tools/NetworkTool.cs
Normal file
552
Assets/TcgEngine/Scripts/Tools/NetworkTool.cs
Normal file
@@ -0,0 +1,552 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
using Unity.Netcode;
|
||||
using UnityEngine;
|
||||
using Unity.Collections;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TcgEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// Useful network static function
|
||||
/// </summary>
|
||||
|
||||
public class NetworkTool
|
||||
{
|
||||
//Serialize a [System.Serializable] into bytes
|
||||
public static byte[] Serialize<T>(T obj) where T : class
|
||||
{
|
||||
try
|
||||
{
|
||||
BinaryFormatter bf = new BinaryFormatter();
|
||||
MemoryStream ms = new MemoryStream();
|
||||
bf.Serialize(ms, obj);
|
||||
byte[] bytes = ms.ToArray();
|
||||
ms.Close();
|
||||
return bytes;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError("Serialization error: " + e.Message);
|
||||
return new byte[0];
|
||||
}
|
||||
}
|
||||
|
||||
//Deserialize a [System.Serializable] from bytes
|
||||
public static T Deserialize<T>(byte[] bytes) where T : class
|
||||
{
|
||||
try
|
||||
{
|
||||
BinaryFormatter bf = new BinaryFormatter();
|
||||
MemoryStream ms = new MemoryStream();
|
||||
ms.Write(bytes, 0, bytes.Length);
|
||||
ms.Seek(0, SeekOrigin.Begin);
|
||||
T obj = (T)bf.Deserialize(ms);
|
||||
ms.Close();
|
||||
return obj;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError("Deserialization error: " + e.Message);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
//Serialize a INetworkSerializable to bytes
|
||||
public static byte[] NetSerialize<T>(T obj, int size = 128) where T : INetworkSerializable, new()
|
||||
{
|
||||
if (obj == null)
|
||||
return new byte[0];
|
||||
|
||||
try
|
||||
{
|
||||
FastBufferWriter writer = new FastBufferWriter(size, Allocator.Temp, TcgNetwork.MsgSizeMax);
|
||||
writer.WriteNetworkSerializable(obj);
|
||||
byte[] bytes = writer.ToArray();
|
||||
writer.Dispose();
|
||||
return bytes;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError("Serialization error: " + e.Message);
|
||||
return new byte[0];
|
||||
}
|
||||
}
|
||||
|
||||
//Deserialize a INetworkSerializable from bytes
|
||||
public static T NetDeserialize<T>(byte[] bytes) where T : INetworkSerializable, new()
|
||||
{
|
||||
if (bytes == null || bytes.Length == 0)
|
||||
return default(T);
|
||||
|
||||
try
|
||||
{
|
||||
FastBufferReader reader = new FastBufferReader(bytes, Allocator.Temp);
|
||||
reader.ReadNetworkSerializable(out T obj);
|
||||
reader.Dispose();
|
||||
return obj;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError("Deserialization error: " + e.Message);
|
||||
return default(T);
|
||||
}
|
||||
}
|
||||
|
||||
//Serialize an array using Netcode
|
||||
public static void NetSerializeArray<TS>(BufferSerializer<TS> serializer, ref string[] array) where TS : IReaderWriter
|
||||
{
|
||||
if (serializer.IsReader)
|
||||
{
|
||||
int size = 0;
|
||||
serializer.SerializeValue(ref size);
|
||||
array = new string[size];
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
string val = "";
|
||||
serializer.SerializeValue(ref val);
|
||||
array[i] = val;
|
||||
}
|
||||
}
|
||||
|
||||
if (serializer.IsWriter)
|
||||
{
|
||||
int size = array.Length;
|
||||
serializer.SerializeValue(ref size);
|
||||
for (int i = 0; i < size; i++)
|
||||
serializer.SerializeValue(ref array[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//Serialize an array using Netcode
|
||||
public static void NetSerializeArray<T, TS>(BufferSerializer<TS> serializer, ref T[] array) where T : INetworkSerializable, new() where TS : IReaderWriter
|
||||
{
|
||||
if (serializer.IsReader)
|
||||
{
|
||||
int size = 0;
|
||||
serializer.SerializeValue(ref size);
|
||||
array = new T[size];
|
||||
for(int i=0; i<size; i++)
|
||||
{
|
||||
T val = new T();
|
||||
serializer.SerializeValue(ref val);
|
||||
array[i] = val;
|
||||
}
|
||||
}
|
||||
|
||||
if (serializer.IsWriter)
|
||||
{
|
||||
int size = array.Length;
|
||||
serializer.SerializeValue(ref size);
|
||||
for (int i = 0; i < size; i++)
|
||||
serializer.SerializeValue(ref array[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] SerializeInt32(int data)
|
||||
{
|
||||
return System.BitConverter.GetBytes(data);
|
||||
}
|
||||
|
||||
public static int DeserializeInt32(byte[] bytes)
|
||||
{
|
||||
if (bytes != null && bytes.Length > 0)
|
||||
return System.BitConverter.ToInt32(bytes, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static byte[] SerializeUInt64(ulong data)
|
||||
{
|
||||
return System.BitConverter.GetBytes(data);
|
||||
}
|
||||
|
||||
public static ulong DeserializeUInt64(byte[] bytes)
|
||||
{
|
||||
if (bytes != null && bytes.Length > 0)
|
||||
return System.BitConverter.ToUInt64(bytes, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static byte[] SerializeString(string data)
|
||||
{
|
||||
if(data != null)
|
||||
return System.Text.Encoding.UTF8.GetBytes(data);
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
public static string DeserializeString(byte[] bytes)
|
||||
{
|
||||
if (bytes != null)
|
||||
return System.Text.Encoding.UTF8.GetString(bytes);
|
||||
return null;
|
||||
}
|
||||
|
||||
public static string SerializeToString<T>(T obj) where T : class
|
||||
{
|
||||
byte[] bytes = Serialize<T>(obj);
|
||||
return Convert.ToBase64String(bytes);
|
||||
}
|
||||
|
||||
public static T DeserializeFromString<T>(string str) where T : class
|
||||
{
|
||||
byte[] bytes = Convert.FromBase64String(str);
|
||||
return Deserialize<T>(bytes);
|
||||
}
|
||||
|
||||
public static void SerializeObject<T, T1>(BufferSerializer<T> serializer, ref T1 data) where T : IReaderWriter where T1 : class
|
||||
{
|
||||
string sdata = "";
|
||||
if (serializer.IsWriter)
|
||||
{
|
||||
sdata = SerializeToString(data);
|
||||
}
|
||||
serializer.SerializeValue(ref sdata, true);
|
||||
if (serializer.IsReader)
|
||||
{
|
||||
data = DeserializeFromString<T1>(sdata);
|
||||
}
|
||||
}
|
||||
|
||||
public static void SerializeDictionary<T, T1, T2>(BufferSerializer<T> serializer, ref Dictionary<T1, T2> data)
|
||||
where T : IReaderWriter where T1 : unmanaged, IComparable, IConvertible, IComparable<T1>, IEquatable<T1> where T2 : unmanaged, IComparable, IConvertible, IComparable<T2>, IEquatable<T2>
|
||||
{
|
||||
int count = data != null ? data.Count : 0;
|
||||
serializer.SerializeValue(ref count);
|
||||
|
||||
if (serializer.IsWriter)
|
||||
{
|
||||
foreach (KeyValuePair<T1, T2> pair in data)
|
||||
{
|
||||
T1 key = pair.Key;
|
||||
T2 val = pair.Value;
|
||||
serializer.SerializeValue(ref key);
|
||||
serializer.SerializeValue(ref val);
|
||||
}
|
||||
}
|
||||
if (serializer.IsReader)
|
||||
{
|
||||
data = new Dictionary<T1, T2>();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
T1 key = new T1();
|
||||
T2 val = new T2();
|
||||
serializer.SerializeValue(ref key);
|
||||
serializer.SerializeValue(ref val);
|
||||
data.Add(key, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void SerializeDictionaryEnum<T, T1, T2>(BufferSerializer<T> serializer, ref Dictionary<T1, T2> data)
|
||||
where T : IReaderWriter where T1 : unmanaged, Enum where T2 : unmanaged, IComparable, IConvertible, IComparable<T2>, IEquatable<T2>
|
||||
{
|
||||
int count = data != null ? data.Count : 0;
|
||||
serializer.SerializeValue(ref count);
|
||||
|
||||
if (serializer.IsWriter)
|
||||
{
|
||||
foreach (KeyValuePair<T1, T2> pair in data)
|
||||
{
|
||||
T1 key = pair.Key;
|
||||
T2 val = pair.Value;
|
||||
serializer.SerializeValue(ref key);
|
||||
serializer.SerializeValue(ref val);
|
||||
}
|
||||
}
|
||||
if (serializer.IsReader)
|
||||
{
|
||||
data = new Dictionary<T1, T2>();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
T1 key = new T1();
|
||||
T2 val = new T2();
|
||||
serializer.SerializeValue(ref key);
|
||||
serializer.SerializeValue(ref val);
|
||||
data.Add(key, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void SerializeDictionary<T, T2>(BufferSerializer<T> serializer, ref Dictionary<string, T2> data)
|
||||
where T : IReaderWriter where T2 : unmanaged, IComparable, IConvertible, IComparable<T2>, IEquatable<T2>
|
||||
{
|
||||
int count = data != null ? data.Count : 0;
|
||||
serializer.SerializeValue(ref count);
|
||||
|
||||
if (serializer.IsWriter)
|
||||
{
|
||||
foreach (KeyValuePair<string, T2> pair in data)
|
||||
{
|
||||
string key = pair.Key;
|
||||
T2 val = pair.Value;
|
||||
serializer.SerializeValue(ref key);
|
||||
serializer.SerializeValue(ref val);
|
||||
}
|
||||
}
|
||||
if (serializer.IsReader)
|
||||
{
|
||||
data = new Dictionary<string, T2>();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
string key = "";
|
||||
T2 val = new T2();
|
||||
serializer.SerializeValue(ref key);
|
||||
serializer.SerializeValue(ref val);
|
||||
data.Add(key, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void SerializeDictionary<T>(BufferSerializer<T> serializer, ref Dictionary<string, string> data)
|
||||
where T : IReaderWriter
|
||||
{
|
||||
int count = data != null ? data.Count : 0;
|
||||
serializer.SerializeValue(ref count);
|
||||
|
||||
if (serializer.IsWriter)
|
||||
{
|
||||
foreach (KeyValuePair<string, string> pair in data)
|
||||
{
|
||||
string key = pair.Key;
|
||||
string val = pair.Value;
|
||||
serializer.SerializeValue(ref key);
|
||||
serializer.SerializeValue(ref val);
|
||||
}
|
||||
}
|
||||
if (serializer.IsReader)
|
||||
{
|
||||
data = new Dictionary<string, string>();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
string key = "";
|
||||
string val = "";
|
||||
serializer.SerializeValue(ref key);
|
||||
serializer.SerializeValue(ref val);
|
||||
data.Add(key, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void SerializeDictionaryNetObject<T, T2>(BufferSerializer<T> serializer, ref Dictionary<string, T2> data)
|
||||
where T : IReaderWriter where T2 : INetworkSerializable, new()
|
||||
{
|
||||
int count = data != null ? data.Count : 0;
|
||||
serializer.SerializeValue(ref count);
|
||||
|
||||
if (serializer.IsWriter)
|
||||
{
|
||||
foreach (KeyValuePair<string, T2> pair in data)
|
||||
{
|
||||
string key = pair.Key;
|
||||
T2 val = pair.Value;
|
||||
serializer.SerializeValue(ref key);
|
||||
serializer.SerializeNetworkSerializable(ref val);
|
||||
}
|
||||
}
|
||||
if (serializer.IsReader)
|
||||
{
|
||||
data = new Dictionary<string, T2>();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
string key = "";
|
||||
T2 val = new T2();
|
||||
serializer.SerializeValue(ref key);
|
||||
serializer.SerializeNetworkSerializable(ref val);
|
||||
data.Add(key, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void SerializeDictionaryNetObject<T, T1, T2>(BufferSerializer<T> serializer, ref Dictionary<T1, T2> data)
|
||||
where T : IReaderWriter where T1 : unmanaged, IComparable, IConvertible, IComparable<T1>, IEquatable<T1> where T2 : INetworkSerializable, new()
|
||||
{
|
||||
int count = data != null ? data.Count : 0;
|
||||
serializer.SerializeValue(ref count);
|
||||
|
||||
if (serializer.IsWriter)
|
||||
{
|
||||
foreach (KeyValuePair<T1, T2> pair in data)
|
||||
{
|
||||
T1 key = pair.Key;
|
||||
T2 val = pair.Value;
|
||||
serializer.SerializeValue(ref key);
|
||||
serializer.SerializeNetworkSerializable(ref val);
|
||||
}
|
||||
}
|
||||
if (serializer.IsReader)
|
||||
{
|
||||
data = new Dictionary<T1, T2>();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
T1 key = new T1();
|
||||
T2 val = new T2();
|
||||
serializer.SerializeValue(ref key);
|
||||
serializer.SerializeNetworkSerializable(ref val);
|
||||
data.Add(key, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void SerializeDictionaryObject<T, T2>(BufferSerializer<T> serializer, ref Dictionary<string, T2> data)
|
||||
where T : IReaderWriter where T2 : class, new()
|
||||
{
|
||||
int count = data != null ? data.Count : 0;
|
||||
serializer.SerializeValue(ref count);
|
||||
|
||||
if (serializer.IsWriter)
|
||||
{
|
||||
foreach (KeyValuePair<string, T2> pair in data)
|
||||
{
|
||||
string key = pair.Key;
|
||||
T2 val = pair.Value;
|
||||
serializer.SerializeValue(ref key);
|
||||
SerializeObject(serializer, ref val);
|
||||
}
|
||||
}
|
||||
if (serializer.IsReader)
|
||||
{
|
||||
data = new Dictionary<string, T2>();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
string key = "";
|
||||
T2 val = new T2();
|
||||
serializer.SerializeValue(ref key);
|
||||
SerializeObject(serializer, ref val);
|
||||
data.Add(key, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void SerializeDictionaryObject<T, T1, T2>(BufferSerializer<T> serializer, ref Dictionary<T1, T2> data)
|
||||
where T : IReaderWriter where T1 : unmanaged, IComparable, IConvertible, IComparable<T1>, IEquatable<T1> where T2 : class, new()
|
||||
{
|
||||
int count = data != null ? data.Count : 0;
|
||||
serializer.SerializeValue(ref count);
|
||||
|
||||
if (serializer.IsWriter)
|
||||
{
|
||||
foreach (KeyValuePair<T1, T2> pair in data)
|
||||
{
|
||||
T1 key = pair.Key;
|
||||
T2 val = pair.Value;
|
||||
serializer.SerializeValue(ref key);
|
||||
SerializeObject(serializer, ref val);
|
||||
}
|
||||
}
|
||||
if (serializer.IsReader)
|
||||
{
|
||||
data = new Dictionary<T1, T2>();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
T1 key = new T1();
|
||||
T2 val = new T2();
|
||||
serializer.SerializeValue(ref key);
|
||||
SerializeObject(serializer, ref val);
|
||||
data.Add(key, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void SerializeDictionaryEnumObject<T, T1, T2>(BufferSerializer<T> serializer, ref Dictionary<T1, T2> data)
|
||||
where T : IReaderWriter where T1 : unmanaged, Enum where T2 : class, new()
|
||||
{
|
||||
int count = data != null ? data.Count : 0;
|
||||
serializer.SerializeValue(ref count);
|
||||
|
||||
if (serializer.IsWriter)
|
||||
{
|
||||
foreach (KeyValuePair<T1, T2> pair in data)
|
||||
{
|
||||
T1 key = pair.Key;
|
||||
T2 val = pair.Value;
|
||||
serializer.SerializeValue(ref key);
|
||||
SerializeObject(serializer, ref val);
|
||||
}
|
||||
}
|
||||
if (serializer.IsReader)
|
||||
{
|
||||
data = new Dictionary<T1, T2>();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
T1 key = new T1();
|
||||
T2 val = new T2();
|
||||
serializer.SerializeValue(ref key);
|
||||
SerializeObject(serializer, ref val);
|
||||
data.Add(key, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static ushort Hash16(string string_id)
|
||||
{
|
||||
return (ushort) string_id.GetHashCode();
|
||||
}
|
||||
|
||||
public static uint Hash32(string string_id)
|
||||
{
|
||||
return (uint) string_id.GetHashCode();
|
||||
}
|
||||
|
||||
public static ulong Hash64(string string_id)
|
||||
{
|
||||
string s1 = string_id.Substring(0, string_id.Length / 2);
|
||||
string s2 = string_id.Substring(string_id.Length / 2);
|
||||
ulong id = (uint)s1.GetHashCode();
|
||||
id = id << 32;
|
||||
id = id | (uint)s2.GetHashCode();
|
||||
return id;
|
||||
}
|
||||
|
||||
public static IPAddress ResolveDns(string url)
|
||||
{
|
||||
#if !UNITY_WEBGL
|
||||
IPAddress[] ips = Dns.GetHostAddresses(url);
|
||||
if (ips != null && ips.Length > 0)
|
||||
return ips[0];
|
||||
#else
|
||||
Debug.LogWarning("Dns.GetHostAddresses not working on WebGL, try using direct IP address instead of host url");
|
||||
#endif
|
||||
return null;
|
||||
}
|
||||
|
||||
//Converts a host (either domain or IP) into an IP
|
||||
public static string HostToIP(string host)
|
||||
{
|
||||
bool success = IPAddress.TryParse(host, out IPAddress address);
|
||||
if (success)
|
||||
return address.ToString(); //Already an IP
|
||||
IPAddress ip = ResolveDns(host); //Not an IP, resolve DNS
|
||||
if (ip != null)
|
||||
return ip.ToString();
|
||||
return "";
|
||||
}
|
||||
|
||||
public static string GetLocalIp()
|
||||
{
|
||||
//Get Internal IP
|
||||
IPHostEntry hostEntry = Dns.GetHostEntry(Dns.GetHostName());
|
||||
foreach (IPAddress ip in hostEntry.AddressList)
|
||||
{
|
||||
if (ip.AddressFamily == AddressFamily.InterNetwork)
|
||||
{
|
||||
return ip.ToString();
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static async Task<string> GetOnlineIp()
|
||||
{
|
||||
//Get External IP
|
||||
WebResponse res = await WebTool.SendRequest("https://api.ipify.org");
|
||||
if (res.success)
|
||||
return res.data;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/TcgEngine/Scripts/Tools/NetworkTool.cs.meta
Normal file
11
Assets/TcgEngine/Scripts/Tools/NetworkTool.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3ecdd15b88c2b1747b0d1942b9efc825
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
68
Assets/TcgEngine/Scripts/Tools/Pool.cs
Normal file
68
Assets/TcgEngine/Scripts/Tools/Pool.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace TcgEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// A pool reuses Memory for objects that are constantly created/destroyed, to prevent always allocating more memory
|
||||
/// Makes the AI much much much faster
|
||||
/// </summary>
|
||||
|
||||
public class Pool<T> where T : new()
|
||||
{
|
||||
private HashSet<T> in_use = new HashSet<T>();
|
||||
private Stack<T> available = new Stack<T>();
|
||||
|
||||
public T Create()
|
||||
{
|
||||
if (available.Count > 0)
|
||||
{
|
||||
T elem = available.Pop();
|
||||
in_use.Add(elem);
|
||||
return elem;
|
||||
}
|
||||
T new_obj = new T();
|
||||
in_use.Add(new_obj);
|
||||
return new_obj;
|
||||
}
|
||||
|
||||
public void Dispose(T elem)
|
||||
{
|
||||
in_use.Remove(elem);
|
||||
available.Push(elem);
|
||||
}
|
||||
|
||||
public void DisposeAll()
|
||||
{
|
||||
foreach (T obj in in_use)
|
||||
available.Push(obj);
|
||||
in_use.Clear();
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
in_use.Clear();
|
||||
available.Clear();
|
||||
}
|
||||
|
||||
public HashSet<T> GetAllActive()
|
||||
{
|
||||
return in_use;
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { return in_use.Count; }
|
||||
}
|
||||
|
||||
public int CountAvailable
|
||||
{
|
||||
get { return available.Count; }
|
||||
}
|
||||
|
||||
public int CountCapacity
|
||||
{
|
||||
get { return in_use.Count + available.Count; }
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/TcgEngine/Scripts/Tools/Pool.cs.meta
Normal file
11
Assets/TcgEngine/Scripts/Tools/Pool.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8671537f63a2a0a44bff3e6f1defd7e1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
31
Assets/TcgEngine/Scripts/Tools/RPMat.cs
Normal file
31
Assets/TcgEngine/Scripts/Tools/RPMat.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace TcgEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// Change material based on Render Pipeline
|
||||
/// </summary>
|
||||
|
||||
public class RPMat : MonoBehaviour
|
||||
{
|
||||
public Material mat_urp;
|
||||
|
||||
private SpriteRenderer render;
|
||||
private Image image;
|
||||
|
||||
void Start()
|
||||
{
|
||||
render = GetComponent<SpriteRenderer>();
|
||||
image = GetComponent<Image>();
|
||||
|
||||
if (render != null && GameTool.IsURP())
|
||||
render.material = mat_urp;
|
||||
if (image != null && GameTool.IsURP())
|
||||
image.material = mat_urp;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
11
Assets/TcgEngine/Scripts/Tools/RPMat.cs.meta
Normal file
11
Assets/TcgEngine/Scripts/Tools/RPMat.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d98a4654f52ab40419eed3ad7fb6fb77
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
255
Assets/TcgEngine/Scripts/Tools/ResolveQueue.cs
Normal file
255
Assets/TcgEngine/Scripts/Tools/ResolveQueue.cs
Normal file
@@ -0,0 +1,255 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace TcgEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// Resolve abilties and actions one by one, with an optional delay in between each
|
||||
/// </summary>
|
||||
|
||||
public class ResolveQueue
|
||||
{
|
||||
private Pool<AbilityQueueElement> ability_elem_pool = new Pool<AbilityQueueElement>();
|
||||
private Pool<SecretQueueElement> secret_elem_pool = new Pool<SecretQueueElement>();
|
||||
private Pool<AttackQueueElement> attack_elem_pool = new Pool<AttackQueueElement>();
|
||||
private Pool<CallbackQueueElement> callback_elem_pool = new Pool<CallbackQueueElement>();
|
||||
|
||||
private Queue<AbilityQueueElement> ability_queue = new Queue<AbilityQueueElement>();
|
||||
private Queue<SecretQueueElement> secret_queue = new Queue<SecretQueueElement>();
|
||||
private Queue<AttackQueueElement> attack_queue = new Queue<AttackQueueElement>();
|
||||
private Queue<CallbackQueueElement> callback_queue = new Queue<CallbackQueueElement>();
|
||||
|
||||
private Game game_data;
|
||||
private bool is_resolving = false;
|
||||
private float resolve_delay = 0f;
|
||||
private bool skip_delay = false;
|
||||
|
||||
public ResolveQueue(Game data, bool skip)
|
||||
{
|
||||
game_data = data;
|
||||
skip_delay = skip;
|
||||
}
|
||||
|
||||
public void SetData(Game data)
|
||||
{
|
||||
game_data = data;
|
||||
}
|
||||
|
||||
public virtual void Update(float delta)
|
||||
{
|
||||
if (resolve_delay > 0f)
|
||||
{
|
||||
resolve_delay -= delta;
|
||||
if (resolve_delay <= 0f)
|
||||
ResolveAll();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void AddAbility(AbilityData ability, Card caster, Card triggerer, Action<AbilityData, Card, Card> callback)
|
||||
{
|
||||
if (ability != null && caster != null)
|
||||
{
|
||||
AbilityQueueElement elem = ability_elem_pool.Create();
|
||||
elem.caster = caster;
|
||||
elem.triggerer = triggerer;
|
||||
elem.ability = ability;
|
||||
elem.callback = callback;
|
||||
ability_queue.Enqueue(elem);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void AddAttack(Card attacker, Card target, Action<Card, Card, bool> callback, bool skip_cost = false)
|
||||
{
|
||||
if (attacker != null && target != null)
|
||||
{
|
||||
AttackQueueElement elem = attack_elem_pool.Create();
|
||||
elem.attacker = attacker;
|
||||
elem.target = target;
|
||||
elem.ptarget = null;
|
||||
elem.skip_cost = skip_cost;
|
||||
elem.callback = callback;
|
||||
attack_queue.Enqueue(elem);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void AddAttack(Card attacker, Player target, Action<Card, Player, bool> callback, bool skip_cost = false)
|
||||
{
|
||||
if (attacker != null && target != null)
|
||||
{
|
||||
AttackQueueElement elem = attack_elem_pool.Create();
|
||||
elem.attacker = attacker;
|
||||
elem.target = null;
|
||||
elem.ptarget = target;
|
||||
elem.skip_cost = skip_cost;
|
||||
elem.pcallback = callback;
|
||||
attack_queue.Enqueue(elem);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void AddSecret(AbilityTrigger secret_trigger, Card secret, Card trigger, Action<AbilityTrigger, Card, Card> callback)
|
||||
{
|
||||
if (secret != null && trigger != null)
|
||||
{
|
||||
SecretQueueElement elem = secret_elem_pool.Create();
|
||||
elem.secret_trigger = secret_trigger;
|
||||
elem.secret = secret;
|
||||
elem.triggerer = trigger;
|
||||
elem.callback = callback;
|
||||
secret_queue.Enqueue(elem);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void AddCallback(Action callback)
|
||||
{
|
||||
if (callback != null)
|
||||
{
|
||||
CallbackQueueElement elem = callback_elem_pool.Create();
|
||||
elem.callback = callback;
|
||||
callback_queue.Enqueue(elem);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Resolve()
|
||||
{
|
||||
if (ability_queue.Count > 0)
|
||||
{
|
||||
//Resolve Ability
|
||||
AbilityQueueElement elem = ability_queue.Dequeue();
|
||||
ability_elem_pool.Dispose(elem);
|
||||
elem.callback?.Invoke(elem.ability, elem.caster, elem.triggerer);
|
||||
}
|
||||
else if (secret_queue.Count > 0)
|
||||
{
|
||||
//Resolve Secret
|
||||
SecretQueueElement elem = secret_queue.Dequeue();
|
||||
secret_elem_pool.Dispose(elem);
|
||||
elem.callback?.Invoke(elem.secret_trigger, elem.secret, elem.triggerer);
|
||||
}
|
||||
else if (attack_queue.Count > 0)
|
||||
{
|
||||
//Resolve Attack
|
||||
AttackQueueElement elem = attack_queue.Dequeue();
|
||||
attack_elem_pool.Dispose(elem);
|
||||
if (elem.ptarget != null)
|
||||
elem.pcallback?.Invoke(elem.attacker, elem.ptarget, elem.skip_cost);
|
||||
else
|
||||
elem.callback?.Invoke(elem.attacker, elem.target, elem.skip_cost);
|
||||
}
|
||||
else if (callback_queue.Count > 0)
|
||||
{
|
||||
CallbackQueueElement elem = callback_queue.Dequeue();
|
||||
callback_elem_pool.Dispose(elem);
|
||||
elem.callback.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void ResolveAll(float delay)
|
||||
{
|
||||
SetDelay(delay);
|
||||
ResolveAll(); //Resolve now if no delay
|
||||
}
|
||||
|
||||
public virtual void ResolveAll()
|
||||
{
|
||||
if (is_resolving)
|
||||
return;
|
||||
|
||||
is_resolving = true;
|
||||
while (CanResolve())
|
||||
{
|
||||
Resolve();
|
||||
}
|
||||
is_resolving = false;
|
||||
}
|
||||
|
||||
public virtual void SetDelay(float delay)
|
||||
{
|
||||
if (!skip_delay)
|
||||
{
|
||||
resolve_delay = Mathf.Max(resolve_delay, delay);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool CanResolve()
|
||||
{
|
||||
if (resolve_delay > 0f)
|
||||
return false; //Is waiting delay
|
||||
if (game_data.state == GameState.GameEnded)
|
||||
return false; //Cant execute anymore when game is ended
|
||||
if (game_data.selector != SelectorType.None)
|
||||
return false; //Waiting for player input, in the middle of resolve loop
|
||||
return attack_queue.Count > 0 || ability_queue.Count > 0 || secret_queue.Count > 0 || callback_queue.Count > 0;
|
||||
}
|
||||
|
||||
public virtual bool IsResolving()
|
||||
{
|
||||
return is_resolving || resolve_delay > 0f;
|
||||
}
|
||||
|
||||
public virtual void Clear()
|
||||
{
|
||||
attack_elem_pool.DisposeAll();
|
||||
ability_elem_pool.DisposeAll();
|
||||
secret_elem_pool.DisposeAll();
|
||||
callback_elem_pool.DisposeAll();
|
||||
attack_queue.Clear();
|
||||
ability_queue.Clear();
|
||||
secret_queue.Clear();
|
||||
callback_queue.Clear();
|
||||
}
|
||||
|
||||
public Queue<AttackQueueElement> GetAttackQueue()
|
||||
{
|
||||
return attack_queue;
|
||||
}
|
||||
|
||||
public Queue<AbilityQueueElement> GetAbilityQueue()
|
||||
{
|
||||
return ability_queue;
|
||||
}
|
||||
|
||||
public Queue<SecretQueueElement> GetSecretQueue()
|
||||
{
|
||||
return secret_queue;
|
||||
}
|
||||
|
||||
public Queue<CallbackQueueElement> GetCallbackQueue()
|
||||
{
|
||||
return callback_queue;
|
||||
}
|
||||
}
|
||||
|
||||
public class AbilityQueueElement
|
||||
{
|
||||
public AbilityData ability;
|
||||
public Card caster;
|
||||
public Card triggerer;
|
||||
public Action<AbilityData, Card, Card> callback;
|
||||
}
|
||||
|
||||
public class AttackQueueElement
|
||||
{
|
||||
public Card attacker;
|
||||
public Card target;
|
||||
public Player ptarget;
|
||||
public bool skip_cost;
|
||||
public Action<Card, Card, bool> callback;
|
||||
public Action<Card, Player, bool> pcallback;
|
||||
}
|
||||
|
||||
public class SecretQueueElement
|
||||
{
|
||||
public AbilityTrigger secret_trigger;
|
||||
public Card secret;
|
||||
public Card triggerer;
|
||||
public Action<AbilityTrigger, Card, Card> callback;
|
||||
}
|
||||
|
||||
public class CallbackQueueElement
|
||||
{
|
||||
public Action callback;
|
||||
}
|
||||
}
|
||||
11
Assets/TcgEngine/Scripts/Tools/ResolveQueue.cs.meta
Normal file
11
Assets/TcgEngine/Scripts/Tools/ResolveQueue.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: afa420d55af82614bb984510550d0b55
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
98
Assets/TcgEngine/Scripts/Tools/SaveTool.cs
Normal file
98
Assets/TcgEngine/Scripts/Tools/SaveTool.cs
Normal file
@@ -0,0 +1,98 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TcgEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// Script to write a class to the disk, or to read a file containing class from the disk
|
||||
/// </summary>
|
||||
|
||||
[System.Serializable]
|
||||
public class SaveTool
|
||||
{
|
||||
//Load any file to a class, make sure the class is marked with [System.Serializable]
|
||||
public static T LoadFile<T>(string filename) where T : class
|
||||
{
|
||||
T data = null;
|
||||
string fullpath = Application.persistentDataPath + "/" + filename;
|
||||
if (IsValidFilename(filename) && File.Exists(fullpath))
|
||||
{
|
||||
FileStream file = null;
|
||||
try
|
||||
{
|
||||
BinaryFormatter bf = new BinaryFormatter();
|
||||
file = File.Open(fullpath, FileMode.Open);
|
||||
data = (T)bf.Deserialize(file);
|
||||
file.Close();
|
||||
}
|
||||
catch (System.Exception e) { Debug.Log("Error Loading Data " + e); if (file != null) file.Close(); }
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
//Save any class to a file, make sure the class is marked with [System.Serializable]
|
||||
public static void SaveFile<T>(string filename, T data) where T : class
|
||||
{
|
||||
if (IsValidFilename(filename))
|
||||
{
|
||||
FileStream file = null;
|
||||
try
|
||||
{
|
||||
BinaryFormatter bf = new BinaryFormatter();
|
||||
string fullpath = Application.persistentDataPath + "/" + filename;
|
||||
file = File.Create(fullpath);
|
||||
bf.Serialize(file, data);
|
||||
file.Close();
|
||||
}
|
||||
catch (System.Exception e) { Debug.Log("Error Saving Data " + e); if (file != null) file.Close(); }
|
||||
}
|
||||
}
|
||||
|
||||
public static void DeleteFile(string filename)
|
||||
{
|
||||
string fullpath = Application.persistentDataPath + "/" + filename;
|
||||
if (File.Exists(fullpath))
|
||||
File.Delete(fullpath);
|
||||
}
|
||||
|
||||
//Return all save files
|
||||
public static List<string> GetAllSave(string extension = "")
|
||||
{
|
||||
List<string> saves = new List<string>();
|
||||
string[] files = Directory.GetFiles(Application.persistentDataPath);
|
||||
foreach (string file in files)
|
||||
{
|
||||
if (file.EndsWith(extension))
|
||||
{
|
||||
string filename = Path.GetFileName(file);
|
||||
if (!saves.Contains(filename))
|
||||
saves.Add(filename);
|
||||
}
|
||||
}
|
||||
return saves;
|
||||
}
|
||||
|
||||
public static bool DoesFileExist(string filename)
|
||||
{
|
||||
string fullpath = Application.persistentDataPath + "/" + filename;
|
||||
return IsValidFilename(filename) && File.Exists(fullpath);
|
||||
}
|
||||
|
||||
public static bool IsValidFilename(string filename)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(filename))
|
||||
return false; //Filename cant be blank
|
||||
|
||||
foreach (char c in Path.GetInvalidFileNameChars())
|
||||
{
|
||||
if (filename.Contains(c.ToString()))
|
||||
return false; //Dont allow any special characters
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
11
Assets/TcgEngine/Scripts/Tools/SaveTool.cs.meta
Normal file
11
Assets/TcgEngine/Scripts/Tools/SaveTool.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2dbbb87db1e098c41847b4715abd92a1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
31
Assets/TcgEngine/Scripts/Tools/SceneNav.cs
Normal file
31
Assets/TcgEngine/Scripts/Tools/SceneNav.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace TcgEngine
|
||||
{
|
||||
//Script to manage transitions between scenes
|
||||
public class SceneNav
|
||||
{
|
||||
public static void RestartLevel()
|
||||
{
|
||||
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
|
||||
}
|
||||
|
||||
public static void GoTo(string scene)
|
||||
{
|
||||
SceneManager.LoadScene(scene);
|
||||
}
|
||||
|
||||
public static string GetCurrentScene()
|
||||
{
|
||||
return SceneManager.GetActiveScene().name;
|
||||
}
|
||||
|
||||
public static bool DoSceneExist(string scene)
|
||||
{
|
||||
return Application.CanStreamedLevelBeLoaded(scene);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/TcgEngine/Scripts/Tools/SceneNav.cs.meta
Normal file
11
Assets/TcgEngine/Scripts/Tools/SceneNav.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 933adfda5408a474e8936d703933b7ae
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
59
Assets/TcgEngine/Scripts/Tools/TimeTool.cs
Normal file
59
Assets/TcgEngine/Scripts/Tools/TimeTool.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TcgEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// Class that simplifies the code for waiting for X seconds or waiting for condition
|
||||
/// Also allows to call coroutines outside of a MonoBehaviour
|
||||
/// </summary>
|
||||
|
||||
public class TimeTool
|
||||
{
|
||||
//--- Coroutine Code ----
|
||||
|
||||
public static void WaitFor(float time, Action callback)
|
||||
{
|
||||
StartCoroutine(WaitForRun(time, callback));
|
||||
}
|
||||
|
||||
public static void WaitUntil(Func<bool> condition, Action callback)
|
||||
{
|
||||
StartCoroutine(WaitUntilRun(condition, callback));
|
||||
}
|
||||
|
||||
private static IEnumerator WaitForRun(float time, Action callback) { yield return new WaitForSeconds(time); callback?.Invoke(); }
|
||||
private static IEnumerator WaitUntilRun(Func<bool> condition, Action callback) { yield return new WaitUntil(condition); callback?.Invoke(); }
|
||||
|
||||
public static Coroutine StartCoroutine(IEnumerator routine)
|
||||
{
|
||||
return TimeToolMono.Inst.StartCoroutine(routine);
|
||||
}
|
||||
|
||||
public static void StopCoroutine(Coroutine routine)
|
||||
{
|
||||
TimeToolMono.Inst.StopCoroutine(routine);
|
||||
}
|
||||
|
||||
//--- Tasks Code ----
|
||||
|
||||
//Do not use Task.Delay since its broken on some platform (like WebGl), use this instead
|
||||
public static async Task Delay(int miliseconds)
|
||||
{
|
||||
#if UNITY_WEBGL
|
||||
//WebGL Task.Delay is broken
|
||||
float seconds = miliseconds / 1000f;
|
||||
float start_time = Time.time;
|
||||
while (Time.time < start_time + seconds)
|
||||
await Task.Yield();
|
||||
#else
|
||||
//More performant on desktop/mobile
|
||||
await Task.Delay(miliseconds);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
11
Assets/TcgEngine/Scripts/Tools/TimeTool.cs.meta
Normal file
11
Assets/TcgEngine/Scripts/Tools/TimeTool.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 70c48b4b7b41aad449e94747a355299b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
34
Assets/TcgEngine/Scripts/Tools/TimeToolMono.cs
Normal file
34
Assets/TcgEngine/Scripts/Tools/TimeToolMono.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TcgEngine
|
||||
{
|
||||
public class TimeToolMono : MonoBehaviour
|
||||
{
|
||||
private static TimeToolMono _instance;
|
||||
|
||||
public Coroutine StartRoutine(IEnumerator routine)
|
||||
{
|
||||
return StartCoroutine(routine);
|
||||
}
|
||||
|
||||
public void StopRoutine(Coroutine routine)
|
||||
{
|
||||
StopCoroutine(routine);
|
||||
}
|
||||
|
||||
public static TimeToolMono Inst
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
GameObject ntool = new GameObject("TimeTool");
|
||||
_instance = ntool.AddComponent<TimeToolMono>();
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/TcgEngine/Scripts/Tools/TimeToolMono.cs.meta
Normal file
11
Assets/TcgEngine/Scripts/Tools/TimeToolMono.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8dc0cf85047b7af41a6a18095ff0b14a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
415
Assets/TcgEngine/Scripts/Tools/WebTool.cs
Normal file
415
Assets/TcgEngine/Scripts/Tools/WebTool.cs
Normal file
@@ -0,0 +1,415 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using UnityEngine.Networking;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using System.Net;
|
||||
using System.IO;
|
||||
using System.Collections;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TcgEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// Tool to send HTTP web resquests
|
||||
/// </summary>
|
||||
|
||||
public class WebRequest
|
||||
{
|
||||
public const string METHOD_GET = "GET";
|
||||
public const string METHOD_POST = "POST";
|
||||
public const string METHOD_PATCH = "PATCH";
|
||||
public const string METHOD_DELETE = "DELETE";
|
||||
public const int timeout = 10;
|
||||
|
||||
public static UnityWebRequest Create(string url)
|
||||
{
|
||||
UnityWebRequest request = new UnityWebRequest(url, METHOD_GET);
|
||||
request.SetRequestHeader("Content-Type", "application/json");
|
||||
request.downloadHandler = new DownloadHandlerBuffer();
|
||||
request.timeout = timeout;
|
||||
return request;
|
||||
}
|
||||
|
||||
public static UnityWebRequest Create(string url, string method, string json_data, string token)
|
||||
{
|
||||
UnityWebRequest request = new UnityWebRequest(url, method);
|
||||
request.SetRequestHeader("Content-Type", "application/json");
|
||||
if(token != null)
|
||||
request.SetRequestHeader("Authorization", token);
|
||||
request.downloadHandler = new DownloadHandlerBuffer();
|
||||
request.timeout = timeout;
|
||||
|
||||
if (method != METHOD_GET && !string.IsNullOrEmpty(json_data))
|
||||
{
|
||||
UploadHandler uploader = new UploadHandlerRaw(Encoding.UTF8.GetBytes(json_data));
|
||||
uploader.contentType = "application/json";
|
||||
request.uploadHandler = uploader;
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
public static UnityWebRequest CreateRaw(string url, string method, string contentType, byte[] data, string token)
|
||||
{
|
||||
UnityWebRequest request = new UnityWebRequest(url, method);
|
||||
request.SetRequestHeader("Content-Type", contentType);
|
||||
if (token != null)
|
||||
request.SetRequestHeader("Authorization", token);
|
||||
request.downloadHandler = new DownloadHandlerBuffer();
|
||||
request.timeout = timeout;
|
||||
|
||||
if (method != METHOD_GET && !string.IsNullOrEmpty(contentType))
|
||||
{
|
||||
UploadHandler uploader = new UploadHandlerRaw(data);
|
||||
uploader.contentType = contentType;
|
||||
request.uploadHandler = uploader;
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
public static UnityWebRequest CreateHeader(string url)
|
||||
{
|
||||
UnityWebRequest request = UnityWebRequest.Head(url);
|
||||
return request;
|
||||
}
|
||||
|
||||
public static UnityWebRequest CreateTexture(string url)
|
||||
{
|
||||
UnityWebRequest request = UnityWebRequestTexture.GetTexture(url);
|
||||
request.SetRequestHeader("Content-Type", "image/png");
|
||||
return request;
|
||||
}
|
||||
|
||||
public static UnityWebRequest CreateImageUploadForm(string url, string path, byte[] data, string token)
|
||||
{
|
||||
List<IMultipartFormSection> requestData = new List<IMultipartFormSection>();
|
||||
requestData.Add(new MultipartFormDataSection("path", path, "text"));
|
||||
requestData.Add(new MultipartFormFileSection("data", data, "file.png", "image/png"));
|
||||
|
||||
UnityWebRequest request = UnityWebRequest.Post(url, requestData);
|
||||
if (token != null)
|
||||
request.SetRequestHeader("Authorization", token);
|
||||
request.timeout = 200;
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
public static WebResponse GetResponse(UnityWebRequest request)
|
||||
{
|
||||
WebResponse res = new WebResponse();
|
||||
res.success = request.responseCode >= 200 && request.responseCode < 300;
|
||||
res.status = request.responseCode;
|
||||
res.error = request.error;
|
||||
res.data = "";
|
||||
if (request.downloadHandler != null)
|
||||
res.data = request.downloadHandler.text;
|
||||
return res;
|
||||
}
|
||||
|
||||
public static HeadResponse GetHeadResponse(UnityWebRequest request)
|
||||
{
|
||||
|
||||
HeadResponse res = new HeadResponse();
|
||||
res.success = request.responseCode >= 200 && request.responseCode < 300;
|
||||
res.status = request.responseCode;
|
||||
|
||||
string type = request.GetResponseHeader("Content-Type");
|
||||
DateTime.TryParse(request.GetResponseHeader("Last-Modified"), out DateTime date);
|
||||
int.TryParse(request.GetResponseHeader("Content-Length"), out int size);
|
||||
|
||||
res.content_type = type;
|
||||
res.last_edit = date;
|
||||
res.size = size;
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
public class WebTool
|
||||
{
|
||||
public static T JsonToObject<T>(string json)
|
||||
{
|
||||
T value = (T)Activator.CreateInstance(typeof(T));
|
||||
try
|
||||
{
|
||||
value = JsonUtility.FromJson<T>(json);
|
||||
}
|
||||
catch (Exception) { }
|
||||
return value;
|
||||
}
|
||||
|
||||
public static T[] JsonToArray<T>(string json)
|
||||
{
|
||||
ListJson<T> list = new ListJson<T>();
|
||||
list.list = new T[0];
|
||||
try
|
||||
{
|
||||
string wrap_json = "{ \"list\": " + json + "}";
|
||||
list = JsonUtility.FromJson<ListJson<T>>(wrap_json);
|
||||
return list.list;
|
||||
}
|
||||
catch (Exception) { }
|
||||
return new T[0];
|
||||
}
|
||||
|
||||
public static string ToJson(object data)
|
||||
{
|
||||
return JsonUtility.ToJson(data);
|
||||
}
|
||||
|
||||
public static int Parse(string int_str, int default_val = 0)
|
||||
{
|
||||
bool success = int.TryParse(int_str, out int val);
|
||||
return success ? val : default_val;
|
||||
}
|
||||
|
||||
public static async Task<WebResponse> SendRequest(string url)
|
||||
{
|
||||
UnityWebRequest req = WebRequest.Create(url);
|
||||
return await SendRequest(req);
|
||||
}
|
||||
|
||||
public static async Task<WebResponse> SendRequest(UnityWebRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
var asyncOp = request.SendWebRequest();
|
||||
while (!asyncOp.isDone)
|
||||
await TimeTool.Delay(200);
|
||||
}
|
||||
catch (Exception) {}
|
||||
|
||||
if (request.result != UnityWebRequest.Result.Success)
|
||||
Debug.Log(request.error);
|
||||
|
||||
WebResponse res = WebRequest.GetResponse(request);
|
||||
request.Dispose();
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
public class WebContext
|
||||
{
|
||||
public HttpListenerContext http;
|
||||
public string method;
|
||||
public string token;
|
||||
public string path;
|
||||
public string data;
|
||||
|
||||
public void SendResponse<T>(T value)
|
||||
{
|
||||
string val = WebTool.ToJson(value);
|
||||
SendResponse(val);
|
||||
}
|
||||
|
||||
public void SendResponse(ulong value)
|
||||
{
|
||||
SendResponse(value.ToString());
|
||||
}
|
||||
|
||||
public void SendResponse(int value)
|
||||
{
|
||||
SendResponse(value.ToString());
|
||||
}
|
||||
|
||||
public void SendResponse(bool value)
|
||||
{
|
||||
SendResponse(value.ToString());
|
||||
}
|
||||
|
||||
public void SendResponse(string value)
|
||||
{
|
||||
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(value);
|
||||
SendResponse(bytes, 200);
|
||||
}
|
||||
|
||||
public void SendError(string value)
|
||||
{
|
||||
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(value);
|
||||
SendResponse(bytes, 400);
|
||||
}
|
||||
|
||||
public void SendResponse()
|
||||
{
|
||||
try
|
||||
{
|
||||
WriteHeader();
|
||||
http.Response.StatusCode = 200;
|
||||
http.Response.Close();
|
||||
}
|
||||
catch (Exception e) { Debug.Log(e); }
|
||||
}
|
||||
|
||||
public void SendResponse(byte[] bytes, int code)
|
||||
{
|
||||
try
|
||||
{
|
||||
WriteHeader();
|
||||
http.Response.StatusCode = code;
|
||||
http.Response.OutputStream.Write(bytes, 0, bytes.Length);
|
||||
http.Response.Close();
|
||||
}
|
||||
catch (Exception e) { Debug.Log(e); }
|
||||
}
|
||||
|
||||
private void WriteHeader()
|
||||
{
|
||||
http.Response.Headers.Add("Access-Control-Allow-Origin", "*");
|
||||
http.Response.Headers.Add("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
|
||||
http.Response.Headers.Add("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
|
||||
}
|
||||
|
||||
public T GetData<T>()
|
||||
{
|
||||
return WebTool.JsonToObject<T>(data);
|
||||
}
|
||||
|
||||
public ulong GetInt64()
|
||||
{
|
||||
bool valid = ulong.TryParse(data, out ulong val);
|
||||
return valid ? val : 0;
|
||||
}
|
||||
|
||||
public int GetInt()
|
||||
{
|
||||
bool valid = int.TryParse(data, out int val);
|
||||
return valid ? val : 0;
|
||||
}
|
||||
|
||||
public bool GetBool()
|
||||
{
|
||||
bool valid = bool.TryParse(data, out bool val);
|
||||
return valid ? val : false;
|
||||
}
|
||||
|
||||
public ulong GetClientID()
|
||||
{
|
||||
bool valid = ulong.TryParse(token, out ulong val);
|
||||
return valid ? val : 0;
|
||||
}
|
||||
|
||||
public string GetIP()
|
||||
{
|
||||
return http.Request.RemoteEndPoint.Address.ToString();
|
||||
}
|
||||
|
||||
public string GetKey()
|
||||
{
|
||||
return token;
|
||||
}
|
||||
|
||||
public bool IsKeyValid(string key)
|
||||
{
|
||||
return token == key;
|
||||
}
|
||||
|
||||
public string GetQuery(string key)
|
||||
{
|
||||
try
|
||||
{
|
||||
return http.Request.QueryString.Get(key);
|
||||
}
|
||||
catch (Exception e) { Debug.Log(e); }
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
try
|
||||
{
|
||||
http.Response.Close();
|
||||
}
|
||||
catch (Exception e) { Debug.Log(e); }
|
||||
}
|
||||
|
||||
public static WebContext Create(HttpListenerContext http)
|
||||
{
|
||||
WebContext req = new WebContext();
|
||||
req.http = http;
|
||||
req.path = "";
|
||||
req.data = "";
|
||||
|
||||
try
|
||||
{
|
||||
req.method = http.Request.HttpMethod;
|
||||
req.path = http.Request.RawUrl.Remove(0, 1);
|
||||
req.token = http.Request.Headers.Get("Authorization");
|
||||
|
||||
if (http.Request.InputStream != null)
|
||||
{
|
||||
StreamReader reader = new StreamReader(http.Request.InputStream, http.Request.ContentEncoding);
|
||||
req.data = reader.ReadToEnd();
|
||||
}
|
||||
}
|
||||
catch (Exception e) { Debug.Log(e); }
|
||||
|
||||
return req;
|
||||
}
|
||||
}
|
||||
|
||||
public struct WebResponse
|
||||
{
|
||||
public bool success;
|
||||
public long status;
|
||||
public string data;
|
||||
public string error;
|
||||
|
||||
public ulong GetInt64()
|
||||
{
|
||||
bool valid = ulong.TryParse(data, out ulong val);
|
||||
return valid ? val : 0;
|
||||
}
|
||||
|
||||
public int GetInt()
|
||||
{
|
||||
bool valid = int.TryParse(data, out int val);
|
||||
return valid ? val : 0;
|
||||
}
|
||||
|
||||
public bool GetBool()
|
||||
{
|
||||
bool valid = bool.TryParse(data, out bool val);
|
||||
return valid ? val : false;
|
||||
}
|
||||
|
||||
public T GetData<T>()
|
||||
{
|
||||
return WebTool.JsonToObject<T>(data);
|
||||
}
|
||||
|
||||
public string GetError()
|
||||
{
|
||||
ErrorResponse err = WebTool.JsonToObject<ErrorResponse>(data);
|
||||
if(err != null)
|
||||
return err.error;
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
public class HeadResponse
|
||||
{
|
||||
public bool success;
|
||||
public long status;
|
||||
public DateTime last_edit;
|
||||
public int size;
|
||||
public string content_type;
|
||||
}
|
||||
|
||||
|
||||
[Serializable]
|
||||
public class ErrorResponse
|
||||
{
|
||||
public string error;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class ListJson<T>
|
||||
{
|
||||
public T[] list;
|
||||
public string error;
|
||||
}
|
||||
}
|
||||
11
Assets/TcgEngine/Scripts/Tools/WebTool.cs.meta
Normal file
11
Assets/TcgEngine/Scripts/Tools/WebTool.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b6db2a236e57b06458f732737ff1afc3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user