@@ -42,7 +42,7 @@ public void OnGUI()
4242
4343 EditorGUILayout . LabelField ( "The version you are upgrading to has a greater major version. This means that there are non backwards compatibile changes. \n " +
4444 "For more information about the MLAPI versioning, please visit SemVer.org" , warningStyle ) ;
45- EditorGUILayout . LabelField ( "It's ALWAYS recommended to do a backup when upgrading major versions. If your project doesn't compile " +
45+ EditorGUILayout . LabelField ( "It's ALWAYS recommended to do a backup AND reading all the breaking changes when upgrading major versions. If your project doesn't compile " +
4646 "There is good chance serialized data will be PERMANENTLY LOST. Don't be stupid." , errorStyle ) ;
4747 EditorGUILayout . LabelField ( "Here are the versions with breaking changes you are skipping." , EditorStyles . wordWrappedLabel ) ;
4848 GUILayout . Space ( 5 ) ;
@@ -194,14 +194,27 @@ public class GithubRelease
194194 public GithubAsset [ ] assets ;
195195}
196196
197+ [ Serializable ]
198+ public class TransportArtifactDefinition
199+ {
200+ public TransportArtifact [ ] artifacts ;
201+ }
202+
197203[ Serializable ]
198204public class TransportArtifact
199205{
200206 public string id ;
201- public string description ;
202207 public string name ;
208+ public string description ;
203209 public string path ;
204210 public string credits ;
211+ public string licence ;
212+ public string platform_compatibility_description ;
213+ public bool net35 ;
214+ public bool net45 ;
215+ public bool preferNet45 ;
216+ public bool experimental ;
217+ public int mlapi_major_version ;
205218}
206219
207220[ Serializable ]
@@ -227,7 +240,8 @@ public class MLAPIEditor : EditorWindow
227240 private const string TRANSPORT_ARTIFACT_PATH_URL = "https://api.github.com/repos/MidLevel/MLAPI.Transports/contents/artifact_paths.json" ;
228241 private const string TRANSPORT_ARTIFACT_DOWNLOAD_URL_TEMPLATE = "https://ci.appveyor.com/api/projects/MidLevel/MLAPI-Transports/artifacts/<path>?branch=master" ;
229242 private GithubRelease [ ] releases = new GithubRelease [ 0 ] ;
230- private TransportArtifact [ ] transportArtifacts = new TransportArtifact [ 0 ] ;
243+ private TransportArtifactDefinition transportArtifacts = null ;
244+ private int [ ] transportVersionSelections = new int [ 0 ] ;
231245 private bool [ ] releaseFoldoutStatus = new bool [ 0 ] ;
232246 private bool [ ] transportFoldoutStatus = new bool [ 0 ] ;
233247
@@ -361,28 +375,61 @@ private void OnGUI()
361375 }
362376 else if ( tab == 1 )
363377 {
364- if ( transportFoldoutStatus != null )
378+ MLAPIVersion currentMLAPIVersion = MLAPIVersion . Parse ( currentVersion ) ;
379+
380+ if ( transportArtifacts != null && transportArtifacts . artifacts != null && transportFoldoutStatus != null )
365381 {
366- for ( int i = 0 ; i < transportFoldoutStatus . Length ; i ++ )
382+ for ( int i = 0 ; i < transportArtifacts . artifacts . Length ; i ++ )
367383 {
368- if ( transportArtifacts [ i ] == null )
384+ if ( transportArtifacts . artifacts [ i ] == null )
369385 continue ;
370386
371- transportFoldoutStatus [ i ] = EditorGUILayout . Foldout ( transportFoldoutStatus [ i ] , transportArtifacts [ i ] . name ) ;
387+ string transportDirectory = Path . Combine ( Path . Combine ( Path . Combine ( Application . dataPath , "MLAPI" ) , "OfficialTransports" ) , transportArtifacts . artifacts [ i ] . id ) ;
388+ bool isInstalled = Directory . Exists ( transportDirectory ) && Directory . GetFiles ( transportDirectory ) . Length > 0 ;
389+
390+ transportFoldoutStatus [ i ] = EditorGUILayout . Foldout ( transportFoldoutStatus [ i ] , transportArtifacts . artifacts [ i ] . name + ( ( isInstalled ) ? " - [Installed]" : "" ) ) ;
372391
373392 if ( transportFoldoutStatus [ i ] )
374393 {
375394 EditorGUI . indentLevel ++ ;
376395
377- string transportDirectory = Path . Combine ( Path . Combine ( Path . Combine ( Application . dataPath , "MLAPI" ) , "OfficialTransports" ) , transportArtifacts [ i ] . id ) ;
378-
379396 EditorGUILayout . LabelField ( "Description" , EditorStyles . boldLabel ) ;
380- EditorGUILayout . LabelField ( transportArtifacts [ i ] . description , EditorStyles . wordWrappedLabel ) ;
397+ EditorGUILayout . LabelField ( transportArtifacts . artifacts [ i ] . description , EditorStyles . wordWrappedLabel ) ;
381398
382399 EditorGUILayout . LabelField ( "Credits" , EditorStyles . boldLabel ) ;
383- EditorGUILayout . LabelField ( transportArtifacts [ i ] . credits , EditorStyles . wordWrappedLabel ) ;
400+ EditorGUILayout . LabelField ( transportArtifacts . artifacts [ i ] . credits , EditorStyles . wordWrappedLabel ) ;
401+
402+ EditorGUILayout . LabelField ( "Platform Compatibility" , EditorStyles . boldLabel ) ;
403+ EditorGUILayout . LabelField ( transportArtifacts . artifacts [ i ] . platform_compatibility_description , EditorStyles . wordWrappedLabel ) ;
404+
405+ EditorGUILayout . LabelField ( "Licence" , EditorStyles . boldLabel ) ;
406+ EditorGUILayout . LabelField ( transportArtifacts . artifacts [ i ] . licence , EditorStyles . wordWrappedLabel ) ;
407+
408+ if ( currentMLAPIVersion . MAJOR != ( byte ) transportArtifacts . artifacts [ i ] . mlapi_major_version )
409+ {
410+ EditorGUILayout . Space ( ) ;
411+ GUIStyle style = new GUIStyle ( EditorStyles . wordWrappedLabel ) ;
412+ style . normal . textColor = new Color ( 1f , 0f , 0f ) ;
413+ EditorGUILayout . LabelField ( "The MLAPI version you have installed through the installer has a different major version from the transports major version. You have version v" + currentMLAPIVersion . ToString ( ) + " while this transport targets version v" + transportArtifacts . artifacts [ i ] . mlapi_major_version + ".x.x. This means there could potentially be compatibility issues, but its not guaranteed. If you have installed the MLAPI manually and have version v" + transportArtifacts . artifacts [ i ] . mlapi_major_version + ".x.x you can ignore this message." , style ) ;
414+ EditorGUILayout . Space ( ) ;
415+ }
384416
385- if ( Directory . Exists ( transportDirectory ) && Directory . GetFiles ( transportDirectory ) . Length > 0 )
417+ if ( transportArtifacts . artifacts [ i ] . experimental )
418+ {
419+ EditorGUILayout . Space ( ) ;
420+ GUIStyle style = new GUIStyle ( EditorStyles . boldLabel ) ;
421+ style . normal . textColor = new Color ( 1f , 0.5f , 0f ) ;
422+ EditorGUILayout . LabelField ( "Experimental" , style ) ;
423+ }
424+ else
425+ {
426+ EditorGUILayout . Space ( ) ;
427+ GUIStyle style = new GUIStyle ( EditorStyles . boldLabel ) ;
428+ style . normal . textColor = new Color ( 0f , 1f , 0f ) ;
429+ EditorGUILayout . LabelField ( "Stable" , style ) ;
430+ }
431+
432+ if ( isInstalled )
386433 {
387434 GUIStyle boldStyle = new GUIStyle ( EditorStyles . boldLabel ) ;
388435 boldStyle . normal . textColor = new Color ( 0.3f , 1f , 0.3f ) ;
@@ -397,6 +444,31 @@ private void OnGUI()
397444 if ( GUILayout . Button ( "Remove" ) )
398445 {
399446 Directory . Delete ( transportDirectory , true ) ;
447+
448+ string metaFileName = transportDirectory ;
449+
450+ if ( metaFileName . EndsWith ( Path . DirectorySeparatorChar . ToString ( ) ) ||
451+ metaFileName . EndsWith ( Path . AltDirectorySeparatorChar . ToString ( ) ) )
452+ {
453+ metaFileName = metaFileName . Substring ( metaFileName . Length , metaFileName . Length - 1 ) ;
454+ }
455+
456+ metaFileName += ".meta" ;
457+
458+ if ( File . Exists ( metaFileName ) )
459+ {
460+ File . Delete ( metaFileName ) ;
461+ }
462+
463+ try
464+ {
465+ AssetDatabase . Refresh ( ) ;
466+ }
467+ catch ( Exception e )
468+ {
469+ Debug . LogError ( e . ToString ( ) ) ;
470+ Debug . LogError ( e . GetType ( ) . FullName ) ;
471+ }
400472 }
401473 }
402474 else
@@ -421,7 +493,7 @@ private void OnGUI()
421493 string lastUpdatedString = lastUpdated == 0 ? "Never" : new DateTime ( lastUpdated ) . ToShortTimeString ( ) ;
422494 GUILayout . Label ( "Last checked: " + lastUpdatedString , EditorStyles . centeredGreyMiniLabel ) ;
423495
424- if ( canRefetch && GUILayout . Button ( "Fetch releases " ) )
496+ if ( canRefetch && GUILayout . Button ( "Fetch All " ) )
425497 EditorCoroutine . Start ( FetchAll ( ) ) ;
426498 if ( ! string . IsNullOrEmpty ( statusMessage ) )
427499 GUILayout . Label ( statusMessage , EditorStyles . centeredGreyMiniLabel ) ;
@@ -582,7 +654,16 @@ private IEnumerator InstallRelease(int index)
582654 statusMessage = "" ;
583655 if ( ! downloadFail )
584656 currentVersion = releases [ index ] . tag_name ; //Only set this if there was no fail. This is to allow them to still retry the download
585- AssetDatabase . Refresh ( ) ;
657+
658+ try
659+ {
660+ AssetDatabase . Refresh ( ) ;
661+ }
662+ catch ( Exception e )
663+ {
664+ Debug . LogError ( e . ToString ( ) ) ;
665+ Debug . LogError ( e . GetType ( ) . FullName ) ;
666+ }
586667 }
587668 showProgressBar = false ;
588669 statusMessage = "" ;
@@ -598,27 +679,31 @@ private IEnumerator InstallTransport(int index)
598679 statusMessage = "Cleaning transport folder" ;
599680 yield return null ;
600681
601- string transportDirectory = Path . Combine ( Path . Combine ( Path . Combine ( Application . dataPath , "MLAPI" ) , "OfficialTransports" ) , transportArtifacts [ index ] . id ) ;
682+ // Create the MLAPI directory if it doesnt exist, for example with manual installs.
683+ if ( ! Directory . Exists ( Application . dataPath + "/MLAPI/" ) )
684+ Directory . CreateDirectory ( Application . dataPath + "/MLAPI/" ) ;
685+
686+ string transportDirectory = Path . Combine ( Path . Combine ( Path . Combine ( Application . dataPath , "MLAPI" ) , "OfficialTransports" ) , transportArtifacts . artifacts [ index ] . id ) ;
602687
603688 if ( Directory . Exists ( transportDirectory ) )
604689 Directory . Delete ( transportDirectory , true ) ;
605690
606691 Directory . CreateDirectory ( transportDirectory ) ;
607692
608693
609- using ( UnityWebRequest www = UnityWebRequest . Get ( TRANSPORT_ARTIFACT_DOWNLOAD_URL_TEMPLATE . Replace ( "<path>" , transportArtifacts [ index ] . path ) ) )
694+ using ( UnityWebRequest www = UnityWebRequest . Get ( TRANSPORT_ARTIFACT_DOWNLOAD_URL_TEMPLATE . Replace ( "<path>" , transportArtifacts . artifacts [ index ] . path ) ) )
610695 {
611696 www . SendWebRequest ( ) ;
612697 while ( ! www . isDone && string . IsNullOrEmpty ( www . error ) )
613698 {
614- statusMessage = "Downloading " + transportArtifacts [ index ] . name + " " + www . downloadProgress + "%" ;
699+ statusMessage = "Downloading " + transportArtifacts . artifacts [ index ] . name + " " + www . downloadProgress + "%" ;
615700 yield return null ;
616701 }
617702
618703 if ( ! string . IsNullOrEmpty ( www . error ) )
619704 {
620705 //Some kind of error
621- statusMessage = "Failed to download asset " + transportArtifacts [ index ] . name + ". Error: " + www . error ;
706+ statusMessage = "Failed to download asset " + transportArtifacts . artifacts [ index ] . name + ". Error: " + www . error ;
622707 double startTime = EditorApplication . timeSinceStartup ;
623708 //Basically = yield return new WaitForSeconds(5);
624709 while ( EditorApplication . timeSinceStartup - startTime <= 5f )
@@ -627,34 +712,50 @@ private IEnumerator InstallTransport(int index)
627712 }
628713 else
629714 {
630- statusMessage = "Writing " + transportArtifacts [ index ] . name + " to disk" ;
715+ statusMessage = "Writing " + transportArtifacts . artifacts [ index ] . name + " to disk" ;
631716 yield return null ;
632717
633- File . WriteAllBytes ( Path . Combine ( transportDirectory , transportArtifacts [ index ] . path ) , www . downloadHandler . data ) ;
718+ File . WriteAllBytes ( Path . Combine ( transportDirectory , transportArtifacts . artifacts [ index ] . path ) , www . downloadHandler . data ) ;
634719
635- if ( ! transportArtifacts [ index ] . path . EndsWith ( ".zip" ) )
720+ if ( ! transportArtifacts . artifacts [ index ] . path . EndsWith ( ".zip" ) )
636721 {
637- // TODO: Invalid extension
722+ Debug . LogError ( "Transport does not have a valid .zip extension. Is the editor outdated?" ) ;
638723 }
639724 else
640725 {
641- statusMessage = "Unzipping " + transportArtifacts [ index ] . name ;
726+ statusMessage = "Unzipping " + transportArtifacts . artifacts [ index ] . name ;
642727
643- ZipStorer zip = ZipStorer . Open ( Path . Combine ( transportDirectory , transportArtifacts [ index ] . path ) , FileAccess . Read ) ;
728+ ZipStorer zip = ZipStorer . Open ( Path . Combine ( transportDirectory , transportArtifacts . artifacts [ index ] . path ) , FileAccess . Read ) ;
644729 List < ZipStorer . ZipFileEntry > dir = zip . ReadCentralDir ( ) ;
645730
731+ bool net35Exists = dir . Exists ( x => x . FilenameInZip . Contains ( "net35" ) ) ;
732+ bool net45Exists = dir . Exists ( x => x . FilenameInZip . Contains ( "net45" ) ) ;
733+
734+ #if NET_4_6
735+ bool supportsNet45 = true ;
736+ #else
737+ bool supportsNet45 = false ;
738+ #endif
739+
740+ bool useNet35 = ( ! supportsNet45 || ! net45Exists || ! transportArtifacts . artifacts [ index ] . preferNet45 ) && net35Exists ;
741+ bool useNet45 = net45Exists && supportsNet45 && ! useNet35 ;
742+
743+ if ( ! useNet35 && ! useNet45 )
744+ {
745+ Debug . LogError ( ( "Could not download transport \" " + transportArtifacts . artifacts [ index ] + "\" . There is no valid target for your platform." ) ) ;
746+ }
747+
646748 foreach ( ZipStorer . ZipFileEntry entry in dir )
647749 {
648- if ( entry . FilenameInZip . Contains ( "net35" ) )
750+ if ( ( useNet35 && entry . FilenameInZip . Contains ( "net35" ) ) ||
751+ ( useNet45 && entry . FilenameInZip . Contains ( "net45" ) ) )
649752 {
650753 string fileName = Path . GetFileName ( entry . FilenameInZip ) ;
651754 zip . ExtractFile ( entry , Path . Combine ( transportDirectory , fileName ) ) ;
652755 }
653756 }
654757
655758 zip . Close ( ) ;
656-
657- statusMessage = "" ;
658759 }
659760
660761 yield return null ;
@@ -664,7 +765,16 @@ private IEnumerator InstallTransport(int index)
664765 yield return null ;
665766 statusMessage = "" ;
666767 showProgressBar = false ;
667- AssetDatabase . Refresh ( ) ;
768+
769+ try
770+ {
771+ AssetDatabase . Refresh ( ) ;
772+ }
773+ catch ( Exception e )
774+ {
775+ Debug . LogError ( e . ToString ( ) ) ;
776+ Debug . LogError ( e . GetType ( ) . FullName ) ;
777+ }
668778 }
669779
670780 private IEnumerator FetchAll ( )
@@ -684,7 +794,9 @@ private IEnumerator FetchAll()
684794 if ( ! string . IsNullOrEmpty ( www . error ) )
685795 {
686796 //Some kind of error
687- statusMessage = "Failed to fetch releases. Error: " + www . error ;
797+ statusMessage = "Failed to " +
798+ "fetch rel" +
799+ "eases. Error: " + www . error ;
688800 double startTime = EditorApplication . timeSinceStartup ;
689801 //Basically = yield return new WaitForSeconds(5);
690802 while ( EditorApplication . timeSinceStartup - startTime <= 5f )
@@ -788,55 +900,23 @@ private IEnumerator FetchAll()
788900 {
789901 string decodedJson = Encoding . UTF8 . GetString ( Convert . FromBase64String ( githubContent . content ) ) ;
790902
791- //This makes it from a json array to the individual objects in the array.
792- //The JSON serializer cant take arrays. We have to split it up outselves.
793- List < string > transportsJson = new List < string > ( ) ;
794- int depth = 0 ;
795- StringBuilder builder = new StringBuilder ( ) ;
796- for ( int i = 1 ; i < decodedJson . Length - 1 ; i ++ )
903+ transportArtifacts = JsonUtility . FromJson < TransportArtifactDefinition > ( decodedJson ) ;
904+
905+ if ( transportArtifacts == null )
797906 {
798- if ( decodedJson [ i ] == '[' )
799- depth ++ ;
800- else if ( decodedJson [ i ] == ']' )
801- depth -- ;
802- else if ( decodedJson [ i ] == '{' )
803- depth ++ ;
804- else if ( decodedJson [ i ] == '}' )
805- depth -- ;
806-
807- if ( ( depth == 0 && decodedJson [ i ] != ',' ) || depth > 0 )
808- builder . Append ( decodedJson [ i ] ) ;
809- if ( depth == 0 && ( decodedJson [ i ] == ',' || i == decodedJson . Length - 2 ) )
810- {
811- transportsJson . Add ( builder . ToString ( ) ) ;
812- builder . Length = 0 ;
813- }
814- //Parse in smaller batches
815- if ( i % ( decodedJson . Length / 100 ) == 0 )
816- {
817- statusMessage = "Splitting JSON " + ( i / ( float ) decodedJson . Length ) * 100f + "%" ;
818- yield return null ;
819- }
820- statusMessage = "" ;
907+ transportArtifacts = new TransportArtifactDefinition ( ) ;
821908 }
822909
823- transportArtifacts = new TransportArtifact [ transportsJson . Count ] ;
824- transportFoldoutStatus = new bool [ transportsJson . Count ] ;
825- for ( int i = 0 ; i < transportsJson . Count ; i ++ )
910+ if ( transportArtifacts . artifacts == null )
826911 {
827- transportArtifacts [ i ] = JsonUtility . FromJson < TransportArtifact > ( transportsJson [ i ] ) ;
828- transportFoldoutStatus [ i ] = false ;
829-
830- if ( i % ( transportsJson . Count / 30f ) == 0 )
831- {
832- yield return null ;
833- statusMessage = "Parsing JSON " + ( i / ( float ) transportsJson . Count ) * 100f + "%" ;
834- }
912+ transportArtifacts . artifacts = new TransportArtifact [ 0 ] ;
835913 }
914+
915+ transportFoldoutStatus = new bool [ transportArtifacts . artifacts . Length ] ;
836916 }
837917 else
838918 {
839- // TODO: Invalid format
919+ Debug . LogError ( "The artifact manifest had an unsupported encoding: " + githubContent . encoding + ". Supported encodings are base64" ) ;
840920 }
841921
842922
0 commit comments