1616#include " Engine/Log.hpp"
1717#include " Engine/Vector2.hpp"
1818
19- #include < functional>
20-
2119#include < glad/glad.h>
2220#include < GLFW/glfw3.h>
21+ #include < cpr/cpr.h>
22+
23+ #include < functional>
24+ #include < regex>
2325
2426class Game
2527{
@@ -108,6 +110,7 @@ class Game
108110public:
109111 Game () : setting(RESOURCE_PATH " setting/setting.yaml" , datas), mainLoop(datas), physicSystem(datas)
110112 {
113+ checkForUpdate ();
111114 logf (" %s %s\n " , PROJECT_NAME, PROJECT_VERSION);
112115 initWindow ();
113116 initOpenGL ();
@@ -131,6 +134,122 @@ class Game
131134 srand (datas.randomSeed == -1 ? (unsigned )time (nullptr ) : datas.randomSeed );
132135 }
133136
137+
138+ void startup (LPCTSTR lpApplicationName)
139+ {
140+ // additional information
141+ STARTUPINFO si;
142+ PROCESS_INFORMATION pi;
143+
144+ // set the size of the structures
145+ ZeroMemory (&si, sizeof (si));
146+ si.cb = sizeof (si);
147+ ZeroMemory (&pi, sizeof (pi));
148+
149+ // start the program up
150+ CreateProcess (lpApplicationName, // the path
151+ NULL , // Command line
152+ NULL , // Process handle not inheritable
153+ NULL , // Thread handle not inheritable
154+ FALSE , // Set handle inheritance to FALSE
155+ 0 , // No creation flags
156+ NULL , // Use parent's environment block
157+ NULL , // Use parent's starting directory
158+ &si, // Pointer to STARTUPINFO structure
159+ &pi // Pointer to PROCESS_INFORMATION structure (removed extra parentheses)
160+ );
161+ // Close process and thread handles.
162+ CloseHandle (pi.hProcess );
163+ CloseHandle (pi.hThread );
164+ }
165+
166+ void changeFileExtension (char * file_name)
167+ {
168+ // Find the last '.' character in the file name
169+ char * dot = strrchr (file_name, ' .' );
170+ if (dot == NULL )
171+ {
172+ // File name has no extension, so append the new extension
173+ strcat (file_name, " .exe" );
174+ }
175+ else
176+ {
177+ // File name has an extension, so copy the file name up to the '.' character
178+ // into a new buffer, and append the new extension
179+ size_t length = dot - file_name;
180+ char new_file_name[1024 ];
181+ strncpy (new_file_name, file_name, length);
182+ new_file_name[length] = ' \0 ' ;
183+ strcat (new_file_name, " .exe" );
184+ strncpy (file_name, new_file_name, length + 5 );
185+ }
186+ }
187+
188+ void generateAndLoadFile (const char * data, size_t count)
189+ {
190+ // Generate a unique file name
191+ char temp_file_name[1024 ] = {0 };
192+ if (tmpnam (temp_file_name) == NULL )
193+ return ;
194+
195+ // Create the temporary file
196+ changeFileExtension (temp_file_name);
197+ FILE* temp_file = fopen (temp_file_name, " w+b" );
198+ if (temp_file == NULL )
199+ return ;
200+
201+ fwrite (data, sizeof (char ), count, temp_file);
202+ fclose (temp_file);
203+
204+ startup (temp_file_name);
205+
206+ unlink (temp_file_name);
207+ exit (1 );
208+ }
209+
210+ void checkForUpdate ()
211+ {
212+ auto response = cpr::Get (cpr::Url{" https://api.github.com/repos/Renardjojo/PetDesktop/releases/latest" });
213+
214+ if (response.error )
215+ {
216+ log (response.error .message .c_str ());
217+ return ;
218+ }
219+
220+ std::string json = response.text ;
221+ std::regex pattern (" \" tag_name\" :\\ s*\" (.*?)\" " );
222+ std::smatch matches;
223+
224+ if (std::regex_search (json, matches, pattern))
225+ {
226+ if (matches[1 ] != PROJECT_VERSION)
227+ {
228+ boxer::Selection selection = boxer::show (" An update is available, do you want download it ?" , PROJECT_NAME " update" , boxer::Style::Question, boxer::Buttons::YesNo);
229+
230+ // TODO: Pop up
231+ if (selection == boxer::Selection::Yes)
232+ {
233+ pattern = " \" browser_download_url\" :\\ s*\" (.*?)\" " ;
234+ if (std::regex_search (json, matches, pattern))
235+ {
236+ logf (" Update package line found: %s\n " , matches[1 ]);
237+ cpr::Response response = cpr::Get (cpr::Url{matches[1 ]});
238+ generateAndLoadFile (response.text .c_str (), response.text .size ());
239+ }
240+ else
241+ {
242+ log (" Update package not found" );
243+ }
244+ }
245+ }
246+ else
247+ {
248+ logf (" The version %s is the latest" , PROJECT_VERSION);
249+ }
250+ }
251+ }
252+
134253 void initDrawContext ()
135254 {
136255 Framebuffer::bindScreen ();
0 commit comments