/// <summary> /// Fügt eine entsprechende Datendatei in den entsprechenden Order: /// c-data /// r-data /// m-data /// </summary> /// <param name="client"></param> /// <param name="?"></param> public void AddFileToUpdateFolder(FTPSClient client, string folder, string relFilename, EFileType fileType) { //In Update Verzeichniss legen IList<DirectoryListItem> hashDirs=client.GetDirectoryList(folder+"/"); //Updatedatei anlegen string uniqueID=Various.GetUniqueID(); string uniqueIDSHA1=Hash.SHA1.HashString(uniqueID); string filenameLocal=FileSystem.TempPath+uniqueIDSHA1; List<string> lines=new List<string>(); lines.Add(relFilename); lines.Add(fileType.ToString()); File.WriteAllLines(filenameLocal, lines.ToArray()); //Updatedatei hochladen foreach(DirectoryListItem dli in hashDirs) { if(Globals.ClientID==dli.Name) continue; client.PutFile(filenameLocal, folder+"/"+dli.Name+"/"+uniqueIDSHA1); } //Log Globals.Log.Add(LogLevel.Information, "Updatedatei {0} wurde hochgeladen ({1}).", relFilename, folder); }
/// <summary> /// update.exe <source> <ftpServer> <username> <password> /// </summary> /// <param name="args"></param> static void Main(string[] args) { if(args.Length!=4) { Console.WriteLine("update.exe <sourceFolder> <ftpServer> <username> <password>"); return; } string sourceFolder=args[0]; string ftpServer=args[1]; string username=args[2]; string password=args[3]; //Dateien zum upload ermitteln List<string> filesToUpload=new List<string>(); filesToUpload.AddRange(FileSystem.GetFiles(sourceFolder, true, "*.*")); //FTP Verbindung aufbauen FTPSClient Client=new FTPSClient(); NetworkCredential networkCredential=new NetworkCredential(); networkCredential.Domain=ftpServer; networkCredential.UserName=username; networkCredential.Password=password; try { Client.Connect(networkCredential.Domain, networkCredential, ESSLSupportMode.ClearText); } catch(Exception exception) { Console.WriteLine("Fehler: {0}", exception.Message); return; } //Hashtabelle laden Dictionary<string, string> file2Hash=new Dictionary<string, string>(); string filenameHashTable=FileSystem.ApplicationPath+"update.hash"; if(FileSystem.ExistsFile(filenameHashTable)) { string[] lines=File.ReadAllLines(filenameHashTable); foreach(string line in lines) { string[] parts=line.Split(new char[] { '\t' }, StringSplitOptions.RemoveEmptyEntries); file2Hash.Add(parts[0], parts[1]); //Filename, SHA1 Hash } } //Dateien hochladen int saveCounter=0; int ftpRefreshCounter=0; for(int fileCounter=0; fileCounter<filesToUpload.Count; fileCounter++) { string file=filesToUpload[fileCounter]; //Überprüfung ob Datei hochgeladen werden muss bool fileMustBeUploaded=true; if(file2Hash.ContainsKey(file)) { string hashFile=Hash.SHA1.HashFile(file); if(file2Hash[file]==hashFile) { fileMustBeUploaded=false; } } //Datei hochloaden if(fileMustBeUploaded) { try { if(file2Hash.ContainsKey(file)) { //Bestehenden Key/Value modifizieren file2Hash[file]=Hash.SHA1.HashFile(file); } else { //Neuen Key anlegen file2Hash.Add(file, Hash.SHA1.HashFile(file)); } Console.WriteLine("({0}/{1}) - Lade Datei {2} hoch...", fileCounter+1, filesToUpload.Count, FileSystem.GetFilename(file)); string uploadf=FileSystem.GetRelativePath(file, sourceFolder); uploadf=uploadf.Replace('\\', '/'); string directory=FileSystem.GetPath(uploadf, true).Replace('\\', '/'); string[] dirParts=directory.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); if(directory!="") { string buildDirectory=""; for(int i=0; i<dirParts.Length; i++) { buildDirectory+=dirParts[i]+"/"; Client.EnsureDirectory(buildDirectory); } } saveCounter++; Client.PutFile(file, uploadf); } catch (Exception ex) { Console.WriteLine("({0}/{1}) - Fehler beim Upload von Datei {2}.", fileCounter+1, filesToUpload.Count, FileSystem.GetFilename(file)); Console.WriteLine("({0}/{1}) - Meldung {2}.", fileCounter+1, filesToUpload.Count, ex.ToString()); Client.Close(); return; } } else { Console.WriteLine("({0}/{1}) - Überspringe Datei {2}...", fileCounter+1, filesToUpload.Count, FileSystem.GetFilename(file)); } if(saveCounter>100) { saveCounter=0; SaveHashFile(filenameHashTable, file2Hash); } //KeepAlive Pakete senden ftpRefreshCounter++; if(ftpRefreshCounter>10000) { ftpRefreshCounter=0; Client.KeepAlive(); } } Client.Close(); //Save hash file SaveHashFile(filenameHashTable, file2Hash); }
static void UpdateWorldmap(bool all, bool clearCache) { List<string> files=FileSystem.GetFiles(Globals.folder_data_maps, true, "*.tmx"); if(files==null) { Console.WriteLine("Es wurden keine Maps gefunden."); Console.WriteLine("Eventuell ist der Pfad des Repositories in der Konfigurationdatei falsch."); return; } string temp=FileSystem.TempPath+"Invertika Editor"+FileSystem.PathDelimiter; string tempFmMonsterSpreading=FileSystem.TempPath+"Invertika Editor"+FileSystem.PathDelimiter+"fm-monster-spreading"+FileSystem.PathDelimiter; string tempFmMusic=FileSystem.TempPath+"Invertika Editor"+FileSystem.PathDelimiter+"fm-music"+FileSystem.PathDelimiter; #region Bilderordner löschen und neu anlegen Console.WriteLine("Bereinige Bilderordner..."); FileSystem.RemoveDirectory(temp, true); FileSystem.CreateDirectory(temp, true); FileSystem.CreateDirectory(tempFmMonsterSpreading, true); FileSystem.CreateDirectory(tempFmMusic, true); #endregion #region Bilder berechnen //int debug=0; foreach(string i in files) { Console.WriteLine("Überprüfe für Map {0} auf Aktualisierung...", FileSystem.GetFilename(i)); GC.Collect(2); //Nur sichtbare Weltkarte rendern. if(!all) { Map map=new Map(0, FileSystem.GetFilenameWithoutExt(i)); //if(map.MapType=="iw") continue; //if(map.MapType=="uw") continue; if(map.MapType=="ow") { if(map.X>=-7&&map.X<=7&&map.Y>=-7&&map.Y<=7) { //nichts tun (sprich rendern) } else { continue; } } } //Hashvergleich string text=File.ReadAllText(i); string textHash=Hash.SHA1.HashString(text); string xmlPath="xml.CalcMapImages."+FileSystem.GetFilenameWithoutExt(i); string xmlHash; try { xmlHash=Globals.Options.GetElementAsString(xmlPath); } catch { xmlHash=""; } //xmlHash=""; //DEBUG if(xmlHash=="") { Globals.Options.WriteElement("xml.CalcMapImages."+FileSystem.GetFilenameWithoutExt(i), textHash); } else { Globals.Options.WriteElement(xmlPath, textHash); } if(clearCache==false) { if(textHash==xmlHash) continue; } //Karte berechnen Console.WriteLine("Berechne Bilder für Map {0}", FileSystem.GetFilename(i)); TMX file=new TMX(i); Graphic pic=file.Render(); int imageSizeOriginalWidth=(int)pic.Width; int imageSizeOriginalHeight=(int)pic.Height; double imageVerhaeltnis=imageSizeOriginalWidth/(double)imageSizeOriginalHeight; //int imageSize=6400; int imageSize=800; pic=pic.Resize(imageSize, (int)(imageSize/imageVerhaeltnis)); bool next=true; while(next) { string fn=FileSystem.GetFilenameWithoutExt(i); string fnNumeric=temp+fn+"-"+imageSize+".png"; pic.SaveToFile(fnNumeric); //Featuremap Monster Spreading string fnMonsterSpreading=tempFmMonsterSpreading+fn+"-"+imageSize+".png"; Imaging.SaveFeatureMapMonsterSpreading(Globals.folder_data, fnMonsterSpreading, pic, file); //Featuremap Music string fnMusic=tempFmMusic+fn+"-"+imageSize+".png"; SaveFeatureMapMusic(fnMusic, pic, file); switch(imageSize) { //case 6400: // { // imageSize=1600; // break; // } //case 100: // { // //Minimap zusätzlich speichern // string fnMinimap=Globals.folder_clientdata_graphics_minimaps+fn+".png"; // pic.SaveToFile(fnMinimap); // break; // } case 10: { next=false; break; } } imageSize=GetNextImageSize(imageSize); pic=pic.Resize(imageSize, (int)(imageSize/imageVerhaeltnis)); GC.Collect(3); } //Debug //debug++; //if(debug>5) break; } #endregion #region Bilder per FTP hochladen List<string> filesToUpload=new List<string>(); filesToUpload.AddRange(FileSystem.GetFiles(temp, true, "*.png")); Console.WriteLine("Lade {0} Dateien hoch...", filesToUpload.Count); FTPSClient Client=new FTPSClient(); NetworkCredential networkCredential=new NetworkCredential(); networkCredential.Domain=Globals.Options.GetElementAsString("xml.Options.FTP.Worldmap.Server"); networkCredential.UserName=Globals.Options.GetElementAsString("xml.Options.FTP.Worldmap.User"); networkCredential.Password=Globals.Options.GetElementAsString("xml.Options.FTP.Worldmap.Password"); try { Client.Connect(networkCredential.Domain, networkCredential, ESSLSupportMode.ClearText); } catch(Exception exception) { Console.WriteLine("Fehler: {0}", exception.Message); return; } //Ordner für die Feature Maps if(!Client.Exists("fm-monster-spreading/ow-o0000-o0000-o0000-800.png")) //Monster Spreading { Client.CreateDirectory("fm-monster-spreading"); } if(!Client.Exists("fm-music/ow-o0000-o0000-o0000-800.png")) //Music { Client.CreateDirectory("fm-music"); } for(int i=0;i<filesToUpload.Count;i++) { string filename=filesToUpload[i]; try { Console.WriteLine("Lade Bild {0} hoch...", FileSystem.GetFilename(filename)); string uploadf=FileSystem.GetRelativePath(filename, temp); uploadf=uploadf.Replace('\\', '/'); //Client.UploadFile(i, uploadf); Client.PutFile(filename, uploadf); } catch { Console.WriteLine("Fehler beim Upload von Bild {0}.", FileSystem.GetFilename(filename)); Thread.Sleep(2000); Console.WriteLine("Stelle Verbindung wieder her...", FileSystem.GetFilename(filename)); Client.Connect(networkCredential.Domain, networkCredential, ESSLSupportMode.ClearText); i--; } } Client.Close(); #endregion Globals.Options.Save(); Console.WriteLine("Weltkarte geupdatet"); }
public void UpdateFromRemote(FTPSClient client, string syncFolder) { #region Removed List<FileReturn> filesToUpdate=GetFilesFromUpdateFolder(client, "r-data"); if(filesToUpdate.Count>0) { foreach(FileReturn fileReturn in filesToUpdate) { if(fileReturn.FileType==EFileType.File) { string localFilename=syncFolder+"/"+fileReturn.Filename; FileSystem.RemoveFile(localFilename); Globals.Log.Add(LogLevel.Information, "Lokal: Datei {0} wurde gelöscht (x-data).", fileReturn.Filename); } else if(fileReturn.FileType==EFileType.Directory) { throw new NotImplementedException(); } } } #endregion #region Created filesToUpdate=GetFilesFromUpdateFolder(client, "c-data"); if(filesToUpdate.Count>0) { foreach(FileReturn fileReturn in filesToUpdate) { if(fileReturn.FileType==EFileType.File) { string localFilename=syncFolder+"/"+fileReturn.Filename; client.GetFile("x-data/"+fileReturn.Filename, localFilename); Globals.Log.Add(LogLevel.Information, "Lokal: Datei {0} wurde erzeugt (x-data).", fileReturn.Filename); } else if(fileReturn.FileType==EFileType.Directory) { string localFilename=syncFolder+"/"+fileReturn.Filename; client.GetFile("x-data/"+fileReturn.Filename, localFilename); Globals.Log.Add(LogLevel.Information, "Lokal: Verzeichnis {0} wurde erzeugt (x-data).", fileReturn.Filename); } } } #endregion #region Modified filesToUpdate=GetFilesFromUpdateFolder(client, "m-data"); if(filesToUpdate.Count>0) { foreach(FileReturn fileReturn in filesToUpdate) { if(fileReturn.FileType==EFileType.File) { string localFilename=syncFolder+"/"+fileReturn.Filename; client.GetFile("x-data/"+fileReturn.Filename, localFilename); Globals.Log.Add(LogLevel.Information, "Lokal: Datei {0} wurde modifiziert (x-data).", fileReturn.Filename); } else if(fileReturn.FileType==EFileType.Directory) { throw new NotImplementedException(); } } } #endregion }
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) { //ServicePointManager.ServerCertificateValidationCallback=delegate //{ // return true; //}; RemoteCertificateValidationCallback certificateCallback=new RemoteCertificateValidationCallback(ValidateServerCertificate); string syncFolder=Globals.Options.GetElementAsString("xml.Options.Paths.SyncFolder"); string ftpServer=Globals.Options.GetElementAsString("xml.Options.FTP.Server"); string ftpUser=Globals.Options.GetElementAsString("xml.Options.FTP.User"); string ftpPassword=Globals.Options.GetElementAsString("xml.Options.FTP.Password"); string ftpProtocol=Globals.Options.GetElementAsString("xml.Options.FTP.Protocol"); if(FileSystem.ExistsDirectory(syncFolder)) { if(ftpServer!=""&&ftpUser!=""&ftpPassword!=""&ftpProtocol!="") { //Connect FTPSClient client=new FTPSClient(); //NetworkCredital NetworkCredential credential=new NetworkCredential(ftpUser, ftpPassword); //client.Connect(ftpServer, credential, ESSLSupportMode.ControlAndDataChannelsRequired); client.Connect(ftpServer, credential, ESSLSupportMode.ControlAndDataChannelsRequired, certificateCallback); #region Verzeichnisstruktur überprüfen und nach Bedarf anlegen //Test auf leeres Verzeichnis IList<DirectoryListItem> files=client.GetDirectoryList(); bool existXData=false; bool existHData=false; bool existLData=false; bool existCData=false; bool existMData=false; bool existRData=false; bool existCfsInfo=false; foreach(DirectoryListItem file in files) { if(file.IsDirectory) { switch(file.Name) { case "x-data": { existXData=true; break; } case "h-data": { existHData=true; break; } case "l-data": { existLData=true; break; } case "c-data": { existCData=true; break; } case "m-data": { existMData=true; break; } case "r-data": { existRData=true; break; } } } else //File { switch(file.Name) { case "cfsinfo": { existCfsInfo=true; break; } } } } //CfsInfo anlegen if(existCfsInfo==false) { List<string> version=new List<string>(); version.Add("1"); //Repository Version string versionFilenameLocal=FileSystem.TempPath+"cfsinfo-"+Various.GetTimeID(); File.WriteAllLines(versionFilenameLocal, version.ToArray()); client.PutFile(versionFilenameLocal, "cfsinfo"); } else //Version überprüfen { string versionFilenameLocal=FileSystem.TempPath+"cfsinfo-"+Various.GetTimeID(); client.GetFile("cfsinfo", versionFilenameLocal); string[] cfsinfo=File.ReadAllLines(versionFilenameLocal); int version=Convert.ToInt32(cfsinfo[0]); if(version!=1) { MessageBox.Show("CloudFileSync ist nicht mit der Version des Repositories kompatibel!", "Hinweis", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } } if(existXData==false) client.MakeDir("x-data"); //Datenordner if(existHData==false) client.MakeDir("h-data"); //Hashdaten if(existLData==false) client.MakeDir("l-data"); //Lockdaten if(existCData==false) client.MakeDir("c-data"); //Createdaten if(existMData==false) client.MakeDir("m-data"); //Modifieddaten if(existRData==false) client.MakeDir("r-data"); //Removedaten //Überprüfen ob meine Clientverzeichnisse existieren CheckAndCreateClientFolder(client, "c-data"); CheckAndCreateClientFolder(client, "m-data"); CheckAndCreateClientFolder(client, "r-data"); #endregion //Init Datenbestand (Sync) UpdateFromRemote(client, syncFolder); //Neu erzeugte oder geänderte Dateien ermitteln List<string> syncFolderFiles=FileSystem.GetFiles(syncFolder, true); //Neue Lokale Dateien hochladen foreach(string file in syncFolderFiles) { string relFilename=FileSystem.GetRelativePath(file, syncFolder, true); string hashRemote=GetHistoryHash(client, relFilename); string hashLocal=Hash.SHA1.HashFile(file); if(hashRemote!=hashLocal) { filesCreated.Add(file); } } //gelöschte Dateien ermitteln List<string> hashFiles=GetHashFiles(client); foreach(string hashFile in hashFiles) { string filenameToTest=FileSystem.GetPathWithPathDelimiter(syncFolder)+hashFile.Replace('\\', FileSystem.PathDelimiter); syncFolderFiles.Remove(filenameToTest); } foreach(string file in syncFolderFiles) { if(filesCreated.IndexOf(file)==-1) //Datei soll nicht hochgeladen werden, sondern wurde wirklich auf einem anderen Client gelöscht { string relFilename=FileSystem.GetRelativePath(file, syncFolder, true); FileSystem.RemoveFile(file); Globals.Log.Add(LogLevel.Information, "Lokal: Datei {0} wurde gelöscht.", relFilename); } } //FilesystemWatcher aktivieren fileSystemWatcher.Path=syncFolder; fileSystemWatcher.EnableRaisingEvents=true; #region Endlosschleife für Syncronisation while(true) { if(e.Cancel==true) return; List<string> fileToRemoveFromList=new List<string>(); //Dateien hochladen #region Created files lock(filesCreated) { foreach(string fileCreated in filesCreated) { string relFilename=FileSystem.GetRelativePath(fileCreated, syncFolder, true); relFilename=relFilename.Replace("\\", "/"); bool locked=GetFileLock(client, relFilename); if(locked) { if(FileSystem.IsDirectory(fileCreated)) //Directory { client.CreateDirectory("x-data/"+relFilename); fileToRemoveFromList.Add(fileCreated); Globals.Log.Add(LogLevel.Information, "Remote: Verzeichnis {0} wurde erstellt (x-data).", relFilename); //In Created Verzeichnisse legen AddFileToUpdateFolder(client, "c-data", relFilename, EFileType.Directory); //Globals.Log.Add(LogLevel.Information, "Updatedatei {0} wurde hochgeladen (c-data).", relFilename); } else //File { //Hashdatei ändern AddHistoryHash(client, fileCreated, relFilename); Globals.Log.Add(LogLevel.Information, "Remote: Hash für {0} wurde geändert (x-data).", relFilename); //Datei hochladen CreateFTPDirectories(client, "x-data/"+relFilename); client.PutFile(fileCreated, "x-data/"+relFilename); fileToRemoveFromList.Add(fileCreated); Globals.Log.Add(LogLevel.Information, "Remote: Datei {0} wurde hochgeladen (x-data).", relFilename); //In Created Verzeichnisse legen AddFileToUpdateFolder(client, "c-data", relFilename, EFileType.File); //Globals.Log.Add(LogLevel.Information, "Updatedatei {0} wurde hochgeladen (c-data).", relFilename); } } RemoveFileLock(client, relFilename); } foreach(string rFile in fileToRemoveFromList) { filesCreated.Remove(rFile); } } fileToRemoveFromList.Clear(); #endregion #region Changed Files lock(filesChanged) { foreach(string fileChanged in filesChanged) { string relFilename=FileSystem.GetRelativePath(fileChanged, syncFolder, true); relFilename=relFilename.Replace("\\", "/"); bool locked=GetFileLock(client, relFilename); if(locked) { if(FileSystem.IsDirectory(fileChanged)) //Directory { //Sollte bei Verzeichnissen ignoriert werden } else //File { //Hashdatei ändern AddHistoryHash(client, fileChanged, relFilename); Globals.Log.Add(LogLevel.Information, "Remote: Hash für {0} wurde geändert (x-data).", relFilename); //Datei hochladen client.PutFile(fileChanged, "x-data/"+relFilename); fileToRemoveFromList.Add(fileChanged); Globals.Log.Add(LogLevel.Information, "Remote: Datei {0} wurde modifiziert (x-data).", relFilename); //In Created Verzeichnisse legen AddFileToUpdateFolder(client, "m-data", relFilename, EFileType.File); } } RemoveFileLock(client, relFilename); } foreach(string rFile in fileToRemoveFromList) { filesChanged.Remove(rFile); } } fileToRemoveFromList.Clear(); #endregion #region Deleted Files lock(filesDeleted) { foreach(string fileDeleted in filesDeleted) { string relFilename=FileSystem.GetRelativePath(fileDeleted, syncFolder, true); relFilename=relFilename.Replace("\\", "/"); bool locked=GetFileLock(client, relFilename); if(locked) { if(FileSystem.IsDirectory(fileDeleted)) //Directory { client.RemoveDir(fileDeleted); //client.PutFile(fileChanged, "x-data/"+relFilename); fileToRemoveFromList.Add(fileDeleted); Globals.Log.Add(LogLevel.Information, "Remote: Verzeichnis {0} wurde gelöscht (x-data).", relFilename); //In Created Verzeichnisse legen AddFileToUpdateFolder(client, "r-data", relFilename, EFileType.File); } else //File { //Hashdatei löchen RemoveHistoryHash(client, relFilename); Globals.Log.Add(LogLevel.Information, "Remote: Hash für {0} wurde gelöscht (x-data).", relFilename); //Datei löschen client.DeleteFile("x-data/"+relFilename); fileToRemoveFromList.Add(fileDeleted); Globals.Log.Add(LogLevel.Information, "Remote: Datei {0} wurde gelöscht (x-data).", relFilename); //In Created Verzeichnisse legen AddFileToUpdateFolder(client, "r-data", relFilename, EFileType.File); } } RemoveFileLock(client, relFilename); } foreach(string rFile in fileToRemoveFromList) { filesDeleted.Remove(rFile); } } fileToRemoveFromList.Clear(); #endregion //Neue Dateien herunterladen bzw. gelöscht Dateien löschen UpdateFromRemote(client, syncFolder); //Halbe Sekunde warten Thread.Sleep(500); } #endregion //string fileInfo=Globals.Options.GetElementAsString("xml.Sync.Filesystem.Test.txt"); //client.PutFile("D:\\AlexFTPS_bin_1.0.2.zip", "xxx.xxx"); } } }
public string GetHistoryHash(FTPSClient client, string relFilename) { string fileNameFTP=relFilename.Replace("/", "\\"); fileNameFTP="h-data/"+fileNameFTP; if(client.Exists(fileNameFTP)) //Neuen Hash hinzufügen { string hashFilenameLocal=FileSystem.TempPath+FileSystem.GetFilename(fileNameFTP); client.GetFile(fileNameFTP, hashFilenameLocal); List<string> hashInfo=new List<string>(); hashInfo.AddRange(File.ReadAllLines(hashFilenameLocal)); return hashInfo[0]; } else //keine Hashdatei vorhanden { return ""; } }
public bool RemoveHistoryHash(FTPSClient client, string file) { file=file.Replace("/", "\\"); file="h-data/"+file; try { client.DeleteFile(file); return true; } catch { return false; } }
/// <summary> /// Gibt die Updatedateien eines Verzeichnisses zurück /// </summary> /// <param name="client"></param> /// <param name="folder"></param> /// <returns></returns> public List<FileReturn> GetFilesFromUpdateFolder(FTPSClient client, string folder) { List<FileReturn> ret=new List<FileReturn>(); //In Update Verzeichniss legen string updateFolder=folder+"/"+Globals.ClientID+"/"; IList<DirectoryListItem> updateFiles=client.GetDirectoryList(updateFolder); //TODO evt FTPException abfangen //Sicherheitspause falls gerade noch eine Datei angelegt wurde Thread.Sleep(500); //Updatedatei herunterladen und auswerten foreach(DirectoryListItem dli in updateFiles) { string filenameLocal=FileSystem.TempPath+dli.Name; client.GetFile(updateFolder+dli.Name, filenameLocal); string[] lines=File.ReadAllLines(filenameLocal); string filename=lines[0]; //Datei hinzufügen EFileType fileType=GetFileType(lines[1]); //Updatedatei löschen client.DeleteFile(updateFolder+dli.Name); } return ret; }
public List<string> GetHashFiles(FTPSClient client) { List<string> ret=new List<string>(); string hashFolder="h-data/"; IList<DirectoryListItem> hashFiles=client.GetDirectoryList(hashFolder); //TODO evt FTPException abfangen //Updatedatei herunterladen und auswerten foreach(DirectoryListItem dli in hashFiles) { ret.Add(dli.Name); } return ret; }
/// <summary> /// Holt einen Dateilock /// </summary> /// <param name="client"></param> /// <param name="file"></param> /// <returns></returns> public bool GetFileLock(FTPSClient client, string file) { file=file.Replace("/", "\\"); file="l-data/"+file; if(client.Exists(file)) //Auf Lock überprüfen { Thread.Sleep(500); if(client.Exists(file)) //Nochmal Auf Lock überprüfen { return false; //Lock konnte nicht geholt werden } } //Lock erzeugen string lockFilenameLocal=FileSystem.TempPath+FileSystem.GetFilename(file); string lockFilenameLocalCheck=FileSystem.TempPath+FileSystem.GetFilename(file)+".check"; List<string> lines=new List<string>(); lines.Add(Globals.ClientID); File.WriteAllLines(lockFilenameLocal, lines.ToArray()); client.PutFile(lockFilenameLocal, file); //Lock überprüfen client.GetFile(file, lockFilenameLocalCheck); string[] linesLockFile=File.ReadAllLines(lockFilenameLocalCheck); string lockID=linesLockFile[0]; if(Globals.ClientID==lockID) //Überprüfen ob das Lock ein Client Lock ist { return true; } else //Kein Client eigenes Lock { return false; } }
public void CreateFTPDirectories(FTPSClient client, string filename) { string path=FileSystem.GetPath(filename, true, false); string[] parts=path.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); string newPath=""; foreach(string part in parts) { newPath+=part; //client.GetDirectoryList if(client.Exists(newPath)==false) { client.EnsureDirectory(newPath); } newPath+="/"; } }
/// <summary> /// Schaut ob die Client Folder da sind bzw erstellt sie /// </summary> /// <param name="client"></param> /// <param name="dir"></param> public void CheckAndCreateClientFolder(FTPSClient client, string dir) { client.PushCurrentDirectory(); client.SetCurrentDirectory(dir); IList<DirectoryListItem> files=client.GetDirectoryList(); bool existClientDirectory=false; foreach(DirectoryListItem file in files) { if(file.IsDirectory) { if(file.Name==Globals.ClientID) { existClientDirectory=true; } } } if(existClientDirectory==false) { client.MakeDir(Globals.ClientID); } //client.SetCurrentDirectory(".."); client.PopCurrentDirectory(); }
/// <summary> /// Holt einen Dateilock /// </summary> /// <param name="client"></param> /// <param name="file"></param> /// <returns>true = New hash / </returns> public bool AddHistoryHash(FTPSClient client, string file, string relFilename) { string fileNameFTP=relFilename.Replace("/", "\\"); fileNameFTP="h-data/"+fileNameFTP; string fileHash=Hash.SHA1.HashFile(file); if(client.Exists(fileNameFTP)) //Neuen Hash hinzufügen { string hashFilenameLocal=FileSystem.TempPath+FileSystem.GetFilename(fileNameFTP); client.GetFile(fileNameFTP, hashFilenameLocal); List<string> hashInfo=new List<string>(); hashInfo.AddRange(File.ReadAllLines(hashFilenameLocal)); if(hashInfo[0]==fileHash) { return false; } else { hashInfo.Add(fileHash); File.WriteAllLines(hashFilenameLocal, hashInfo.ToArray()); client.PutFile(hashFilenameLocal, fileNameFTP); return true; } } else //Hash Datei erzeugen { List<string> hashFile=new List<string>(); hashFile.Add(fileHash); //Repository Version string hashFilenameLocal=FileSystem.TempPath+"hash-"+Various.GetTimeID(); File.WriteAllLines(hashFilenameLocal, hashFile.ToArray()); client.PutFile(hashFilenameLocal, fileNameFTP); return true; } }
static void Main(string[] args) { #region Init if(args.Length!=1) { Console.WriteLine("Argument fehlt:"); Console.WriteLine("z.B. mono autoupdate.exe autoupdate.xml"); return; } if(!FileSystem.ExistsFile(args[0])) { Console.WriteLine("Angegebene Datei existiert nicht."); return; } XmlData config; try { config=new XmlData(args[0]); } catch(Exception e) { Console.WriteLine("Konfiguration konnte nicht gelesen werden."); Console.WriteLine(e.ToString()); return; } Console.WriteLine("Autoupdate 1.2.1 wurde gestartet..."); string workfolder_original=Directory.GetCurrentDirectory(); string misc_servername=config.GetElementAsString("xml.misc.servername"); string ftp_data_server=config.GetElementAsString("xml.ftp.data.server"); string ftp_data_user=config.GetElementAsString("xml.ftp.data.user"); string ftp_data_password=config.GetElementAsString("xml.ftp.data.password"); bool irc_active=false; string irc_network=""; string irc_channel=""; if(config.GetElementAsString("xml.irc.active")!="") { irc_active=Convert.ToBoolean(config.GetElementAsString("xml.irc.active")); irc_network=config.GetElementAsString("xml.irc.network"); irc_channel=config.GetElementAsString("xml.irc.channel"); } string ftp_update_server=config.GetElementAsString("xml.ftp.update.server"); string ftp_update_user=config.GetElementAsString("xml.ftp.update.user"); string ftp_update_password=config.GetElementAsString("xml.ftp.update.password"); bool activate_data=Convert.ToBoolean(config.GetElementAsString("xml.activate.data")); bool activate_update=Convert.ToBoolean(config.GetElementAsString("xml.activate.update")); string path_temp_folder=FileSystem.GetPathWithPathDelimiter(config.GetElementAsString("xml.path.temp")); string path_repostiory_trunk=FileSystem.GetPathWithPathDelimiter(config.GetElementAsString("xml.path.repository.trunk")); string path_repostiory_server=path_repostiory_trunk+"server/"; string path_repostiory_data=path_repostiory_trunk+"data/"; string path_repostiory_data_scripts=path_repostiory_data+"/scripts/"; string path_repostiory_data_maps=path_repostiory_data+"/maps/"; string path_server_root=FileSystem.GetPathWithPathDelimiter(config.GetElementAsString("xml.path.server.root")); string path_server_data=path_server_root+"data/"; string path_server_data_scripts=path_server_data+"scripts/"; string path_server_data_maps=path_server_data+"maps/"; string path_server_start_script=path_server_root+"start-server.sh"; string path_server_stop_script=path_server_root+"stop-server.sh"; List<string> ExcludesDirsClient=new List<string>(); ExcludesDirsClient.Add("maps_templates"); ExcludesDirsClient.Add("maps_rules"); ExcludesDirsClient.Add("scripts"); ExcludesDirsClient.Add(".git"); List<string> ExcludesDirsServer=new List<string>(); ExcludesDirsServer.Add("maps_templates"); ExcludesDirsServer.Add("maps_rules"); ExcludesDirsServer.Add("graphics"); ExcludesDirsServer.Add("music"); ExcludesDirsServer.Add("sfx"); ExcludesDirsServer.Add(".git"); List<string> ExcludeFiles=new List<string>(); ExcludeFiles.Add("CMakeLists.txt"); #endregion #region IRC Message absetzen if(irc_active) { Console.WriteLine("Sende IRC Nachricht..."); irc.SendDelay=200; irc.AutoRetry=true; irc.ActiveChannelSyncing=true; string[] serverlist=new string[] { irc_network }; int port=6667; irc.Connect(serverlist, port); irc.Login("Autoupdate", "Autoupdate", 0, "AutoupdateIRC"); irc.RfcJoin("#invertika"); Random rnd=new Random(); string funkyWord=FunkyWords[rnd.Next(FunkyWords.Length)]; irc.SendMessage(SendType.Message, irc_channel, String.Format("Autoupdate wurde auf dem Server {0} gestartet. {1}", misc_servername, funkyWord)); new Thread(new ThreadStart(StartIRCListen)).Start(); } #endregion #region Repository updaten Console.WriteLine("Update Repository..."); Directory.SetCurrentDirectory(path_repostiory_data); ProcessHelpers.StartProcess("git", "pull", true); #endregion #region Server stoppen und Serverdaten löschen Console.WriteLine("Stoppe Server..."); Directory.SetCurrentDirectory(path_server_root); ProcessHelpers.StartProcess(path_server_stop_script, "", false); Console.WriteLine("Lösche Serverdaten..."); if(FileSystem.ExistsDirectory(path_server_data)) { FileSystem.RemoveDirectory(path_server_data, true, true); } Console.WriteLine("Lösche temporäres Verzeichnis..."); if(FileSystem.ExistsDirectory(path_temp_folder)) { FileSystem.RemoveDirectory(path_temp_folder, true, true); } #endregion #region Neue Serverdaten kopieren Directory.SetCurrentDirectory(path_server_root); Console.WriteLine("Kopiere neue Serverdaten..."); FileSystem.CreateDirectory(path_server_data_maps, true); FileSystem.CopyDirectory(path_repostiory_data, path_server_data, true, ExcludesDirsServer, ExcludeFiles); #endregion #region Clientdaten Console.WriteLine("Erzeuge Verzeichnis mit Clientdaten..."); string clientPath=path_temp_folder+"clientdata"+FileSystem.PathDelimiter; FileSystem.CreateDirectory(clientPath, true); FileSystem.CreateDirectory(clientPath+"data"+FileSystem.PathDelimiter, true); FileSystem.CopyDirectory(path_repostiory_data, clientPath+"data"+FileSystem.PathDelimiter, true, ExcludesDirsClient); List<string> clientDataFiles=FileSystem.GetFiles(clientPath, true); #endregion #region Clientdaten Update erzeugen und hochladen if(activate_update) { Console.WriteLine("Erstelle Zip Datei für Update..."); clientPath=clientPath+"data"+FileSystem.PathDelimiter; //Zip erstellen string zipFilename=path_temp_folder+"update-"+Various.GetTimeID()+".zip"; ZipFile z=ZipFile.Create(zipFilename); z.BeginUpdate(); int fivePercent=clientDataFiles.Count/20; int countZipFiles=0; foreach(string i in clientDataFiles) { countZipFiles++; if(FileSystem.GetExtension(i).ToLower()=="ogg") { Console.WriteLine("Datei {0} aus dem Update ausgeschlossen.", FileSystem.GetFilename(i)); continue; } string rel=FileSystem.GetRelativePath(i, clientPath, true); z.Add(i, rel); if(countZipFiles%fivePercent==0) { Console.Write("."); } } z.CommitUpdate(); z.Close(); //adler 32 ICSharpCode.SharpZipLib.Checksums.Adler32 adler=new ICSharpCode.SharpZipLib.Checksums.Adler32(); FileStream fs=new FileStream(zipFilename, FileMode.Open, FileAccess.Read); BinaryReader br=new BinaryReader(fs); byte[] textToHash=br.ReadBytes((int)fs.Length); adler.Reset(); adler.Update(textToHash); string adler32=String.Format("{0:x}", adler.Value); //Ressources string resFile=path_temp_folder+FileSystem.PathDelimiter+"resources2.txt"; StreamWriter sw=new StreamWriter(resFile); sw.WriteLine("{0} {1}", FileSystem.GetFilename(zipFilename), adler32); sw.Close(); //Newsfile string newsFile=path_temp_folder+FileSystem.PathDelimiter+"news.txt"; sw=new StreamWriter(newsFile); sw.WriteLine("##3 Serenity"); sw.WriteLine("##0"); sw.WriteLine("##0 Entwicklerserver des Invertika Projektes"); sw.WriteLine("##0 Automatisches Update wird nach jedem"); sw.WriteLine("##0 Commit im Repository vorgenommen."); sw.WriteLine("##0"); sw.WriteLine("##0 Status: in Betrieb"); sw.WriteLine("##0 Autoupdate vom {0}, {1} Uhr.", DateTime.Now.ToShortDateString(), DateTime.Now.ToShortTimeString()); sw.WriteLine("##0"); sw.WriteLine("##2 Das Invertika Development Team"); sw.WriteLine("##0"); sw.Close(); //Upload Console.WriteLine("Beginne FTP Upload der Update Dateien..."); FTPSClient Client=new FTPSClient(); NetworkCredential networkCredential=new NetworkCredential(); networkCredential.Domain=ftp_update_server; networkCredential.UserName=ftp_update_user; networkCredential.Password=ftp_update_password; Console.WriteLine("Verbinde mich mit FTP {0} mittels des Nutzers {1}.", ftp_update_server, ftp_update_user); Client.Connect(networkCredential.Domain, networkCredential, ESSLSupportMode.ClearText); List<string> currentFTPFiles=Client.GetDirectoryFiles(""); //TODO muss getestet werden Console.WriteLine("Lösche bestehende Updatedateien auf dem FTP Server..."); foreach(string i in currentFTPFiles) { if(i.IndexOf("update")!=-1) { Client.DeleteFile(i); } } Console.WriteLine("Lade Updatedatei hoch..."); Client.PutFile(zipFilename, FileSystem.GetFilename(zipFilename)); Client.PutFile(resFile, FileSystem.GetFilename(resFile)); Client.PutFile(newsFile, FileSystem.GetFilename(newsFile)); Client.Close(); } #endregion #region Server wieder starten Console.WriteLine("Starte Server neu..."); Directory.SetCurrentDirectory(path_server_root); ProcessHelpers.StartProcess(path_server_start_script, "", false); #endregion #region Clientdaten Data erzeugen und hochladen if(activate_data) { //Upload Console.WriteLine("Beginne FTP Upload der Data Dateien..."); FTPSClient ClientData=new FTPSClient(); NetworkCredential networkCredential=new NetworkCredential(); networkCredential.Domain=ftp_data_server; networkCredential.UserName=ftp_data_user; networkCredential.Password=ftp_data_password; Console.WriteLine("Verbinde mich mit FTP {0} mittels des Nutzers {1}.", ftp_data_server, ftp_data_user); ClientData.Connect(networkCredential.Domain, networkCredential, ESSLSupportMode.ClearText); Console.WriteLine("Lade Data Dateien hoch..."); foreach(string ftpfile in clientDataFiles) { string relativeName=FileSystem.GetRelativePath(ftpfile, clientPath); string dirToCreate=FileSystem.GetPath(relativeName, true); if(dirToCreate!="") { string[] folders=dirToCreate.Split(FileSystem.PathDelimiter); string dirTemp=""; foreach(string i in folders) { if(i.Trim()=="") continue; if(i=="/") continue; dirTemp+=i+FileSystem.PathDelimiter; try { ClientData.CreateDirectory(dirTemp); } catch { } } } Console.WriteLine("Datei {0} wird hochgeladen...", relativeName); ClientData.PutFile(ftpfile, relativeName); } ClientData.Close(); } #endregion #region IRC Message absetzen und aus Channel verschwinden if(irc_active) { Console.WriteLine("Sende IRC Nachricht..."); irc.SendMessage(SendType.Message, irc_channel, String.Format("Autoupdate wurde auf dem Server {0} beendet und manaserv wieder gestartet.", misc_servername)); Thread.Sleep(15000); irc.Disconnect(); } #endregion #region Ende Console.WriteLine("Autoupdate beenden"); #endregion }