Jump to content
  • 0

Adapt automatic backup Acis to Frozen


heladito

Question

hi guys! anyone can help me to adapt this code for jfrozen rev 1132?

 

Index: net.sf.l2j;Config.JAVA
===================================================================
--- net.sf.l2j;Config.JAVA (revision)
+++ net.sf.l2j;Config.JAVA (working copy)

+   /** Auto Save Data Base */
+   public static boolean ENABLE_BACKUP_BOOLEAN;
+   public static String NAME_DATA_BASE;


+   ENABLE_BACKUP_BOOLEAN = Boolean.parseBoolean(aCis.getProperty("AutoSaveDB", "True"));
+   NAME_DATA_BASE = aCis.getProperty("URL_DB", "aCis");




Index: Dev.AutoBackup;BackupDBSave.JAVA
===================================================================
--- Dev.AutoBackup;BackupDBSave.JAVA (revision)
+++ Dev.AutoBackup;BackupDBSave.JAVA (working copy)

+   package Dev.AutoBackup;
+
+   import java.io.BufferedReader;
+   import java.io.File;
+   import java.io.FileInputStream;
+   import java.io.FileOutputStream;
+   import java.io.IOException;
+   import java.io.InputStreamReader;
+   import java.net.URL;
+   import java.sql.Connection;
+   import java.sql.PreparedStatement;
+   import java.sql.ResultSet;
+   import java.text.DateFormat;
+   import java.text.SimpleDateFormat;
+   import java.util.Date;
+   import java.util.zip.ZipEntry;
+   import java.util.zip.ZipOutputStream;
+
+   import net.sf.l2j.commons.concurrent.ThreadPool;
+
+   import net.sf.l2j.Config;
+   import net.sf.l2j.L2DatabaseFactory;
+   import net.sf.l2j.util.Mysql;
+
+
+   /**
+    * @author COMBATE
+    *
+    * note to RESTORE
+    * Unzip the file
+    * Then go to database via navicat and run Execute SQL File
+    * Then declick the option "Run multiple queries in each execution" to avoid conflict with locks of tables
+    */
+   public class BackupDBSave
+   {
+       private String database_name = Config.NAME_DATA_BASE;
+       private boolean DEBUG_SYSTEM = false;
+       private long initializeAfterTime = 1000 * 60 * 60 * 1; // Start in 2 hour
+       private long checkEveryTime = 1000 * 60 * 60 * 1; // Every 6 hours
+    
+       protected BackupDBSave()
+       {
+           ThreadPool.scheduleAtFixedRate(() -> BackupDBToSql(), initializeAfterTime, checkEveryTime);
+        
+           System.out.println("Database Backup Manager: Loaded");
+       }
+
+       public void BackupDBToSql()
+       {
+           String pathOfMysql = "\"";
+        
+           Connection con = null;
+           PreparedStatement statement = null;
+           ResultSet rs = null;
+        
+           try
+           {
+               con = L2DatabaseFactory.getInstance().getConnection();
+               statement = con.prepareStatement("SELECT @@basedir");
+               rs = statement.executeQuery();
+            
+               while (rs.next())
+               {
+                   pathOfMysql += rs.getString(1);
+               }
+           }
+           catch (Exception e)
+           {
+               e.printStackTrace();
+           }
+           finally
+           {
+               Mysql.closeQuietly(con, statement, rs);
+           }
+        
+           if (pathOfMysql.isEmpty())
+           {
+               System.out.println("Error on backup database. Empty path of mysql.");
+               return;
+           }
+        
+           // Give the specific path (pathOfMysql out = C:\Program Files\MySQL\MySQL Server 5.7\)
+           pathOfMysql += "bin\\mysqldump" + "\"";
+        
+           if(DEBUG_SYSTEM) System.out.println("Path of mysql: " + pathOfMysql);
+        
+           // Initialize code for backup
+           try
+           {
+               // Section for path of system
+               URL applicationRootPathURL = getClass().getProtectionDomain().getCodeSource().getLocation();
+               File applicationRootPath = new File(applicationRootPathURL.getPath());
+               File myFile = new File(applicationRootPath.getParent());
+               File lastMyFile = new File(myFile.getParent());
+
+               String dbUser = Config.DATABASE_LOGIN;
+               String dbPass = Config.DATABASE_PASSWORD;
+            
+               String commandOfMysqlDump = " " + database_name + " --single-transaction -u" + dbUser + " -p" + dbPass + " --skip-create-options --skip-comments --disable-keys > ";
+            
+               /* NOTE: Creating Path Constraints for folder saving */
+               /* NOTE: Here the backup folder is created for saving inside it */
+               String folderPath = "backup";
+            
+               /* NOTE: Creating Folder if it does not exist */
+               File f1 = new File(folderPath);
+               f1.mkdir();
+            
+               /* NOTE: Creating Path Constraints for backup saving */
+               /* NOTE: Here the backup is saved in a folder called backup with the name backup.sql */
+               String pathUntilDirectory = (lastMyFile.getAbsolutePath() + "\\backup\\").replaceAll("%20", " ");
+               String savePath = ("\""+pathUntilDirectory + "backup.sql\"").replaceAll("%20", " ");
+
+               /* NOTE: Used to create a cmd command */
+               String commandToExecute = "cmd /c "+ pathOfMysql + commandOfMysqlDump + savePath;
+            
+               if (DEBUG_SYSTEM)
+               {
+                   System.out.println("Save path of sql file: " + savePath);
+                   System.out.println("Command To Execute: " + commandToExecute);
+               }
+            
+               /* NOTE: Executing the command here */
+               Process runtimeProcess = Runtime.getRuntime().exec(new String[] {"cmd", "/c", commandToExecute });
+            
+               if (DEBUG_SYSTEM)
+               {
+                   BufferedReader stdInput = new BufferedReader(new InputStreamReader(runtimeProcess.getInputStream()));
+                   BufferedReader stdError = new BufferedReader(new InputStreamReader(runtimeProcess.getErrorStream()));
+                
+                   // read the output from the command
+                   System.out.println("Here is the standard output of the command:\n");
+                   String s = null;
+                   while ((s = stdInput.readLine()) != null) {
+                       System.out.println(s);
+                   }
+                
+                   // read any errors from the attempted command
+                   System.out.println("Here is the standard error of the command (if any):\n");
+                   while ((s = stdError.readLine()) != null) {
+                       System.out.println(s);
+                   }
+               }
+            
+               int processComplete = runtimeProcess.waitFor();
+            
+               /* NOTE: processComplete=0 if correctly executed, will contain other values if not */
+               if (processComplete == 0)
+               {
+                   System.out.println("Backup to SQL Complete");
+                
+                   // Zip the sql file
+                   zipAFile(pathUntilDirectory);
+                
+                   // Delete the backup.sql file
+                   deleteAFile(savePath.replaceAll("\"", ""));
+               }
+               else
+               {
+                   System.out.println("Backup to SQL Failure");
+               }
+           }
+           catch (IOException | InterruptedException ex)
+           {
+               System.out.println("Error at Backuprestore" + ex.getMessage());
+           }
+       }
+    
+       @SuppressWarnings("resource")
+       private static void zipAFile(String pathToSave)
+       {
+           byte[] buffer = new byte[1024];
+        
+           try
+           {
+               DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH-mm-ss");
+               Date date = new Date();
+            
+               FileOutputStream fos = new FileOutputStream(pathToSave + "Backup_"+dateFormat.format(date)+".zip");
+               ZipOutputStream zos = new ZipOutputStream(fos);
+               ZipEntry ze = new ZipEntry("backup.sql");
+               zos.putNextEntry(ze);
+               FileInputStream in = new FileInputStream(pathToSave + "\\backup.sql");
+            
+               int len;
+               while ((len = in.read(buffer)) > 0)
+               {
+                   zos.write(buffer, 0, len);
+               }
+            
+               in.close();
+               zos.closeEntry();
+            
+               // remember close it
+               zos.close();
+            
+               System.out.println("Done the zip of backup.");
+            
+           }
+           catch (IOException ex)
+           {
+               ex.printStackTrace();
+           }
+        
+       }
+    
+       private static void deleteAFile(String path) {
+           try{
+               File file = new File(path);
+               System.out.println(file.delete() ? (file.getName() + " is deleted!") : ("Delete operation is failed."));
+            
+           }catch(Exception e){
+
+               e.printStackTrace();
+
+           }
+       }
+
+       public static BackupDBSave getInstance()
+       {
+           return SingletonHolder._instance;
+       }
+    
+       private static class SingletonHolder
+       {
+           protected static final BackupDBSave _instance = new BackupDBSave();
+       }
+   }
+    

