Title Screen

Polished UI for the title screen
Added login, registration and session management to CultClient
Connected title screen to CultClient login and registration
This commit is contained in:
hyperion51 2020-03-26 02:49:09 +00:00
commit 95947355c2
37 changed files with 4639 additions and 2433 deletions

View file

@ -1,6 +1,8 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using LiteNetLib;
using MessagePack;
using UniRx;
@ -10,14 +12,30 @@ public static class CultClient {
public static Action<string> Logger = s =>
MainThreadDispatcher.Post(_=>Debug.Log(s),null);
public static NetManager Client;
public static event Action<string> OnError;
public static int Ping;
private static NetManager _client;
private static NetPeer _peer;
private static Dictionary<Type, NotAnActionCollection> _messageCallbacks = new Dictionary<Type, NotAnActionCollection>();
private static Guid _token;
private static MD5 _hasher = MD5.Create();
public static bool Verified => _token != Guid.Empty;
public static bool Connected => _client != null;
public static void Send<T>(T m) where T : Message
{
Logger($"Sending message {MessagePackSerializer.SerializeToJson(m as Message)}");
_peer.Send(m as Message);
if (Connected)
{
if (Verified || m is LoginMessage || m is RegisterMessage || m is VerifyMessage)
{
Logger($"Sending message {MessagePackSerializer.SerializeToJson(m as Message)}");
_peer.Send(m as Message);
}
else Logger("Cannot send message, client is not verified!");
}
else Logger("Cannot send message, client is not connected!");
}
public static void ClearMessageListeners()
@ -32,38 +50,84 @@ public static class CultClient {
((ActionCollection<T>)_messageCallbacks[typeof(T)]).Add(callback);
}
public static void Login(string auth, string password)
{
if (8 < password.Length && password.Length < 32)
Send(new LoginMessage
{
Auth = auth,
Password = _hasher.ComputeHash(Encoding.UTF8.GetBytes(password))
});
else Logger("Invalid Password");
}
public static void Register(string email, string username, string password)
{
if (8 < password.Length && password.Length < 32)
Send(new RegisterMessage
{
Email = email,
Name = username,
Password = _hasher.ComputeHash(Encoding.UTF8.GetBytes(password))
});
else Logger("Invalid Password");
}
public static void Connect(string host = "localhost", int port = 3075)
{
EventBasedNetListener listener = new EventBasedNetListener();
Client = new NetManager(listener)
_client = new NetManager(listener)
{
// UnsyncedEvents = true,
// MergeEnabled = true,
// NatPunchEnabled = true
};
Client.Start(3074);
_peer = Client.Connect(host, port, "aetheria-cc65a44d");
Observable.EveryUpdate().Subscribe(_ => Client.PollEvents());
_client.Start(3074);
_peer = _client.Connect(host, port, "aetheria-cc65a44d");
Observable.EveryUpdate().Subscribe(_ => _client.PollEvents());
listener.NetworkErrorEvent += (point, code) => Logger($"{point.Address}: Error {code}");
listener.NetworkReceiveEvent += (peer, reader, method) =>
{
Logger($"Received message: {MessagePackSerializer.ConvertToJson(new ReadOnlyMemory<byte>(reader.RawData))}");
var message = MessagePackSerializer.Deserialize<Message>(reader.RawData);
var type = message.GetType();
if (!Verified)
{
switch (message)
{
case LoginSuccessMessage loginSuccess:
_token = loginSuccess.Session;
return;
case ErrorMessage error:
OnError?.Invoke(error.Error);
return;
}
}
if (_messageCallbacks.ContainsKey(type))
typeof(ActionCollection<>).MakeGenericType(new[] {type}).GetMethod("Invoke").Invoke(_messageCallbacks[type], new object[] {message});
typeof(ActionCollection<>).MakeGenericType(new[] {type}).GetMethod("Invoke")
.Invoke(_messageCallbacks[type], new object[] {message});
else
Logger(
$"Received {type.Name} message but no one is listening for it so I'll just leave it here " +
$"¯\\_(ツ)_/¯\n{MessagePackSerializer.ConvertToJson(new ReadOnlyMemory<byte>(reader.RawData))}");
};
listener.PeerConnectedEvent += peer =>
{
Logger($"Peer {peer.EndPoint.Address}:{peer.EndPoint.Port} connected.");
_peer = peer;
// onConnect();
};
listener.PeerDisconnectedEvent += (peer, info) =>
{
Logger($"Peer {peer.EndPoint.Address}:{peer.EndPoint.Port} disconnected: {info.Reason}.");
_peer = null;
};
// listener.NetworkLatencyUpdateEvent += (peer, latency) => Logger($"Ping received: {latency} ms");
listener.NetworkLatencyUpdateEvent +=
(peer, latency) => Ping = latency; //Logger($"Ping received: {latency} ms");
}
}

View file

