bool ProjectFileWriter::LoadFromFile(gd::Project & project, const gd::String & filename) { //Load the XML document structure TiXmlDocument doc; if ( !doc.LoadFile(filename.ToLocale().c_str()) ) { gd::String errorTinyXmlDesc = doc.ErrorDesc(); gd::String error = _( "Error while loading :" ) + "\n" + errorTinyXmlDesc + "\n\n" +_("Make sure the file exists and that you have the right to open the file."); gd::LogError( error ); return false; } #if defined(GD_IDE_ONLY) project.SetProjectFile(filename); project.SetDirty(false); #endif TiXmlHandle hdl( &doc ); gd::SerializerElement rootElement; ConvertANSIXMLFile(hdl, doc, filename); //Load the root element TiXmlElement * rootXmlElement = hdl.FirstChildElement("project").ToElement(); //Compatibility with GD <= 3.3 if (!rootXmlElement) rootXmlElement = hdl.FirstChildElement("Project").ToElement(); if (!rootXmlElement) rootXmlElement = hdl.FirstChildElement("Game").ToElement(); //End of compatibility code gd::Serializer::FromXML(rootElement, rootXmlElement); //Unsplit the project #if defined(GD_IDE_ONLY) && !defined(GD_NO_WX_GUI) wxString projectPath = wxFileName::FileName(filename).GetPath(); gd::Splitter splitter; splitter.Unsplit(rootElement, [&projectPath](gd::String path, gd::String name) { TiXmlDocument doc; gd::SerializerElement rootElement; gd::String filename = projectPath + path + "-" + MakeFileNameSafe(name); if (!doc.LoadFile(filename.ToLocale().c_str())) { gd::String errorTinyXmlDesc = doc.ErrorDesc(); gd::String error = _( "Error while loading :" ) + "\n" + errorTinyXmlDesc + "\n\n" +_("Make sure the file exists and that you have the right to open the file."); gd::LogError(error); return rootElement; } TiXmlHandle hdl( &doc ); gd::Serializer::FromXML(rootElement, hdl.FirstChildElement().ToElement()); return rootElement; }); #endif //Unserialize the whole project project.UnserializeFrom(rootElement); return true; }
/** * Show a dialog so as to get a text from user */ bool GD_EXTENSION_API ShowTextInput( RuntimeScene & scene, gd::Variable & variable, const gd::String & message, const gd::String & title ) { sf::Clock timeSpent; gd::String result; //Display the box #if defined(WINDOWS) CInputBox ibox(NULL); if (ibox.DoModal(title.ToWide().c_str(), message.ToWide().c_str())) result = gd::String::FromWide(ibox.Text); #endif #if defined(LINUX) || defined(MACOS) std::string strResult; nw::TextInput dialog(title.ToLocale(), message.ToLocale(), strResult); dialog.wait_until_closed(); result = gd::String::FromLocale(strResult); //Convert from locale #endif scene.GetTimeManager().NotifyPauseWasMade(timeSpent.getElapsedTime().asMicroseconds());//Don't take the time spent in this function in account. //Update the variable variable.SetString(result); return true; }
bool ProjectFileWriter::SaveToFile(const gd::Project & project, const gd::String & filename, bool forceSingleFile) { //Serialize the whole project gd::SerializerElement rootElement; project.SerializeTo(rootElement); #if defined(GD_IDE_ONLY) && !defined(GD_NO_WX_GUI) if (project.IsFolderProject() && !forceSingleFile) //Optionally split the project { wxString projectPath = wxFileName::FileName(filename).GetPath(); gd::Splitter splitter; auto splitElements = splitter.Split(rootElement, { "/layouts/layout", "/externalEvents/externalEvents", "/externalLayouts/externalLayout", }); for (auto & element : splitElements) { //Create a partial XML document TiXmlDocument doc; doc.LinkEndChild(new TiXmlDeclaration("1.0", "UTF-8", "")); TiXmlElement * root = new TiXmlElement("projectPartial"); doc.LinkEndChild(root); gd::Serializer::ToXML(element.element, root); //And write the element in it gd::String filename = projectPath + element.path + "-" + MakeFileNameSafe(element.name); gd::RecursiveMkDir::MkDir(wxFileName::FileName(filename).GetPath()); if (!doc.SaveFile(filename.ToLocale().c_str())) { gd::LogError( _( "Unable to save file ") + filename + _("!\nCheck that the drive has enough free space, is not write-protected and that you have read/write permissions." ) ); return false; } } } #endif //Create the main XML document TiXmlDocument doc; doc.LinkEndChild(new TiXmlDeclaration( "1.0", "UTF-8", "" )); TiXmlElement * root = new TiXmlElement( "project" ); doc.LinkEndChild(root); gd::Serializer::ToXML(rootElement, root); //Write XML to file if ( !doc.SaveFile( filename.ToLocale().c_str() ) ) { gd::LogError( _( "Unable to save file ") + filename + _("!\nCheck that the drive has enough free space, is not write-protected and that you have read/write permissions." ) ); return false; } return true; }
/** * Display a simple message box. */ void GD_EXTENSION_API ShowMessageBox( RuntimeScene & scene, const gd::String & message, const gd::String & title ) { sf::Clock timeSpent; //Display the box #if defined(WINDOWS) MessageBoxW(NULL, message.ToWide().c_str(), title.ToWide().c_str(), MB_ICONINFORMATION); #endif #if defined(LINUX) || defined(MACOS) nw::MsgBox msgBox(title.ToLocale(), message.ToLocale()); msgBox.wait_until_closed(); #endif scene.GetTimeManager().NotifyPauseWasMade(timeSpent.getElapsedTime().asMicroseconds());//Don't take the time spent in this function in account. }
void AnalyticsSender::SendData(gd::String collection, SerializerElement & data) { #if !defined(GD_NO_WX_GUI) //Check if we are allowed to send these data. bool sendInfo; wxConfigBase::Get()->Read("/Startup/SendInfo", &sendInfo, true); if (!sendInfo) return; data.SetAttribute("gdVersion", VersionWrapper::FullString()); data.SetAttribute("os", gd::String(wxGetOsDescription())); data.SetAttribute("lang", gd::String(wxLocale::GetLanguageCanonicalName(LocaleManager::Get()->GetLanguage()))); if (wxConfig::Get()) data.SetAttribute("openingCount", wxConfig::Get()->ReadDouble("Startup/OpeningCount", 0)); // Create request std::cout << "Sending analytics data..."; std::cout.flush(); sf::Http Http; Http.setHost("http://api.keen.io"); sf::Http::Request request; request.setMethod(sf::Http::Request::Post); request.setField("Content-Type", "application/json"); request.setUri("/3.0/projects/"+projectId.ToLocale()+"/events/"+collection.ToLocale()+"?api_key="+writeKey.ToLocale()); request.setBody(Serializer::ToJSON(data).ToSfString()); // Send the request sf::Http::Response response = Http.sendRequest(request, sf::seconds(2)); std::cout << "done (" << response.getStatus() << ")" << std::endl; #endif }
gd::String NativeFileSystem::ReadFile(const gd::String & file) { std::ifstream t(file.ToLocale().c_str()); std::stringstream buffer; buffer << t.rdbuf(); return gd::String::FromUTF8(buffer.str()); }
gd::String ResourcesLoader::LoadPlainText( const gd::String & filename ) { gd::String text; if (resFile.ContainsFile(filename)) { char* buffer = resFile.GetFile(filename); if (!buffer) { cout << "Failed to read a file from resource file: " << filename << endl; } else { text = gd::String::FromUTF8(std::string(buffer)); } } else { ifstream file(filename.ToLocale().c_str(), ios::in); if(!file.fail()) { string ligne; while(getline(file, ligne)) text += gd::String::FromUTF8(ligne)+"\n"; file.close(); } else cout << "Failed to read a file: " << filename << endl; } return text; }
void GD_API DownloadFile( const gd::String & host, const gd::String & uri, const gd::String & outputfilename ) { // Separate the host and the port number auto hostInfo = host.Split(U':'); if(hostInfo.size() < 2) return; //Invalid address (there should be two elements: "http" and "//the.domain.com") // Create Http sf::Http http; http.setHost(hostInfo[0].ToUTF8() + ":" + hostInfo[1].ToUTF8(), hostInfo.size() > 2 ? hostInfo[2].To<unsigned short>() : 0); // Create request sf::Http::Request Request; Request.setMethod(sf::Http::Request::Get); Request.setUri(uri.ToUTF8()); // Send request & Get response sf::Http::Response datas = http.sendRequest(Request); ofstream ofile(outputfilename.ToLocale().c_str(), ios_base::binary); if ( ofile.is_open() ) { ofile.write(datas.getBody().c_str(),datas.getBody().size()); ofile.close(); return; } cout << "Downloading file : Unable to open output file " << outputfilename; return; }
bool GD_API FileExists( const gd::String & file ) { TiXmlDocument doc; if ( !doc.LoadFile(file.ToLocale().c_str()) && doc.ErrorId() == 2) return false; return true ; }
bool NativeFileSystem::WriteToFile(const gd::String & filename, const gd::String & content) { std::ofstream file( filename.ToLocale().c_str() ); if ( file.is_open() ) { file << content.ToUTF8(); file.close(); return true; } return false; }
void HttpServer::Run(gd::String indexDirectory) { //Some options ( Last option must be NULL ) std::string indexDirectoryLocale = indexDirectory.ToLocale(); const char *options[] = {"listening_ports", "2828", "document_root", indexDirectoryLocale.c_str(), NULL}; //Setup callbacks, i.e. nothing to do :) struct mg_callbacks callbacks; memset(&callbacks, 0, sizeof(callbacks)); ctx = mg_start(&callbacks, NULL, options); }
void GD_EXTENSION_API CaptureScreen( RuntimeScene & scene, const gd::String & destFileName, const gd::String & destImageName ) { if ( !scene.renderWindow ) return; sf::Image capture = scene.renderWindow->capture(); if ( !destFileName.empty() ) capture.saveToFile(destFileName.ToLocale()); if ( !destImageName.empty() && scene.GetImageManager()->HasLoadedSFMLTexture(destImageName) ) { std::shared_ptr<SFMLTextureWrapper> sfmlTexture = scene.GetImageManager()->GetSFMLTexture(destImageName); sfmlTexture->image = capture; sfmlTexture->texture.loadFromImage(sfmlTexture->image); //Do not forget to update the associated texture } }
/** * Show a message box with Yes/No buttons */ void GD_EXTENSION_API ShowYesNoMsgBox( RuntimeScene & scene, gd::Variable & variable, const gd::String & message, const gd::String & title ) { sf::Clock timeSpent; gd::String result; //Display the box #if defined(WINDOWS) if( MessageBoxW(NULL, message.ToWide().c_str(), title.ToWide().c_str(), MB_ICONQUESTION | MB_YESNO) == IDYES) result = "yes"; else result = "no"; #endif #if defined(LINUX) || defined(MACOS) nw::YesNoMsgBox dialog(title.ToLocale(), message.ToLocale(), result.Raw()); dialog.wait_until_closed(); #endif scene.GetTimeManager().NotifyPauseWasMade(timeSpent.getElapsedTime().asMicroseconds());//Don't take the time spent in this function in account. //Update the variable variable.SetString(result); //Can only be "yes" or "no", no need to encode in UTF8 }
std::shared_ptr<gd::Platform> PlatformLoader::LoadPlatformInManager(gd::String fullpath) { std::cout << "Loading platform " << fullpath << "..." << std::endl; Handle platformHdl = OpenLibrary(fullpath.ToLocale().c_str()); //Use the system locale for filepath if (platformHdl == NULL) { gd::String error = DynamicLibraryLastError(); cout << "Loading of "<< fullpath <<" failed." << endl; cout << "Error returned : \"" << error << "\"" << endl; #if defined(GD_IDE_ONLY) && !defined(GD_NO_WX_GUI) wxString userMsg = _("Platform ") + fullpath + _(" could not be loaded.\nContact the developer for more information.\n\nDetailed log:\n") + error; wxMessageBox(userMsg, _("Platform not compatible"), wxOK | wxICON_EXCLAMATION); #endif } else { CreatePlatformFunPtr createFunPtr = (CreatePlatformFunPtr)GetSymbol(platformHdl, "CreateGDPlatform"); DestroyPlatformFunPtr destroyFunPtr = (DestroyPlatformFunPtr)GetSymbol(platformHdl, "DestroyGDPlatform"); if ( createFunPtr == NULL || destroyFunPtr == NULL ) { cout << "Loading of "<< fullpath <<" failed (no valid create/destroy functions)." << endl; CloseLibrary(platformHdl); #if defined(GD_IDE_ONLY) && !defined(GD_NO_WX_GUI) wxString userMsg = _("Platform ")+ fullpath + _(" could not be loaded.\nContact the developer for more information.\n\nDetailed log:\nNo valid create/destroy functions." ); wxMessageBox(userMsg, _("Platform not compatible"), wxOK | wxICON_EXCLAMATION); #endif } else { #if defined(GD_IDE_ONLY) && !defined(GD_NO_WX_GUI) gd::LocaleManager::Get()->AddCatalog(wxFileName(fullpath).GetName()); //In editor, load catalog associated with extension, if any. #endif std::shared_ptr<gd::Platform> platform(createFunPtr(), destroyFunPtr); std::cout << "Loading of " << fullpath << " done." << std::endl; gd::PlatformManager::Get()->AddPlatform(platform); std::cout << "Registration in platform manager of " << fullpath << " done." << std::endl; return platform; } } return std::shared_ptr<gd::Platform>(); }
void GD_EXTENSION_API OpenSFMLTextureFromFile( RuntimeScene & scene, const gd::String & fileName, const gd::String & imageName ) { //Get or create the texture in memory std::shared_ptr<SFMLTextureWrapper> newTexture; if ( !scene.GetImageManager()->HasLoadedSFMLTexture(imageName) ) newTexture = std::shared_ptr<SFMLTextureWrapper>(new SFMLTextureWrapper); else newTexture = scene.GetImageManager()->GetSFMLTexture(imageName); //Open the SFML image and the SFML texture newTexture->image.loadFromFile(fileName.ToLocale()); newTexture->texture.loadFromImage(newTexture->image); //Do not forget to update the associated texture scene.GetImageManager()->SetSFMLTextureAsPermanentlyLoaded(imageName, newTexture); }
long int ResourcesLoader::GetBinaryFileSize( const gd::String & filename) { if (resFile.ContainsFile(filename)) return resFile.GetFileSize(filename); else { ifstream file (filename.ToLocale().c_str(), ios::in|ios::binary|ios::ate); if (file.is_open()) { return file.tellg(); } } std::cout << "Binary file " << filename << " cannot be read. " << std::endl; return 0; }
sf::SoundBuffer ResourcesLoader::LoadSoundBuffer( const gd::String & filename ) { sf::SoundBuffer sbuffer; if (resFile.ContainsFile(filename)) { char* buffer = resFile.GetFile(filename); if (buffer==NULL) cout << "Failed to get the file of a sound buffer from resource file: " << filename << endl; if (!sbuffer.loadFromMemory(buffer, resFile.GetFileSize(filename))) cout << "Failed to load a sound buffer from resource file: " << filename << endl; } else if (!sbuffer.loadFromFile(filename.ToLocale())) cout << "Failed to load a sound buffer: " << filename << endl; return sbuffer; }
sf::Texture ResourcesLoader::LoadSFMLTexture(const gd::String & filename) { sf::Texture texture; if (resFile.ContainsFile(filename)) { char* buffer = resFile.GetFile(filename); if (buffer==NULL) cout << "Failed to get the file of a SFML texture from resource file: " << filename << endl; if (!texture.loadFromMemory(buffer, resFile.GetFileSize(filename))) cout << "Failed to load a SFML texture from resource file: " << filename << endl; } else if (!texture.loadFromFile(filename.ToLocale())) cout << "Failed to load a SFML texture: " << filename << endl; return texture; }
bool ProjectFileWriter::LoadFromJSONFile(gd::Project & project, const gd::String & filename) { std::ifstream ifs(filename.ToLocale().c_str()); if (!ifs.is_open()) { gd::String error = _( "Unable to open the file.") + _("Make sure the file exists and that you have the right to open the file."); gd::LogError(error); return false; } project.SetProjectFile(filename); project.SetDirty(false); std::string str((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>()); gd::SerializerElement rootElement = gd::Serializer::FromJSON(str); project.UnserializeFrom(rootElement); return true; }
bool ProjectFileWriter::SaveToJSONFile(const gd::Project & project, const gd::String & filename) { //Serialize the whole project gd::SerializerElement rootElement; project.SerializeTo(rootElement); //Write JSON to file gd::String str = gd::Serializer::ToJSON(rootElement); std::ofstream ofs(filename.ToLocale().c_str()); if (!ofs.is_open()) { gd::LogError( _( "Unable to save file ")+ filename + _("!\nCheck that the drive has enough free space, is not write-protected and that you have read/write permissions." ) ); return false; } ofs << str; ofs.close(); return true; }
sf::Http::Response::Status EventStoreDialog::FetchTemplate(gd::String id) { nameTxt->SetLabel("Loading the template..."); descriptionEdit->SetValue(""); gd::SafeYield::Do(); // Create request sf::Http Http(host.ToLocale(), port); sf::Http::Request request; request.setMethod(sf::Http::Request::Get); request.setUri("/events/"+id.ToLocale()); // Send the request sf::Http::Response response = Http.sendRequest(request, sf::seconds(2)); if (response.getStatus() == sf::Http::Response::Ok) loadedTemplate = Serializer::FromJSON(response.getBody()); return response.getStatus(); }
/** * Display an "open file" dialog */ void GD_EXTENSION_API ShowOpenFile( RuntimeScene & scene, gd::Variable & variable, const gd::String & title, gd::String filters ) { sf::Clock timeSpent; gd::String result; //Display the dialog #if defined(WINDOWS) //Process filters to match windows dialogs filters style. filters.Raw() = filters.Raw()+'\0'; std::replace(filters.Raw().begin(), filters.Raw().end(), '|', '\0'); OPENFILENAMEW toGetFileName; //Struct for the dialog wchar_t filePath[MAX_PATH]; _wgetcwd(filePath, MAX_PATH); ZeroMemory(&toGetFileName, sizeof(OPENFILENAMEW)); toGetFileName.lStructSize = sizeof(OPENFILENAMEW); toGetFileName.hwndOwner = NULL; toGetFileName.lpstrFile = filePath; toGetFileName.nMaxFile = MAX_PATH; toGetFileName.lpstrFilter = filters == "\0" ? NULL : filters.ToWide().c_str(); toGetFileName.nFilterIndex = 1; toGetFileName.Flags = OFN_PATHMUSTEXIST | OFN_NOCHANGEDIR;; if(GetOpenFileNameW(&toGetFileName) == TRUE) result = gd::String::FromWide(filePath); #endif #if defined(LINUX) || defined(MACOS) std::string strResult; nw::OpenFile * dialog = new nw::OpenFile(title.ToLocale(), true, strResult); dialog->wait_until_closed(); result = gd::String::FromLocale(strResult); #endif scene.GetTimeManager().NotifyPauseWasMade(timeSpent.getElapsedTime().asMicroseconds());//Don't take the time spent in this function in account. //Update the variable variable.SetString(result); }
std::pair<sf::Font *, char *> ResourcesLoader::LoadFont(const gd::String & filename) { if (resFile.ContainsFile(filename)) { char* buffer = resFile.GetFile(filename); size_t bufferSize = resFile.GetFileSize(filename); if (buffer==NULL) { cout << "Failed to get the file of a font from resource file:" << filename << endl; return std::make_pair((sf::Font*)NULL, (char*)NULL); } sf::Font * font = new sf::Font(); char * fontBuffer = new char[bufferSize]; memcpy(fontBuffer, buffer, bufferSize); if (!font->loadFromMemory(fontBuffer, bufferSize)) { cout << "Failed to load a font from resource file: " << filename << endl; delete font; delete fontBuffer; return std::make_pair((sf::Font*)NULL, (char*)NULL); } return std::make_pair(font, fontBuffer); } else { sf::Font * font = new sf::Font(); if (!font->loadFromFile(filename.ToLocale())) { cout << "Failed to load a font from a file: " << filename << endl; delete font; return std::make_pair<sf::Font*, char*>(NULL, NULL); } return std::make_pair(font, (char*)nullptr); } }
void ProjectFileWriter::ConvertANSIXMLFile(TiXmlHandle & hdl, TiXmlDocument & doc, const gd::String & filename) { //COMPATIBILITY CODE WITH ANSI GDEVELOP ( <= 3.6.83 ) #if defined(GD_IDE_ONLY) && !defined(GD_NO_WX_GUI) //There should not be any problem with encoding in compiled games //Get the declaration element TiXmlDeclaration * declXmlElement = hdl.FirstChild().ToNode()->ToDeclaration(); if(strcmp(declXmlElement->Encoding(), "UTF-8") != 0) { std::cout << "This is a legacy GDevelop project, checking if it is already encoded in UTF8..." << std::endl; //The document has not been converted for/saved by GDevelop UTF8, now, try to determine if the project //was saved on Linux and is already in UTF8 or on Windows and still in the locale encoding. bool isNotInUTF8 = false; std::ifstream docStream; docStream.open(filename.ToLocale(), std::ios::in); while( !docStream.eof() ) { std::string docLine; std::getline(docStream, docLine); if( !gd::String::FromUTF8(docLine).IsValid() ) { //The file contains an invalid character, //the file has been saved by the legacy ANSI Windows version of GDevelop // -> stop reading the file and start converting from the locale to UTF8 isNotInUTF8 = true; break; } } docStream.close(); //If the file is not encoded in UTF8, encode it if(isNotInUTF8) { std::cout << "The project file is not encoded in UTF8, conversion started... "; //Create a temporary file #if defined(WINDOWS) //Convert using the current locale wxString tmpFileName = wxFileName::CreateTempFileName(""); std::ofstream outStream; docStream.open(filename.ToLocale(), std::ios::in); outStream.open(tmpFileName, std::ios::out | std::ios::trunc); while( !docStream.eof() ) { std::string docLine; std::string convLine; std::getline(docStream, docLine); sf::Utf8::fromAnsi(docLine.begin(), docLine.end(), std::back_inserter(convLine)); outStream << convLine << '\n'; } outStream.close(); docStream.close(); #else //Convert using iconv command tool wxString tmpFileName = wxStandardPaths::Get().GetUserConfigDir() + "/gdevelop_converted_project"; gd::String iconvCall = gd::String("iconv -f LATIN1 -t UTF-8 \"") + filename.ToLocale() + "\" "; #if defined(MACOS) iconvCall += "> \"" + tmpFileName + "\""; #else iconvCall += "-o \"" + tmpFileName + "\""; #endif std::cout << "Executing " << iconvCall << std::endl; system(iconvCall.c_str()); #endif //Reload the converted file, forcing UTF8 encoding as the XML header is false (still written ISO-8859-1) doc.LoadFile(std::string(tmpFileName).c_str(), TIXML_ENCODING_UTF8); std::cout << "Finished." << std::endl; gd::LogMessage(_("Your project has been upgraded to be used with GDevelop 4.\nIf you save it, you won't be able to open it with an older version: please do a backup of your project file if you want to go back to GDevelop 3.")); } } #endif //END OF COMPATIBILITY CODE }
bool Music::OpenFromFile(const gd::String& filename) { #if defined(GD_IDE_ONLY) file = filename; #endif return music.openFromFile(filename.ToLocale()); }
/** * Execute a system-specific command */ void GD_API ExecuteCmd( const gd::String & cmd ) { system(cmd.ToLocale().c_str()); return; }
/** * Delete a file */ void GD_API GDDeleteFile( const gd::String & filename ) { remove(filename.ToLocale().c_str()); return; }
void GD_EXTENSION_API SaveSFMLTextureToFile( RuntimeScene & scene, const gd::String & fileName, const gd::String & imageName ) { if ( !scene.GetImageManager()->HasLoadedSFMLTexture(imageName) ) return; scene.GetImageManager()->GetSFMLTexture(imageName)->image.saveToFile(fileName.ToLocale()); }