Index: Dev.AutoBackup;Mysql.JAVA
===================================================================
--- Dev.AutoBackup;Mysql.JAVA (revision)
+++ Dev.AutoBackup;Mysql.JAVA (working copy)

+   package Dev.AutoBackup;
+
+
+   import java.sql.Connection;
+   import java.sql.PreparedStatement;
+   import java.sql.ResultSet;
+   import java.sql.SQLException;
+   import java.sql.Statement;
+   import java.util.logging.Logger;
+
+   import net.sf.l2j.L2DatabaseFactory;
+
+   /**
+    * @author COMBATE
+    *
+    */
+   public abstract class Mysql
+   {
+       private static final Logger _log = Logger.getLogger(Mysql.class.getName());
+
+       /**
+        * Performs a simple sql queries where unnecessary control parameters <BR>
+        * NOTE: In this method, the parameters passed are not valid for SQL-injection!
+        * @param db
+        * @param query
+        * @param vars
+        * @return
+        */
+       public static boolean setEx(L2DatabaseFactory db, String query, Object... vars)
+       {
+           Connection con = null;
+           Statement statement = null;
+           PreparedStatement pstatement = null;
+           boolean successed = true;
+        
+           try
+           {
+               if(db == null)
+                   db = L2DatabaseFactory.getInstance();
+
+               con = db.getConnection();
+               if(vars.length == 0)
+               {
+                   statement = con.createStatement();
+                   statement.executeUpdate(query);
+                   statement.close();
+               }
+               else
+               {
+                   pstatement = con.prepareStatement(query);
+                   setVars(pstatement, vars);
+                   pstatement.executeUpdate();
+                   pstatement.close();
+               }
+               con.close();
+           }
+           catch(Exception e)
+           {
+               _log.warning("Could not execute update '" + query + "': " + e);
+               e.printStackTrace();
+               successed = false;
+           }
+           finally
+           {
+               closeQuietly(con, pstatement);
+               closeQuietly(statement);
+           }
+           return successed;
+       }
+
+       public static void setVars(PreparedStatement statement, Object... vars) throws SQLException
+       {
+           Number n;
+           long long_val;
+           double double_val;
+           for(int i = 0; i < vars.length; i++)
+               if(vars[i] instanceof Number)
+               {
+                   n = (Number) vars[i];
+                   long_val = n.longValue();
+                   double_val = n.doubleValue();
+                   if(long_val == double_val)
+                       statement.setLong(i + 1, long_val);
+                   else
+                       statement.setDouble(i + 1, double_val);
+               }
+               else if(vars[i] instanceof String)
+                   statement.setString(i + 1, (String) vars[i]);
+       }
+
+       public static boolean set(String query, Object... vars)
+       {
+           return setEx(null, query, vars);
+       }
+
+       public static boolean set(String query)
+       {
+           return setEx(null, query);
+       }
+    
+       public static void closeQuietly(Connection conn)
+       {
+           try {
+               close(conn);
+           } catch (SQLException e) { // NOPMD
+               // quiet
+           }
+       }
+
+       public static void closeQuietly(Connection conn, Statement stmt, ResultSet rs) {
+
+           try {
+               closeQuietly(rs);
+           } finally {
+               try {
+                   closeQuietly(stmt);
+               } finally {
+                   closeQuietly(conn);
+               }
+           }
+       }
+    
+       public static void closeQuietly(Connection conn, Statement stmt)
+       {
+           try {
+               closeQuietly(stmt);
+           } finally {
+               closeQuietly(conn);
+           }
+       }
+
+       public static void closeQuietly(ResultSet rs) {
+           try {
+               close(rs);
+           } catch (SQLException e) { // NOPMD
+               // quiet
+           }
+       }
+
+       public static void closeQuietly(Statement stmt) {
+           try {
+               close(stmt);
+           } catch (SQLException e) { // NOPMD
+               // quiet
+           }
+       }
+
+       public static void close(Connection conn) throws SQLException {
+           if (conn != null) {
+               conn.close();
+           }
+       }
+
+       public static void close(ResultSet rs) throws SQLException {
+           if (rs != null) {
+               rs.close();
+           }
+       }
+
+       public static void close(Statement stmt) throws SQLException {
+           if (stmt != null) {
+               stmt.close();
+           }
+       }
+   }
+

