├── README.md └── Editor └── Uploader.cs /README.md: -------------------------------------------------------------------------------- 1 | This is a simple FTP uploader for Unity. An editor window allows you to specify 2 | a server and user credentials then directly build and upload your game there. 3 | 4 | Note that the ability to programmatically build a game requires Unity Pro. 5 | -------------------------------------------------------------------------------- /Editor/Uploader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Net; 4 | using UnityEditor; 5 | using UnityEngine; 6 | 7 | /// 8 | /// An editor extension for uploading built files directly to a (S)FTP server. 9 | /// 10 | class FTPUploader : EditorWindow 11 | { 12 | enum Protocol { FTP, SFTP } 13 | 14 | // Application info: 15 | 16 | public static readonly Version version = new Version(0, 1); 17 | const string applicationName = "Uploader"; 18 | 19 | bool showMoreOptions; 20 | 21 | // Labels: 22 | 23 | GUIContent protocolLabel = new GUIContent("Protocol"); 24 | GUIContent serverLabel = new GUIContent("Server"); 25 | GUIContent usernameLabel = new GUIContent("User Name"); 26 | GUIContent passwordLabel = new GUIContent("Password"); 27 | GUIContent uploadLabel = new GUIContent("Upload"); 28 | GUIContent moreOptionsLabel = new GUIContent("More Options"); 29 | GUIContent pathLabel = new GUIContent("Initial Path", "The directory to upload to on the server."); 30 | GUIContent filenameLabel = new GUIContent("File Name", "The name of the .unity3d file that's created."); 31 | 32 | /// 33 | /// Initializes the window. 34 | /// 35 | [MenuItem("Window/Uploader")] 36 | static void Init () 37 | { 38 | // Show existing open window, or make new one. 39 | Uploader window = EditorWindow.GetWindow(typeof(Uploader)) as Uploader; 40 | window.Show(); 41 | } 42 | 43 | /// 44 | /// Displays the upload form. 45 | /// 46 | void OnGUI () 47 | { 48 | // Fetch existing stored values. 49 | var protocol = (Protocol)EditorPrefs.GetInt(applicationName + " protocol", (int)Protocol.FTP); 50 | var server = EditorPrefs.GetString(applicationName + " server", ""); 51 | var username = EditorPrefs.GetString(applicationName + " username", ""); 52 | var password = EditorPrefs.GetString(applicationName + " password", ""); 53 | var filename = EditorPrefs.GetString(applicationName + " filename", "game"); 54 | var initialPath = EditorPrefs.GetString(applicationName + " initialpath", ""); 55 | 56 | // Get new values. 57 | protocol = (Protocol)EditorGUILayout.EnumPopup(protocolLabel, protocol); 58 | server = EditorGUILayout.TextField(serverLabel, server); 59 | username = EditorGUILayout.TextField(usernameLabel, username); 60 | password = EditorGUILayout.PasswordField(passwordLabel, password); 61 | 62 | // More options: 63 | 64 | showMoreOptions = EditorGUILayout.Foldout(showMoreOptions, moreOptionsLabel); 65 | 66 | if (showMoreOptions) { 67 | filename = EditorGUILayout.TextField(filenameLabel, filename); 68 | initialPath = EditorGUILayout.TextField(pathLabel, initialPath); 69 | } 70 | 71 | // Store new values. 72 | EditorPrefs.SetInt(applicationName + " protocol", (int)protocol); 73 | EditorPrefs.SetString(applicationName + " server", server); 74 | EditorPrefs.SetString(applicationName + " username", username); 75 | EditorPrefs.SetString(applicationName + " password", password); 76 | EditorPrefs.SetString(applicationName + " filename", filename); 77 | EditorPrefs.SetString(applicationName + " initialpath", initialPath); 78 | 79 | filename += ".unity3d"; 80 | 81 | EditorGUILayout.BeginHorizontal(); 82 | 83 | GUILayout.FlexibleSpace(); 84 | 85 | if (GUILayout.Button(uploadLabel)) { 86 | try { 87 | Build(filename); 88 | 89 | switch (protocol) { 90 | case Protocol.FTP: 91 | FTPUpload(filename, server, username, password, initialPath); 92 | break; 93 | 94 | case Protocol.SFTP: 95 | SFTPUpload(filename, server, username, password, initialPath); 96 | break; 97 | } 98 | } catch (Exception e) { 99 | Debug.LogError("Unable to upload game: " + e.Message); 100 | } 101 | } 102 | 103 | EditorGUILayout.EndHorizontal(); 104 | } 105 | 106 | /// 107 | /// Builds the web player. 108 | /// 109 | /// The name of the file to build; 110 | static void Build (string filename) 111 | { 112 | var result = BuildPipeline.BuildPlayer(new string[] {}, filename, BuildTarget.WebPlayer, BuildOptions.Development); 113 | 114 | if (result != "") { 115 | throw new Exception("Unable to build file: " + result); 116 | } 117 | } 118 | 119 | /// 120 | /// Uploads a file through FTP. 121 | /// 122 | /// The path to the file to upload. 123 | /// The server to use. 124 | /// The username to use. 125 | /// The password to use. 126 | /// The path on the server to upload to. 127 | static void Upload (string filename, string server, string username, string password, string initialPath) 128 | { 129 | var file = new FileInfo(filename); 130 | var address = new Uri("ftp://" + server + "/" + Path.Combine(initialPath, file.Name)); 131 | var request = FtpWebRequest.Create(address) as FtpWebRequest; 132 | 133 | // Upload options: 134 | 135 | // Provide credentials 136 | request.Credentials = new NetworkCredential(username, password); 137 | 138 | // Set control connection to closed after command execution 139 | request.KeepAlive = false; 140 | 141 | // Specify command to be executed 142 | request.Method = WebRequestMethods.Ftp.UploadFile; 143 | 144 | // Specify data transfer type 145 | request.UseBinary = true; 146 | 147 | // Notify server about size of uploaded file 148 | request.ContentLength = file.Length; 149 | 150 | // Set buffer size to 2KB. 151 | var bufferLength = 2048; 152 | var buffer = new byte[bufferLength]; 153 | var contentLength = 0; 154 | 155 | // Open file stream to read file 156 | var fs = file.OpenRead(); 157 | 158 | try { 159 | // Stream to which file to be uploaded is written. 160 | var stream = request.GetRequestStream(); 161 | 162 | // Read from file stream 2KB at a time. 163 | contentLength = fs.Read(buffer, 0, bufferLength); 164 | 165 | // Loop until stream content ends. 166 | while (contentLength != 0) { 167 | //Debug.Log("Progress: " + ((fs.Position / fs.Length) * 100f)); 168 | // Write content from file stream to FTP upload stream. 169 | stream.Write(buffer, 0, contentLength); 170 | contentLength = fs.Read(buffer, 0, bufferLength); 171 | } 172 | 173 | // Close file and request streams 174 | stream.Close(); 175 | fs.Close(); 176 | } catch (Exception e) { 177 | Debug.LogError("Error uploading file: " + e.Message); 178 | return; 179 | } 180 | 181 | Debug.Log("Upload successful."); 182 | } 183 | } 184 | --------------------------------------------------------------------------------