creatorversion.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "io"
  6. "log"
  7. "os"
  8. "os/exec"
  9. "strconv"
  10. "strings"
  11. )
  12. /*
  13. 说明:
  14. 大厅部分的project.manifest需要拷贝回resources/version,打包需要重新编译一次
  15. */
  16. const PthSep = string(os.PathSeparator)
  17. type VersionInfo struct {
  18. Url string
  19. Version string
  20. PubDir string
  21. OutDir string
  22. PrePubDir string
  23. Modules []string
  24. Cdn_dir string
  25. MetaVersion string
  26. XXTeaSign string
  27. XXTeaKey string
  28. EncodeSufix []string
  29. }
  30. func Marshal(v VersionInfo) []byte {
  31. data, err := json.Marshal(v)
  32. if err != nil {
  33. log.Fatal(err)
  34. }
  35. return data
  36. }
  37. func Unmarshal(data []byte) VersionInfo {
  38. var user VersionInfo
  39. err := json.Unmarshal(data, &user)
  40. if err != nil {
  41. log.Fatal(err)
  42. }
  43. return user
  44. }
  45. func Read() []byte {
  46. fp, err := os.OpenFile("./creatorversion.json", os.O_RDONLY, 0755)
  47. defer fp.Close()
  48. if err != nil {
  49. log.Fatal(err)
  50. }
  51. data := make([]byte, 1024)
  52. n, err := fp.Read(data)
  53. if err != nil {
  54. log.Fatal(err)
  55. }
  56. return data[:n]
  57. }
  58. func Write(data []byte) {
  59. fp, err := os.OpenFile("./creatorversion.json", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
  60. if err != nil {
  61. log.Fatal(err)
  62. }
  63. defer fp.Close()
  64. _, err = fp.Write(data)
  65. if err != nil {
  66. log.Fatal(err)
  67. }
  68. }
  69. func removeManifest(srcPath string) {
  70. dir, err := os.ReadDir(srcPath)
  71. if err != nil {
  72. return
  73. }
  74. for _, fi := range dir {
  75. if fi.IsDir() { // 忽略目录
  76. removeManifest(srcPath + PthSep + fi.Name())
  77. } else {
  78. if fi.Name() == "project.manifest" || fi.Name() == "version.manifest" {
  79. os.Remove(srcPath + PthSep + fi.Name())
  80. }
  81. }
  82. }
  83. }
  84. func makeManifest(version, url, dir, out_dir, name string) {
  85. fmt.Println("makeManifest ", version, url, dir, out_dir, name)
  86. cmd := exec.Command("node", "version_generator.js", "-v", version, "-u", url,
  87. "-s", dir, "-d", out_dir, "-n", name)
  88. stdout, err := cmd.StdoutPipe()
  89. if err != nil {
  90. log.Fatal(err)
  91. }
  92. // 保证关闭输出流
  93. defer stdout.Close()
  94. // 运行命令
  95. if err := cmd.Start(); err != nil {
  96. log.Fatal(err)
  97. }
  98. // 读取输出结果
  99. opBytes, err := io.ReadAll(stdout)
  100. if err != nil {
  101. log.Fatal(err)
  102. }
  103. log.Println(string(opBytes))
  104. cmd.Start()
  105. cmd.Wait()
  106. }
  107. func isNeedEncode(file string, postFixes []string) bool {
  108. for _, v := range postFixes {
  109. if strings.HasSuffix(file, v) {
  110. return true
  111. }
  112. }
  113. return false
  114. }
  115. func main() {
  116. defer func() {
  117. fmt.Println("结束,按任意键退出")
  118. var endInput string
  119. fmt.Scanln(&endInput)
  120. }()
  121. versionInfo := Unmarshal(Read())
  122. fmt.Println(versionInfo)
  123. if len(os.Args) >= 2 && os.Args[1] == "decode" {
  124. fmt.Println("开始还原加密")
  125. StartDecodeDir(versionInfo.PubDir+PthSep+"assets", versionInfo.PubDir+PthSep+"assets",
  126. versionInfo.XXTeaKey, versionInfo.XXTeaSign, versionInfo.EncodeSufix)
  127. return
  128. }
  129. v := strings.Split(versionInfo.Version, ".")
  130. if len(v) <= 0 {
  131. return
  132. }
  133. if versionInfo.XXTeaKey != "" {
  134. fmt.Println("xxtea 加密")
  135. StartEncodeDir(versionInfo.PubDir+PthSep+"assets", versionInfo.PubDir+PthSep+"assets",
  136. versionInfo.XXTeaKey, versionInfo.XXTeaSign, versionInfo.EncodeSufix)
  137. }
  138. // 拷贝预发布
  139. fmt.Println("正在拷贝预发布")
  140. os.RemoveAll(versionInfo.PrePubDir)
  141. copyDir(versionInfo.PubDir+PthSep+"src", versionInfo.PrePubDir+PthSep+"src")
  142. copyDir(versionInfo.PubDir+PthSep+"assets", versionInfo.PrePubDir+PthSep+"assets")
  143. outputVersion := versionInfo.Version
  144. outputDir := fmt.Sprintf("release%v%v", PthSep, outputVersion)
  145. os.RemoveAll(outputDir)
  146. os.MkdirAll(outputDir+PthSep+"assets", 0777)
  147. subModule := "assets" // subpackages
  148. // 子模块编译到assets目录中去了,先把子模块代码抽出来
  149. for _, v := range versionInfo.Modules {
  150. fmt.Println("正在生成manifest", v)
  151. //moduleDest := outputDir + PthSep + subModule + PthSep + v
  152. //os.MkdirAll(moduleDest, 0777)
  153. makeManifest(versionInfo.Version, versionInfo.Url+"assets/"+v+"/",
  154. versionInfo.PrePubDir+PthSep+subModule+PthSep+v,
  155. versionInfo.PrePubDir+PthSep+subModule+PthSep+v, "")
  156. CopyFile(versionInfo.PubDir+subModule+PthSep+v+"/project.manifest", versionInfo.PrePubDir+PthSep+subModule+PthSep+v+"/project.manifest")
  157. src := versionInfo.PrePubDir + PthSep + subModule + PthSep + v
  158. dst := outputDir + PthSep + subModule + PthSep + v
  159. fmt.Printf("转移模块 %v -> %v\n", src, dst)
  160. err := os.Rename(src, dst)
  161. if err != nil {
  162. fmt.Printf("%v\n", err)
  163. }
  164. }
  165. /**outputDir = fmt.Sprintf("release%v%v", PthSep, outputVersion)
  166. fmt.Println("正在copy src目录")
  167. copyDir(versionInfo.PubDir+"/src", fmt.Sprintf("%v/src", outputDir))
  168. fmt.Println("正在copy assets")
  169. copyDir(versionInfo.PubDir+"/assets", fmt.Sprintf("%v/assets", outputDir))*/
  170. fmt.Println("正在制作大厅 manifest")
  171. makeManifest(versionInfo.Version, versionInfo.Url, versionInfo.PrePubDir, versionInfo.PrePubDir, "")
  172. CopyFile(versionInfo.OutDir+"/project.manifest", versionInfo.PrePubDir+PthSep+"project.manifest")
  173. CopyFile(outputDir+PthSep+"/project.manifest", versionInfo.PrePubDir+PthSep+"project.manifest")
  174. CopyFile(outputDir+PthSep+"/version.manifest", versionInfo.PrePubDir+PthSep+"version.manifest")
  175. copyDir(versionInfo.PrePubDir+PthSep+"src", outputDir+PthSep+"src")
  176. copyDir(versionInfo.PrePubDir+PthSep+"assets", outputDir+PthSep+"assets")
  177. // 把大厅的manifest拷贝到build目录下
  178. fmt.Println("正在拷贝大厅 manifest")
  179. CopyFile(versionInfo.PubDir+subModule+PthSep+versionInfo.MetaVersion, versionInfo.PrePubDir+PthSep+"project.manifest")
  180. // 通过比较,生成delta文件
  181. if versionInfo.Cdn_dir != "" {
  182. fmt.Println("正在生成delta 文件 ", versionInfo.Cdn_dir)
  183. deltaDir := fmt.Sprintf("delta%v%v", PthSep, outputVersion)
  184. compareFolder(outputDir, versionInfo.Cdn_dir, deltaDir)
  185. }
  186. // 删除无用部分
  187. fmt.Println("正在删除无更新游戏目录")
  188. for _, v := range versionInfo.Modules {
  189. dir := fmt.Sprintf("delta%v%v/assets/%s", PthSep, outputVersion, v)
  190. if isDeltaEmpty(dir) {
  191. fmt.Printf(" %s\n", dir)
  192. os.RemoveAll(dir)
  193. }
  194. }
  195. // 版本维护
  196. lastVersion, _ := strconv.ParseInt(v[len(v)-1], 10, 32)
  197. lastVersion++
  198. v[len(v)-1] = fmt.Sprintf("%d", lastVersion)
  199. newVersion := fmt.Sprintf("%v", v[0])
  200. for i := 1; i < len(v); i++ {
  201. newVersion = fmt.Sprintf("%v.%v", newVersion, v[i])
  202. }
  203. versionInfo.Version = newVersion
  204. fmt.Println("正在更新版本号 为 ", versionInfo.Version)
  205. data := Marshal(versionInfo)
  206. Write(data)
  207. }