@ -0,0 +1,102 @@
using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class FlatButton : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler
{
public event Action<FlatButton> OnClick;
public float StateDamping;
// public RectTransform Tab;
public Image Fill;
public Image Outline;
public TextMeshProUGUI Label;
public VerticalLayoutGroup LabelLayout;
public FlatButtonState CurrentState = FlatButtonState.Unselected;
public bool DisableClickWhenSelected = true;
public FlatButtonAppearance UnselectedAppearance;
public FlatButtonAppearance SelectedAppearance;
public FlatButtonAppearance HoverAppearance;
public FlatButtonAppearance ClickAppearance;
private RectOffset _defaultPadding;
private float _currentPadding;
private void Start()
{
_defaultPadding = LabelLayout.padding;
_currentPadding = _defaultPadding.left;
}
public void OnPointerEnter(PointerEventData eventData)
{
if (CurrentState == FlatButtonState.Unselected)
CurrentState = FlatButtonState.Hover;
}
public void OnPointerExit(PointerEventData eventData)
{
if (CurrentState == FlatButtonState.Hover)
CurrentState = FlatButtonState.Unselected;
}
public void OnPointerClick(PointerEventData eventData)
{
if (!DisableClickWhenSelected || CurrentState != FlatButtonState.Selected)
{
Fill.color = ClickAppearance.FillColor;
Outline.color = ClickAppearance.OutlineColor;
OnClick?.Invoke(this);
}
}
private void Update()
{
FlatButtonAppearance appearance;
switch (CurrentState)
{
case FlatButtonState.Unselected:
appearance = UnselectedAppearance;
break;
case FlatButtonState.Selected:
appearance = SelectedAppearance;
break;
case FlatButtonState.Hover:
appearance = HoverAppearance;
break;
default:
appearance = new FlatButtonAppearance();
break;
}
Fill.color = Color.Lerp(Fill.color, appearance.FillColor, StateDamping * Time.deltaTime);
Outline.color = Color.Lerp(Outline.color, appearance.OutlineColor, StateDamping * Time.deltaTime);
_currentPadding = Mathf.Lerp(_currentPadding, appearance.LayoutPadding, StateDamping * Time.deltaTime);
LabelLayout.padding = new RectOffset
{
bottom = _defaultPadding.bottom,
top = _defaultPadding.top,
left = (int) _currentPadding,
right = (int) _currentPadding
};
}
}
public enum FlatButtonState
{
Unselected,
Selected,
Hover
}
[Serializable]
public struct FlatButtonAppearance
{
public Color FillColor;
public Color OutlineColor;
public int LayoutPadding;
}

View file

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 2ddfc923291e13a458e7e78f2100c021
guid: 9ec664fdf25c943478e0ca99c935c2fd
MonoImporter:
externalObjects: {}
serializedVersion: 2

View file

@ -1,17 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class Scr_Log_In : MonoBehaviour
{
public void Change_Scene()
{
SceneManager.LoadScene("Main");
}
}

View file

@ -10,6 +10,17 @@ public class NameAttribute : Attribute
}
}
[AttributeUsage(AttributeTargets.Class)]
public class RethinkTableAttribute : Attribute
{
public string TableName;
public RethinkTableAttribute(string tableName)
{
TableName = tableName;
}
}
public class UpdateOrderAttribute : Attribute
{
public int Order;

View file

@ -45,6 +45,7 @@ public abstract class DatabaseEntry
[IgnoreMember] public GameContext Context { get; set; }
}
[RethinkTable("Users")]
[MessagePackObject]
[JsonObject(MemberSerialization.OptIn)]
public class Player : DatabaseEntry, INamedEntry
@ -58,8 +59,8 @@ public class Player : DatabaseEntry, INamedEntry
[JsonProperty("username")] [Key(3)]
public string Username;
[JsonProperty("salt")] [Key(4)]
public string Salt;
[JsonProperty("corporation")] [Key(4)]
public Guid Corporation;
[IgnoreMember] public string EntryName
{
@ -68,6 +69,7 @@ public class Player : DatabaseEntry, INamedEntry
}
}
[RethinkTable("Galaxy")]
[MessagePackObject]
[JsonObject(MemberSerialization.OptIn)]
public class Corporation : DatabaseEntry, INamedEntry

View file

@ -28,8 +28,8 @@ public class PingMessage : Message
[MessagePackObject]
public class LoginMessage : Message
{
[Key(0)] public string Email;
[Key(1)] public string Password;
[Key(0)] public string Auth;
[Key(1)] public byte[] Password;
}
[MessagePackObject]
@ -37,7 +37,7 @@ public class RegisterMessage : Message
{
[Key(0)] public string Name;
[Key(1)] public string Email;
[Key(2)] public string Password;
[Key(2)] public byte[] Password;
}
[MessagePackObject]

View file