Index: net.sf.l2j.gameserver;GameServer.JAVA
===================================================================
--- net.sf.l2j.gameserver;GameServer.JAVA (revision)
+++ net.sf.l2j.gameserver;GameServer.JAVA (working copy)

+   import Dev.AutoBackup.BackupDBSave;

+   StringUtil.printSection("DataBase Auto Save");
+   if (Config.ENABLE_BACKUP_BOOLEAN) {
+       BackupDBSave.getInstance();
+       LOGGER.info("[DataBase Auto Save]: Enabled");
+   }else
+   {
+       LOGGER.info("[DataBase Auto Save]: Desatived");
+   }

Index: gameserver.config.aCis.aCis.properties
===================================================================
--- gameserver.config.aCis.aCis.properties (revision)
+++ gameserver.config.aCis.aCis.properties (working copy)

# Enable Auto Save DataBase
AutoSaveDB = True

#Name DataBase
#Ex: l2jdb
URL_DB = aCis

 

Link to comment
Share on other sites

4 answers to this question

Recommended Posts

  • 0

Make backup database with runned server it's stupid idea. Backup will always is outdated. Better add to bat/sh scripts the dump task for saving database snapshot with relevant data.

Link to comment
Share on other sites

  • 0
5 hours ago, Rootware said:

