I'm trying to use the FMETP asset implementing the pun script following the information from the web page and the process that I'm doing in unity editor is object with FMETP Encoder assignig the FMStreamPun method to send the bit -> New Object with FMStreamPun script signing the FMETP Encoder.
Doing that the decoder doesn't receive the information from the encoder.
Do you know something about that topic?
This is the FMStreamPun Script
using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using FMETP;
public class FMStreamPun : Photon.Pun.MonoBehaviourPun, IPunObservable
{
private Queue<byte[]> appendQueueSendData = new Queue<byte[]>();
public int appendQueueSendDataCount { get { return appendQueueSendData.Count; } }
public UnityEventByteArray OnDataByteReadyEvent = new UnityEventByteArray();
public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
Debug.Log("entro al seriaize view");
if (stream.IsWriting)
{
Debug.Log("is writting");
//Send the meta data of the byte[] queue length
stream.SendNext(appendQueueSendDataCount);
//Sending the queued byte[]
while (appendQueueSendDataCount > 0)
{
byte[] sentData = appendQueueSendData.Dequeue();
stream.SendNext(sentData);
}
}
if (stream.IsReading)
{
if (!photonView.IsMine)
{
//Get the queue length
int streamCount = (int)stream.ReceiveNext();
for (int i = 0; i < streamCount; i++)
{
//reading stream one by one
byte[] receivedData = (byte[])stream.ReceiveNext();
OnDataByteReadyEvent.Invoke(receivedData);
}
}
}
}
public void Action_SendData(byte[] inputData)
{
Debug.Log("entro al action send data");
//inputData(byte[]) is the encoded byte[] from your encoder
//doesn't require any stream, when there is only one player in the room
//if (PhotonNetwork.CurrentRoom.PlayerCount > 1)
//{
appendQueueSendData.Enqueue(inputData);
//}
}
}
I'm using both assets but I can't find any way to receive the information ito de decoder
Related
What I am trying to do is take a texture(any texture) from unity and use a webhook from discord to send it to discord.
This is what I have so far keep in mind I started coding not long ago so I'm not very familiar with this;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
public class SendMessage : MonoBehaviour
{
public string Message, Subject;
public string webhook;
public Texture2D screenshot;
// Start is called before the first frame update
void Start()
{
}
IEnumerator SendWebHook(string link, string message, System.Action<bool> action)
{
WWWForm form = new WWWForm();
form.AddField("content", message + screenshot.EncodeToPNG());
using (UnityWebRequest www = UnityWebRequest.Post(link, form))
{
yield return www.SendWebRequest();
if(www.isNetworkError || www.isHttpError)
{
Debug.Log(www.error);
action(false);
}
else
{
action(true);
}
}
}
public void send()
{
StartCoroutine(SendWebHook(webhook, Subject + Message, (success) =>
{
if(success)
{
Debug.Log("good");
}
}));
}
}
I am developing a QR code decoder for my project.
I took the reference from Unity Zxing QR code scanner integration
I am using unity 2018+ and Vuforia 7+
Can Anyone help me where I have made a mistake?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Vuforia;
using ZXing;
using System;
[AddComponentMenu("System/QRScanner")]
public class QRScanner : MonoBehaviour
{
private bool cameraInitialized;
private BarcodeReader barCodeReader;
void Start()
{
barCodeReader = new BarcodeReader();
StartCoroutine(InitializeCamera());
}
private IEnumerator InitializeCamera()
{
// Waiting a little seem to avoid the Vuforia's crashes.
yield return new WaitForSeconds(1.25f);
var isFrameFormatSet = CameraDevice.Instance.SetFrameFormat(Image.PIXEL_FORMAT.GRAYSCALE, true);
Debug.Log(String.Format("FormatSet : {0}", isFrameFormatSet));
// Force autofocus.
var isAutoFocus = CameraDevice.Instance.SetFocusMode(CameraDevice.FocusMode.FOCUS_MODE_CONTINUOUSAUTO);
if (!isAutoFocus)
{
CameraDevice.Instance.SetFocusMode(CameraDevice.FocusMode.FOCUS_MODE_NORMAL);
}
Debug.Log(String.Format("AutoFocus : {0}", isAutoFocus));
cameraInitialized = true;
}
private void Update()
{
if (cameraInitialized)
{
try
{
var cameraFeed = CameraDevice.Instance.GetCameraImage(Image.PIXEL_FORMAT.GRAYSCALE);
if (cameraFeed == null)
{
return;
}
var data = barCodeReader.Decode(cameraFeed.Pixels, cameraFeed.BufferWidth, cameraFeed.BufferHeight, RGBLuminanceSource.BitmapFormat.RGB24);
if (data != null)
{
// QRCode detected.
Debug.Log("Detected");
Debug.Log(data.Text);
}
else
{
Debug.Log("No QR code detected !");
}
}
catch (Exception e)
{
Debug.LogError(e.Message);
}
}
}
}
Result right now: "QR code not detected".
Target which I am using working on other qr code reader app
I am trying to stream some data between 2 editors using a simple tcp client/server setup:
Server:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine;
public class TCPTestServer : MonoBehaviour {
#region private members
/// <summary>
/// TCPListener to listen for incomming TCP connection
/// requests.
/// </summary>
private TcpListener tcpListener;
/// <summary>
/// Background thread for TcpServer workload.
/// </summary>
private Thread tcpListenerThread;
/// <summary>
/// Create handle to connected tcp client.
/// </summary>
private TcpClient connectedTcpClient;
#endregion
// Use this for initialization
void Start () {
// Start TcpServer background thread
tcpListenerThread = new Thread (new ThreadStart(ListenForIncommingRequests));
tcpListenerThread.IsBackground = true;
tcpListenerThread.Start();
}
// Update is called once per frame
void Update () {
SendMessage();
}
/// <summary>
/// Runs in background TcpServerThread; Handles incomming TcpClient requests
/// </summary>
private void ListenForIncommingRequests () {
try {
// Create listener on localhost port 8052.
tcpListener = new TcpListener(IPAddress.Parse("myip"), 65535);
tcpListener.Start();
Debug.Log("Server is listening");
Byte[] bytes = new Byte[1024];
while (true) {
using (connectedTcpClient = tcpListener.AcceptTcpClient()) {
// Get a stream object for reading
using (NetworkStream stream = connectedTcpClient.GetStream()) {
int length;
// Read incomming stream into byte arrary.
while ((length = stream.Read(bytes, 0, bytes.Length)) != 0) {
var incommingData = new byte[length];
Array.Copy(bytes, 0, incommingData, 0, length);
// Convert byte array to string message.
string clientMessage = Encoding.ASCII.GetString(incommingData);
Debug.Log("client message received as: " + clientMessage);
}
}
}
}
}
catch (SocketException socketException) {
Debug.Log("SocketException " + socketException.ToString());
}
}
/// <summary>
/// Send message to client using socket connection.
/// </summary>
private void SendMessage() {
if (connectedTcpClient == null) {
return;
}
try {
// Get a stream object for writing.
NetworkStream stream = connectedTcpClient.GetStream();
if (stream.CanWrite) {
string serverMessage = this.gameObject.transform.position.ToString();
// Convert string message to byte array.
byte[] serverMessageAsByteArray = Encoding.ASCII.GetBytes(serverMessage);
// Write byte array to socketConnection stream.
stream.Write(serverMessageAsByteArray, 0, serverMessageAsByteArray.Length);
Debug.Log("Server sent his message - should be received by client");
}
}
catch (SocketException socketException) {
Debug.Log("Socket exception: " + socketException);
}
}
void OnApplicationQuit()
{
tcpListenerThread.Abort();
connectedTcpClient.Close ();
}
}
Client:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine;
public class TCPTestClient : MonoBehaviour {
#region private members
private TcpClient socketConnection;
private Thread clientReceiveThread;
#endregion
// Use this for initialization
void Start () {
ConnectToTcpServer();
}
// Update is called once per frame
void Update () {
if (Input.GetKeyDown(KeyCode.Space)) {
SendMessage();
}
}
/// <summary>
/// Setup socket connection.
/// </summary>
private void ConnectToTcpServer () {
try {
clientReceiveThread = new Thread (new ThreadStart(ListenForData));
clientReceiveThread.IsBackground = true;
clientReceiveThread.Start();
}
catch (Exception e) {
Debug.Log("On client connect exception " + e);
}
}
/// <summary>
/// Runs in background clientReceiveThread; Listens for incomming data.
/// </summary>
private void ListenForData() {
try {
socketConnection = new TcpClient("myip", 65535);
Byte[] bytes = new Byte[1024];
while (true) {
// Get a stream object for reading
using (NetworkStream stream = socketConnection.GetStream()) {
int length;
// Read incomming stream into byte arrary.
while ((length = stream.Read(bytes, 0, bytes.Length)) != 0) {
var incommingData = new byte[length];
Array.Copy(bytes, 0, incommingData, 0, length);
// Convert byte array to string message.
string serverMessage = Encoding.ASCII.GetString(incommingData);
Debug.Log("server message received as: " + serverMessage);
}
}
}
}
catch (SocketException socketException) {
Debug.Log("Socket exception: " + socketException);
}
}
/// <summary>
/// Send message to server using socket connection.
/// </summary>
private void SendMessage() {
if (socketConnection == null) {
return;
}
try {
// Get a stream object for writing.
NetworkStream stream = socketConnection.GetStream();
if (stream.CanWrite) {
string clientMessage = "This is a message from one of your clients.";
// Convert string message to byte array.
byte[] clientMessageAsByteArray = Encoding.ASCII.GetBytes(clientMessage);
// Write byte array to socketConnection stream.
stream.Write(clientMessageAsByteArray, 0, clientMessageAsByteArray.Length);
//Debug.Log("Client sent his message - should be received by server");
}
}
catch (SocketException socketException) {
Debug.Log("Socket exception: " + socketException);
}
}
void OnApplicationQuit()
{
clientReceiveThread.Abort();
socketConnection.Close ();
}
}
This works in local but wont work if i run the server and client seperately in two different computers. Moreover, i triend ping.eu and my port seems closed even if i forwarded from my firewall settings. What am I doing wrong?
The Load balancer accepts incoming requests, re-sends them to multiple servers, and returns the answers from the servers to the awaiting clients.
// Dispatcher.cs
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace LoadBallancer {
public class Dispatcher
{
// set the TcpListener on port 8890
int port = 8890;
TcpListener server;
List<CoreComm> processors = new List<CoreComm>();
static void Main()
{
var dispatcher = new Dispatcher();
dispatcher.ListenForRequests();
}
public Dispatcher()
{
server = new TcpListener(IPAddress.Any, port);
}
public void ListenForRequests()
{
server.Start();
while (true)
{
try
{
// Start listening for client requests
// Enter the listening loop
Console.Write("Waiting for a connection... ");
lock(server)
{
// Perform a blocking call to accept requests.
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("Connected.");
ThreadPool.QueueUserWorkItem(ThreadProc, client);
}
}
catch (Exception e)
{
Console.WriteLine("Exception: {0}", e);
}
}
}
private static void ThreadProc(object obj)
{
var processor = new CoreComm((TcpClient)obj);
processor.ReSendRequest(null);
}
}
}
// CoreComm.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Configuration;
using System.Threading;
namespace LoadBallancer
{
public class IamServer
{
public string Url { get; set; }
public int Port { get; set; }
public string Type { get; set; }
}
public class CoreComm
{
// Buffer for reading data
int bufSize = 1024;
static List<IamServer> servers = new List<IamServer>();
protected TcpClient acceptorSocket;
NetworkStream acceptorStream;
protected TcpClient clientSocket;
protected List<KeyValuePair<int, byte[]>> requestPackets = new List<KeyValuePair<int, byte[]>>();
static CoreComm()
{
// reading config for servers' parameters
}
public CoreComm(TcpClient socket)
{
acceptorSocket = socket;
// Get a stream object for reading and writing
acceptorStream = acceptorSocket.GetStream();
}
private void ReadFromAcceptorStream()
{
// Loop to receive all the data sent by the client.
while (acceptorStream.DataAvailable)
{
byte[] requestBuffer = new byte[bufSize];
int i = acceptorStream.Read(requestBuffer, 0, requestBuffer.Length);
requestPackets.Add(new KeyValuePair<int, byte[]>(i, requestBuffer));
}
}
public void ReSendRequest(Object threadContext)
{
ReadFromAcceptorStream();
var servers = GetDestinationServers(null);
if (servers.Count == 0)
acceptorStream.Write(ErrMessage, 0, ErrMessage.Length);
else
// for debug only send the first in the list
SendRequestToServer(servers[0]);
// Shutdown and end connection
acceptorSocket.Close();
}
public void SendRequestToServer(IamServer server)
{
clientSocket = new TcpClient();
clientSocket.Connect(server.Url, server.Port);
NetworkStream clientStream = clientSocket.GetStream();
foreach (var packet in requestPackets)
clientStream.Write(packet.Value, 0, packet.Key);
var requestBuffer = new byte[bufSize];
while (clientStream.DataAvailable)
{
int i = clientStream.Read(requestBuffer, 0, requestBuffer.Length);
acceptorStream.Write(requestBuffer, 0, i);
}
clientSocket.Close();
}
// Mock up of the real load balancing algorithm
static int lastServerAnswered = 0;
public List<IamServer> GetDestinationServers(string requestData)
{
// processing to determine the query destinations
lock(servers)
{
// patch
int currentServerNum = lastServerAnswered;
lastServerAnswered ++ ;
if (lastServerAnswered > servers.Count - 1)
lastServerAnswered = 0;
return new List<IamServer> { servers[currentServerNum] };
}
}
}
}
So it works right when I set break-point in the code and does not work otherwise.
Any ideas?
The problem was found to be in the code:
while (clientStream.DataAvailable)
{
int i = clientStream.Read(requestBuffer, 0, requestBuffer.Length);
acceptorStream.Write(requestBuffer, 0, i);
}
Actually it happened that for some packets clientStream.DataAvailable was false even if there was still remaining data to be received. The solution is based on the application level protocol for which the Load Balancer had been developed that sends in the first 4 bytes of the stream the number of the total bytes that are sent.The code becomes as follows:
var responseBuffer = new byte[bufSize];
int numTotalBytesStreamed = clientStream.Read(responseBuffer, 0, responseBuffer.Length);
int numBytesToStream = GetNumBytesInTheStream(responseBuffer);
acceptorStream.Write(responseBuffer, 0, numTotalBytesStreamed);
while (numBytesToStream > numTotalBytesStreamed)
{
while (!clientStream.DataAvailable)
Thread.Sleep(1);
int numMoreBytesStreamed = clientStream.Read(responseBuffer, 0, responseBuffer.Length);
acceptorStream.Write(responseBuffer, 0, numMoreBytesStreamed);
numTotalBytesStreamed += numMoreBytesStreamed;
}
acceptorStream.Flush();
clientSocket.Close();
The solution works and is extremely stable for continuous loads of hundreds of requests per second.
I've successfully logged in with Google Play services in Unity, but I have a problem now that i have a class that contains some data like this:
public static class GameData
{
public static Dictionary<string, object> Name_Dic = new Dictionary<string, object>()
{
{"laura",""},
{"steph ",""},
{"Ryan",""},
};
public static Dictionary<string, string> Dialogs_Dic = new Dictionary<string, string>()
{
{"A1", "Hello"},
{"A2", "Nice"},
{"A3", "Test"},
};
public const int nbrTotal_Int = 2;
public const int TestNumber_Int = 5;
}
I have to save these data to the Google Cloud and after that load them from cloud, but i m confused i don't understand if i have to convert the dictionary in the GameManager class into String and then in to Bytes[] in order to save them in the Google Cloud or what can i do exactly. and the int variables i should convert them into string then into bytes[]. i ve searched into the internet and i can't found an explanation or tutorial for that and in the official documentation or the samples in the documentation it is not clear what can i do. Can you please help me please. Thanks a lot
Update
Hello,
Thanks for your answer, i ve written a code that let me save these variables to Google Cloud, here it is a part of the serialization the dictionary and the ints. is it correct like this. thanks for your answer.
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
public class Connect : MonoBehaviour
{
public Dictionary Name_Dic = new Dictionary()
{
{"laura",""},
{"steph ",""},
{"Ryan",""},
};
public Dictionary Dialogs_Dic = new Dictionary()
{
{"A1", "Hello"},
{"A2", "Nice"},
{"A3", "Test"},
};
public int nbrTotal_Int = 2;
public int TestNumber_Int = 5;
public void WriteFunction() {
ISavedGameMetadata currentGame = null;
Action<SavedGameRequestStatus, ISavedGameMetadata> writeCallback =
(SavedGameRequestStatus status, ISavedGameMetadata game) => {
Debug.Log(" Saved Game Write: " + status.ToString());
};
// CALLBACK: Handle the result of a binary read
Action<SavedGameRequestStatus, byte[]> readBinaryCallback =
(SavedGameRequestStatus status, byte[] data) =>
{
Debug.Log(" Saved Game Binary Read: " + status.ToString());
if (status == SavedGameRequestStatus.Success)
{
try {
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open(Application.persistentDataPath + "/gameInfo.dat",
FileMode.Open);
GameData data = new GameData();
// Two Dictionary
data.Name_Dic = Name_Dic;
data.Dialogs_Dic = Dialogs_Dic;
// Two Int
data.nbrTotal_Int = nbrTotal_Int;
data.TestNumber_Int = TestNumber_Int;
bf.Serialize(file, data);
file.Close();
} catch (Exception e) {
Debug.Log(" Saved Game Write: convert exception");
}
WriteSavedGame(currentGame, data, writeCallback);
}
};
}
}
[Serializable]
public class GameData
{
public Dictionary Name_Dic = new Dictionary()
{
{"laura",""},
{"steph ",""},
{"Ryan",""},
};
public Dictionary Dialogs_Dic = new Dictionary()
{
{"A1", "Hello"},
{"A2", "Nice"},
{"A3", "Test"},
};
public int nbrTotal_Int = 2;
public int TestNumber_Int = 5;
}``