1+ using System . IO ;
2+ using System . IO . Compression ;
3+ using System . Threading ;
4+ using UnityEditor ;
5+ using UnityEditor . Build ;
6+ using UnityEditor . Build . Reporting ;
7+ using UnityEngine ;
8+
9+ namespace RimuruDev . Unity_CustomBuildUpdater . CustomBuildUpdater . Editor
10+ {
11+ public class BuildVersionUpdater : IPreprocessBuildWithReport , IPostprocessBuildWithReport
12+ {
13+ public int callbackOrder => 0 ;
14+
15+ private static BuildConfig config ;
16+ private static string defaultBuildPath = "Builds" ;
17+
18+ private void LoadConfig ( )
19+ {
20+ config = Resources . Load < BuildConfig > ( "Editor/BuildConfig" ) ;
21+ if ( config == null )
22+ {
23+ Debug . LogError ( "BuildConfig not found. Please create it in the Resources/Editor folder." ) ;
24+ }
25+ }
26+
27+ public void OnPreprocessBuild ( BuildReport report )
28+ {
29+ LoadConfig ( ) ;
30+
31+ if ( config == null )
32+ return ;
33+
34+ EnsureVersionFileExists ( ) ;
35+
36+ var version = GetNextVersion ( ) ;
37+ PlayerSettings . bundleVersion = version ;
38+
39+ PlayerSettings . productName = config . productName ;
40+ PlayerSettings . companyName = config . companyName ;
41+
42+ Debug . Log ( $ "New version: { version } ") ;
43+ }
44+
45+ public void OnPostprocessBuild ( BuildReport report )
46+ {
47+ LoadConfig ( ) ;
48+
49+ if ( config == null )
50+ return ;
51+
52+ var buildPath = report . summary . outputPath ;
53+ var extension = GetBuildExtension ( report . summary . platform ) ;
54+ var finalBuildPath = GetFinalBuildPath ( buildPath , extension ) ;
55+
56+ if ( Directory . Exists ( buildPath ) || File . Exists ( buildPath ) )
57+ {
58+ RenameBuildPath ( buildPath , finalBuildPath ) ;
59+ Debug . Log ( $ "Build renamed to: { finalBuildPath } ") ;
60+ }
61+
62+ Thread . Sleep ( 1000 ) ;
63+
64+ if ( config . archiveBuild )
65+ {
66+ ArchiveBuild ( finalBuildPath ) ;
67+ }
68+ }
69+
70+ private void EnsureVersionFileExists ( )
71+ {
72+ var versionFilePath = Path . Combine ( Application . dataPath , "Resources/Editor/version.txt" ) ;
73+ if ( ! File . Exists ( versionFilePath ) )
74+ {
75+ Directory . CreateDirectory ( Path . GetDirectoryName ( versionFilePath ) ) ;
76+ File . WriteAllText ( versionFilePath , "1.0.0.0" ) ;
77+ }
78+ }
79+
80+ private string GetNextVersion ( )
81+ {
82+ var versionFilePath = Path . Combine ( Application . dataPath , "Resources/Editor/version.txt" ) ;
83+ var version = File . ReadAllText ( versionFilePath ) ;
84+ var versionParts = version . Split ( '.' ) ;
85+ var major = int . Parse ( versionParts [ 0 ] ) ;
86+ var feature = int . Parse ( versionParts [ 1 ] ) ;
87+ var bugfix = int . Parse ( versionParts [ 2 ] ) ;
88+ var build = int . Parse ( versionParts [ 3 ] ) ;
89+ build ++ ;
90+
91+ switch ( config . versionType )
92+ {
93+ case VersionType . Major :
94+ major ++ ;
95+ feature = 0 ;
96+ bugfix = 0 ;
97+ build = 1 ;
98+ break ;
99+ case VersionType . Feature :
100+ feature ++ ;
101+ bugfix = 0 ;
102+ build = 1 ;
103+ break ;
104+ case VersionType . Bugfix :
105+ bugfix ++ ;
106+ build = 1 ;
107+ break ;
108+ case VersionType . Build :
109+ break ;
110+ }
111+
112+ version = $ "{ major } .{ feature } .{ bugfix } .{ build } ";
113+ File . WriteAllText ( versionFilePath , version ) ;
114+ return version ;
115+ }
116+
117+ private string GetBuildExtension ( BuildTarget platform )
118+ {
119+ switch ( platform )
120+ {
121+ case BuildTarget . StandaloneWindows :
122+ case BuildTarget . StandaloneWindows64 :
123+ return ".exe" ;
124+ case BuildTarget . WebGL :
125+ return "" ;
126+ default :
127+ return "" ;
128+ }
129+ }
130+
131+ private string GetFinalBuildPath ( string buildPath , string extension )
132+ {
133+ string finalPath ;
134+ if ( config . buildPathType == BuildPathType . Default )
135+ {
136+ finalPath = Path . Combine ( Application . dataPath , ".." , defaultBuildPath ,
137+ $ "{ config . companyName } .{ config . productName } .v{ PlayerSettings . bundleVersion } { extension } ") ;
138+ }
139+ else
140+ {
141+ finalPath = Path . Combine ( config . customBuildPath ,
142+ $ "{ config . companyName } .{ config . productName } .v{ PlayerSettings . bundleVersion } { extension } ") ;
143+ }
144+
145+ return finalPath ;
146+ }
147+
148+ private void RenameBuildPath ( string oldPath , string newPath )
149+ {
150+ try
151+ {
152+ if ( Directory . Exists ( oldPath ) )
153+ {
154+ Directory . Move ( oldPath , newPath ) ;
155+ }
156+ else if ( File . Exists ( oldPath ) )
157+ {
158+ File . Move ( oldPath , newPath ) ;
159+ }
160+ }
161+ catch ( DirectoryNotFoundException directoryNotFoundException )
162+ {
163+ Debug . Log (
164+ "<color=red>You have collected the project in the wrong folder that you specified in the settings!!!</color>" ) ;
165+ Debug . LogException ( directoryNotFoundException ) ;
166+ }
167+ }
168+
169+ private void ArchiveBuild ( string buildPath )
170+ {
171+ var archivePath = buildPath + ".zip" ;
172+
173+ if ( ! File . Exists ( archivePath ) )
174+ {
175+ CreateZipFromDirectory ( buildPath , archivePath ) ;
176+ }
177+ else
178+ {
179+ for ( var i = 1 ; i < 100 ; i ++ )
180+ {
181+ var numberedArchivePath = buildPath + $ "_{ i } .zip";
182+ if ( ! File . Exists ( numberedArchivePath ) )
183+ {
184+ CreateZipFromDirectory ( buildPath , numberedArchivePath ) ;
185+ break ;
186+ }
187+ }
188+ }
189+
190+ Debug . Log ( $ "Build archived to: { archivePath } ") ;
191+ }
192+
193+ private void CreateZipFromDirectory ( string sourceDir , string zipFile )
194+ {
195+ using ( var zip = ZipFile . Open ( zipFile , ZipArchiveMode . Create ) )
196+ {
197+ var dirInfo = new DirectoryInfo ( sourceDir ) ;
198+
199+ foreach ( var file in dirInfo . GetFiles ( ) )
200+ {
201+ zip . CreateEntryFromFile ( file . FullName , file . Name ) ;
202+ }
203+
204+ foreach ( var dir in dirInfo . GetDirectories ( ) )
205+ {
206+ AddDirectoryToZip ( zip , dir , dir . Name ) ;
207+ }
208+ }
209+ }
210+
211+ private void AddDirectoryToZip ( ZipArchive zip , DirectoryInfo dir , string entryName )
212+ {
213+ foreach ( var file in dir . GetFiles ( ) )
214+ {
215+ zip . CreateEntryFromFile ( file . FullName , Path . Combine ( entryName , file . Name ) ) ;
216+ }
217+
218+ foreach ( var subDir in dir . GetDirectories ( ) )
219+ {
220+ AddDirectoryToZip ( zip , subDir , Path . Combine ( entryName , subDir . Name ) ) ;
221+ }
222+ }
223+ }
224+ }
0 commit comments