@ -5,6 +5,7 @@ using MessagePack;
using Newtonsoft.Json;
using Unity.Mathematics;
[RethinkTable("Galaxy")]
[MessagePackObject]
[JsonObject(MemberSerialization.OptIn)]
public class ZoneData : DatabaseEntry, INamedEntry
@ -34,6 +35,7 @@ public class ZoneData : DatabaseEntry, INamedEntry
}
}
[RethinkTable("Galaxy")]
[MessagePackObject]
[JsonObject(MemberSerialization.OptIn)]
public class Station : DatabaseEntry, INamedEntry
@ -57,6 +59,9 @@ public class Station : DatabaseEntry, INamedEntry
[JsonProperty("selling")] [Key(6)]
public Dictionary<Guid, float> SellPrices = new Dictionary<Guid, float>();
[JsonProperty("zone")] [Key(7)]
public Guid Zone;
[IgnoreMember] public string EntryName
{
get => Name;
@ -64,6 +69,7 @@ public class Station : DatabaseEntry, INamedEntry
}
}
[RethinkTable("Galaxy")]
[MessagePackObject]
[JsonObject(MemberSerialization.OptIn)]
public class PlanetData : DatabaseEntry, INamedEntry
@ -77,6 +83,9 @@ public class PlanetData : DatabaseEntry, INamedEntry
[JsonProperty("mass")] [Key(3)]
public float Mass;
[JsonProperty("zone")] [Key(4)]
public Guid Zone;
[IgnoreMember] public string EntryName
{
get => Name;
@ -84,6 +93,7 @@ public class PlanetData : DatabaseEntry, INamedEntry
}
}
[RethinkTable("Galaxy")]
[MessagePackObject]
[JsonObject(MemberSerialization.OptIn)]
public class OrbitData : DatabaseEntry
@ -99,4 +109,7 @@ public class OrbitData : DatabaseEntry
[JsonProperty("period")] [Key(4)]
public float Period;
[JsonProperty("zone")] [Key(5)]
public Guid Zone;
}

View file

@ -1,8 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Switch_state : MonoBehaviour
{
}

View file

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: c062bd8d0dfb2714a8098c6299ac8741
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -6,96 +6,7 @@ using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class TabButton : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler
public class TabButton : FlatButton
{
public event Action<TabButton> OnClick;
public float StateDamping;
public RectTransform Tab;
public Image Fill;
public Image Outline;
public TextMeshProUGUI Label;
public VerticalLayoutGroup LabelLayout;
public TabButtonState CurrentState = TabButtonState.Unselected;
public TabButtonAppearance UnselectedAppearance;
public TabButtonAppearance SelectedAppearance;
public TabButtonAppearance HoverAppearance;
public TabButtonAppearance ClickAppearance;
private RectOffset _defaultPadding;
private float _currentPadding;
private void Start()
{
_defaultPadding = LabelLayout.padding;
_currentPadding = _defaultPadding.left;
}
public void OnPointerEnter(PointerEventData eventData)
{
if (CurrentState == TabButtonState.Unselected)
CurrentState = TabButtonState.Hover;
}
public void OnPointerExit(PointerEventData eventData)
{
if (CurrentState == TabButtonState.Hover)
CurrentState = TabButtonState.Unselected;
}
public void OnPointerClick(PointerEventData eventData)
{
if (CurrentState != TabButtonState.Selected)
{
Fill.color = ClickAppearance.FillColor;
Outline.color = ClickAppearance.OutlineColor;
OnClick?.Invoke(this);
}
}
private void Update()
{
TabButtonAppearance appearance;
switch (CurrentState)
{
case TabButtonState.Unselected:
appearance = UnselectedAppearance;
break;
case TabButtonState.Selected:
appearance = SelectedAppearance;
break;
case TabButtonState.Hover:
appearance = HoverAppearance;
break;
default:
appearance = new TabButtonAppearance();
break;
}
Fill.color = Color.Lerp(Fill.color, appearance.FillColor, StateDamping * Time.deltaTime);
Outline.color = Color.Lerp(Outline.color, appearance.OutlineColor, StateDamping * Time.deltaTime);
_currentPadding = Mathf.Lerp(_currentPadding, appearance.LayoutPadding, StateDamping * Time.deltaTime);
LabelLayout.padding = new RectOffset
{
bottom = _defaultPadding.bottom,
top = _defaultPadding.top,
left = (int) _currentPadding,
right = (int) _currentPadding
};
}
}
public enum TabButtonState
{
Unselected,
Selected,
Hover
}
[Serializable]
public struct TabButtonAppearance
{
public Color FillColor;
public Color OutlineColor;
public int LayoutPadding;
}

View file

@ -19,12 +19,12 @@ public class TabGroup : MonoBehaviour
{
if (_currentButton != null)
{
_currentButton.CurrentState = TabButtonState.Unselected;
_currentButton.CurrentState = FlatButtonState.Unselected;
_currentButton.Tab.gameObject.SetActive(false);
}
_currentButton = thisButton;
_currentButton.CurrentState = TabButtonState.Selected;
_currentButton.CurrentState = FlatButtonState.Selected;
_currentButton.Tab.gameObject.SetActive(true);
OnTabChange?.Invoke(_currentButton);
};