test
testing
This commit is contained in:
+5
@@ -0,0 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dcbd9d9cedc5c08428abc8d2aea83a12
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
userData:
|
||||
+209
@@ -0,0 +1,209 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// <copyright file="AccountService.cs" company="Exit Games GmbH">
|
||||
// Photon Cloud Account Service - Copyright (C) 2012 Exit Games GmbH
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// Provides methods to register a new user-account for the Photon Cloud and
|
||||
// get the resulting appId.
|
||||
// </summary>
|
||||
// <author>developer@exitgames.com</author>
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
using System.Net.Security;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
public class AccountService
|
||||
{
|
||||
private const string ServiceUrl = "https://service.exitgames.com/AccountExt/AccountServiceExt.aspx";
|
||||
|
||||
private Action<AccountService> registrationCallback; // optional (when using async reg)
|
||||
|
||||
public string Message { get; private set; } // msg from server (in case of success, this is the appid)
|
||||
|
||||
protected internal Exception Exception { get; set; } // exceptions in account-server communication
|
||||
|
||||
public string AppId { get; private set; }
|
||||
|
||||
public int ReturnCode { get; private set; } // 0 = OK. anything else is a error with Message
|
||||
|
||||
public enum Origin : byte { ServerWeb = 1, CloudWeb = 2, Pun = 3, Playmaker = 4 };
|
||||
|
||||
/// <summary>
|
||||
/// Creates a instance of the Account Service to register Photon Cloud accounts.
|
||||
/// </summary>
|
||||
public AccountService()
|
||||
{
|
||||
WebRequest.DefaultWebProxy = null;
|
||||
ServicePointManager.ServerCertificateValidationCallback = Validator;
|
||||
}
|
||||
|
||||
public static bool Validator(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors policyErrors)
|
||||
{
|
||||
return true; // any certificate is ok in this case
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to create a Photon Cloud Account.
|
||||
/// Check ReturnCode, Message and AppId to get the result of this attempt.
|
||||
/// </summary>
|
||||
/// <param name="email">Email of the account.</param>
|
||||
/// <param name="origin">Marks which channel created the new account (if it's new).</param>
|
||||
public void RegisterByEmail(string email, Origin origin)
|
||||
{
|
||||
this.registrationCallback = null;
|
||||
this.AppId = string.Empty;
|
||||
this.Message = string.Empty;
|
||||
this.ReturnCode = -1;
|
||||
|
||||
string result;
|
||||
try
|
||||
{
|
||||
WebRequest req = HttpWebRequest.Create(this.RegistrationUri(email, (byte)origin));
|
||||
HttpWebResponse resp = req.GetResponse() as HttpWebResponse;
|
||||
|
||||
// now read result
|
||||
StreamReader reader = new StreamReader(resp.GetResponseStream());
|
||||
result = reader.ReadToEnd();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Message = "Failed to connect to Cloud Account Service. Please register via account website.";
|
||||
this.Exception = ex;
|
||||
return;
|
||||
}
|
||||
|
||||
this.ParseResult(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to create a Photon Cloud Account asynchronously.
|
||||
/// Once your callback is called, check ReturnCode, Message and AppId to get the result of this attempt.
|
||||
/// </summary>
|
||||
/// <param name="email">Email of the account.</param>
|
||||
/// <param name="origin">Marks which channel created the new account (if it's new).</param>
|
||||
/// <param name="callback">Called when the result is available.</param>
|
||||
public void RegisterByEmailAsync(string email, Origin origin, Action<AccountService> callback = null)
|
||||
{
|
||||
this.registrationCallback = callback;
|
||||
this.AppId = string.Empty;
|
||||
this.Message = string.Empty;
|
||||
this.ReturnCode = -1;
|
||||
|
||||
try
|
||||
{
|
||||
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(this.RegistrationUri(email, (byte)origin));
|
||||
req.Timeout = 5000;
|
||||
req.BeginGetResponse(this.OnRegisterByEmailCompleted, req);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Message = "Failed to connect to Cloud Account Service. Please register via account website.";
|
||||
this.Exception = ex;
|
||||
if (this.registrationCallback != null)
|
||||
{
|
||||
this.registrationCallback(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal callback with result of async HttpWebRequest (in RegisterByEmailAsync).
|
||||
/// </summary>
|
||||
/// <param name="ar"></param>
|
||||
private void OnRegisterByEmailCompleted(IAsyncResult ar)
|
||||
{
|
||||
try
|
||||
{
|
||||
HttpWebRequest request = (HttpWebRequest)ar.AsyncState;
|
||||
HttpWebResponse response = request.EndGetResponse(ar) as HttpWebResponse;
|
||||
|
||||
if (response != null && response.StatusCode == HttpStatusCode.OK)
|
||||
{
|
||||
// no error. use the result
|
||||
StreamReader reader = new StreamReader(response.GetResponseStream());
|
||||
string result = reader.ReadToEnd();
|
||||
|
||||
this.ParseResult(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
// a response but some error on server. show message
|
||||
this.Message = "Failed to connect to Cloud Account Service. Please register via account website.";
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// not even a response. show message
|
||||
this.Message = "Failed to connect to Cloud Account Service. Please register via account website.";
|
||||
this.Exception = ex;
|
||||
}
|
||||
|
||||
if (this.registrationCallback != null)
|
||||
{
|
||||
this.registrationCallback(this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the service-call Uri, escaping the email for security reasons.
|
||||
/// </summary>
|
||||
/// <param name="email">Email of the account.</param>
|
||||
/// <param name="origin">1 = server-web, 2 = cloud-web, 3 = PUN, 4 = playmaker</param>
|
||||
/// <returns>Uri to call.</returns>
|
||||
private Uri RegistrationUri(string email, byte origin)
|
||||
{
|
||||
string emailEncoded = Uri.EscapeDataString(email);
|
||||
string uriString = string.Format("{0}?email={1}&origin={2}", ServiceUrl, emailEncoded, origin);
|
||||
|
||||
return new Uri(uriString);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the Json response and applies it to local properties.
|
||||
/// </summary>
|
||||
/// <param name="result"></param>
|
||||
private void ParseResult(string result)
|
||||
{
|
||||
if (string.IsNullOrEmpty(result))
|
||||
{
|
||||
this.Message = "Server's response was empty. Please register through account website during this service interruption.";
|
||||
return;
|
||||
}
|
||||
|
||||
Dictionary<string, string> values = JsonConvert.DeserializeObject<Dictionary<string, string>>(result);
|
||||
if (values == null)
|
||||
{
|
||||
this.Message = "Service temporarily unavailable. Please register through account website.";
|
||||
return;
|
||||
}
|
||||
|
||||
int returnCodeInt = -1;
|
||||
string returnCodeString = string.Empty;
|
||||
string message;
|
||||
|
||||
values.TryGetValue("ReturnCode", out returnCodeString);
|
||||
values.TryGetValue("Message", out message);
|
||||
int.TryParse(returnCodeString, out returnCodeInt);
|
||||
|
||||
this.ReturnCode = returnCodeInt;
|
||||
if (returnCodeInt == 0)
|
||||
{
|
||||
// returnCode == 0 means: all ok. message is new AppId
|
||||
this.AppId = message;
|
||||
}
|
||||
else
|
||||
{
|
||||
// any error gives returnCode != 0
|
||||
this.AppId = string.Empty;
|
||||
this.Message = message;
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 166dfe22956ef0341b28e18d0499e363
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
BIN
Binary file not shown.
+7
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0268f98d7c649564a818b0768fc68d4b
|
||||
MonoAssemblyImporter:
|
||||
serializedVersion: 1
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
userData:
|
||||
+341
@@ -0,0 +1,341 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// <copyright file="PhotonConverter.cs" company="Exit Games GmbH">
|
||||
// PhotonNetwork Framework for Unity - Copyright (C) 2011 Exit Games GmbH
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// Script to convert a Unity Networking project to PhotonNetwork.
|
||||
// </summary>
|
||||
// <author>developer@exitgames.com</author>
|
||||
// ----------------------------------------------------------------------------
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
public class PhotonConverter : Photon.MonoBehaviour
|
||||
{
|
||||
|
||||
public static void RunConversion()
|
||||
{
|
||||
//Ask if user has made a backup.
|
||||
bool result = EditorUtility.DisplayDialog("Conversion", "Did you create a backup of your project before converting?", "Yes", "Abort conversion");
|
||||
if (!result)
|
||||
{
|
||||
return;
|
||||
}
|
||||
//REAAAALY?
|
||||
result = EditorUtility.DisplayDialog("Conversion", "Disclaimer: The code conversion feature is quite crude, but should do it's job well (see the sourcecode). A backup is therefore strongly recommended!", "Yes, I've made a backup: GO", "Abort");
|
||||
if (!result)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Output(EditorApplication.timeSinceStartup + " Started conversion of Unity networking -> Photon");
|
||||
|
||||
//Ask to save current scene (optional)
|
||||
EditorApplication.SaveCurrentSceneIfUserWantsTo();
|
||||
|
||||
EditorUtility.DisplayProgressBar("Converting..", "Starting.", 0);
|
||||
|
||||
//Convert NetworkViews to PhotonViews in Project prefabs
|
||||
//Ask the user if we can move all prefabs to a resources folder
|
||||
bool movePrefabs = EditorUtility.DisplayDialog("Conversion", "Can all prefabs that use a PhotonView be moved to a Resources/ folder? You need this if you use Network.Instantiate.", "Yes", "No");
|
||||
|
||||
|
||||
string[] prefabs = Directory.GetFiles("Assets/", "*.prefab", SearchOption.AllDirectories);
|
||||
foreach (string prefab in prefabs)
|
||||
{
|
||||
EditorUtility.DisplayProgressBar("Converting..", "Object:" + prefab, 0.6f);
|
||||
|
||||
Object[] objs = (Object[])AssetDatabase.LoadAllAssetsAtPath(prefab);
|
||||
int converted = 0;
|
||||
foreach (Object obj in objs)
|
||||
{
|
||||
if (obj != null && obj.GetType() == typeof(GameObject))
|
||||
converted += ConvertNetworkView(((GameObject)obj).GetComponents<NetworkView>(), false);
|
||||
}
|
||||
if (movePrefabs && converted > 0)
|
||||
{
|
||||
//This prefab needs to be under the root of a Resources folder!
|
||||
string path = prefab.Replace("\\", "/");
|
||||
int lastSlash = path.LastIndexOf("/");
|
||||
int resourcesIndex = path.LastIndexOf("/Resources/");
|
||||
if (resourcesIndex != lastSlash - 10)
|
||||
{
|
||||
if (path.Contains("/Resources/"))
|
||||
{
|
||||
Debug.LogWarning("Warning, prefab [" + prefab + "] was already in a resources folder. But has been placed in the root of another one!");
|
||||
}
|
||||
//This prefab NEEDS to be placed under a resources folder
|
||||
string resourcesFolder = path.Substring(0, lastSlash) + "/Resources/";
|
||||
EnsureFolder(resourcesFolder);
|
||||
string newPath = resourcesFolder + path.Substring(lastSlash + 1);
|
||||
string error = AssetDatabase.MoveAsset(prefab, newPath);
|
||||
if (error != "")
|
||||
Debug.LogError(error);
|
||||
Output("Fixed prefab [" + prefab + "] by moving it into a resources folder.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Convert NetworkViews to PhotonViews in scenes
|
||||
string[] sceneFiles = Directory.GetFiles("Assets/", "*.unity", SearchOption.AllDirectories);
|
||||
foreach (string sceneName in sceneFiles)
|
||||
{
|
||||
EditorApplication.OpenScene(sceneName);
|
||||
EditorUtility.DisplayProgressBar("Converting..", "Scene:" + sceneName, 0.2f);
|
||||
|
||||
int converted2 = ConvertNetworkView((NetworkView[])GameObject.FindObjectsOfType(typeof(NetworkView)), true);
|
||||
if (converted2 > 0)
|
||||
{
|
||||
//This will correct all prefabs: The prefabs have gotten new components, but the correct ID's were lost in this case
|
||||
PhotonViewInspector.VerifyAllSceneViews();
|
||||
|
||||
Output("Replaced " + converted2 + " NetworkViews with PhotonViews in scene: " + sceneName);
|
||||
EditorApplication.SaveScene(EditorApplication.currentScene);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//Convert C#/JS scripts (API stuff)
|
||||
List<string> scripts = new List<string>();
|
||||
scripts.AddRange(Directory.GetFiles("Assets/", "*.cs", SearchOption.AllDirectories));
|
||||
scripts.AddRange(Directory.GetFiles("Assets/", "*.js", SearchOption.AllDirectories));
|
||||
scripts.AddRange(Directory.GetFiles("Assets/", "*.boo", SearchOption.AllDirectories));
|
||||
EditorUtility.DisplayProgressBar("Converting..", "Scripts..", 0.9f);
|
||||
ConvertScripts(scripts);
|
||||
|
||||
Output(EditorApplication.timeSinceStartup + " Completed conversion!");
|
||||
|
||||
EditorUtility.ClearProgressBar();
|
||||
}
|
||||
|
||||
static void ConvertScripts(List<string> scripts)
|
||||
{
|
||||
foreach (string script in scripts)
|
||||
{
|
||||
if (script.Contains("PhotonNetwork"))//Don't convert this file (and others)
|
||||
continue;
|
||||
if (script.Contains("Image Effects"))
|
||||
continue;
|
||||
|
||||
string text = File.ReadAllText(script);
|
||||
|
||||
text = ConvertToPhotonAPI(script, text);
|
||||
|
||||
File.WriteAllText(script, text);
|
||||
}
|
||||
foreach (string script in scripts){
|
||||
AssetDatabase.ImportAsset(script, ImportAssetOptions.ForceUpdate);
|
||||
}
|
||||
}
|
||||
|
||||
static string ConvertToPhotonAPI(string file, string input)
|
||||
{
|
||||
bool isJS = file.Contains(".js");
|
||||
|
||||
file =file.Replace("\\", "/"); // Get Class name for JS
|
||||
string className = file.Substring(file.LastIndexOf("/")+1);
|
||||
className = className.Substring(0, className.IndexOf("."));
|
||||
|
||||
|
||||
//REGEXP STUFF
|
||||
//Valid are: Space { } , /n /r
|
||||
//string NOT_VAR = @"([^A-Za-z0-9_\[\]\.]+)";
|
||||
string NOT_VAR_WITH_DOT = @"([^A-Za-z0-9_]+)";
|
||||
|
||||
//string VAR_NONARRAY = @"[^A-Za-z0-9_]";
|
||||
|
||||
|
||||
|
||||
//NetworkView
|
||||
{
|
||||
input = PregReplace(input, NOT_VAR_WITH_DOT + "NetworkView" + NOT_VAR_WITH_DOT, "$1PhotonView$2");
|
||||
input = PregReplace(input, NOT_VAR_WITH_DOT + "networkView" + NOT_VAR_WITH_DOT, "$1photonView$2");
|
||||
input = PregReplace(input, NOT_VAR_WITH_DOT + "stateSynchronization" + NOT_VAR_WITH_DOT, "$1synchronization$2");
|
||||
//.RPC
|
||||
input = PregReplace(input, NOT_VAR_WITH_DOT + "RPCMode.Server" + NOT_VAR_WITH_DOT, "$1PhotonTargets.MasterClient$2");
|
||||
input = PregReplace(input, NOT_VAR_WITH_DOT + "RPCMode" + NOT_VAR_WITH_DOT, "$1PhotonTargets$2");
|
||||
}
|
||||
|
||||
//NetworkMessageInfo: 100%
|
||||
{
|
||||
input = PregReplace(input, NOT_VAR_WITH_DOT + "NetworkMessageInfo" + NOT_VAR_WITH_DOT, "$1PhotonMessageInfo$2");
|
||||
input = PregReplace(input, NOT_VAR_WITH_DOT + "networkView" + NOT_VAR_WITH_DOT, "$1photonView$2");
|
||||
}
|
||||
|
||||
//NetworkViewID:
|
||||
{
|
||||
input = PregReplace(input, NOT_VAR_WITH_DOT + "NetworkViewID" + NOT_VAR_WITH_DOT, "$1PhotonViewID$2");
|
||||
}
|
||||
|
||||
//NetworkPlayer
|
||||
{
|
||||
input = PregReplace(input, NOT_VAR_WITH_DOT + "NetworkPlayer" + NOT_VAR_WITH_DOT, "$1PhotonPlayer$2");
|
||||
}
|
||||
|
||||
//Network
|
||||
{
|
||||
//Monobehaviour callbacks
|
||||
{
|
||||
input = PregReplace(input, NOT_VAR_WITH_DOT + "OnPlayerConnected" + NOT_VAR_WITH_DOT, "$1OnPhotonPlayerConnected$2");
|
||||
input = PregReplace(input, NOT_VAR_WITH_DOT + "OnPlayerDisconnected" + NOT_VAR_WITH_DOT, "$1OnPhotonPlayerDisconnected$2");
|
||||
input = PregReplace(input, NOT_VAR_WITH_DOT + "OnNetworkInstantiate" + NOT_VAR_WITH_DOT, "$1OnPhotonInstantiate$2");
|
||||
input = PregReplace(input, NOT_VAR_WITH_DOT + "OnSerializeNetworkView" + NOT_VAR_WITH_DOT, "$1OnPhotonSerializeView$2");
|
||||
input = PregReplace(input, NOT_VAR_WITH_DOT + "BitStream" + NOT_VAR_WITH_DOT, "$1PhotonStream$2");
|
||||
|
||||
//Not completely the same meaning
|
||||
input = PregReplace(input, NOT_VAR_WITH_DOT + "OnServerInitialized" + NOT_VAR_WITH_DOT, "$1OnCreatedRoom$2");
|
||||
input = PregReplace(input, NOT_VAR_WITH_DOT + "OnConnectedToServer" + NOT_VAR_WITH_DOT, "$1OnJoinedRoom$2");
|
||||
|
||||
input = PregReplace(input, NOT_VAR_WITH_DOT + "OnFailedToConnectToMasterServer" + NOT_VAR_WITH_DOT, "$1OnFailedToConnectToPhoton$2");
|
||||
input = PregReplace(input, NOT_VAR_WITH_DOT + "OnFailedToConnect" + NOT_VAR_WITH_DOT, "$1OnFailedToConnect_OBSELETE$2");
|
||||
}
|
||||
|
||||
//Variables
|
||||
{
|
||||
|
||||
input = PregReplace(input, NOT_VAR_WITH_DOT + "Network.connections" + NOT_VAR_WITH_DOT, "$1PhotonNetwork.playerList$2");
|
||||
input = PregReplace(input, NOT_VAR_WITH_DOT + "Network.isServer" + NOT_VAR_WITH_DOT, "$1PhotonNetwork.isMasterClient$2");
|
||||
input = PregReplace(input, NOT_VAR_WITH_DOT + "Network.isClient" + NOT_VAR_WITH_DOT, "$1PhotonNetwork.isNonMasterClientInRoom$2");
|
||||
|
||||
input = PregReplace(input, NOT_VAR_WITH_DOT + "NetworkPeerType" + NOT_VAR_WITH_DOT, "$1ConnectionState$2");
|
||||
input = PregReplace(input, NOT_VAR_WITH_DOT + "Network.peerType" + NOT_VAR_WITH_DOT, "$1PhotonNetwork.connectionState$2");
|
||||
input = PregReplace(input, NOT_VAR_WITH_DOT + "ConnectionState.Server" + NOT_VAR_WITH_DOT, "$1PhotonNetwork.isMasterClient$2");
|
||||
input = PregReplace(input, NOT_VAR_WITH_DOT + "ConnectionState.Client" + NOT_VAR_WITH_DOT, "$1PhotonNetwork.isNonMasterClientInRoom$2");
|
||||
input = PregReplace(input, NOT_VAR_WITH_DOT + "PhotonNetwork.playerList.Length" + NOT_VAR_WITH_DOT, "$1PhotonNetwork.playerList.Count$2");
|
||||
|
||||
/*DROPPED:
|
||||
minimumAllocatableViewIDs
|
||||
natFacilitatorIP is dropped
|
||||
natFacilitatorPort is dropped
|
||||
connectionTesterIP
|
||||
connectionTesterPort
|
||||
proxyIP
|
||||
proxyPort
|
||||
useProxy
|
||||
proxyPassword
|
||||
*/
|
||||
}
|
||||
|
||||
//Methods
|
||||
{
|
||||
input = PregReplace(input, NOT_VAR_WITH_DOT + "Network.InitializeServer" + NOT_VAR_WITH_DOT, "$1PhotonNetwork.JoinRoom$2");//Either Join or Create room
|
||||
input = PregReplace(input, NOT_VAR_WITH_DOT + "Network.Connect" + NOT_VAR_WITH_DOT, "$1PhotonNetwork.JoinRoom$2");
|
||||
input = PregReplace(input, NOT_VAR_WITH_DOT + "Network.GetAveragePing" + NOT_VAR_WITH_DOT, "$1PhotonNetwork.GetPing$2");
|
||||
input = PregReplace(input, NOT_VAR_WITH_DOT + "Network.GetLastPing" + NOT_VAR_WITH_DOT, "$1PhotonNetwork.GetPing$2");
|
||||
/*DROPPED:
|
||||
TestConnection
|
||||
TestConnectionNAT
|
||||
HavePublicAddress
|
||||
*/
|
||||
}
|
||||
|
||||
//Overall
|
||||
input = PregReplace(input, NOT_VAR_WITH_DOT + "Network" + NOT_VAR_WITH_DOT, "$1PhotonNetwork$2");
|
||||
}
|
||||
|
||||
//General
|
||||
{
|
||||
if (input.Contains("Photon")) //Only use the PhotonMonoBehaviour if we use photonView and friends.
|
||||
{
|
||||
if (isJS)//JS
|
||||
{
|
||||
if (input.Contains("extends MonoBehaviour"))
|
||||
input = PregReplace(input, "extends MonoBehaviour", "extends Photon.MonoBehaviour");
|
||||
else
|
||||
input = "class " + className + " extends Photon.MonoBehaviour {\n" + input + "\n}";
|
||||
}
|
||||
else //C#
|
||||
input = PregReplace(input, ": MonoBehaviour", ": Photon.MonoBehaviour");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
static string PregReplace(string input, string[] pattern, string[] replacements)
|
||||
{
|
||||
if (replacements.Length != pattern.Length)
|
||||
Debug.LogError("Replacement and Pattern Arrays must be balanced");
|
||||
|
||||
for (var i = 0; i < pattern.Length; i++)
|
||||
{
|
||||
input = Regex.Replace(input, pattern[i], replacements[i]);
|
||||
}
|
||||
|
||||
return input;
|
||||
}
|
||||
static string PregReplace(string input, string pattern, string replacement)
|
||||
{
|
||||
return Regex.Replace(input, pattern, replacement);
|
||||
|
||||
}
|
||||
|
||||
static void EnsureFolder(string path)
|
||||
{
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
static int ConvertNetworkView(NetworkView[] netViews, bool isScene)
|
||||
{
|
||||
for (int i = netViews.Length - 1; i >= 0; i--)
|
||||
{
|
||||
NetworkView netView = netViews[i];
|
||||
PhotonView view = netView.gameObject.AddComponent<PhotonView>();
|
||||
if (isScene)
|
||||
{
|
||||
//Get scene ID
|
||||
string str = netView.viewID.ToString().Replace("SceneID: ", "");
|
||||
int firstSpace = str.IndexOf(" ");
|
||||
str = str.Substring(0, firstSpace);
|
||||
int oldViewID = int.Parse(str);
|
||||
|
||||
view.viewID = new PhotonViewID(oldViewID, null);
|
||||
view.SetSceneID(oldViewID);
|
||||
EditorUtility.SetDirty(view);
|
||||
EditorUtility.SetDirty(view.gameObject);
|
||||
}
|
||||
view.observed = netView.observed;
|
||||
if (netView.stateSynchronization == NetworkStateSynchronization.Unreliable)
|
||||
{
|
||||
view.synchronization = ViewSynchronization.Unreliable;
|
||||
}
|
||||
else if (netView.stateSynchronization == NetworkStateSynchronization.ReliableDeltaCompressed)
|
||||
{
|
||||
view.synchronization = ViewSynchronization.ReliableDeltaCompressed;
|
||||
}
|
||||
else
|
||||
{
|
||||
view.synchronization = ViewSynchronization.Off;
|
||||
}
|
||||
DestroyImmediate(netView, true);
|
||||
}
|
||||
AssetDatabase.Refresh();
|
||||
AssetDatabase.SaveAssets();
|
||||
|
||||
return netViews.Length;
|
||||
}
|
||||
|
||||
|
||||
static void Output(string str)
|
||||
{
|
||||
Debug.Log(((int)EditorApplication.timeSinceStartup) + " " + str);
|
||||
}
|
||||
static void ConversionError(string file, string str)
|
||||
{
|
||||
Debug.LogError("Scrip conversion[" + file + "]: " + str);
|
||||
}
|
||||
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 15757b26cd9b53247be86da9e8da19dd
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
+629
@@ -0,0 +1,629 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// <copyright file="PhotonEditor.cs" company="Exit Games GmbH">
|
||||
// PhotonNetwork Framework for Unity - Copyright (C) 2011 Exit Games GmbH
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// MenuItems and in-Editor scripts for PhotonNetwork.
|
||||
// </summary>
|
||||
// <author>developer@exitgames.com</author>
|
||||
// ----------------------------------------------------------------------------
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
[InitializeOnLoad]
|
||||
public class PhotonEditor : EditorWindow
|
||||
{
|
||||
protected static AccountService.Origin RegisterOrigin = AccountService.Origin.Pun;
|
||||
|
||||
protected Vector2 scrollPos = Vector2.zero;
|
||||
|
||||
protected static string DocumentationLocation = "Assets/Photon Unity Networking/PhotonNetwork-Documentation.pdf";
|
||||
|
||||
protected static string UrlFreeLicense = "http://www.exitgames.com/Download/Photon";
|
||||
|
||||
protected static string UrlDevNet = "http://doc.exitgames.com/photon-cloud";
|
||||
|
||||
protected static string UrlForum = "http://forum.exitgames.com";
|
||||
|
||||
protected static string UrlCompare = "http://doc.exitgames.com/photon-cloud";
|
||||
|
||||
protected static string UrlHowToSetup = "http://doc.exitgames.com/photon-server/PhotonIn5Min/#cat-First%20Steps";
|
||||
|
||||
protected static string UrlAppIDExplained = "http://doc.exitgames.com/photon-cloud/PhotonDashboard/#cat-getting_started";
|
||||
|
||||
protected static string UrlAccountPage = "https://www.exitgames.com/Account/SignIn?email="; // opened in browser
|
||||
|
||||
|
||||
private enum GUIState
|
||||
{
|
||||
Uninitialized,
|
||||
|
||||
Main,
|
||||
|
||||
Setup
|
||||
}
|
||||
|
||||
private enum PhotonSetupStates
|
||||
{
|
||||
RegisterForPhotonCloud,
|
||||
|
||||
EmailAlreadyRegistered,
|
||||
|
||||
SetupPhotonCloud,
|
||||
|
||||
SetupSelfHosted
|
||||
}
|
||||
|
||||
private GUIState guiState = GUIState.Uninitialized;
|
||||
|
||||
private bool isSetupWizard = false;
|
||||
|
||||
private PhotonSetupStates photonSetupState = PhotonSetupStates.RegisterForPhotonCloud;
|
||||
|
||||
private static double lastWarning = 0;
|
||||
|
||||
private string photonAddress = "127.0.0.1";
|
||||
|
||||
private int photonPort = ServerSettings.DefaultMasterPort;
|
||||
|
||||
private string emailAddress = string.Empty;
|
||||
|
||||
private string cloudAppId = string.Empty;
|
||||
|
||||
private static int lastPhotonViewListLength = -1;
|
||||
|
||||
private static UnityEngine.Object lastFirstElement;
|
||||
|
||||
private static string lastScene = string.Empty;
|
||||
|
||||
private static bool dontCheckPunSetupField;
|
||||
|
||||
/// <summary>
|
||||
/// Can be used to (temporarily) disable the checks for PUN Setup and scene PhotonViews.
|
||||
/// This will prevent scene PhotonViews from being updated, so be careful.
|
||||
/// When you re-set this value, checks are used again and scene PhotonViews get IDs as needed.
|
||||
/// </summary>
|
||||
protected static bool dontCheckPunSetup
|
||||
{
|
||||
get
|
||||
{
|
||||
return dontCheckPunSetupField;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (dontCheckPunSetupField != value)
|
||||
{
|
||||
lastPhotonViewListLength = 0;
|
||||
dontCheckPunSetupField = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static Type WindowType = typeof(PhotonEditor);
|
||||
|
||||
protected static string WindowTitle = "PUN Setup Wizard";
|
||||
|
||||
[MenuItem("Window/Photon Unity Networking")]
|
||||
protected static void Init()
|
||||
{
|
||||
PhotonEditor.ReLoadCurrentSeetings();
|
||||
|
||||
PhotonEditor win = GetWindow(WindowType, false, WindowTitle) as PhotonEditor;
|
||||
win.ReApplySettingsToWindow();
|
||||
}
|
||||
|
||||
static PhotonEditor()
|
||||
{
|
||||
EditorApplication.projectWindowChanged += EditorUpdate;
|
||||
EditorApplication.hierarchyWindowChanged += EditorUpdate;
|
||||
EditorApplication.playmodeStateChanged += PlaymodeStateChanged;
|
||||
}
|
||||
|
||||
// called in editor, opens wizard for initial setup, keeps scene PhotonViews up to date and closes connections when compiling (to avoid issues)
|
||||
private static void EditorUpdate()
|
||||
{
|
||||
if (dontCheckPunSetup)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// serverSetting is null when the file gets deleted. otherwise, the wizard should only run once and only if hosting option is not (yet) set
|
||||
if (!PhotonEditor.Current.DisableAutoOpenWizard && PhotonEditor.Current.HostType == ServerSettings.HostingOption.NotSet)
|
||||
{
|
||||
ShowRegistrationWizard();
|
||||
}
|
||||
|
||||
// Workaround for TCP crash. Plus this surpresses any other recompile errors.
|
||||
if (EditorApplication.isCompiling)
|
||||
{
|
||||
if (PhotonNetwork.connected)
|
||||
{
|
||||
if (lastWarning > EditorApplication.timeSinceStartup - 3)
|
||||
{
|
||||
// Prevent error spam
|
||||
Debug.LogWarning("Unity recompile forced a Photon Disconnect");
|
||||
lastWarning = EditorApplication.timeSinceStartup;
|
||||
}
|
||||
|
||||
PhotonNetwork.Disconnect();
|
||||
}
|
||||
}
|
||||
else if (!EditorApplication.isPlaying)
|
||||
{
|
||||
// The following code could be optimized if Unity provides the right callbacks.
|
||||
// The current performance is 'OK' as we do check if the list changes (add/remove/duplicate should always change the length)
|
||||
|
||||
// We are currently checking all selected PhotonViews on hierarchy- and on project-change
|
||||
// Instead, we only want to check this when an NEW asset is placed in a scene (at editor time)
|
||||
// We need some sort of "OnCreated" call for scene objects.
|
||||
UnityEngine.Object[] objs = Selection.GetFiltered(typeof(PhotonView), SelectionMode.ExcludePrefab | SelectionMode.Editable | SelectionMode.Deep);
|
||||
if (objs.Length > 0 && (objs.Length != lastPhotonViewListLength || (lastFirstElement != objs[0])))
|
||||
{
|
||||
bool changed = false;
|
||||
foreach (UnityEngine.Object obj in objs)
|
||||
{
|
||||
PhotonView view = obj as PhotonView;
|
||||
if (!PhotonViewInspector.VerifySceneView(view))
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed)
|
||||
{
|
||||
Debug.Log("PUN: Corrected one or more scene-PhotonViews.");
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
lastPhotonViewListLength = objs.Length;
|
||||
lastFirstElement = objs[0];
|
||||
}
|
||||
|
||||
// Check the newly opened scene for wrong PhotonViews
|
||||
// This can happen when changing a prefab while viewing scene A. Instances in scene B will not be corrected.
|
||||
if (lastScene != EditorApplication.currentScene && EditorApplication.currentScene != string.Empty)
|
||||
{
|
||||
lastScene = EditorApplication.currentScene;
|
||||
PhotonViewInspector.VerifyAllSceneViews();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// called in editor on change of play-mode (used to show a message popup that connection settings are incomplete)
|
||||
private static void PlaymodeStateChanged()
|
||||
{
|
||||
if (dontCheckPunSetup || EditorApplication.isPlaying || !EditorApplication.isPlayingOrWillChangePlaymode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (PhotonEditor.Current.HostType == ServerSettings.HostingOption.NotSet)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Warning", "You have not yet run the Photon setup wizard! Your game won't be able to connect. See Windows -> Photon Unity Networking.", "Ok");
|
||||
}
|
||||
}
|
||||
|
||||
private void SwitchMenuState(GUIState newState)
|
||||
{
|
||||
this.guiState = newState;
|
||||
if (this.isSetupWizard && newState != GUIState.Setup)
|
||||
{
|
||||
this.Close();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Creates an Editor window, showing the cloud-registration wizard for Photon (entry point to setup PUN).</summary>
|
||||
protected static void ShowRegistrationWizard()
|
||||
{
|
||||
PhotonEditor.Current.DisableAutoOpenWizard = true;
|
||||
PhotonEditor.Save();
|
||||
|
||||
PhotonEditor window = (PhotonEditor)GetWindow(WindowType, false, WindowTitle, true);
|
||||
window.isSetupWizard = true;
|
||||
window.InitPhotonSetupWindow();
|
||||
}
|
||||
|
||||
/// <summary>Re-initializes the Photon Setup window and shows one of three states: register cloud, setup cloud, setup self-hosted.</summary>
|
||||
protected void InitPhotonSetupWindow()
|
||||
{
|
||||
this.SwitchMenuState(GUIState.Setup);
|
||||
|
||||
this.ReApplySettingsToWindow();
|
||||
|
||||
switch (PhotonEditor.Current.HostType)
|
||||
{
|
||||
case ServerSettings.HostingOption.PhotonCloud:
|
||||
this.photonSetupState = PhotonSetupStates.SetupPhotonCloud;
|
||||
break;
|
||||
case ServerSettings.HostingOption.SelfHosted:
|
||||
this.photonSetupState = PhotonSetupStates.SetupSelfHosted;
|
||||
break;
|
||||
case ServerSettings.HostingOption.NotSet:
|
||||
default:
|
||||
this.photonSetupState = PhotonSetupStates.RegisterForPhotonCloud;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnGUI()
|
||||
{
|
||||
this.scrollPos = GUILayout.BeginScrollView(this.scrollPos);
|
||||
|
||||
if (this.guiState == GUIState.Uninitialized)
|
||||
{
|
||||
this.ReApplySettingsToWindow();
|
||||
this.guiState = (PhotonEditor.Current.HostType == ServerSettings.HostingOption.NotSet) ? GUIState.Setup : GUIState.Main;
|
||||
}
|
||||
|
||||
if (this.guiState == GUIState.Main)
|
||||
{
|
||||
this.OnGuiMainWizard();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.OnGuiRegisterCloudApp();
|
||||
}
|
||||
|
||||
GUILayout.EndScrollView();
|
||||
}
|
||||
|
||||
protected virtual void OnGuiRegisterCloudApp()
|
||||
{
|
||||
GUI.skin.label.wordWrap = true;
|
||||
if (!this.isSetupWizard)
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
if (GUILayout.Button("Close setup", GUILayout.ExpandWidth(false)))
|
||||
{
|
||||
this.SwitchMenuState(GUIState.Main);
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.Space(15);
|
||||
}
|
||||
|
||||
if (this.photonSetupState == PhotonSetupStates.RegisterForPhotonCloud)
|
||||
{
|
||||
GUI.skin.label.fontStyle = FontStyle.Bold;
|
||||
GUILayout.Label("Connect to Photon Cloud");
|
||||
GUI.skin.label.fontStyle = FontStyle.Normal;
|
||||
|
||||
GUILayout.Label("Your e-mail address is required to access your own free app.");
|
||||
this.emailAddress = EditorGUILayout.TextField("Email:", this.emailAddress);
|
||||
|
||||
if (GUILayout.Button("Send"))
|
||||
{
|
||||
GUIUtility.keyboardControl = 0;
|
||||
this.RegisterWithEmail(this.emailAddress);
|
||||
}
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
GUILayout.Label("I am already signed up. Let me enter my AppId.");
|
||||
if (GUILayout.Button("Setup"))
|
||||
{
|
||||
this.photonSetupState = PhotonSetupStates.SetupPhotonCloud;
|
||||
}
|
||||
|
||||
GUILayout.Label("I want to register by a website.");
|
||||
if (GUILayout.Button("Open account website"))
|
||||
{
|
||||
EditorUtility.OpenWithDefaultApp(UrlAccountPage + Uri.EscapeUriString(this.emailAddress));
|
||||
}
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
}
|
||||
else if (this.photonSetupState == PhotonSetupStates.EmailAlreadyRegistered)
|
||||
{
|
||||
GUI.skin.label.fontStyle = FontStyle.Bold;
|
||||
GUILayout.Label("Oops!");
|
||||
GUI.skin.label.fontStyle = FontStyle.Normal;
|
||||
|
||||
GUILayout.Label("The provided e-mail-address has already been registered.");
|
||||
|
||||
if (GUILayout.Button("Mh, see my account page"))
|
||||
{
|
||||
EditorUtility.OpenWithDefaultApp(UrlAccountPage + Uri.EscapeUriString(this.emailAddress));
|
||||
}
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
GUILayout.Label("Ah, I know my Application ID. Get me to setup.");
|
||||
GUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("Cancel"))
|
||||
{
|
||||
this.photonSetupState = PhotonSetupStates.RegisterForPhotonCloud;
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Setup"))
|
||||
{
|
||||
this.photonSetupState = PhotonSetupStates.SetupPhotonCloud;
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
else if (this.photonSetupState == PhotonSetupStates.SetupPhotonCloud)
|
||||
{
|
||||
// cloud setup
|
||||
GUI.skin.label.fontStyle = FontStyle.Bold;
|
||||
GUILayout.Label("Connect to Photon Cloud");
|
||||
GUI.skin.label.fontStyle = FontStyle.Normal;
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
this.OnGuiSetupCloudAppId();
|
||||
this.OnGuiCompareAndHelpOptions();
|
||||
}
|
||||
else if (this.photonSetupState == PhotonSetupStates.SetupSelfHosted)
|
||||
{
|
||||
// self-hosting setup
|
||||
GUI.skin.label.fontStyle = FontStyle.Bold;
|
||||
GUILayout.Label("Setup own Photon Host");
|
||||
GUI.skin.label.fontStyle = FontStyle.Normal;
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
this.OnGuiSetupSelfhosting();
|
||||
this.OnGuiCompareAndHelpOptions();
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnGuiMainWizard()
|
||||
{
|
||||
// settings button
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Label("Settings", EditorStyles.boldLabel, GUILayout.Width(100));
|
||||
if (GUILayout.Button(new GUIContent("Setup", "Setup wizard for setting up your own server or the cloud.")))
|
||||
{
|
||||
this.InitPhotonSetupWindow();
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.Space(12);
|
||||
|
||||
// converter
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Label("Converter", EditorStyles.boldLabel, GUILayout.Width(100));
|
||||
if (GUILayout.Button(new GUIContent("Start", "Converts pure Unity Networking to Photon Unity Networking.")))
|
||||
{
|
||||
PhotonConverter.RunConversion();
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.Space(12);
|
||||
|
||||
// add PhotonView
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Label("Component", EditorStyles.boldLabel, GUILayout.Width(100));
|
||||
if (GUILayout.Button(new GUIContent("Add PhotonView", "Also in menu: Component, Miscellaneous")))
|
||||
{
|
||||
if (Selection.activeGameObject != null)
|
||||
{
|
||||
Selection.activeGameObject.AddComponent<PhotonView>();
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.Space(22);
|
||||
|
||||
// license
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Label("Licenses", EditorStyles.boldLabel, GUILayout.Width(100));
|
||||
|
||||
if (GUILayout.Button(new GUIContent("Download Free", "Get your free license for up to 100 concurrent players.")))
|
||||
{
|
||||
EditorUtility.OpenWithDefaultApp(UrlFreeLicense);
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.Space(12);
|
||||
|
||||
// documentation
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.Label("Documentation", EditorStyles.boldLabel, GUILayout.Width(100));
|
||||
GUILayout.BeginVertical();
|
||||
if (GUILayout.Button(new GUIContent("Open PDF", "Opens the local documentation pdf.")))
|
||||
{
|
||||
EditorUtility.OpenWithDefaultApp(DocumentationLocation);
|
||||
}
|
||||
|
||||
if (GUILayout.Button(new GUIContent("Open DevNet", "Online documentation for Photon.")))
|
||||
{
|
||||
EditorUtility.OpenWithDefaultApp(UrlDevNet);
|
||||
}
|
||||
|
||||
if (GUILayout.Button(new GUIContent("Open Cloud Dashboard", "Review Cloud App information and statistics.")))
|
||||
{
|
||||
EditorUtility.OpenWithDefaultApp(UrlAccountPage + Uri.EscapeUriString(this.emailAddress));
|
||||
}
|
||||
|
||||
if (GUILayout.Button(new GUIContent("Open Forum", "Online support for Photon.")))
|
||||
{
|
||||
EditorUtility.OpenWithDefaultApp(UrlForum);
|
||||
}
|
||||
|
||||
GUILayout.EndVertical();
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
protected virtual void OnGuiCompareAndHelpOptions()
|
||||
{
|
||||
EditorGUILayout.Separator();
|
||||
GUILayout.Label("I am not quite sure how 'my own host' compares to 'cloud'.");
|
||||
if (GUILayout.Button("See comparison page"))
|
||||
{
|
||||
Application.OpenURL(UrlCompare);
|
||||
}
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
GUILayout.Label("Questions? Need help or want to give us feedback? You are most welcome!");
|
||||
if (GUILayout.Button("See the Photon Forum"))
|
||||
{
|
||||
Application.OpenURL(UrlForum);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnGuiSetupCloudAppId()
|
||||
{
|
||||
GUILayout.Label("Your APP ID:");
|
||||
|
||||
this.cloudAppId = EditorGUILayout.TextField(this.cloudAppId);
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("Cancel"))
|
||||
{
|
||||
GUIUtility.keyboardControl = 0;
|
||||
this.ReApplySettingsToWindow();
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Save"))
|
||||
{
|
||||
GUIUtility.keyboardControl = 0;
|
||||
|
||||
PhotonEditor.Current.UseCloud(this.cloudAppId);
|
||||
PhotonEditor.Save();
|
||||
|
||||
EditorUtility.DisplayDialog("Success", "Saved your settings.", "ok");
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
GUILayout.Label("Running my app in the cloud was fun but...\nLet me setup my own Photon server.");
|
||||
|
||||
if (GUILayout.Button("Switch to own host"))
|
||||
{
|
||||
this.photonAddress = ServerSettings.DefaultServerAddress;
|
||||
this.photonPort = ServerSettings.DefaultMasterPort;
|
||||
this.photonSetupState = PhotonSetupStates.SetupSelfHosted;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnGuiSetupSelfhosting()
|
||||
{
|
||||
GUILayout.Label("Your Photon Host");
|
||||
|
||||
this.photonAddress = EditorGUILayout.TextField("IP:", this.photonAddress);
|
||||
this.photonPort = EditorGUILayout.IntField("Port:", this.photonPort);
|
||||
|
||||
// photonProtocol = (ExitGames.Client.Photon.ConnectionProtocol)EditorGUILayout.EnumPopup("Protocol:", photonProtocol);
|
||||
GUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("Cancel"))
|
||||
{
|
||||
GUIUtility.keyboardControl = 0;
|
||||
this.ReApplySettingsToWindow();
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Save"))
|
||||
{
|
||||
GUIUtility.keyboardControl = 0;
|
||||
|
||||
PhotonEditor.Current.UseMyServer(this.photonAddress, this.photonPort, null);
|
||||
PhotonEditor.Save();
|
||||
|
||||
EditorUtility.DisplayDialog("Success", "Saved your settings.", "ok");
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.Separator();
|
||||
|
||||
GUILayout.Label("Running my own server is too much hassle..\nI want to give Photon's free app a try.");
|
||||
|
||||
if (GUILayout.Button("Get the free cloud app"))
|
||||
{
|
||||
this.cloudAppId = string.Empty;
|
||||
this.photonSetupState = PhotonSetupStates.RegisterForPhotonCloud;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void RegisterWithEmail(string email)
|
||||
{
|
||||
EditorUtility.DisplayProgressBar("Connecting", "Connecting to the account service..", 0.5f);
|
||||
var client = new AccountService();
|
||||
client.RegisterByEmail(email, RegisterOrigin); // this is the synchronous variant using the static RegisterOrigin. "result" is in the client
|
||||
|
||||
EditorUtility.ClearProgressBar();
|
||||
if (client.ReturnCode == 0)
|
||||
{
|
||||
PhotonEditor.Current.UseCloud(client.AppId);
|
||||
PhotonEditor.Save();
|
||||
this.ReApplySettingsToWindow();
|
||||
this.photonSetupState = PhotonSetupStates.SetupPhotonCloud;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (client.Message.Contains("Email already registered"))
|
||||
{
|
||||
this.photonSetupState = PhotonSetupStates.EmailAlreadyRegistered;
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorUtility.DisplayDialog("Error", client.Message, "OK");
|
||||
// Debug.Log(client.Exception);
|
||||
this.photonSetupState = PhotonSetupStates.RegisterForPhotonCloud;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region SettingsFileHandling
|
||||
|
||||
private static ServerSettings currentSettings;
|
||||
|
||||
public static ServerSettings Current
|
||||
{
|
||||
get
|
||||
{
|
||||
if (currentSettings == null)
|
||||
{
|
||||
ReLoadCurrentSeetings();
|
||||
|
||||
// if still not loaded, create one
|
||||
if (currentSettings == null)
|
||||
{
|
||||
currentSettings = (ServerSettings)ScriptableObject.CreateInstance(typeof(ServerSettings));
|
||||
string settingsPath = Path.GetDirectoryName(PhotonNetwork.serverSettingsAssetPath);
|
||||
if (!Directory.Exists(settingsPath))
|
||||
{
|
||||
Directory.CreateDirectory(settingsPath);
|
||||
AssetDatabase.ImportAsset(settingsPath);
|
||||
}
|
||||
|
||||
AssetDatabase.CreateAsset(currentSettings, PhotonNetwork.serverSettingsAssetPath);
|
||||
}
|
||||
}
|
||||
|
||||
return currentSettings;
|
||||
}
|
||||
|
||||
protected set
|
||||
{
|
||||
currentSettings = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static void Save()
|
||||
{
|
||||
EditorUtility.SetDirty(PhotonEditor.Current);
|
||||
}
|
||||
|
||||
public static void ReLoadCurrentSeetings()
|
||||
{
|
||||
PhotonEditor.Current = (ServerSettings)AssetDatabase.LoadAssetAtPath(PhotonNetwork.serverSettingsAssetPath, typeof(ServerSettings));
|
||||
}
|
||||
|
||||
protected void ReApplySettingsToWindow()
|
||||
{
|
||||
this.cloudAppId = string.IsNullOrEmpty(PhotonEditor.Current.AppID) ? string.Empty : PhotonEditor.Current.AppID;
|
||||
this.photonAddress = string.IsNullOrEmpty(PhotonEditor.Current.ServerAddress) ? string.Empty : PhotonEditor.Current.ServerAddress;
|
||||
this.photonPort = PhotonEditor.Current.ServerPort;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dabbbed2a74eac44dac281f20d706ba8
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
+380
@@ -0,0 +1,380 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
// <copyright file="PhotonViewInspector.cs" company="Exit Games GmbH">
|
||||
// PhotonNetwork Framework for Unity - Copyright (C) 2011 Exit Games GmbH
|
||||
// </copyright>
|
||||
// <summary>
|
||||
// Custom inspector for the PhotonView component.
|
||||
// </summary>
|
||||
// <author>developer@exitgames.com</author>
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
[CustomEditor(typeof(PhotonView))]
|
||||
public class PhotonViewInspector : Editor
|
||||
{
|
||||
private bool doubleView = false;
|
||||
|
||||
private static PhotonView lastView;
|
||||
|
||||
private static GameObject GetPrefabParent(GameObject mp)
|
||||
{
|
||||
#if UNITY_2_6_1 || UNITY_2_6 || UNITY_3_0 || UNITY_3_0_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4
|
||||
// Unity 3.4 and older use EditorUtility
|
||||
return (EditorUtility.GetPrefabParent(mp) as GameObject);
|
||||
#else
|
||||
// Unity 3.5 uses PrefabUtility
|
||||
return PrefabUtility.GetPrefabParent(mp) as GameObject;
|
||||
#endif
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
EditorGUIUtility.LookLikeInspector();
|
||||
EditorGUI.indentLevel = 1;
|
||||
|
||||
PhotonView mp = (PhotonView)this.target;
|
||||
bool isProjectPrefab = EditorUtility.IsPersistent(mp.gameObject);
|
||||
|
||||
if (!EditorApplication.isPlaying)
|
||||
{
|
||||
if (mp != lastView)
|
||||
{
|
||||
// First opening of this viewID
|
||||
if (!isProjectPrefab)
|
||||
{
|
||||
if (!IsSceneViewIDFree(mp.viewID.ID, mp))
|
||||
{
|
||||
Debug.LogWarning("PhotonView: Wrong view ID(" + mp.viewID.ID + ") on " + mp.name + ", checking entire scene for fixes...");
|
||||
VerifyAllSceneViews();
|
||||
}
|
||||
}
|
||||
|
||||
lastView = mp;
|
||||
}
|
||||
}
|
||||
|
||||
SerializedObject sObj = new SerializedObject(mp);
|
||||
SerializedProperty sceneProp = sObj.FindProperty("sceneViewID");
|
||||
|
||||
// SerializedProperty sceneProp2 = sObj.FindProperty("isSceneView");
|
||||
|
||||
// FIX for an issue where a prefab(with photon view) is dragged to the scene and its changes APPLIED
|
||||
// This means that the scene assigns a ID, but this ID may not be saved to the prefab.
|
||||
// Unity's prefab AssetImporter doesn't seem to work (3.4), hence this nasty workaround.
|
||||
// Desired values:
|
||||
// scene = true true proj = false false. Thus, error case=
|
||||
if (sceneProp.isInstantiatedPrefab && !sceneProp.prefabOverride)
|
||||
{
|
||||
// Fix the assignment
|
||||
// EDIT: THIS ISSUE HAS BEEN FIXED IN PHOTONVIEW.CS BY CHECKING FOR THE PhotonViewSetup_FindMatchingRoot in Setup();
|
||||
// #if !UNITY_3_5
|
||||
// sceneProp.prefabOverride = true;
|
||||
// #endif
|
||||
sObj.ApplyModifiedProperties();
|
||||
|
||||
// FIX THE EDITOR PREFAB: set it to 0
|
||||
GameObject prefabParent = GetPrefabParent(mp.gameObject);
|
||||
if (prefabParent != null)
|
||||
{
|
||||
// find all PhotonViews on prefab, including those on inactive components to assign a PhotonViewId
|
||||
PhotonView[] views = prefabParent.transform.root.GetComponentsInChildren<PhotonView>(true) as PhotonView[];
|
||||
foreach (PhotonView viewX in views)
|
||||
{
|
||||
MakeProjectView(viewX);
|
||||
}
|
||||
|
||||
// ForceUpdate re-import for the prefab
|
||||
ForceAssetUpdate(mp.gameObject);
|
||||
}
|
||||
|
||||
// Assign the desired scene IDs back (they were reset to 0 by applying)
|
||||
PhotonView[] views2 = mp.transform.root.GetComponentsInChildren<PhotonView>();
|
||||
foreach (PhotonView view in views2)
|
||||
{
|
||||
int wantedID = view.viewID.ID;
|
||||
view.SetSceneID(wantedID);
|
||||
EditorUtility.SetDirty(view);
|
||||
}
|
||||
}
|
||||
|
||||
// Setup
|
||||
if (!isProjectPrefab)
|
||||
{
|
||||
if (mp.viewID.ID == 0)
|
||||
{
|
||||
SetViewID(mp, GetFreeSceneID(mp));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mp.viewID.ID != 0 || mp.isSceneView)
|
||||
{
|
||||
// Correct the settings
|
||||
Debug.LogWarning("Correcting view ID on project prefab (should be unassigned, but it was " + mp.viewID.ID + ")");
|
||||
MakeProjectView(mp);
|
||||
}
|
||||
}
|
||||
|
||||
// OWNER
|
||||
if (isProjectPrefab)
|
||||
{
|
||||
EditorGUILayout.LabelField("Owner:", "Set at runtime");
|
||||
}
|
||||
else if (mp.isSceneView)
|
||||
{
|
||||
EditorGUILayout.LabelField("Owner:", "Scene");
|
||||
}
|
||||
else if (mp.owner == null)
|
||||
{
|
||||
EditorGUILayout.LabelField("Owner:", "null, disconnected?");
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.LabelField("Owner:", "[" + mp.owner.ID + "] " + mp.owner.name);
|
||||
}
|
||||
|
||||
// View ID
|
||||
if (isProjectPrefab)
|
||||
{
|
||||
EditorGUILayout.LabelField("View ID", "Set at runtime");
|
||||
}
|
||||
else if (EditorApplication.isPlaying)
|
||||
{
|
||||
if (mp.owner != null)
|
||||
{
|
||||
EditorGUILayout.LabelField("View ID", "[" + mp.owner.ID + "] " + mp.viewID);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.LabelField("View ID", mp.viewID + string.Empty);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int newID = EditorGUILayout.IntField("View ID", mp.viewID.ID);
|
||||
if (GUI.changed)
|
||||
{
|
||||
SetViewID(mp, newID);
|
||||
}
|
||||
|
||||
if (this.doubleView)
|
||||
{
|
||||
GUI.color = Color.red;
|
||||
EditorGUILayout.LabelField("ERROR:", "Invalid view ID");
|
||||
GUI.color = Color.white;
|
||||
}
|
||||
|
||||
if (GUI.changed)
|
||||
{
|
||||
this.ChangedSetting();
|
||||
this.doubleView = false;
|
||||
PhotonView[] photonViews = Resources.FindObjectsOfTypeAll(typeof(PhotonView)) as PhotonView[];
|
||||
foreach (PhotonView view in photonViews)
|
||||
{
|
||||
if (view.isSceneView && view.viewID == mp.viewID && view != mp)
|
||||
{
|
||||
this.doubleView = true;
|
||||
EditorUtility.DisplayDialog("Error", "There is already a viewID with ID=" + view.viewID, "OK");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// OBSERVING
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
// Using a lower version then 3.4? Remove the TRUE in the next line to fix an compile error
|
||||
string title = string.Empty;
|
||||
int firstOpen = 0;
|
||||
if (mp.observed != null)
|
||||
{
|
||||
firstOpen = mp.observed.ToString().IndexOf('(');
|
||||
}
|
||||
|
||||
if (firstOpen > 0)
|
||||
{
|
||||
title = mp.observed.ToString().Substring(firstOpen - 1);
|
||||
}
|
||||
|
||||
mp.observed = (Component)EditorGUILayout.ObjectField("Observe: " + title, mp.observed, typeof(Component), true);
|
||||
if (GUI.changed)
|
||||
{
|
||||
this.ChangedSetting();
|
||||
if (mp.observed != null)
|
||||
{
|
||||
mp.synchronization = ViewSynchronization.ReliableDeltaCompressed;
|
||||
}
|
||||
else
|
||||
{
|
||||
mp.synchronization = ViewSynchronization.Off;
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
if (mp.synchronization == ViewSynchronization.Off)
|
||||
{
|
||||
GUI.color = Color.grey;
|
||||
}
|
||||
|
||||
mp.synchronization = (ViewSynchronization)EditorGUILayout.EnumPopup("Observe option:", mp.synchronization);
|
||||
if (GUI.changed)
|
||||
{
|
||||
this.ChangedSetting();
|
||||
if (mp.synchronization != ViewSynchronization.Off && mp.observed == null)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Warning", "Setting the synchronization option only makes sense if you observe something.", "OK, I will fix it.");
|
||||
}
|
||||
}
|
||||
|
||||
if (mp.observed != null)
|
||||
{
|
||||
Type type = mp.observed.GetType();
|
||||
if (type == typeof(Transform))
|
||||
{
|
||||
mp.onSerializeTransformOption = (OnSerializeTransform)EditorGUILayout.EnumPopup("Serialization:", mp.onSerializeTransformOption);
|
||||
}
|
||||
else if (type == typeof(Rigidbody))
|
||||
{
|
||||
mp.onSerializeRigidBodyOption = (OnSerializeRigidBody)EditorGUILayout.EnumPopup("Serialization:", mp.onSerializeRigidBodyOption);
|
||||
}
|
||||
}
|
||||
|
||||
GUI.color = Color.white;
|
||||
EditorGUIUtility.LookLikeControls();
|
||||
}
|
||||
|
||||
private void ChangedSetting()
|
||||
{
|
||||
PhotonView mp = (PhotonView)this.target;
|
||||
if (!EditorApplication.isPlaying)
|
||||
{
|
||||
EditorUtility.SetDirty(mp);
|
||||
}
|
||||
}
|
||||
|
||||
public static void MakeProjectView(PhotonView view)
|
||||
{
|
||||
view.viewID = new PhotonViewID(0, null);
|
||||
view.SetSceneID(0);
|
||||
EditorUtility.SetDirty(view);
|
||||
}
|
||||
|
||||
private static void SetViewID(PhotonView mp, int ID)
|
||||
{
|
||||
ID = Mathf.Clamp(ID, 1, PhotonNetwork.MAX_VIEW_IDS - 1);
|
||||
|
||||
if (!IsSceneViewIDFree(ID, mp))
|
||||
{
|
||||
ID = GetFreeSceneID(mp);
|
||||
}
|
||||
|
||||
if (mp.viewID.ID != ID)
|
||||
{
|
||||
mp.viewID = new PhotonViewID(ID, null);
|
||||
}
|
||||
|
||||
if (!EditorApplication.isPlaying)
|
||||
{
|
||||
mp.SetSceneID(mp.viewID.ID);
|
||||
ForceAssetUpdate(mp.gameObject);
|
||||
}
|
||||
|
||||
EditorUtility.SetDirty(mp);
|
||||
}
|
||||
|
||||
public static void ForceAssetUpdate(GameObject mp)
|
||||
{
|
||||
GameObject pPrefab = GetPrefabParent(mp);
|
||||
if (pPrefab != null)
|
||||
{
|
||||
pPrefab = pPrefab.transform.root.gameObject;
|
||||
string assetPath = AssetDatabase.GetAssetPath(pPrefab);
|
||||
if (assetPath == string.Empty)
|
||||
{
|
||||
Debug.LogError("No assetpath for " + pPrefab);
|
||||
}
|
||||
|
||||
AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate);
|
||||
}
|
||||
}
|
||||
|
||||
private static int GetFreeSceneID(PhotonView targetView)
|
||||
{
|
||||
// No need for bit shifting as scene is "player 0".
|
||||
/* Hashtable takenIDs = new Hashtable();
|
||||
PhotonView[] views = (PhotonView[])GameObject.FindObjectsOfType(typeof(PhotonView));
|
||||
foreach (PhotonView view in views)
|
||||
{
|
||||
takenIDs[view.viewID] = view;
|
||||
}*/
|
||||
for (int i = 1; i < PhotonNetwork.MAX_VIEW_IDS; i++)
|
||||
{
|
||||
if (IsSceneViewIDFree(i, targetView))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
EditorUtility.DisplayDialog("Error", "You ran out of view ID's (" + PhotonNetwork.MAX_VIEW_IDS + "). Something is seriously wrong!", "OK");
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static bool IsSceneViewIDFree(int ID, PhotonView targetView)
|
||||
{
|
||||
if (ID <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
PhotonView[] photonViews = Resources.FindObjectsOfTypeAll(typeof(PhotonView)) as PhotonView[];
|
||||
foreach (PhotonView view in photonViews)
|
||||
{
|
||||
if (!view.isSceneView)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (view != targetView && view.viewID != null && view.viewID.ID == ID)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static int VerifyAllSceneViews()
|
||||
{
|
||||
int correctedViews = 0;
|
||||
PhotonView[] photonViews = Resources.FindObjectsOfTypeAll(typeof(PhotonView)) as PhotonView[];
|
||||
foreach (PhotonView view in photonViews)
|
||||
{
|
||||
if (!VerifySceneView(view))
|
||||
{
|
||||
correctedViews++;
|
||||
}
|
||||
}
|
||||
|
||||
if (correctedViews > 0)
|
||||
{
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
return correctedViews;
|
||||
}
|
||||
|
||||
public static bool VerifySceneView(PhotonView view)
|
||||
{
|
||||
if (!EditorUtility.IsPersistent(view.gameObject) && !IsSceneViewIDFree(view.viewID.ID, view))
|
||||
{
|
||||
SetViewID(view, GetFreeSceneID(view));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e73a30c46df19194f873ea7a9ce12753
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
using System.Collections;
|
||||
|
||||
public class PhotonViewPrefabApply : AssetPostprocessor
|
||||
{
|
||||
static void OnPostprocessAllAssets(
|
||||
string[] importedAssets,
|
||||
string[] deletedAssets,
|
||||
string[] movedAssets,
|
||||
string[] movedFromAssetPaths)
|
||||
{
|
||||
bool weChangedPhotonViews = false;
|
||||
|
||||
// Strips any scene settings from PhotonViews in prefabs.
|
||||
// (i.e.: assigned viewIDs are removed)
|
||||
foreach (string str in importedAssets)
|
||||
{
|
||||
if (str.EndsWith(".prefab"))
|
||||
{
|
||||
Object[] objs = (Object[])AssetDatabase.LoadAllAssetsAtPath(str);
|
||||
foreach (Object obj in objs)
|
||||
{
|
||||
if (obj != null && obj.GetType() == typeof(GameObject))
|
||||
{
|
||||
PhotonView[] views = ((GameObject)obj).GetComponents<PhotonView>();
|
||||
foreach (PhotonView view in views)
|
||||
PhotonViewInspector.MakeProjectView(view);
|
||||
|
||||
if (views.Length > 0)
|
||||
weChangedPhotonViews = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Problem here: VerifyAllSceneViews will only fix the prefabs instances in the current open scene, not for other scenes!
|
||||
// See PhotonEditor.EditorUpdate: Here we will check all newly opened scenes for this possible issue.
|
||||
// No known issues as of 5 March 2011 this seems to work fine with changing viewIDs on prefabs etc. (Even for scenes that are not open) - Mike/Leepo
|
||||
if (weChangedPhotonViews)
|
||||
{
|
||||
PhotonViewInspector.VerifyAllSceneViews();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8fc479a7e9762e6419b446c9fa57fcfb
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
Reference in New Issue
Block a user