Make backup database with runned server it's stupid idea. Backup will always is outdated. Better add to bat/sh scripts the dump task for saving database snapshot with relevant data.

Hi @Rootware ! thanks for answer. can, maybe if u have some time, tell me how can i do it that?

Link to comment
Share on other sites

  • 0

"mysql generate backup" on Google. And yes, it is kinda stupid to save during runtime since some data is stored only when server shutdowns, or when player shutdowns. If you save in middle of nowhere, then data integrity will be different than when server is currently closing.

 

Properly close your server, then use mysqldump.

 

It's the typical sort of code which "sounds cool", but is at best pointless, at worst dangerous (since you can save things in middle of something, and got no guarantee the actual engine properly ended).

 

An "ok" move would be to generate it only when server actually shutdowned, after all server operations ended.

Edited by Tryskell
Link to comment
Share on other sites

  • 0
5 hours ago, Tryskell said:

"mysql generate backup" on Google. And yes, it is kinda stupid to save during runtime since some data is stored only when server shutdowns, or when player shutdowns. If you save in middle of nowhere, then data integrity will be different than when server is currently closing.

 

Properly close your server, then use mysqldump.

 

It's the typical sort of code which "sounds cool", but is at best pointless, at worst dangerous (since you can save things in middle of something, and got no guarantee the actual engine properly ended).

 

An "ok" move would be to generate it only when server actually shutdowned, after all server operations ended.

@Tryskell hi man! so, you say make a sincronized backup with mysql when the server restart?

Link to comment
Share on other sites

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.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



  • Posts

    • DISCORD : utchiha_market telegram : https://t.me/utchiha_market SELLIX STORE : https://utchihamkt.mysellix.io/ Join our server for more products : https://discord.gg/hood-services https://campsite.bio/utchihaamkt  
    • Server Rates: » Xp 500x. » Sp 500x. » Aden 500x. » Drop 1x. » PartyXp 2x. » PartySp 2x. » Starting character level -61. Enchant rates: » Safe enchant +4. » Blessed and simple scrolls max enchant (+16). » Crystal scrolls max enchant (+20). » Simple enchant scrolls chance – 65%. » Blessed enchant scrolls chance – 100%. » Crystal enchant scrolls chance – 50% Augmentations: » Mid life stone skill chance – 5%. » High life stone skill chance – 10%. » Top life stone skill chance – 20%. » Augments 1+1 Unique features: » Main town – Giran » Automatic-Manual Potions. » Working 2 castle sieges. (Giran-Aden) » SPS cancel lasts 10 seconds and than buffs come back. » Stackable scrolls, lifestones, book of giants. » Unique pvp zone » More then 11 active raid bosses. » Wedding system. » Unique farming areas. » Npc skill enchanter. » Full npc buffer with auto buff. » Max count of buffs – 55. » Max subclasses – 4. » Free and no quest class change. » Free and no quest sub class. » Raid boss drop nobless item. » No weight limit. » Unique protection anti-hwy armor for archers/daggers etc. » Ingame password change. » Top pvp/pk/online ranks NPC. » Unique monsters & NPC. » Interlude retail skills. » Server up-time [24/7] [99]%. » Perfect class balance (all class can kill all class depending on players skill and setup knowledge,gear,augmentations). » Announcements on double kills triple kills etc. » Announcements on Grand Boss death , with the name of the killer as well as clan name of the player. » Information Npc in game with all servers infromations. Custom server gear : 1). Titanium Armor Lv.1 2). Epic Armor Lv.2 3). Epic Weapons-Kamikaze-Black S grade (Same Stats) 4). Demonic-Angelic Wings-Baium Hair-Custom Accessories (SameStats) 5). Custom Fighter/Mage tattoo Lv1-Lv2-Lv3 6). Shirt (STR,CON,INT +1) 7). Custom Shields Server Commands: .tvtjoin .tvtleave – Join or leave tvt event. .ctfjoin .ctfleave – Join or leave ctf event. .dmjoin .dmleave – Join of leave dm event. .online – current online players count. .repair – repairs stuck character in world. .menu – opens online menu panel. .exit – PVP zone exit in case you are bullied. .changepassword - Opens online menu then u can change ur password in game. .farm - Enable/disable autofarm Event system: » TVT event » CTF event » DM event » Tournament Event » Party Zone » Unique event shop. Olympiad game: » Retail olympiad game. » Competition period [1] week. » Olympiad start time [18:00] end [00:00] GMT+2. » New Heroes every Sunday.
    • Tomorrow grand opening lests go 🙂 
    • New season of Warfire X150 has been postponed to September 28th.
  • Topics

×
×
  • Create New...