gamecreator Posted June 1, 2019 Share Posted June 1, 2019 This program checks a file online to see if its timestamp is different from one you have saved. If it's different, it downloads the file and patches your old file with it. This is thanks to the libcurl library (which is bundled with Leadwerks, so you can use it immediately). Usage: Simply create a new C++ project and replace your code with the code below. This prints info to the console so have that enabled if you want to see that (in Visual Studio this in under Project Properties, Linker, System, SubSystem). Make sure you have/create the necessary files and change the first four variables appropriately to point to the proper files. #include "leadwerks.h" using namespace Leadwerks; // This is the patch file we download char onlinepatchfileURL[200] = "http://www.yoursite.com/yourfile.exe"; // This is the name of the temporary downloaded patch file we save char localdownloadedpatchfile[80] = "patchfile"; // This is the executable we replace with the above patch file and then launch char localfiletobepatched[80] = "yourgamefile.exe"; // This file contains the timestamp we compare to the online file above char localtimestampfile[80] = "patchfiletimestamp.txt"; char onlinetimestamp[25]; char localtimestamp[25]; long downloadprogresstimer; // Callback function called regularly by libcurl as a file is downloaded int downloadprogress(void *p, double dltotal, double dlnow, double ultotal, double ulnow) { // Print download progress once a second if(Time::Millisecs()>downloadprogresstimer) { cout << "Downloaded bytes: " << dlnow << " / " << dltotal << "\n"; downloadprogresstimer=Time::Millisecs()+1000; } return 0; } // Compare online timestamp with one we have saved in a file bool ispatchfiletimestampdifferent() { // Retrieve timestamp from local file FILE *fp=fopen(localtimestampfile, "r"); if(fp==NULL) { printf("Error opening local timestamp file: %s\n",localtimestampfile); exit(1); } fgets(localtimestamp, 80, fp); fclose(fp); // Retrieve timestamp from online file // WARNING: some sites may not return a timestamp so this may fail CURL *curl=curl_easy_init(); time_t fileTime = 1; curl_easy_setopt(curl, CURLOPT_URL, onlinepatchfileURL); curl_easy_setopt(curl, CURLOPT_NOBODY, 1); curl_easy_setopt(curl, CURLOPT_FILETIME, 1); curl_easy_perform(curl); curl_easy_getinfo(curl, CURLINFO_FILETIME, &fileTime); curl_easy_cleanup(curl); // Format online timestamp string char buf[80]; struct tm *ts=localtime(&fileTime); strftime(onlinetimestamp, sizeof(buf), "%a %Y-%m-%d %H:%M:%S", ts); // Sanity check to compare two strings // printf("-%s-\n-%s-\n", onlinetimestamp, localtimestamp); // Compare the two dates. Are they different? if(strcmp(onlinetimestamp, localtimestamp)==0) return false; else return true; } bool downloadpatchfile() { CURL *curl; CURLcode res; FILE *fp; curl = curl_easy_init(); if(curl) { fp = fopen(localdownloadedpatchfile, "wb"); if(fp==NULL) { printf("Error opening local patch file: %s\n", localdownloadedpatchfile); exit(1); } curl_easy_setopt(curl, CURLOPT_URL, onlinepatchfileURL); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL); curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, FALSE); curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, downloadprogress); res = curl_easy_perform(curl); curl_easy_cleanup(curl); fclose(fp); if(res == CURLE_OK) { printf("Patch file download complete.\n"); return true; } else printf("Error downloading patch file.\n"); } // Something went wrong... return false; } void savenewtimestamptofile() { FILE *fp; fp = fopen(localtimestampfile, "wb"); if(fp==NULL) { printf("Error opening local timestamp file: %s\n", localtimestampfile); exit(1); } fputs(onlinetimestamp, fp); fclose(fp); } int main(int argc, TCHAR *argv[]) { // Compare online patch file timestamp to one stored in local file // If it's different, download new file and replace old one if(ispatchfiletimestampdifferent()) { printf("Patch file date is different from stored date. Downloading patch file...\n"); downloadprogresstimer=Time::Millisecs(); if(downloadpatchfile()) { savenewtimestamptofile(); // Remove old file remove(localfiletobepatched); // Rename patch file to old file rename(localdownloadedpatchfile, localfiletobepatched); } } else printf("Patch file date is the same as stored date. There is no need to download patch file.\n"); // Launch program STARTUPINFO info={sizeof(info)}; PROCESS_INFORMATION processInfo; if(CreateProcess(argv[1], localfiletobepatched, NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo)) { // WaitForSingleObject(processInfo.hProcess, INFINITE); CloseHandle(processInfo.hProcess); CloseHandle(processInfo.hThread); } else printf("Could not launch program. CreateProcess failed (%d).\n", GetLastError()); } 3 Quote Link to comment Share on other sites More sharing options...
gamecreator Posted June 1, 2019 Author Share Posted June 1, 2019 A possible improvement to this is to use a function like SetFileTime to change the patched exe to match the online patch file. That way you can just compare the two file dates instead of storing the date in a file. Edit: I'm not sure how well this works with Daylight Saving Time and such. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.