394 lines
12 KiB
C#
394 lines
12 KiB
C#
#if !BESTHTTP_DISABLE_SOCKETIO
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
|
|
using UnityEngine;
|
|
using BestHTTP.SocketIO;
|
|
|
|
namespace BestHTTP.Examples
|
|
{
|
|
public sealed class SocketIOWePlaySample : MonoBehaviour
|
|
{
|
|
/// <summary>
|
|
/// Possible states of the game.
|
|
/// </summary>
|
|
enum States
|
|
{
|
|
Connecting,
|
|
WaitForNick,
|
|
Joined
|
|
}
|
|
|
|
/// <summary>
|
|
/// Controls that the server understands as a parameter in the move event.
|
|
/// </summary>
|
|
private string[] controls = new string[] { "left", "right", "a", "b", "up", "down", "select", "start" };
|
|
|
|
/// <summary>
|
|
/// Ratio of the drawn GUI texture from the screen
|
|
/// </summary>
|
|
private const float ratio = 1.5f;
|
|
|
|
/// <summary>
|
|
/// How many messages to keep.
|
|
/// </summary>
|
|
private int MaxMessages = 50;
|
|
|
|
/// <summary>
|
|
/// Current state of the game.
|
|
/// </summary>
|
|
private States State;
|
|
|
|
/// <summary>
|
|
/// The root("/") Socket instance.
|
|
/// </summary>
|
|
private Socket Socket;
|
|
|
|
/// <summary>
|
|
/// The user-selected nickname.
|
|
/// </summary>
|
|
private string Nick = string.Empty;
|
|
|
|
/// <summary>
|
|
/// The message that the user want to send to the chat.
|
|
/// </summary>
|
|
private string messageToSend = string.Empty;
|
|
|
|
/// <summary>
|
|
/// How many user connected to the server.
|
|
/// </summary>
|
|
private int connections;
|
|
|
|
/// <summary>
|
|
/// Local and server sent messages.
|
|
/// </summary>
|
|
private List<string> messages = new List<string>();
|
|
|
|
/// <summary>
|
|
/// The chat scroll position.
|
|
/// </summary>
|
|
private Vector2 scrollPos;
|
|
|
|
/// <summary>
|
|
/// The decoded texture from the server sent binary data
|
|
/// </summary>
|
|
private Texture2D FrameTexture;
|
|
|
|
#region Unity Events
|
|
|
|
void Start()
|
|
{
|
|
// Change an option to show how it should be done
|
|
SocketOptions options = new SocketOptions();
|
|
options.AutoConnect = false;
|
|
|
|
// Create the SocketManager instance
|
|
var manager = new SocketManager(new Uri("http://io.weplay.io/socket.io/"), options);
|
|
|
|
// Keep a reference to the root namespace
|
|
Socket = manager.Socket;
|
|
|
|
// Set up our event handlers.
|
|
Socket.On(SocketIOEventTypes.Connect, OnConnected);
|
|
Socket.On("joined", OnJoined);
|
|
Socket.On("connections", OnConnections);
|
|
Socket.On("join", OnJoin);
|
|
Socket.On("move", OnMove);
|
|
Socket.On("message", OnMessage);
|
|
Socket.On("reload", OnReload);
|
|
|
|
// Don't waste cpu cycles on decoding the payload, we are expecting only binary data with this event,
|
|
// and we can access it through the packet's Attachments property.
|
|
Socket.On("frame", OnFrame, /*autoDecodePayload:*/ false);
|
|
|
|
// Add error handler, so we can display it
|
|
Socket.On(SocketIOEventTypes.Error, OnError);
|
|
|
|
// We set SocketOptions' AutoConnect to false, so we have to call it manually.
|
|
manager.Open();
|
|
|
|
// We are connecting to the server.
|
|
State = States.Connecting;
|
|
}
|
|
|
|
void OnDestroy()
|
|
{
|
|
// Leaving this sample, close the socket
|
|
Socket.Manager.Close();
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
// Go back to the demo selector
|
|
if (Input.GetKeyDown(KeyCode.Escape))
|
|
SampleSelector.SelectedSample.DestroyUnityObject();
|
|
}
|
|
|
|
void OnGUI()
|
|
{
|
|
switch (State)
|
|
{
|
|
case States.Connecting:
|
|
GUIHelper.DrawArea(GUIHelper.ClientArea, true, () =>
|
|
{
|
|
GUILayout.BeginVertical();
|
|
GUILayout.FlexibleSpace();
|
|
GUIHelper.DrawCenteredText("Connecting to the server...");
|
|
GUILayout.FlexibleSpace();
|
|
GUILayout.EndVertical();
|
|
});
|
|
break;
|
|
|
|
case States.WaitForNick:
|
|
GUIHelper.DrawArea(GUIHelper.ClientArea, true, () =>
|
|
{
|
|
DrawLoginScreen();
|
|
});
|
|
break;
|
|
|
|
case States.Joined:
|
|
GUIHelper.DrawArea(GUIHelper.ClientArea, true, () =>
|
|
{
|
|
// Draw Texture
|
|
if (FrameTexture != null)
|
|
GUILayout.Box(FrameTexture);
|
|
|
|
DrawControls();
|
|
DrawChat();
|
|
});
|
|
break;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Helper Functions
|
|
|
|
/// <summary>
|
|
/// Called from an OnGUI event to draw the Login Screen.
|
|
/// </summary>
|
|
void DrawLoginScreen()
|
|
{
|
|
GUILayout.BeginVertical();
|
|
GUILayout.FlexibleSpace();
|
|
|
|
GUIHelper.DrawCenteredText("What's your nickname?");
|
|
|
|
Nick = GUILayout.TextField(Nick);
|
|
|
|
if (GUILayout.Button("Join"))
|
|
Join();
|
|
|
|
GUILayout.FlexibleSpace();
|
|
GUILayout.EndVertical();
|
|
}
|
|
|
|
void DrawControls()
|
|
{
|
|
GUILayout.BeginHorizontal();
|
|
GUILayout.Label("Controls:");
|
|
|
|
for (int i = 0; i < controls.Length; ++i)
|
|
if (GUILayout.Button(controls[i]))
|
|
Socket.Emit("move", controls[i]);
|
|
|
|
GUILayout.Label(" Connections: " + connections);
|
|
|
|
GUILayout.EndHorizontal();
|
|
}
|
|
|
|
void DrawChat(bool withInput = true)
|
|
{
|
|
GUILayout.BeginVertical();
|
|
|
|
// Draw the messages
|
|
scrollPos = GUILayout.BeginScrollView(scrollPos, false, false);
|
|
for (int i = 0; i < messages.Count; ++i)
|
|
GUILayout.Label(messages[i], GUILayout.MinWidth(Screen.width));
|
|
GUILayout.EndScrollView();
|
|
|
|
if (withInput)
|
|
{
|
|
GUILayout.Label("Your message: ");
|
|
|
|
GUILayout.BeginHorizontal();
|
|
|
|
messageToSend = GUILayout.TextField(messageToSend);
|
|
|
|
if (GUILayout.Button("Send", GUILayout.MaxWidth(100)))
|
|
SendMessage();
|
|
|
|
GUILayout.EndHorizontal();
|
|
}
|
|
|
|
GUILayout.EndVertical();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add a message to the message log
|
|
/// </summary>
|
|
/// <param name="msg"></param>
|
|
void AddMessage(string msg)
|
|
{
|
|
messages.Insert(0, msg);
|
|
if (messages.Count > MaxMessages)
|
|
messages.RemoveRange(MaxMessages, messages.Count - MaxMessages);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Send a chat message. The message must be in the messageToSend field.
|
|
/// </summary>
|
|
void SendMessage()
|
|
{
|
|
if (string.IsNullOrEmpty(messageToSend))
|
|
return;
|
|
|
|
Socket.Emit("message", messageToSend);
|
|
AddMessage(string.Format("{0}: {1}", Nick, messageToSend));
|
|
messageToSend = string.Empty;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Join to the game with the nickname stored in the Nick field.
|
|
/// </summary>
|
|
void Join()
|
|
{
|
|
PlayerPrefs.SetString("Nick", Nick);
|
|
|
|
Socket.Emit("join", Nick);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reload the game.
|
|
/// </summary>
|
|
void Reload()
|
|
{
|
|
FrameTexture = null;
|
|
|
|
if (Socket != null)
|
|
{
|
|
Socket.Manager.Close();
|
|
Socket = null;
|
|
|
|
Start();
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region SocketIO Events
|
|
|
|
/// <summary>
|
|
/// Socket connected event.
|
|
/// </summary>
|
|
private void OnConnected(Socket socket, Packet packet, params object[] args)
|
|
{
|
|
if (PlayerPrefs.HasKey("Nick"))
|
|
{
|
|
Nick = PlayerPrefs.GetString("Nick", "NickName");
|
|
Join();
|
|
}
|
|
else
|
|
State = States.WaitForNick;
|
|
|
|
AddMessage("connected");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Local player joined after sending a 'join' event
|
|
/// </summary>
|
|
private void OnJoined(Socket socket, Packet packet, params object[] args)
|
|
{
|
|
State = States.Joined;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Server sent us a 'reload' event.
|
|
/// </summary>
|
|
private void OnReload(Socket socket, Packet packet, params object[] args)
|
|
{
|
|
Reload();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Someone wrote a message to the chat.
|
|
/// </summary>
|
|
private void OnMessage(Socket socket, Packet packet, params object[] args)
|
|
{
|
|
if (args.Length == 1)
|
|
AddMessage(args[0] as string);
|
|
else
|
|
AddMessage(string.Format("{0}: {1}", args[1], args[0]));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Someone (including us) pressed a button.
|
|
/// </summary>
|
|
private void OnMove(Socket socket, Packet packet, params object[] args)
|
|
{
|
|
AddMessage(string.Format("{0} pressed {1}", args[1], args[0]));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Someone joined to the game
|
|
/// </summary>
|
|
private void OnJoin(Socket socket, Packet packet, params object[] args)
|
|
{
|
|
string loc = args.Length > 1 ? string.Format("({0})", args[1]) : string.Empty;
|
|
|
|
AddMessage(string.Format("{0} joined {1}", args[0], loc));
|
|
}
|
|
|
|
/// <summary>
|
|
/// How many players are connected to the game.
|
|
/// </summary>
|
|
private void OnConnections(Socket socket, Packet packet, params object[] args)
|
|
{
|
|
connections = Convert.ToInt32(args[0]);
|
|
}
|
|
|
|
/// <summary>
|
|
/// The server sent us a new picture to draw the game.
|
|
/// </summary>
|
|
private void OnFrame(Socket socket, Packet packet, params object[] args)
|
|
{
|
|
if (State != States.Joined)
|
|
return;
|
|
|
|
if (FrameTexture == null)
|
|
{
|
|
FrameTexture = new Texture2D(0, 0, TextureFormat.RGBA32, false);
|
|
FrameTexture.filterMode = FilterMode.Point;
|
|
}
|
|
|
|
// Binary data usage case 1 - using directly the Attachments property:
|
|
byte[] data = packet.Attachments[0];
|
|
|
|
// Binary data usage case 2 - using the packet's ReconstructAttachmentAsIndex() function
|
|
/*packet.ReconstructAttachmentAsIndex();
|
|
args = packet.Decode(socket.Manager.Encoder);
|
|
data = packet.Attachments[Convert.ToInt32(args[0])];*/
|
|
|
|
// Binary data usage case 3 - using the packet's ReconstructAttachmentAsBase64() function
|
|
/*packet.ReconstructAttachmentAsBase64();
|
|
args = packet.Decode(socket.Manager.Encoder);
|
|
data = Convert.FromBase64String(args[0] as string);*/
|
|
|
|
// Load the server sent picture
|
|
FrameTexture.LoadImage(data);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called on local or remote error.
|
|
/// </summary>
|
|
private void OnError(Socket socket, Packet packet, params object[] args)
|
|
{
|
|
AddMessage(string.Format("--ERROR - {0}", args[0].ToString()));
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
#endif |