mirror of
				https://github.com/ErikasKontenis/SabrehavenServer.git
				synced 2025-10-30 19:56:22 +01:00 
			
		
		
		
	commit client
This commit is contained in:
		
							
								
								
									
										278
									
								
								SabrehavenOTClient/modules/updater/updater.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										278
									
								
								SabrehavenOTClient/modules/updater/updater.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,278 @@ | ||||
| Updater = { } | ||||
|  | ||||
| Updater.maxRetries = 5 | ||||
|  | ||||
| --[[ | ||||
|  | ||||
| ]]-- | ||||
|  | ||||
| local updaterWindow | ||||
| local loadModulesFunction | ||||
| local scheduledEvent | ||||
| local httpOperationId = 0 | ||||
|  | ||||
| local function onLog(level, message, time) | ||||
|   if level == LogError then     | ||||
|     Updater.error(message) | ||||
|     g_logger.setOnLog(nil) | ||||
|   end | ||||
| end | ||||
|  | ||||
| local function initAppWindow() | ||||
|   if g_resources.getLayout() == "mobile" then | ||||
|     g_window.setMinimumSize({ width = 640, height = 360 }) | ||||
|   else | ||||
|     g_window.setMinimumSize({ width = 800, height = 640 })   | ||||
|   end | ||||
|  | ||||
|   -- window size | ||||
|   local size = { width = 1024, height = 600 } | ||||
|   size = g_settings.getSize('window-size', size) | ||||
|   g_window.resize(size) | ||||
|  | ||||
|   -- window position, default is the screen center | ||||
|   local displaySize = g_window.getDisplaySize() | ||||
|   local defaultPos = { x = (displaySize.width - size.width)/2, | ||||
|                        y = (displaySize.height - size.height)/2 } | ||||
|   local pos = g_settings.getPoint('window-pos', defaultPos) | ||||
|   pos.x = math.max(pos.x, 0) | ||||
|   pos.y = math.max(pos.y, 0) | ||||
|   g_window.move(pos) | ||||
|  | ||||
|   -- window maximized? | ||||
|   local maximized = g_settings.getBoolean('window-maximized', false) | ||||
|   if maximized then g_window.maximize() end | ||||
|  | ||||
|   g_window.setTitle(g_app.getName()) | ||||
|   g_window.setIcon('/images/clienticon') | ||||
|    | ||||
|   if g_app.isMobile() then | ||||
|     scheduleEvent(function() | ||||
|       g_app.scale(5.0) | ||||
|     end, 10) | ||||
|   end | ||||
| end | ||||
|  | ||||
| local function loadModules() | ||||
|   if loadModulesFunction then | ||||
|     local tmpLoadFunc = loadModulesFunction | ||||
|     loadModulesFunction = nil | ||||
|     tmpLoadFunc() | ||||
|   end | ||||
| end | ||||
|  | ||||
| local function downloadFiles(url, files, index, retries, doneCallback) | ||||
|   if not updaterWindow then return end | ||||
|   local entry = files[index] | ||||
|   if not entry then -- finished | ||||
|     return doneCallback() | ||||
|   end | ||||
|   local file = entry[1] | ||||
|   local file_checksum = entry[2] | ||||
|    | ||||
|   if retries > 0 then | ||||
|     updaterWindow.downloadStatus:setText(tr("Downloading (%i retry):\n%s", retries, file)) | ||||
|   else | ||||
|     updaterWindow.downloadStatus:setText(tr("Downloading:\n%s", file)) | ||||
|   end | ||||
|   updaterWindow.downloadProgress:setPercent(0) | ||||
|   updaterWindow.mainProgress:setPercent(math.floor(100 * index / #files)) | ||||
|    | ||||
|   httpOperationId = HTTP.download(url .. file, file, | ||||
|     function (file, checksum, err) | ||||
|       if not err and checksum ~= file_checksum then | ||||
|         err = "Invalid checksum of: " .. file .. ".\nShould be " .. file_checksum .. ", is: " .. checksum | ||||
|       end | ||||
|       if err then | ||||
|         if retries >= Updater.maxRetries then | ||||
|           Updater.error("Can't download file: " .. file .. ".\nError: " .. err) | ||||
|         else | ||||
|           scheduledEvent = scheduleEvent(function() | ||||
|             downloadFiles(url, files, index, retries + 1, doneCallback) | ||||
|           end, 250) | ||||
|         end | ||||
|         return | ||||
|       end | ||||
|       downloadFiles(url, files, index + 1, 0, doneCallback) | ||||
|     end, | ||||
|     function (progress, speed) | ||||
|       updaterWindow.downloadProgress:setPercent(progress) | ||||
|       updaterWindow.downloadProgress:setText(speed .. " kbps") | ||||
|     end) | ||||
| end | ||||
|  | ||||
| local function updateFiles(data, keepCurrentFiles) | ||||
|   if not updaterWindow then return end | ||||
|   if type(data) ~= "table" then | ||||
|     return Updater.error("Invalid data from updater api (not table)") | ||||
|   end | ||||
|   if type(data["error"]) == 'string' and data["error"]:len() > 0 then | ||||
|     return Updater.error(data["error"])     | ||||
|   end | ||||
|   if not data["files"] or type(data["url"]) ~= 'string' or data["url"]:len() < 4 then | ||||
|     return Updater.error("Invalid data from updater api: " .. json.encode(data, 2)) | ||||
|   end | ||||
|   if data["keepFiles"] then | ||||
|     keepCurrentFiles = true | ||||
|   end | ||||
|    | ||||
|   local newFiles = false | ||||
|   local finalFiles = {} | ||||
|   local localFiles = g_resources.filesChecksums() | ||||
|   local toUpdate = {} | ||||
|   -- keep all files or files from data/things | ||||
|   for file, checksum in pairs(localFiles) do | ||||
|     if keepCurrentFiles or string.find(file, "data/things") then | ||||
|       table.insert(finalFiles, file) | ||||
|     end | ||||
|   end | ||||
|   -- update files | ||||
|   for file, checksum in pairs(data["files"]) do | ||||
|     table.insert(finalFiles, file) | ||||
|     if not localFiles[file] or localFiles[file] ~= checksum then | ||||
|       table.insert(toUpdate, {file, checksum}) | ||||
|       newFiles = true | ||||
|     end | ||||
|   end | ||||
|   -- update binary | ||||
|   local binary = nil | ||||
|   if type(data["binary"]) == "table" and data["binary"]["file"]:len() > 1 then | ||||
|     local selfChecksum = g_resources.selfChecksum() | ||||
|     if selfChecksum:len() > 0 and selfChecksum ~= data["binary"]["checksum"] then | ||||
|       binary = data["binary"]["file"] | ||||
|       table.insert(toUpdate, {binary, data["binary"]["checksum"]}) | ||||
|     end | ||||
|   end | ||||
|    | ||||
|   if #toUpdate == 0 then -- nothing to update | ||||
|     updaterWindow.mainProgress:setPercent(100) | ||||
|     scheduledEvent = scheduleEvent(Updater.abort, 20) | ||||
|     return | ||||
|   end | ||||
|    | ||||
|   -- update of some files require full client restart | ||||
|   local forceRestart = false | ||||
|   local reloadModules = false | ||||
|   local forceRestartPattern = {"init.lua", "corelib", "updater", "otmod"} | ||||
|   for _, file in ipairs(toUpdate) do | ||||
|     for __, pattern in ipairs(forceRestartPattern) do | ||||
|       if string.find(file[1], pattern) then | ||||
|         forceRestart = true | ||||
|       end | ||||
|       if not string.find(file[1], "data/things") then | ||||
|         reloadModules = true | ||||
|       end | ||||
|     end | ||||
|   end | ||||
|    | ||||
|   updaterWindow.status:setText(tr("Updating %i files", #toUpdate)) | ||||
|   updaterWindow.mainProgress:setPercent(0) | ||||
|   updaterWindow.downloadProgress:setPercent(0) | ||||
|   updaterWindow.downloadProgress:show() | ||||
|   updaterWindow.downloadStatus:show() | ||||
|   updaterWindow.changeUrlButton:hide() | ||||
|   downloadFiles(data["url"], toUpdate, 1, 0, function() | ||||
|     updaterWindow.status:setText(tr("Updating client (may take few seconds)")) | ||||
|     updaterWindow.mainProgress:setPercent(100) | ||||
|     updaterWindow.downloadProgress:hide() | ||||
|     updaterWindow.downloadStatus:hide()  | ||||
|     scheduledEvent = scheduleEvent(function() | ||||
|       local restart = binary or (not loadModulesFunction and reloadModules) or forceRestart | ||||
|       if newFiles then | ||||
|         g_resources.updateData(finalFiles, not restart) | ||||
|       end | ||||
|       if binary then | ||||
|         g_resources.updateExecutable(binary) | ||||
|       end | ||||
|       if restart then | ||||
|         g_app.restart() | ||||
|       else | ||||
|         if reloadModules then | ||||
|           g_modules.reloadModules() | ||||
|         end | ||||
|         Updater.abort() | ||||
|       end | ||||
|     end, 100)   | ||||
|   end) | ||||
| end | ||||
|  | ||||
| -- public functions | ||||
| function Updater.init(loadModulesFunc) | ||||
|   g_logger.setOnLog(onLog) | ||||
|   loadModulesFunction = loadModulesFunc | ||||
|   initAppWindow() | ||||
|   Updater.check() | ||||
| end | ||||
|  | ||||
| function Updater.terminate() | ||||
|   loadModulesFunction = nil | ||||
|   Updater.abort() | ||||
| end | ||||
|  | ||||
| function Updater.abort() | ||||
|   HTTP.cancel(httpOperationId) | ||||
|   removeEvent(scheduledEvent) | ||||
|   if updaterWindow then | ||||
|     updaterWindow:destroy() | ||||
|     updaterWindow = nil | ||||
|   end | ||||
|   loadModules() | ||||
| end | ||||
|  | ||||
| function Updater.check(args) | ||||
|   if updaterWindow then return end | ||||
|    | ||||
|   updaterWindow = g_ui.displayUI('updater') | ||||
|   updaterWindow:show() | ||||
|   updaterWindow:focus() | ||||
|   updaterWindow:raise()   | ||||
|    | ||||
|   local updateData = nil | ||||
|   local function progressUpdater(value) | ||||
|     removeEvent(scheduledEvent) | ||||
|     if value == 100 then | ||||
|       return Updater.error(tr("Timeout")) | ||||
|     end | ||||
|     if updateData and (value > 60 or (not g_app.isMobile() or not ALLOW_CUSTOM_SERVERS or not loadModulesFunc)) then -- gives 3s to set custom updater for mobile version | ||||
|       return updateFiles(updateData) | ||||
|     end | ||||
|     scheduledEvent = scheduleEvent(function() progressUpdater(value + 1) end, 50) | ||||
|     updaterWindow.mainProgress:setPercent(value) | ||||
|   end | ||||
|   progressUpdater(0) | ||||
|  | ||||
|   httpOperationId = HTTP.postJSON(Services.updater, { | ||||
|     version = APP_VERSION, | ||||
|     build = g_app.getVersion(), | ||||
|     os = g_app.getOs(), | ||||
|     platform = g_window.getPlatformType(), | ||||
|     args = args or {} | ||||
|   }, function(data, err) | ||||
|     if err then       | ||||
|       return Updater.error(err) | ||||
|     end | ||||
|     updateData = data | ||||
|   end) | ||||
| end | ||||
|  | ||||
| function Updater.error(message) | ||||
|   removeEvent(scheduledEvent) | ||||
|   if not updaterWindow then return end | ||||
|   displayErrorBox(tr("Updater Error"), message).onOk = function() | ||||
|     Updater.abort() | ||||
|   end | ||||
| end | ||||
|  | ||||
| function Updater.changeUrl() | ||||
|   removeEvent(scheduledEvent) | ||||
|   modules.client_textedit.edit(Services.updater, {title="Enter updater url", width=300}, function(newUrl) | ||||
|     if updaterWindow and newUrl:len() > 4 then | ||||
|       Services.updater = newUrl | ||||
|     end | ||||
|     if updaterWindow then | ||||
|       updaterWindow:destroy() | ||||
|       updaterWindow = nil | ||||
|     end | ||||
|     Updater.check() | ||||
|   end) | ||||
| end | ||||
							
								
								
									
										12
									
								
								SabrehavenOTClient/modules/updater/updater.otmod
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								SabrehavenOTClient/modules/updater/updater.otmod
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| Module | ||||
|   name: updater | ||||
|   description: Updates client | ||||
|   author: otclient@otclient.ovh | ||||
|   website: otclient.ovh | ||||
|   reloadable: false | ||||
|   scripts: [ updater ] | ||||
|   dependencies: [ client_locales, client_styles, client_textedit ] | ||||
|   @onUnload: Updater.terminate() | ||||
|    | ||||
|   load-later: | ||||
|     - client_background | ||||
							
								
								
									
										53
									
								
								SabrehavenOTClient/modules/updater/updater.otui
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								SabrehavenOTClient/modules/updater/updater.otui
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | ||||
| StaticMainWindow | ||||
|   id: updaterWindow | ||||
|   !text: tr('Updater') | ||||
|   width: 350 | ||||
|  | ||||
|   layout: | ||||
|     type: verticalBox | ||||
|     fit-children: true | ||||
|        | ||||
|   Label | ||||
|     id: status | ||||
|     !text: tr('Checking for updates') | ||||
|     text-align: center | ||||
|  | ||||
|   ProgressBar | ||||
|     id: mainProgress | ||||
|     height: 15 | ||||
|     background-color: #4444ff | ||||
|     margin-bottom: 5 | ||||
|     margin-top: 5 | ||||
|  | ||||
|   Label | ||||
|     id: downloadStatus | ||||
|     text-align: center | ||||
|     text-auto-resize: true | ||||
|     text-wrap: true | ||||
|     visible: false | ||||
|  | ||||
|   ProgressBar | ||||
|     id: downloadProgress | ||||
|     height: 15 | ||||
|     background-color: #4444ff | ||||
|     margin-bottom: 5 | ||||
|     margin-top: 5 | ||||
|     visible: false | ||||
|            | ||||
|   Button | ||||
|     id: changeUrlButton | ||||
|     margin-left: 50 | ||||
|     margin-right: 50 | ||||
|     margin-top: 5 | ||||
|     margin-bottom: 10 | ||||
|     !text: tr('Change updater URL') | ||||
|     @onClick: Updater.changeUrl() | ||||
|     $!mobile: | ||||
|       visible: false | ||||
|  | ||||
|   Button | ||||
|     margin-left: 90 | ||||
|     margin-right: 90 | ||||
|     !text: tr('Cancel') | ||||
|     @onClick: Updater.abort() | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 ErikasKontenis
					ErikasKontenis