FileRouter.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. package router
  2. import (
  3. "ARKItems/configs"
  4. "archive/zip"
  5. "encoding/json"
  6. "fmt"
  7. "github.com/gin-gonic/gin"
  8. "io"
  9. "io/ioutil"
  10. "os"
  11. "path/filepath"
  12. "strings"
  13. "time"
  14. )
  15. var (
  16. BackupFileList = make([]string, 0)
  17. // ServerConfigUrls 实际服务器目录,商店插件配置文件位置
  18. ServerConfigUrls = make([]string, 0)
  19. )
  20. func init() {
  21. ReadBackupFileList()
  22. }
  23. func ARKFileRouter(api *gin.RouterGroup) {
  24. //安装插件
  25. api.GET("/installPlugin", InstallArkApiZip)
  26. //保存配置到配置文件
  27. api.GET("/saveConfig", WriteFileConfig)
  28. //更新实际配置文件内容
  29. api.GET("/updateServerShopApiConfig", UpdateServerShopApiConfig)
  30. }
  31. func UpdateServerShopApiConfig(c *gin.Context) {
  32. marshal, err := json.Marshal(ARKConfig)
  33. if err != nil {
  34. fmt.Println(err)
  35. c.JSON(200, CreateResultError(500, "配置文件读取失败"))
  36. }
  37. for i := range ServerConfigUrls {
  38. os.Remove(ServerConfigUrls[i])
  39. ioutil.WriteFile(ServerConfigUrls[i], marshal, 0644)
  40. }
  41. //TODO 可能需要调用rcon功能,更新配置
  42. c.JSON(200, CreateResult())
  43. }
  44. //F:/arkserver/Servers/Server1/ShooterGame/Binaries/Win64/Plugins/ArkShop/config.json
  45. // InstallArkApiZip 安装ArkApi
  46. func InstallArkApiZip(c *gin.Context) {
  47. value := c.Query("compulsion")
  48. //TODO 是否将最新的商店文件写入配置中
  49. //writeNow := c.Query("writeNow")
  50. //是否强制安装
  51. compulsion := value == "true"
  52. urls := ReadArkBackupUrl(configs.ArkApiInstallUrl)
  53. for _, url := range urls {
  54. ServerConfigUrls = append(ServerConfigUrls, url+"/ArkApi/Plugins/ArkShop/config.json")
  55. go InstallZip(compulsion, url)
  56. }
  57. c.JSON(200, CreateResult())
  58. }
  59. // WriteFileConfig 备份实体的配置文件
  60. func WriteFileConfig(c *gin.Context) {
  61. err := BackupFile()
  62. if err != nil {
  63. fmt.Println(err)
  64. c.JSON(200, CreateResultError(500, "备份失败"))
  65. }
  66. //修改目标文件
  67. marshal, err := json.Marshal(ARKConfig)
  68. if err != nil {
  69. fmt.Println(err)
  70. c.JSON(200, CreateResultError(500, "写入失败"))
  71. }
  72. err = os.WriteFile(configs.ARKJsonFilePath, marshal, 0644)
  73. }
  74. // ReadBackupFileList 读取备份文件列表
  75. func ReadBackupFileList() {
  76. entities, err := os.ReadDir(configs.ARKBackupDir)
  77. if err != nil {
  78. fmt.Println(err)
  79. }
  80. //获取备份文件位置
  81. for i := range entities {
  82. BackupFileList = append(BackupFileList, configs.ARKBackupDir+"/"+entities[i].Name())
  83. }
  84. //获取实际的插件配置位置
  85. urls := ReadArkBackupUrl(configs.ArkApiInstallUrl)
  86. for _, url := range urls {
  87. ServerConfigUrls = append(ServerConfigUrls, url+"/ArkApi/Plugins/ArkShop/config.json")
  88. }
  89. }
  90. func BackupFile() error {
  91. //穿件备份文件夹
  92. os.MkdirAll(configs.ARKBackupDir, 0755)
  93. name := ""
  94. //创建备份文件
  95. split := strings.Split(configs.ARKJsonFilePath, "/")
  96. split = strings.Split(split[len(split)-1], ".")
  97. name = split[0] + "-" + time.Now().Format("20060102150405")
  98. for i := 1; i < len(split); i++ {
  99. name += "." + split[i]
  100. }
  101. return CopyFile(configs.ARKJsonFilePath, configs.ARKBackupDir+"/"+name)
  102. }
  103. // CopyFile 复制文件
  104. func CopyFile(src, dest string) error {
  105. // 打开源文件
  106. sourceFile, err := os.Open(src)
  107. if err != nil {
  108. return err
  109. }
  110. defer sourceFile.Close()
  111. // 创建目标文件
  112. split := strings.Split(dest, "/")
  113. str := ""
  114. for i := 0; i < len(split)-1; i++ {
  115. str += split[i] + "/"
  116. err := os.MkdirAll(str, 0755)
  117. if err != nil {
  118. fmt.Println(err)
  119. }
  120. }
  121. destinationFile, err := os.Create(dest)
  122. if err != nil {
  123. return err
  124. }
  125. defer destinationFile.Close()
  126. // 复制文件内容
  127. _, err = io.Copy(destinationFile, sourceFile)
  128. if err != nil {
  129. return err
  130. }
  131. // 确保数据写入目标文件
  132. err = destinationFile.Sync()
  133. if err != nil {
  134. return err
  135. }
  136. return nil
  137. }
  138. // InstallZip 安装服务器插件
  139. func InstallZip(compulsion bool, url string) {
  140. entries, err := os.ReadDir(url)
  141. if err != nil {
  142. fmt.Println(err)
  143. }
  144. if !compulsion {
  145. for i := range entries {
  146. if entries[i].IsDir() && entries[i].Name() == "ArkApi" {
  147. return
  148. }
  149. }
  150. } else {
  151. for i := range entries {
  152. if entries[i].IsDir() && entries[i].Name() == "ArkApi" {
  153. //删除
  154. os.RemoveAll(url + "/ArkApi")
  155. break
  156. }
  157. }
  158. }
  159. err = Unzip(configs.ARKAPiZipPath, url)
  160. }
  161. // ReadArkBackupUrl 读取服务器路径的实际位置
  162. func ReadArkBackupUrl(dir string) []string {
  163. resourcesDir := make([]string, 0)
  164. // 读取目录内容
  165. entries, err := os.ReadDir(dir)
  166. if err != nil {
  167. fmt.Println(err)
  168. return resourcesDir
  169. }
  170. // 遍历目录内容
  171. for _, entry := range entries {
  172. if entry.IsDir() {
  173. readDir, err := os.ReadDir(dir + "/" + entry.Name())
  174. if err != nil {
  175. fmt.Println(err)
  176. return resourcesDir
  177. }
  178. existEngineDir := false
  179. existShooterGameDir := false
  180. existSteamapps := false
  181. for _, subentry := range readDir {
  182. if subentry.IsDir() && subentry.Name() == "Engine" {
  183. existEngineDir = true
  184. }
  185. if subentry.IsDir() && subentry.Name() == "ShooterGame" {
  186. existShooterGameDir = true
  187. }
  188. if subentry.IsDir() && subentry.Name() == "steamapps" {
  189. existSteamapps = true
  190. }
  191. }
  192. if existEngineDir && existShooterGameDir && existSteamapps {
  193. resourcesDir = append(resourcesDir, dir+"/"+entry.Name()+"/ShooterGame/Binaries/Win64")
  194. }
  195. }
  196. }
  197. return resourcesDir
  198. }
  199. // Unzip 解压缩ZIP文件到目标路径
  200. func Unzip(src, dest string) error {
  201. // 打开ZIP文件
  202. reader, err := zip.OpenReader(src)
  203. if err != nil {
  204. return err
  205. }
  206. defer reader.Close()
  207. // 创建目标路径
  208. if err := os.MkdirAll(dest, 0755); err != nil {
  209. return err
  210. }
  211. // 解压每个文件
  212. for _, file := range reader.File {
  213. filePath := filepath.Join(dest, file.Name)
  214. // 检查文件的目录结构
  215. if !strings.HasPrefix(filePath, filepath.Clean(dest)+string(os.PathSeparator)) {
  216. return fmt.Errorf("非法文件路径: %s", filePath)
  217. }
  218. if file.FileInfo().IsDir() {
  219. // 创建目录
  220. if err := os.MkdirAll(filePath, file.Mode()); err != nil {
  221. return err
  222. }
  223. } else {
  224. // 创建文件所在的目录
  225. if err := os.MkdirAll(filepath.Dir(filePath), file.Mode()); err != nil {
  226. return err
  227. }
  228. // 打开ZIP中的文件
  229. zipFile, err := file.Open()
  230. if err != nil {
  231. return err
  232. }
  233. defer zipFile.Close()
  234. // 创建输出文件
  235. outputFile, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, file.Mode())
  236. if err != nil {
  237. return err
  238. }
  239. defer outputFile.Close()
  240. // 将内容拷贝到输出文件
  241. _, err = io.Copy(outputFile, zipFile)
  242. if err != nil {
  243. return err
  244. }
  245. }
  246. }
  247. return nil
  248. }